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 <[email protected]>
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 <[email protected]>
---
 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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to