From d3f4d3e8420a8829cfe80072a322938687b5859c Mon Sep 17 00:00:00 2001 From: Tommy Hughes Date: Mon, 5 Feb 2024 14:27:37 -0600 Subject: [PATCH] [380] enhance SonataFlowClusterPlatform.spec Signed-off-by: Tommy Hughes --- .../sonataflowclusterplatform_types.go | 12 + api/v1alpha08/zz_generated.deepcopy.go | 27 +- ...taflow-operator.clusterserviceversion.yaml | 4 + ...taflow.org_sonataflowclusterplatforms.yaml | 13 + ...taflow.org_sonataflowclusterplatforms.yaml | 13 + ...taflow-operator.clusterserviceversion.yaml | 4 + .../clusterplatform/clusterplatform.go | 4 + controllers/clusterplatform/defaults.go | 55 ++++ controllers/clusterplatform/initialize.go | 4 + controllers/platform/services/services.go | 8 +- controllers/sonataflowplatform_controller.go | 19 +- .../sonataflowplatform_controller_test.go | 24 ++ operator.yaml | 13 + test/e2e/clusterplatform_test.go | 271 ++++++++++++++++++ test/e2e/platform_test.go | 11 +- .../dev/ephemeral/02-sonataflow_platform.yaml | 27 ++ .../dev/ephemeral/kustomization.yaml | 20 ++ ...3-sonataflow_callbackstatetimeouts.sw.yaml | 81 ++++++ .../01-sonataflow_clusterplatform.yaml | 25 ++ .../02-sonataflow_platform.yaml | 32 +++ .../cluster-wide-ephemeral/kustomization.yaml | 17 ++ .../02-sonataflow_platform.yaml | 30 ++ .../ephemeral-data-index/kustomization.yaml | 20 ++ ...3-sonataflow_callbackstatetimeouts.sw.yaml | 81 ++++++ .../02-sonataflow_platform.yaml | 30 ++ .../ephemeral-job-service/kustomization.yaml | 20 ++ ...3-sonataflow_callbackstatetimeouts.sw.yaml | 81 ++++++ test/yaml.go | 4 + 28 files changed, 937 insertions(+), 13 deletions(-) create mode 100644 controllers/clusterplatform/defaults.go create mode 100644 test/e2e/clusterplatform_test.go create mode 100644 test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml create mode 100644 test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml create mode 100644 test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml create mode 100644 test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml create mode 100644 test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml create mode 100644 test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml create mode 100644 test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml diff --git a/api/v1alpha08/sonataflowclusterplatform_types.go b/api/v1alpha08/sonataflowclusterplatform_types.go index b5063545a..d5205d9ca 100644 --- a/api/v1alpha08/sonataflowclusterplatform_types.go +++ b/api/v1alpha08/sonataflowclusterplatform_types.go @@ -31,8 +31,20 @@ type SonataFlowClusterPlatformSpec struct { // PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="PlatformRef" PlatformRef SonataFlowPlatformRef `json:"platformRef"` + // Capabilities defines which platform capabilities should be applied cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Capabilities" + Capabilities *SonataFlowClusterPlatformCapSpec `json:"capabilities,omitempty"` } +// SonataFlowClusterPlatformCapSpec defines which platform capabilities should be applied cluster-wide +type SonataFlowClusterPlatformCapSpec struct { + // Workflows defines which platform capabilities should be applied to workflows cluster-wide. + Workflows []WorkFlowCapability `json:"workflows,omitempty"` +} + +// +kubebuilder:validation:Enum=services +type WorkFlowCapability string + // SonataFlowPlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. type SonataFlowPlatformRef struct { // Name of the SonataFlowPlatform diff --git a/api/v1alpha08/zz_generated.deepcopy.go b/api/v1alpha08/zz_generated.deepcopy.go index cc7870ae5..75e8bf32e 100644 --- a/api/v1alpha08/zz_generated.deepcopy.go +++ b/api/v1alpha08/zz_generated.deepcopy.go @@ -870,7 +870,7 @@ func (in *SonataFlowClusterPlatform) DeepCopyInto(out *SonataFlowClusterPlatform *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } @@ -892,6 +892,26 @@ func (in *SonataFlowClusterPlatform) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SonataFlowClusterPlatformCapSpec) DeepCopyInto(out *SonataFlowClusterPlatformCapSpec) { + *out = *in + if in.Workflows != nil { + in, out := &in.Workflows, &out.Workflows + *out = make([]WorkFlowCapability, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SonataFlowClusterPlatformCapSpec. +func (in *SonataFlowClusterPlatformCapSpec) DeepCopy() *SonataFlowClusterPlatformCapSpec { + if in == nil { + return nil + } + out := new(SonataFlowClusterPlatformCapSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SonataFlowClusterPlatformList) DeepCopyInto(out *SonataFlowClusterPlatformList) { *out = *in @@ -949,6 +969,11 @@ func (in *SonataFlowClusterPlatformRefStatus) DeepCopy() *SonataFlowClusterPlatf func (in *SonataFlowClusterPlatformSpec) DeepCopyInto(out *SonataFlowClusterPlatformSpec) { *out = *in out.PlatformRef = in.PlatformRef + if in.Capabilities != nil { + in, out := &in.Capabilities, &out.Capabilities + *out = new(SonataFlowClusterPlatformCapSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SonataFlowClusterPlatformSpec. diff --git a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml index 95bceb338..cffce25e9 100644 --- a/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml +++ b/bundle/manifests/sonataflow-operator.clusterserviceversion.yaml @@ -190,6 +190,10 @@ spec: name: A SonataFlow Platform version: sonataflow.org/v1alpha08 specDescriptors: + - description: Capabilities defines which platform capabilities should be applied + cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + displayName: Capabilities + path: capabilities - description: PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. displayName: PlatformRef diff --git a/bundle/manifests/sonataflow.org_sonataflowclusterplatforms.yaml b/bundle/manifests/sonataflow.org_sonataflowclusterplatforms.yaml index 0d9a7b209..a5071d1e3 100644 --- a/bundle/manifests/sonataflow.org_sonataflowclusterplatforms.yaml +++ b/bundle/manifests/sonataflow.org_sonataflowclusterplatforms.yaml @@ -49,6 +49,19 @@ spec: description: SonataFlowClusterPlatformSpec defines the desired state of SonataFlowClusterPlatform properties: + capabilities: + description: Capabilities defines which platform capabilities should + be applied cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + properties: + workflows: + description: Workflows defines which platform capabilities should + be applied to workflows cluster-wide. + items: + enum: + - services + type: string + type: array + type: object platformRef: description: PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. diff --git a/config/crd/bases/sonataflow.org_sonataflowclusterplatforms.yaml b/config/crd/bases/sonataflow.org_sonataflowclusterplatforms.yaml index 537d06ba6..152750050 100644 --- a/config/crd/bases/sonataflow.org_sonataflowclusterplatforms.yaml +++ b/config/crd/bases/sonataflow.org_sonataflowclusterplatforms.yaml @@ -50,6 +50,19 @@ spec: description: SonataFlowClusterPlatformSpec defines the desired state of SonataFlowClusterPlatform properties: + capabilities: + description: Capabilities defines which platform capabilities should + be applied cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + properties: + workflows: + description: Workflows defines which platform capabilities should + be applied to workflows cluster-wide. + items: + enum: + - services + type: string + type: array + type: object platformRef: description: PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. diff --git a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml index 3442b0252..1f65bbedb 100644 --- a/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/sonataflow-operator.clusterserviceversion.yaml @@ -74,6 +74,10 @@ spec: name: A SonataFlow Platform version: sonataflow.org/v1alpha08 specDescriptors: + - description: Capabilities defines which platform capabilities should be applied + cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + displayName: Capabilities + path: capabilities - description: PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. displayName: PlatformRef diff --git a/controllers/clusterplatform/clusterplatform.go b/controllers/clusterplatform/clusterplatform.go index 6c1ffe45e..e9a8c86cd 100644 --- a/controllers/clusterplatform/clusterplatform.go +++ b/controllers/clusterplatform/clusterplatform.go @@ -30,6 +30,10 @@ import ( ctrl "sigs.k8s.io/controller-runtime/pkg/client" ) +const ( + PlatformServices operatorapi.WorkFlowCapability = "services" +) + // GetActiveClusterPlatform returns the currently installed active cluster platform. func GetActiveClusterPlatform(ctx context.Context, c ctrl.Client) (*operatorapi.SonataFlowClusterPlatform, error) { return getClusterPlatform(ctx, c, true) diff --git a/controllers/clusterplatform/defaults.go b/controllers/clusterplatform/defaults.go new file mode 100644 index 000000000..17657fc62 --- /dev/null +++ b/controllers/clusterplatform/defaults.go @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package clusterplatform + +import ( + "context" + + operatorapi "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" + "github.com/apache/incubator-kie-kogito-serverless-operator/container-builder/client" + "github.com/apache/incubator-kie-kogito-serverless-operator/log" + "k8s.io/klog/v2" + ctrl "sigs.k8s.io/controller-runtime/pkg/client" +) + +func configureDefaults(ctx context.Context, c client.Client, cp *operatorapi.SonataFlowClusterPlatform, verbose bool) error { + if cp.Spec.Capabilities == nil { + cp.Spec.Capabilities = &operatorapi.SonataFlowClusterPlatformCapSpec{ + Workflows: []operatorapi.WorkFlowCapability{PlatformServices}, + } + } + + return updateClusterPlatform(ctx, c, cp) +} + +func updateClusterPlatform(ctx context.Context, c client.Client, cp *operatorapi.SonataFlowClusterPlatform) error { + sfcPlatform := operatorapi.SonataFlowClusterPlatform{} + if err := c.Get(ctx, ctrl.ObjectKey{Namespace: cp.Namespace, Name: cp.Name}, &sfcPlatform); err != nil { + klog.V(log.E).ErrorS(err, "Error reading the Cluster Platform") + return err + } + + sfcPlatform.Spec = cp.Spec + if err := c.Update(ctx, &sfcPlatform); err != nil { + klog.V(log.E).ErrorS(err, "Error updating the Cluster Platform") + } + + return nil +} diff --git a/controllers/clusterplatform/initialize.go b/controllers/clusterplatform/initialize.go index 15a9b9f82..ac595e366 100644 --- a/controllers/clusterplatform/initialize.go +++ b/controllers/clusterplatform/initialize.go @@ -61,6 +61,10 @@ func (action *initializeAction) Handle(ctx context.Context, cPlatform *operatora } return nil } + + if err = configureDefaults(ctx, action.client, cPlatform, true); err != nil { + return err + } cPlatform.Status.Version = metadata.SpecVersion platformRef := cPlatform.Spec.PlatformRef diff --git a/controllers/platform/services/services.go b/controllers/platform/services/services.go index 33a275fd2..4b442c6a1 100644 --- a/controllers/platform/services/services.go +++ b/controllers/platform/services/services.go @@ -159,7 +159,7 @@ func (d DataIndexHandler) GetServiceBaseUrl() string { } func (d DataIndexHandler) GetLocalServiceBaseUrl() string { - return generateServiceURL(constants.KogitoServiceURLProtocol, d.platform.Namespace, d.GetServiceName()) + return GenerateServiceURL(constants.KogitoServiceURLProtocol, d.platform.Namespace, d.GetServiceName()) } func (d DataIndexHandler) GetEnvironmentVariables() []corev1.EnvVar { @@ -327,7 +327,7 @@ func (j JobServiceHandler) GetServiceBaseUrl() string { } func (j JobServiceHandler) GetLocalServiceBaseUrl() string { - return generateServiceURL(constants.JobServiceURLProtocol, j.platform.Namespace, j.GetServiceName()) + return GenerateServiceURL(constants.JobServiceURLProtocol, j.platform.Namespace, j.GetServiceName()) } func (j JobServiceHandler) GetEnvironmentVariables() []corev1.EnvVar { @@ -395,7 +395,7 @@ func (j JobServiceHandler) MergePodSpec(podSpec corev1.PodSpec) (corev1.PodSpec, func (j JobServiceHandler) GenerateServiceProperties() (*properties.Properties, error) { props := properties.NewProperties() - props.Set(constants.KogitoServiceURLProperty, generateServiceURL(constants.KogitoServiceURLProtocol, j.platform.Namespace, j.GetServiceName())) + props.Set(constants.KogitoServiceURLProperty, GenerateServiceURL(constants.KogitoServiceURLProtocol, j.platform.Namespace, j.GetServiceName())) props.Set(constants.JobServiceKafkaSmallRyeHealthProperty, "false") // add data source reactive URL if j.hasPostgreSQLConfigured() { @@ -447,7 +447,7 @@ func isServicesSet(platform *operatorapi.SonataFlowPlatform) bool { return platform != nil && platform.Spec.Services != nil } -func generateServiceURL(protocol string, namespace string, name string) string { +func GenerateServiceURL(protocol string, namespace string, name string) string { var serviceUrl string if len(namespace) > 0 { serviceUrl = fmt.Sprintf("%s://%s.%s", protocol, name, namespace) diff --git a/controllers/sonataflowplatform_controller.go b/controllers/sonataflowplatform_controller.go index c0ccd3991..a26db2fbe 100644 --- a/controllers/sonataflowplatform_controller.go +++ b/controllers/sonataflowplatform_controller.go @@ -203,11 +203,13 @@ func (r *SonataFlowPlatformReconciler) SonataFlowPlatformUpdateStatus(ctx contex }, } - tpsDI := services.NewDataIndexHandler(target) - tpsDI.SetServiceUrlInStatus(sfPlatform) + if sfcPlatform.Spec.Capabilities != nil && contains(sfcPlatform.Spec.Capabilities.Workflows, clusterplatform.PlatformServices) { + tpsDI := services.NewDataIndexHandler(target) + tpsDI.SetServiceUrlInStatus(sfPlatform) - tpsJS := services.NewJobServiceHandler(target) - tpsJS.SetServiceUrlInStatus(sfPlatform) + tpsJS := services.NewJobServiceHandler(target) + tpsJS.SetServiceUrlInStatus(sfPlatform) + } } else { target.Status.ClusterPlatformRef = nil } @@ -273,3 +275,12 @@ func (r *SonataFlowPlatformReconciler) platformRequests(ctx context.Context, sfc } return requests } + +func contains(slice []operatorapi.WorkFlowCapability, s operatorapi.WorkFlowCapability) bool { + for _, a := range slice { + if a == s { + return true + } + } + return false +} diff --git a/controllers/sonataflowplatform_controller_test.go b/controllers/sonataflowplatform_controller_test.go index 48c7b91c9..abfffb20e 100644 --- a/controllers/sonataflowplatform_controller_test.go +++ b/controllers/sonataflowplatform_controller_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/apache/incubator-kie-kogito-serverless-operator/api/v1alpha08" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/clusterplatform" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform/services" "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" "github.com/apache/incubator-kie-kogito-serverless-operator/test" @@ -753,6 +754,8 @@ func TestSonataFlowPlatformController(t *testing.T) { assert.Equal(t, kscp.Name, ksp.Status.ClusterPlatformRef.Name) assert.Equal(t, kscp.Spec.PlatformRef.Name, ksp.Status.ClusterPlatformRef.PlatformRef.Name) assert.Equal(t, kscp.Spec.PlatformRef.Namespace, ksp.Status.ClusterPlatformRef.PlatformRef.Namespace) + assert.NotNil(t, kscp.Spec.Capabilities) + assert.Contains(t, kscp.Spec.Capabilities.Workflows, clusterplatform.PlatformServices) assert.NotNil(t, ksp.Status.ClusterPlatformRef) assert.Nil(t, ksp.Status.ClusterPlatformRef.Services) @@ -802,5 +805,26 @@ func TestSonataFlowPlatformController(t *testing.T) { assert.NotNil(t, ksp2.Status.ClusterPlatformRef) assert.Equal(t, kscp.Spec.PlatformRef.Name, ksp2.Status.ClusterPlatformRef.PlatformRef.Name) assert.Equal(t, kscp.Spec.PlatformRef.Namespace, ksp2.Status.ClusterPlatformRef.PlatformRef.Namespace) + assert.Nil(t, ksp2.Status.ClusterPlatformRef.Services) + + kscp.Spec.Capabilities = &v1alpha08.SonataFlowClusterPlatformCapSpec{} + assert.NoError(t, cl.Update(context.TODO(), kscp)) + _, err = cr.Reconcile(context.TODO(), cReq) + if err != nil { + t.Fatalf("reconcile: (%v)", err) + } + + _, err = r.Reconcile(context.TODO(), req2) + if err != nil { + t.Fatalf("reconcile: (%v)", err) + } + + assert.NoError(t, cl.Get(context.TODO(), types.NamespacedName{Name: kscp.Name}, kscp)) + assert.NoError(t, cl.Get(context.TODO(), types.NamespacedName{Name: ksp2.Name, Namespace: ksp2.Namespace}, ksp2)) + + assert.NotNil(t, kscp.Spec.Capabilities) + assert.Empty(t, kscp.Spec.Capabilities.Workflows) + assert.NotNil(t, ksp2.Status.ClusterPlatformRef) + assert.Nil(t, ksp2.Status.ClusterPlatformRef.Services) }) } diff --git a/operator.yaml b/operator.yaml index 2869f7079..a4693bd67 100644 --- a/operator.yaml +++ b/operator.yaml @@ -413,6 +413,19 @@ spec: description: SonataFlowClusterPlatformSpec defines the desired state of SonataFlowClusterPlatform properties: + capabilities: + description: Capabilities defines which platform capabilities should + be applied cluster-wide. If nil, defaults to `capabilities.workflows["services"]` + properties: + workflows: + description: Workflows defines which platform capabilities should + be applied to workflows cluster-wide. + items: + enum: + - services + type: string + type: array + type: object platformRef: description: PlatformRef defines which existing SonataFlowPlatform's supporting services should be used cluster-wide. diff --git a/test/e2e/clusterplatform_test.go b/test/e2e/clusterplatform_test.go new file mode 100644 index 000000000..d0b545f69 --- /dev/null +++ b/test/e2e/clusterplatform_test.go @@ -0,0 +1,271 @@ +// Copyright 2024 Apache Software Foundation (ASF) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package e2e + +import ( + //nolint:golint + //nolint:revive + + "bytes" + "fmt" + "math/rand" + "os/exec" + "path/filepath" + "time" + + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/platform/services" + "github.com/apache/incubator-kie-kogito-serverless-operator/controllers/profiles/common/constants" + "github.com/apache/incubator-kie-kogito-serverless-operator/test" + "github.com/apache/incubator-kie-kogito-serverless-operator/test/utils" + + //nolint:golint + //nolint:revive + . "github.com/onsi/ginkgo/v2" + + //nolint:golint + //nolint:revive + . "github.com/onsi/gomega" +) + +var _ = Describe("Validate a clusterplatform", Ordered, func() { + + var ( + projectDir string + targetNamespace string + targetNamespace2 string + ) + + BeforeEach(func() { + targetNamespace = fmt.Sprintf("test-%d", rand.Intn(1024)+1) + cmd := exec.Command("kubectl", "create", "namespace", targetNamespace) + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + targetNamespace2 = fmt.Sprintf("test-%d", rand.Intn(1024)+1) + cmd = exec.Command("kubectl", "create", "namespace", targetNamespace2) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + }) + AfterEach(func() { + // Remove resources in test namespacs with no failure + if !CurrentSpecReport().Failed() { + if len(targetNamespace) > 0 { + cmd := exec.Command("kubectl", "delete", "namespace", targetNamespace, "--wait") + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + } + if len(targetNamespace2) > 0 { + cmd := exec.Command("kubectl", "delete", "namespace", targetNamespace2, "--wait") + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + } + } + }) + var _ = Context("with supporting services enabled", func() { + + DescribeTable("against a platform in a separate namespace", func(testcaseDir string, profile string, persistenceType string, withServices bool) { + By("Deploy the SonataFlowPlatform CR") + var manifests []byte + EventuallyWithOffset(1, func() error { + var err error + cmd := exec.Command("kubectl", "kustomize", filepath.Join(projectDir, + test.GetSonataFlowE2EPlatformServicesDirectory(), profile, clusterWideEphemeral)) + manifests, err = utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + cmd := exec.Command("kubectl", "create", "-n", targetNamespace, "-f", "-") + cmd.Stdin = bytes.NewBuffer(manifests) + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("Wait for SonatatFlowPlatform CR in " + targetNamespace + " to be ready") + // wait for platform to be ready + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "sfplatform", "-n", targetNamespace, "sonataflow-platform", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef}'") + returnedValue, _ := utils.Run(cmd) + println(string(returnedValue)) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("''"))) + + By("Evaluate status of SonataFlowClusterPlatform CR") + cmd = exec.Command("kubectl", "patch", "SonataFlowClusterPlatform", "cluster", "--type", "merge", "-p", `{"spec": {"platformRef": {"namespace": "`+targetNamespace+`"}}}`) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "SonataFlowClusterPlatform", "cluster", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + + if withServices { + By("Deploy SonatatFlowPlatform CR with services configured in " + targetNamespace2) + EventuallyWithOffset(1, func() error { + var err error + cmd := exec.Command("kubectl", "kustomize", filepath.Join(projectDir, + testcaseDir, profile, persistenceType)) + manifests, err = utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + cmd = exec.Command("kubectl", "create", "-n", targetNamespace2, "-f", "-") + cmd.Stdin = bytes.NewBuffer(manifests) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("Wait for SonatatFlowPlatform CR in " + targetNamespace2 + " to be ready") + // wait for platform to be ready + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Not(Equal([]byte("''")))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef.services}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("''"))) + } else { + EventuallyWithOffset(1, func() error { + var err error + cmd := exec.Command("kubectl", "kustomize", filepath.Join(projectDir, + testcaseDir, profile, persistenceType)) + manifests, err = utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + cmd = exec.Command("kubectl", "create", "-n", targetNamespace2, "-f", "-") + cmd.Stdin = bytes.NewBuffer(manifests) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("Wait for SonatatFlowPlatform CR in " + targetNamespace2 + " to be ready") + dataIndexServiceUrl := services.GenerateServiceURL(constants.KogitoServiceURLProtocol, targetNamespace, "sonataflow-platform-"+constants.DataIndexServiceName) + jobServiceUrl := services.GenerateServiceURL(constants.KogitoServiceURLProtocol, targetNamespace, "sonataflow-platform-"+constants.JobServiceName) + // wait for platform to be ready + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef.services.dataIndexRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + dataIndexServiceUrl + "'"))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef.services.jobServiceRef.url}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("'" + jobServiceUrl + "'"))) + } + cmd = exec.Command("kubectl", "delete", "SonataFlowClusterPlatform", "cluster", "--wait") + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + }, + Entry("without services configured", test.GetSonataFlowE2EPlatformNoServicesDirectory(), dev, ephemeral, false), + Entry("with services configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeral, true), + ) + + DescribeTable("against a platform in a separate namespace", func(testcaseDir string, profile string, persistenceType string) { + By("Deploy the SonataFlowPlatform CR") + var manifests []byte + EventuallyWithOffset(1, func() error { + var err error + cmd := exec.Command("kubectl", "kustomize", filepath.Join(projectDir, + test.GetSonataFlowE2EPlatformServicesDirectory(), profile, clusterWideEphemeral)) + manifests, err = utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + cmd := exec.Command("kubectl", "create", "-n", targetNamespace, "-f", "-") + cmd.Stdin = bytes.NewBuffer(manifests) + _, err := utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("Wait for SonatatFlowPlatform CR in " + targetNamespace + " to be ready") + // wait for platform to be ready + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "sfplatform", "-n", targetNamespace, "sonataflow-platform", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef}'") + returnedValue, _ := utils.Run(cmd) + println(string(returnedValue)) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("''"))) + + By("Evaluate status of SonataFlowClusterPlatform CR") + cmd = exec.Command("kubectl", "patch", "SonataFlowClusterPlatform", "cluster", "--type", "merge", "-p", `{"spec": {"platformRef": {"namespace": "`+targetNamespace+`"}}}`) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "SonataFlowClusterPlatform", "cluster", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + + EventuallyWithOffset(1, func() error { + var err error + cmd := exec.Command("kubectl", "kustomize", filepath.Join(projectDir, + testcaseDir, profile, persistenceType)) + manifests, err = utils.Run(cmd) + return err + }, time.Minute, time.Second).Should(Succeed()) + + cmd = exec.Command("kubectl", "create", "-n", targetNamespace2, "-f", "-") + cmd.Stdin = bytes.NewBuffer(manifests) + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + + By("Wait for SonatatFlowPlatform CR in " + targetNamespace2 + " to be ready") + // wait for platform to be ready + EventuallyWithOffset(1, func() error { + cmd = exec.Command("kubectl", "wait", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "--for", "condition=Succeed", "--timeout=5s") + _, err = utils.Run(cmd) + return err + }, 20*time.Minute, 5).Should(Succeed()) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Not(Equal([]byte("''")))) + EventuallyWithOffset(1, func() []byte { + cmd = exec.Command("kubectl", "get", "sfplatform", "-n", targetNamespace2, "sonataflow-platform", "-o", "jsonpath='{.status.clusterPlatformRef.services}'") + returnedValue, _ := utils.Run(cmd) + return returnedValue + }, 20*time.Minute, 5).Should(Equal([]byte("''"))) + + cmd = exec.Command("kubectl", "delete", "SonataFlowClusterPlatform", "cluster", "--wait") + _, err = utils.Run(cmd) + Expect(err).NotTo(HaveOccurred()) + }, + Entry("with only Data Index configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeralDataIndex), + Entry("with only Job Service configured", test.GetSonataFlowE2EPlatformServicesDirectory(), dev, ephemeralJobService), + ) + }) +}) diff --git a/test/e2e/platform_test.go b/test/e2e/platform_test.go index 90c485d75..00f51039c 100644 --- a/test/e2e/platform_test.go +++ b/test/e2e/platform_test.go @@ -36,10 +36,13 @@ import ( ) const ( - ephemeral = "ephemeral" - postgreSQL = "postgreSQL" - dev = "dev" - production = "prod" + ephemeral = "ephemeral" + postgreSQL = "postgreSQL" + dev = "dev" + production = "prod" + clusterWideEphemeral = "cluster-wide-ephemeral" + ephemeralDataIndex = "ephemeral-data-index" + ephemeralJobService = "ephemeral-job-service" ) var _ = Describe("Validate the persistence", Ordered, func() { diff --git a/test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml new file mode 100644 index 000000000..c86ba5127 --- /dev/null +++ b/test/testdata/platform/noservices/dev/ephemeral/02-sonataflow_platform.yaml @@ -0,0 +1,27 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + build: + template: + buildArgs: + - name: QUARKUS_EXTENSION + value: org.kie.kogito:kogito-addons-quarkus-jobs-knative-eventing:999-SNAPSHOT + config: + strategyOptions: + KanikoBuildCacheEnabled: "true" diff --git a/test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml b/test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml new file mode 100644 index 000000000..5441bfce8 --- /dev/null +++ b/test/testdata/platform/noservices/dev/ephemeral/kustomization.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resources: +- 02-sonataflow_platform.yaml + +sortOptions: + order: fifo + diff --git a/test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml new file mode 100644 index 000000000..8bc8a77de --- /dev/null +++ b/test/testdata/platform/noservices/dev/ephemeral/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -0,0 +1,81 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlow +metadata: + name: callbackstatetimeouts + annotations: + sonataflow.org/description: Callback State Timeouts Example k8s + sonataflow.org/version: 0.0.1 + sonataflow.org/profile: dev +spec: + flow: + start: PrintStartMessage + events: + - name: callbackEvent + source: '' + type: callback_event_type + functions: + - name: systemOut + type: custom + operation: sysout + states: + - name: PrintStartMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has started.\"}" + transition: CallbackState + - name: CallbackState + type: callback + action: + name: callbackAction + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has executed the callbackFunction.\"}" + eventRef: callbackEvent + transition: CheckEventArrival + timeouts: + eventTimeout: PT30S + - name: CheckEventArrival + type: switch + dataConditions: + - condition: "${ .eventData != null }" + transition: EventArrived + defaultCondition: + transition: EventNotArrived + - name: EventArrived + type: inject + data: + exitMessage: "The callback event has arrived." + transition: PrintExitMessage + - name: EventNotArrived + type: inject + data: + exitMessage: "The callback event has not arrived, and the timeout has overdue." + transition: PrintExitMessage + - name: PrintExitMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has finalized. \" + .exitMessage + \" eventData: \" + .eventData}" + end: true diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml b/test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml new file mode 100644 index 000000000..57e9735db --- /dev/null +++ b/test/testdata/platform/services/dev/cluster-wide-ephemeral/01-sonataflow_clusterplatform.yaml @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowClusterPlatform +metadata: + name: cluster +spec: + platformRef: + name: sonataflow-platform + namespace: test-ns diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml b/test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml new file mode 100644 index 000000000..c7048fff6 --- /dev/null +++ b/test/testdata/platform/services/dev/cluster-wide-ephemeral/02-sonataflow_platform.yaml @@ -0,0 +1,32 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + build: + template: + buildArgs: + - name: QUARKUS_EXTENSION + value: org.kie.kogito:kogito-addons-quarkus-jobs-knative-eventing:999-SNAPSHOT + config: + strategyOptions: + KanikoBuildCacheEnabled: "true" + services: + dataIndex: + enabled: true + jobService: + enabled: true diff --git a/test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml b/test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml new file mode 100644 index 000000000..b6e60d37b --- /dev/null +++ b/test/testdata/platform/services/dev/cluster-wide-ephemeral/kustomization.yaml @@ -0,0 +1,17 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resources: +- 01-sonataflow_clusterplatform.yaml +- 02-sonataflow_platform.yaml diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml b/test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml new file mode 100644 index 000000000..9c09a82d5 --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-data-index/02-sonataflow_platform.yaml @@ -0,0 +1,30 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + build: + template: + buildArgs: + - name: QUARKUS_EXTENSION + value: org.kie.kogito:kogito-addons-quarkus-jobs-knative-eventing:999-SNAPSHOT + config: + strategyOptions: + KanikoBuildCacheEnabled: "true" + services: + dataIndex: + enabled: false diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml b/test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml new file mode 100644 index 000000000..5441bfce8 --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-data-index/kustomization.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resources: +- 02-sonataflow_platform.yaml + +sortOptions: + order: fifo + diff --git a/test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml new file mode 100644 index 000000000..8bc8a77de --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-data-index/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -0,0 +1,81 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlow +metadata: + name: callbackstatetimeouts + annotations: + sonataflow.org/description: Callback State Timeouts Example k8s + sonataflow.org/version: 0.0.1 + sonataflow.org/profile: dev +spec: + flow: + start: PrintStartMessage + events: + - name: callbackEvent + source: '' + type: callback_event_type + functions: + - name: systemOut + type: custom + operation: sysout + states: + - name: PrintStartMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has started.\"}" + transition: CallbackState + - name: CallbackState + type: callback + action: + name: callbackAction + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has executed the callbackFunction.\"}" + eventRef: callbackEvent + transition: CheckEventArrival + timeouts: + eventTimeout: PT30S + - name: CheckEventArrival + type: switch + dataConditions: + - condition: "${ .eventData != null }" + transition: EventArrived + defaultCondition: + transition: EventNotArrived + - name: EventArrived + type: inject + data: + exitMessage: "The callback event has arrived." + transition: PrintExitMessage + - name: EventNotArrived + type: inject + data: + exitMessage: "The callback event has not arrived, and the timeout has overdue." + transition: PrintExitMessage + - name: PrintExitMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has finalized. \" + .exitMessage + \" eventData: \" + .eventData}" + end: true diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml b/test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml new file mode 100644 index 000000000..9e0bd3ad8 --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-job-service/02-sonataflow_platform.yaml @@ -0,0 +1,30 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlowPlatform +metadata: + name: sonataflow-platform +spec: + build: + template: + buildArgs: + - name: QUARKUS_EXTENSION + value: org.kie.kogito:kogito-addons-quarkus-jobs-knative-eventing:999-SNAPSHOT + config: + strategyOptions: + KanikoBuildCacheEnabled: "true" + services: + jobService: + enabled: false diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml b/test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml new file mode 100644 index 000000000..5441bfce8 --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-job-service/kustomization.yaml @@ -0,0 +1,20 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resources: +- 02-sonataflow_platform.yaml + +sortOptions: + order: fifo + diff --git a/test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml b/test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml new file mode 100644 index 000000000..8bc8a77de --- /dev/null +++ b/test/testdata/platform/services/dev/ephemeral-job-service/sonataflow/03-sonataflow_callbackstatetimeouts.sw.yaml @@ -0,0 +1,81 @@ +# Copyright 2024 Apache Software Foundation (ASF) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: sonataflow.org/v1alpha08 +kind: SonataFlow +metadata: + name: callbackstatetimeouts + annotations: + sonataflow.org/description: Callback State Timeouts Example k8s + sonataflow.org/version: 0.0.1 + sonataflow.org/profile: dev +spec: + flow: + start: PrintStartMessage + events: + - name: callbackEvent + source: '' + type: callback_event_type + functions: + - name: systemOut + type: custom + operation: sysout + states: + - name: PrintStartMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has started.\"}" + transition: CallbackState + - name: CallbackState + type: callback + action: + name: callbackAction + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has executed the callbackFunction.\"}" + eventRef: callbackEvent + transition: CheckEventArrival + timeouts: + eventTimeout: PT30S + - name: CheckEventArrival + type: switch + dataConditions: + - condition: "${ .eventData != null }" + transition: EventArrived + defaultCondition: + transition: EventNotArrived + - name: EventArrived + type: inject + data: + exitMessage: "The callback event has arrived." + transition: PrintExitMessage + - name: EventNotArrived + type: inject + data: + exitMessage: "The callback event has not arrived, and the timeout has overdue." + transition: PrintExitMessage + - name: PrintExitMessage + type: operation + actions: + - name: printSystemOut + functionRef: + refName: systemOut + arguments: + message: "${\"callback-state-timeouts: \" + $WORKFLOW.instanceId + \" has finalized. \" + .exitMessage + \" eventData: \" + .eventData}" + end: true diff --git a/test/yaml.go b/test/yaml.go index 80aed8f5a..5638e53a1 100644 --- a/test/yaml.go +++ b/test/yaml.go @@ -263,6 +263,10 @@ func GetSonataFlowE2EPlatformServicesDirectory() string { return filepath.Join(getTestDataDir(), "platform", "services") } +func GetSonataFlowE2EPlatformNoServicesDirectory() string { + return filepath.Join(getTestDataDir(), "platform", "noservices") +} + func GetSonataFlowE2EPlatformPersistenceSampleDataDirectory(subdir string) string { return filepath.Join(getTestDataDir(), "platform", "persistence", subdir) }