You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by ri...@apache.org on 2023/09/27 18:46:31 UTC

[incubator-kie-kogito-serverless-operator] branch main updated: [KOGITO-9751] - :link: Bind kogito.service.url to the default CM app properties (#264)

This is an automated email from the ASF dual-hosted git repository.

ricardozanini pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-kogito-serverless-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new cd252acd [KOGITO-9751] - :link: Bind kogito.service.url to the default CM app properties (#264)
cd252acd is described below

commit cd252acd31554e3c2c88f6061bf210a0a07aea83
Author: Ricardo Zanini <15...@users.noreply.github.com>
AuthorDate: Wed Sep 27 15:46:27 2023 -0300

    [KOGITO-9751] - :link: Bind kogito.service.url to the default CM app properties (#264)
    
    Signed-off-by: Ricardo Zanini <za...@redhat.com>
---
 controllers/profiles/common/app_properties.go      | 102 +++++++++++++++++++++
 controllers/profiles/common/app_properties_test.go |  30 ++++++
 controllers/profiles/common/mutate_visitors.go     |  33 ++-----
 controllers/profiles/common/object_creators.go     |  13 +--
 .../profiles/common/object_creators_test.go        |   4 +-
 controllers/profiles/dev/object_creators_dev.go    |   4 -
 controllers/profiles/dev/states_dev.go             |   2 +-
 controllers/profiles/prod/deployment_handler.go    |   2 +-
 8 files changed, 147 insertions(+), 43 deletions(-)

diff --git a/controllers/profiles/common/app_properties.go b/controllers/profiles/common/app_properties.go
new file mode 100644
index 00000000..54586936
--- /dev/null
+++ b/controllers/profiles/common/app_properties.go
@@ -0,0 +1,102 @@
+// Copyright 2023 Red Hat, Inc. and/or its affiliates
+//
+// 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 common
+
+import (
+	"fmt"
+
+	"github.com/magiconair/properties"
+	"k8s.io/klog/v2"
+
+	operatorapi "github.com/kiegroup/kogito-serverless-operator/api/v1alpha08"
+	"github.com/kiegroup/kogito-serverless-operator/log"
+)
+
+const (
+	ConfigMapWorkflowPropsVolumeName = "workflow-properties"
+	kogitoServiceUrlProperty         = "kogito.service.url"
+)
+
+var immutableApplicationProperties = "quarkus.http.port=" + defaultHTTPWorkflowPortIntStr.String() + "\n" +
+	"quarkus.http.host=0.0.0.0\n" +
+	// We disable the Knative health checks to not block the dev pod to run if Knative objects are not available
+	// See: https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/eventing/consume-produce-events-with-knative-eventing.html#ref-knative-eventing-add-on-source-configuration
+	"org.kie.kogito.addons.knative.eventing.health-enabled=false\n" +
+	"quarkus.devservices.enabled=false\n" +
+	"quarkus.kogito.devservices.enabled=false\n"
+
+var _ AppPropertyHandler = &appPropertyHandler{}
+
+type AppPropertyHandler interface {
+	WithUserProperties(userProperties string) AppPropertyHandler
+	Build() string
+}
+
+type appPropertyHandler struct {
+	workflow   *operatorapi.SonataFlow
+	properties string
+}
+
+func (a *appPropertyHandler) WithUserProperties(userProperties string) AppPropertyHandler {
+	if len(userProperties) == 0 {
+		return a
+	}
+	props, propErr := properties.LoadString(userProperties)
+	if propErr != nil {
+		// can't load user's properties, ignore it
+		klog.V(log.D).InfoS("Can't load user's property", "workflow", a.workflow.Name, "namespace", a.workflow.Namespace, "properties", userProperties)
+		return a
+	}
+	defaultProps := properties.MustLoadString(a.properties)
+	// we overwrite with the defaults
+	props.Merge(defaultProps)
+	// Disable expansions since it's not our responsibility
+	// Property expansion means resolving ${} within the properties and environment context. Quarkus will do that in runtime.
+	props.DisableExpansion = true
+	a.properties = props.String()
+	return a
+}
+
+func (a *appPropertyHandler) Build() string {
+	return a.properties
+}
+
+// withKogitoServiceUrl adds the property kogitoServiceUrlProperty to the application properties.
+// See Service Discovery https://kubernetes.io/docs/concepts/services-networking/service/#dns
+func (a *appPropertyHandler) withKogitoServiceUrl() AppPropertyHandler {
+	if len(a.workflow.Namespace) > 0 {
+		a.properties = a.properties +
+			fmt.Sprintf("%s=%s.%s\n", kogitoServiceUrlProperty, a.workflow.Name, a.workflow.Namespace)
+	} else {
+		a.properties = a.properties +
+			fmt.Sprintf("%s=%s\n", kogitoServiceUrlProperty, a.workflow.Name)
+	}
+	return a
+}
+
+// NewAppPropertyHandler creates the default workflow configurations property handler
+func NewAppPropertyHandler(workflow *operatorapi.SonataFlow) AppPropertyHandler {
+	handler := &appPropertyHandler{
+		workflow:   workflow,
+		properties: immutableApplicationProperties,
+	}
+	return handler.withKogitoServiceUrl()
+}
+
+// ImmutableApplicationProperties immutable default application properties that can be used with any workflow based on Quarkus.
+// Alias for NewAppPropertyHandler(workflow).Build()
+func ImmutableApplicationProperties(workflow *operatorapi.SonataFlow) string {
+	return NewAppPropertyHandler(workflow).Build()
+}
diff --git a/controllers/profiles/common/app_properties_test.go b/controllers/profiles/common/app_properties_test.go
new file mode 100644
index 00000000..64291f5f
--- /dev/null
+++ b/controllers/profiles/common/app_properties_test.go
@@ -0,0 +1,30 @@
+// Copyright 2023 Red Hat, Inc. and/or its affiliates
+//
+// 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 common
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/kiegroup/kogito-serverless-operator/test"
+)
+
+func Test_appPropertyHandler_WithKogitoServiceUrl(t *testing.T) {
+	workflow := test.GetBaseSonataFlow("default")
+	props := ImmutableApplicationProperties(workflow)
+	assert.Contains(t, props, kogitoServiceUrlProperty)
+	assert.Contains(t, props, workflow.Name+"."+workflow.Namespace)
+}
diff --git a/controllers/profiles/common/mutate_visitors.go b/controllers/profiles/common/mutate_visitors.go
index cf371dcc..1519d897 100644
--- a/controllers/profiles/common/mutate_visitors.go
+++ b/controllers/profiles/common/mutate_visitors.go
@@ -15,7 +15,6 @@
 package common
 
 import (
-	"github.com/magiconair/properties"
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -88,39 +87,27 @@ func ServiceMutateVisitor(workflow *operatorapi.SonataFlow) MutateVisitor {
 	}
 }
 
-func WorkflowPropertiesMutateVisitor(workflow *operatorapi.SonataFlow, defaultProperties string) MutateVisitor {
+func WorkflowPropertiesMutateVisitor(workflow *operatorapi.SonataFlow) MutateVisitor {
 	return func(object client.Object) controllerutil.MutateFn {
 		return func() error {
 			if kubeutil.IsObjectNew(object) {
 				return nil
 			}
-			original, err := WorkflowPropsConfigMapCreator(workflow)
-			if err != nil {
-				return err
-			}
 			cm := object.(*corev1.ConfigMap)
-			cm.Labels = original.GetLabels()
-
+			cm.Labels = workflow.GetLabels()
 			_, hasKey := cm.Data[workflowproj.ApplicationPropertiesFileName]
 			if !hasKey {
 				cm.Data = make(map[string]string, 1)
-				cm.Data[workflowproj.ApplicationPropertiesFileName] = defaultProperties
-			} else {
-				props, propErr := properties.LoadString(cm.Data[workflowproj.ApplicationPropertiesFileName])
-				if propErr != nil {
-					// can't load user's properties, replace with default
-					cm.Data[workflowproj.ApplicationPropertiesFileName] = defaultProperties
-					return nil
-				}
-				originalProps := properties.MustLoadString(original.(*corev1.ConfigMap).Data[workflowproj.ApplicationPropertiesFileName])
-				// we overwrite with the defaults
-				props.Merge(originalProps)
-				// Disable expansions since it's not our responsibility
-				// Property expansion means resolving ${} within the properties and environment context. Quarkus will do that in runtime.
-				props.DisableExpansion = true
-				cm.Data[workflowproj.ApplicationPropertiesFileName] = props.String()
+				cm.Data[workflowproj.ApplicationPropertiesFileName] = ImmutableApplicationProperties(workflow)
+				return nil
 			}
 
+			// In the future, if this needs change, instead we can receive an AppPropertyHandler in this mutator
+			cm.Data[workflowproj.ApplicationPropertiesFileName] =
+				NewAppPropertyHandler(workflow).
+					WithUserProperties(cm.Data[workflowproj.ApplicationPropertiesFileName]).
+					Build()
+
 			return nil
 		}
 	}
diff --git a/controllers/profiles/common/object_creators.go b/controllers/profiles/common/object_creators.go
index 2af3e98d..15e5b7c0 100644
--- a/controllers/profiles/common/object_creators.go
+++ b/controllers/profiles/common/object_creators.go
@@ -37,8 +37,6 @@ const (
 	DefaultHTTPWorkflowPortName = "http"
 	defaultHTTPServicePort      = 80
 
-	ConfigMapWorkflowPropsVolumeName = "workflow-properties"
-
 	// Quarkus Health Check Probe configuration.
 	// See: https://quarkus.io/guides/smallrye-health#running-the-health-check
 
@@ -57,15 +55,6 @@ const (
 
 var defaultHTTPWorkflowPortIntStr = intstr.FromInt(DefaultHTTPWorkflowPortInt)
 
-// DefaultApplicationProperties default application properties added to every Workflow ConfigMap
-var DefaultApplicationProperties = "quarkus.http.port=" + defaultHTTPWorkflowPortIntStr.String() + "\n" +
-	"quarkus.http.host=0.0.0.0\n" +
-	// We disable the Knative health checks to not block the dev pod to run if Knative objects are not available
-	// See: https://kiegroup.github.io/kogito-docs/serverlessworkflow/latest/eventing/consume-produce-events-with-knative-eventing.html#ref-knative-eventing-add-on-source-configuration
-	"org.kie.kogito.addons.knative.eventing.health-enabled=false\n" +
-	"quarkus.devservices.enabled=false\n" +
-	"quarkus.kogito.devservices.enabled=false\n"
-
 // DeploymentCreator is an objectCreator for a base Kubernetes Deployments for profiles that need to deploy the workflow on a vanilla deployment.
 // It serves as a basis for a basic Quarkus Java application, expected to listen on http 8080.
 func DeploymentCreator(workflow *operatorapi.SonataFlow) (client.Object, error) {
@@ -204,5 +193,5 @@ func OpenShiftRouteCreator(workflow *operatorapi.SonataFlow) (client.Object, err
 
 // WorkflowPropsConfigMapCreator creates a ConfigMap to hold the external application properties
 func WorkflowPropsConfigMapCreator(workflow *operatorapi.SonataFlow) (client.Object, error) {
-	return workflowproj.CreateNewAppPropsConfigMap(workflow, DefaultApplicationProperties), nil
+	return workflowproj.CreateNewAppPropsConfigMap(workflow, ImmutableApplicationProperties(workflow)), nil
 }
diff --git a/controllers/profiles/common/object_creators_test.go b/controllers/profiles/common/object_creators_test.go
index f4f3e89b..32bca25d 100644
--- a/controllers/profiles/common/object_creators_test.go
+++ b/controllers/profiles/common/object_creators_test.go
@@ -38,7 +38,7 @@ func Test_ensureWorkflowPropertiesConfigMapMutator(t *testing.T) {
 	cm.SetResourceVersion("1")
 	reflectCm := cm.(*corev1.ConfigMap)
 
-	visitor := WorkflowPropertiesMutateVisitor(workflow, DefaultApplicationProperties)
+	visitor := WorkflowPropertiesMutateVisitor(workflow)
 	mutateFn := visitor(cm)
 
 	assert.NoError(t, mutateFn())
@@ -71,7 +71,7 @@ func Test_ensureWorkflowPropertiesConfigMapMutator_DollarReplacement(t *testing.
 			workflowproj.ApplicationPropertiesFileName: "mp.messaging.outgoing.kogito_outgoing_stream.url=${kubernetes:services.v1/event-listener}",
 		},
 	}
-	mutateVisitorFn := WorkflowPropertiesMutateVisitor(workflow, DefaultApplicationProperties)
+	mutateVisitorFn := WorkflowPropertiesMutateVisitor(workflow)
 
 	err := mutateVisitorFn(existingCM)()
 	assert.NoError(t, err)
diff --git a/controllers/profiles/dev/object_creators_dev.go b/controllers/profiles/dev/object_creators_dev.go
index f69d4400..9b760b7d 100644
--- a/controllers/profiles/dev/object_creators_dev.go
+++ b/controllers/profiles/dev/object_creators_dev.go
@@ -113,10 +113,6 @@ func ensureWorkflowDefConfigMapMutator(workflow *operatorapi.SonataFlow) common.
 	}
 }
 
-func ensureWorkflowDevPropertiesConfigMapMutator(workflow *operatorapi.SonataFlow) common.MutateVisitor {
-	return common.WorkflowPropertiesMutateVisitor(workflow, common.DefaultApplicationProperties)
-}
-
 // mountDevConfigMapsMutateVisitor mounts the required configMaps in the Workflow Dev Deployment
 func mountDevConfigMapsMutateVisitor(flowDefCM, propsCM *corev1.ConfigMap, workflowResCMs []operatorapi.ConfigMapWorkflowResource) common.MutateVisitor {
 	return func(object client.Object) controllerutil.MutateFn {
diff --git a/controllers/profiles/dev/states_dev.go b/controllers/profiles/dev/states_dev.go
index c970ea59..df7cd329 100644
--- a/controllers/profiles/dev/states_dev.go
+++ b/controllers/profiles/dev/states_dev.go
@@ -63,7 +63,7 @@ func (e *ensureRunningWorkflowState) Do(ctx context.Context, workflow *operatora
 	}
 	objs = append(objs, flowDefCM)
 
-	propsCM, _, err := e.ensurers.propertiesConfigMap.Ensure(ctx, workflow, ensureWorkflowDevPropertiesConfigMapMutator(workflow))
+	propsCM, _, err := e.ensurers.propertiesConfigMap.Ensure(ctx, workflow, common.WorkflowPropertiesMutateVisitor(workflow))
 	if err != nil {
 		return ctrl.Result{Requeue: false}, objs, err
 	}
diff --git a/controllers/profiles/prod/deployment_handler.go b/controllers/profiles/prod/deployment_handler.go
index 812f5cc2..105081f3 100644
--- a/controllers/profiles/prod/deployment_handler.go
+++ b/controllers/profiles/prod/deployment_handler.go
@@ -49,7 +49,7 @@ func (d *deploymentHandler) handle(ctx context.Context, workflow *operatorapi.So
 }
 
 func (d *deploymentHandler) handleWithImage(ctx context.Context, workflow *operatorapi.SonataFlow, image string) (reconcile.Result, []client.Object, error) {
-	propsCM, _, err := d.ensurers.propertiesConfigMap.Ensure(ctx, workflow, common.WorkflowPropertiesMutateVisitor(workflow, common.DefaultApplicationProperties))
+	propsCM, _, err := d.ensurers.propertiesConfigMap.Ensure(ctx, workflow, common.WorkflowPropertiesMutateVisitor(workflow))
 	if err != nil {
 		workflow.Status.Manager().MarkFalse(api.RunningConditionType, api.ExternalResourcesNotFoundReason, "Unable to retrieve the properties config map")
 		_, err = d.PerformStatusUpdate(ctx, workflow)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org