All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
s2.spring.automate.ssm.persister.SsmAutomatePersister.kt Maven / Gradle / Ivy
package s2.spring.automate.ssm.persister
import com.fasterxml.jackson.databind.ObjectMapper
import f2.dsl.fnc.invoke
import f2.dsl.fnc.invokeWith
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.emitAll
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.toList
import s2.automate.core.context.AutomateContext
import s2.automate.core.context.InitTransitionAppliedContext
import s2.automate.core.context.TransitionAppliedContext
import s2.automate.core.persist.AutomatePersister
import s2.dsl.automate.S2Automate
import s2.dsl.automate.S2State
import s2.dsl.automate.model.WithS2Id
import s2.dsl.automate.model.WithS2State
import s2.dsl.automate.ssm.toSsm
import ssm.chaincode.dsl.model.Agent
import ssm.chaincode.dsl.model.SessionName
import ssm.chaincode.dsl.model.SsmContext
import ssm.chaincode.dsl.model.SsmSession
import ssm.chaincode.dsl.model.uri.ChaincodeUri
import ssm.chaincode.dsl.model.uri.toSsmUri
import ssm.data.dsl.features.query.DataSsmSessionGetQuery
import ssm.data.dsl.features.query.DataSsmSessionGetQueryFunction
import ssm.tx.dsl.features.ssm.SsmInitCommand
import ssm.tx.dsl.features.ssm.SsmSessionPerformActionCommand
import ssm.tx.dsl.features.ssm.SsmSessionStartCommand
import ssm.tx.dsl.features.ssm.SsmTxInitFunction
import ssm.tx.dsl.features.ssm.SsmTxSessionPerformActionFunction
import ssm.tx.dsl.features.ssm.SsmTxSessionStartFunction
class SsmAutomatePersister : AutomatePersister where
STATE : S2State,
ENTITY : WithS2State,
ENTITY : WithS2Id {
internal lateinit var ssmSessionStartFunction: SsmTxSessionStartFunction
internal lateinit var ssmSessionPerformActionFunction: SsmTxSessionPerformActionFunction
internal lateinit var dataSsmSessionGetQueryFunction: DataSsmSessionGetQueryFunction
internal lateinit var chaincodeUri: ChaincodeUri
internal lateinit var entityType: Class
internal lateinit var agentSigner: Agent
internal lateinit var objectMapper: ObjectMapper
internal var permisive: Boolean = false
override suspend fun load(automateContext: AutomateContext, id: ID & Any): ENTITY? {
val session = getSession(id.toString(), automateContext).item ?: return null
return objectMapper.readValue(session.state.details.public as String, entityType)
}
override suspend fun persist(
transitionContext: TransitionAppliedContext,
): ENTITY {
val entity = transitionContext.entity
val sessionName = entity.s2Id().toString()
val iteration = getIteration(transitionContext.automateContext, sessionName)
val context = SsmSessionPerformActionCommand(
action = transitionContext.msg::class.simpleName!!,
context = SsmContext(
session = entity.s2Id().toString(),
public = objectMapper.writeValueAsString(entity),
private = mapOf(),
iteration = iteration,
),
signerName = agentSigner.name,
chaincodeUri = chaincodeUri
)
ssmSessionPerformActionFunction.invoke(context)
return entity
}
override suspend fun persist(
transitionContext: InitTransitionAppliedContext
): ENTITY {
return persistInternal(flowOf(transitionContext)).toList().first().first
}
private suspend fun persistInternal(
transitionContexts: Flow>
): Flow> {
val collectedContexts = transitionContexts.toList()
// Create a list of SsmSessionStartCommands
val ssmStartCommands = collectedContexts.map { transitionContext ->
val entity = transitionContext.entity
val automate = transitionContext.automateContext.automate
SsmSessionStartCommand(
session = SsmSession(
ssm = automate.name,
session = entity.s2Id().toString(),
roles = mapOf(agentSigner.name to automate.transitions[0].role.name),
public = objectMapper.writeValueAsString(entity),
private = mapOf()
),
signerName = agentSigner.name,
chaincodeUri = chaincodeUri
)
}
// Invoke the ssmSessionStartFunction with all collected commands
ssmSessionStartFunction.invoke(ssmStartCommands.asFlow()).collect()
// Return a flow emitting each event from the collected contexts
return flow {
collectedContexts.forEach { transitionContext ->
emit(transitionContext.entity to transitionContext.event)
}
}
}
private suspend fun getIteration(automateContext: AutomateContext, sessionId: SessionName): Int {
val session = getSession(sessionId, automateContext)
return session.item?.state?.details?.iteration ?: return 0
}
private suspend fun getSession(
sessionId: SessionName,
automateContext: AutomateContext
) = DataSsmSessionGetQuery(
sessionName = sessionId,
ssmUri = chaincodeUri.toSsmUri(automateContext.automate.name)
).invokeWith(dataSsmSessionGetQueryFunction)
override suspend fun persistInitFlow(
transitionContext: Flow>
): Flow {
return persistInternal(transitionContext).map { it.second }
}
override suspend fun persistFlow(
transitionContexts: Flow>
): Flow = flow {
val collectedContexts = transitionContexts.toList()
val ssmCommands = collectedContexts.map { transitionContext ->
val entity = transitionContext.entity
val sessionName = entity.s2Id().toString()
val iteration = getIteration(transitionContext.automateContext, sessionName)
val withEventAsAction = transitionContext.automateContext.automate.withResultAsAction
val action = transitionContext.event?.takeIf { withEventAsAction } ?: transitionContext.msg
SsmSessionPerformActionCommand(
action = action::class.simpleName!!,
context = SsmContext(
session = entity.s2Id().toString(),
public = objectMapper.writeValueAsString(entity),
private = mapOf(),
iteration = iteration,
),
signerName = agentSigner.name,
chaincodeUri = chaincodeUri
)
}.toList()
ssmSessionPerformActionFunction.invoke(ssmCommands.asFlow()).collect()
collectedContexts.forEach { e ->
emit(e.event)
}
}
}