96 lines
3.8 KiB
Go
96 lines
3.8 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"browser.local/platform/domain"
|
|
)
|
|
|
|
func (svc *CoreService) projectPluginLifecycleState(instance domain.ServerInstance, plugin domain.GamePlugin, capability string, result domain.JobExecutionResult, stamp time.Time) error {
|
|
if len(plugin.GameClientBridge.LifecycleProjections) == 0 {
|
|
return nil
|
|
}
|
|
for _, projection := range plugin.GameClientBridge.LifecycleProjections {
|
|
if !containsString(projection.Capabilities, capability) || len(projection.Target.FixedValues) == 0 {
|
|
continue
|
|
}
|
|
if len(projection.ProcessStates) > 0 && !containsString(projection.ProcessStates, strings.TrimSpace(result.ProcessState)) {
|
|
continue
|
|
}
|
|
if err := svc.applyPluginBulkProjection(instance, plugin, projection.Target, stamp); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (svc *CoreService) applyPluginBulkProjection(instance domain.ServerInstance, plugin domain.GamePlugin, target domain.GameClientBridgeBulkProjectionTargetDeclaration, stamp time.Time) error {
|
|
rows, err := svc.store.PluginDataRecords().List(domain.PluginDataFilter{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: target.Collection})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mutations := make([]domain.PluginDataMutation, 0, len(rows))
|
|
activityMutations := []domain.PluginDataMutation{}
|
|
for _, row := range rows {
|
|
if strings.TrimSpace(fmt.Sprint(row.Value[target.MatchField])) != target.MatchValue {
|
|
continue
|
|
}
|
|
value := mergePluginDataValues(row.Value, pluginBulkProjectionValues(target.FixedValues, stamp, row.Value, target.ObservedAtField))
|
|
mutations = append(mutations, domain.PluginDataMutation{Operation: domain.PluginDataMutationPut, Key: row.Key, Value: value})
|
|
if target.ActivityTarget != nil {
|
|
activity := pluginBulkActivityValue(*target.ActivityTarget, row.Value, stamp)
|
|
activityKey, keyErr := pluginDataRowKey(activity, target.ActivityTarget.UpsertKeys)
|
|
if keyErr != nil {
|
|
return keyErr
|
|
}
|
|
activityMutations = append(activityMutations, domain.PluginDataMutation{Operation: domain.PluginDataMutationPut, Key: activityKey, Value: activity})
|
|
}
|
|
}
|
|
if len(mutations) > 0 {
|
|
if _, err := svc.applyPluginDataTransaction(domain.PluginDataTransaction{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: target.Collection, Mutations: mutations}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if len(activityMutations) > 0 && target.ActivityTarget != nil {
|
|
if _, err := svc.applyPluginDataTransaction(domain.PluginDataTransaction{PluginID: plugin.ID, ServerInstanceID: instance.ID, Collection: target.ActivityTarget.Collection, Mutations: activityMutations}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func pluginBulkProjectionValues(fixedValues map[string]string, stamp time.Time, row map[string]any, observedAtField string) map[string]any {
|
|
value := make(map[string]any, len(fixedValues)+1)
|
|
for key, fixed := range fixedValues {
|
|
value[key] = renderPluginValueTemplate(fixed, row)
|
|
}
|
|
if observedAtField != "" {
|
|
value[observedAtField] = stamp.UTC().Format(time.RFC3339Nano)
|
|
}
|
|
return value
|
|
}
|
|
|
|
func pluginBulkActivityValue(target domain.GameClientBridgeBulkActivityTargetDeclaration, row map[string]any, stamp time.Time) map[string]any {
|
|
value := make(map[string]any, len(target.RowMappings)+len(target.FixedValues)+1)
|
|
for destination, source := range target.RowMappings {
|
|
value[destination] = row[source]
|
|
}
|
|
for key, fixed := range target.FixedValues {
|
|
value[key] = renderPluginValueTemplate(fixed, row)
|
|
}
|
|
if target.ObservedAtField != "" {
|
|
value[target.ObservedAtField] = stamp.UTC().Format(time.RFC3339Nano)
|
|
}
|
|
return value
|
|
}
|
|
|
|
func renderPluginValueTemplate(template string, row map[string]any) string {
|
|
result := template
|
|
for key, value := range row {
|
|
result = strings.ReplaceAll(result, "{{"+key+"}}", fmt.Sprint(value))
|
|
}
|
|
return result
|
|
}
|