Skip to content

Commit

Permalink
kogito-serverless-operator: generate stable names for workflow resources
Browse files Browse the repository at this point in the history
Motivation:
Workflowproj generates a configmap per schema or subflow or specs in a
separate file for each one, however the name is not deterministic. In
one iteration you can get the specs in
01-configmap-FLOWNAME-resources.yaml and in the next iteration the same
content will go in 02-configmap-FLOWNAME-resources.yaml.

While the flow spec file will be updated accordingly and stay correct,
the behaviour generates lots of changes when tracking changes in git.

Modification:
This fix will make the generation behaviour deterministic by sorting the
resources iteration prior to generating them and also add the related
schemas|specs/subflows to the generated file name:

Result:
old schema configmap manifest:
0x-configmap-FLOWNAME-resources.yaml

new schema configmap manifest:
01-configmap-FLOWNAME-resources-schemas.yaml

old specs config map manifest:
0x-configmap-FLOWNAME-resources.yaml

new specs configmap manifest:
02-configmap-FLOWNAME-resources-specs.yaml

old subflows config map manifest:
0x-configmap-FLOWNAME-resources.yaml

new subflows configmap manifest:
01-configmap-FLOWNAME-resources-subflows.yaml

Also the name of the config map itself will get the name related to the
content like: '03-FLOWNAME-resources-schemas'

Signed-off-by: Roy Golan <[email protected]>
  • Loading branch information
rgolangh committed Jun 2, 2024
1 parent 326a19b commit b375a10
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
24 changes: 18 additions & 6 deletions packages/sonataflow-operator/workflowproj/workflowproj.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ package workflowproj
import (
"context"
"fmt"
"io"
"strings"

"github.com/pkg/errors"
"github.com/serverlessworkflow/sdk-go/v2/model"
"github.com/serverlessworkflow/sdk-go/v2/parser"
"io"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/kubernetes/scheme"
"sort"
"strings"

"github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api/metadata"
operatorapi "github.com/apache/incubator-kie-tools/packages/sonataflow-operator/api/v1alpha08"
Expand Down Expand Up @@ -264,13 +264,25 @@ func (w *workflowProjectHandler) parseRawResources() error {
}

resourceCount := 1
for path, resources := range w.rawResources {
paths := []string{}
for k := range w.rawResources {
paths = append(paths, k)
}
// Sort the paths to generate a deterministric list of files.
// Without sorting Golang map iteration on the strings is inconsistent because
// iteration order is not specified, so each time we could get 01-configmap-NAME-resources.yaml
// with schemas, and the next time with subflows, or other way round.
sort.Strings(paths)
for _, path := range paths {
// For better usability also convenience we add the 'path' from which the config map is taken
// so the config map file will have a meaningful name like
// 01-configmap-NAME-resources-specs.yaml or -subflow.yaml or -schemas.yaml
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Namespace: w.namespace, Name: fmt.Sprintf("%02d-%s-resources", resourceCount, w.name)},
ObjectMeta: metav1.ObjectMeta{Namespace: w.namespace, Name: fmt.Sprintf("%02d-%s-resources-%s", resourceCount, w.name, path)},
Data: map[string]string{},
}

for _, r := range resources {
for _, r := range w.rawResources[path] {
contents, err := io.ReadAll(r.contents)
if err != nil {
return err
Expand Down
10 changes: 5 additions & 5 deletions packages/sonataflow-operator/workflowproj/workflowproj_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func Test_Handler_WorkflowMinimalAndPropsAndSpec(t *testing.T) {
assert.Equal(t, "hello-props", proj.Properties.Name)
assert.NotEmpty(t, proj.Properties.Data)
assert.Equal(t, 1, len(proj.Resources))
assert.Equal(t, "01-hello-resources", proj.Resources[0].Name)
assert.Equal(t, "01-hello-resources-specs", proj.Resources[0].Name)
assert.Equal(t, proj.Workflow.Spec.Resources.ConfigMaps[0].ConfigMap.Name, proj.Resources[0].Name)

}
Expand Down Expand Up @@ -114,8 +114,8 @@ func Test_Handler_WorkflowMinimalAndPropsAndSpecAndGeneric(t *testing.T) {
assert.Equal(t, "hello-props", proj.Properties.Name)
assert.NotEmpty(t, proj.Properties.Data)
assert.Equal(t, 2, len(proj.Resources))
assert.Equal(t, "01-hello-resources", proj.Resources[0].Name)
assert.Equal(t, "02-hello-resources", proj.Resources[1].Name)
assert.Equal(t, "01-hello-resources-files", proj.Resources[0].Name)
assert.Equal(t, "02-hello-resources-specs", proj.Resources[1].Name)
assert.Equal(t, proj.Workflow.Spec.Resources.ConfigMaps[0].ConfigMap.Name, proj.Resources[0].Name)
assert.Equal(t, proj.Workflow.Spec.Resources.ConfigMaps[1].ConfigMap.Name, proj.Resources[1].Name)
data, err := getResourceDataWithFileName(proj.Resources, "myopenapi.json")
Expand Down Expand Up @@ -158,8 +158,8 @@ func Test_Handler_WorklflowServiceAndPropsAndSpec_SaveAs(t *testing.T) {

expectedFiles := []string{
"01-configmap_service-props.yaml",
"02-configmap_01-service-resources.yaml",
"03-configmap_02-service-resources.yaml",
"02-configmap_01-service-resources-files.yaml",
"03-configmap_02-service-resources-specs.yaml",
"04-sonataflow_service.yaml",
}
expectedKinds := []schema.GroupVersionKind{
Expand Down

0 comments on commit b375a10

Please sign in to comment.