From df896470e928cea90896a7014ae233becfb7a1c4 Mon Sep 17 00:00:00 2001 From: stiv03 Date: Mon, 15 Sep 2025 11:34:47 +0300 Subject: [PATCH 1/4] Get existing offering and service plan during binding failure LMCROSSITXSADEPLOY-3280 --- .../controller/process/Messages.java | 3 ++- ...indingUnbindingOperationBaseExecution.java | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java index 73e8e26094..b622d3d0ef 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java @@ -183,7 +183,8 @@ public class Messages { public static final String ERROR_WHILE_POLLING_SERVICE_BINDING_OPERATIONS_BETWEEN_APP_0_AND_SERVICE_INSTANCE_1 = "Error while polling service binding operations between app: \"{0}\" and service instance \"{1}\""; public static final String ERROR_WHILE_CHECKING_SERVICE_BINDING_OPERATIONS_BETWEEN_APP_0_AND_SERVICE_INSTANCE_1 = "Error while checking service binding operations between app: \"{0}\" and service instance \"{1}\""; public static final String ERROR_WHILE_CHECKING_SERVICE_BINDING_OPERATIONS_0 = "Error while checking service binding operations for service binding: \"{0}\""; - public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH = "Async operation for service binding between app \"{0}\" and service instance \"{1}\" failed with \"{2}\""; + public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH = "Async operation for service binding between app \"{0}\" and service instance \"{1}\" with offering \"{2}\" and plan \"{3}\" failed with \"{4}\""; + public static final String ASYNC_OPERATION_FOR_USER_PROVIDED_SERVICE_BINDING_FAILED_WITH = "Async operation for service binding between app \"{0}\" and user-provided service instance \"{1}\" failed with \"{2}\""; public static final String ASYNC_OPERATION_FOR_SERVICE_KEY_FAILED_WITH = "Async operation for service key of service instance \"{0}\" failed with \"{1}\""; public static final String ASYNC_OPERATION_FOR_OPTIONAL_SERVICE_KEY_FAILED_WITH = "Async operation for service key of optional service instance \"{0}\" failed with \"{1}\""; public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FOR_OPTIONAL_SERVICE_FAILED_WITH = "Async operation for service binding for optional service between app \"{0}\" and service instance \"{1}\" failed with \"{2}\""; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java index 1fd21af746..0acdeac4c9 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java @@ -1,10 +1,13 @@ package org.cloudfoundry.multiapps.controller.process.steps; +import java.text.MessageFormat; import java.util.List; import java.util.function.Consumer; +import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClient; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudApplication; import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudAsyncJob; +import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceInstance; import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended; import org.cloudfoundry.multiapps.controller.process.Messages; import org.cloudfoundry.multiapps.controller.process.variables.Variables; @@ -35,9 +38,26 @@ protected Consumer getOnCompleteHandler(ProcessContext context) { protected Consumer getOnErrorHandler(ProcessContext context) { CloudApplication app = context.getVariable(Variables.APP_TO_PROCESS); String serviceInstanceName = context.getVariable(Variables.SERVICE_TO_UNBIND_BIND); + + CloudControllerClient client = context.getControllerClient(); + CloudServiceInstance serviceInstance = client.getServiceInstance(serviceInstanceName, false); + return serviceBindingJob -> context.getStepLogger() - .error(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH, app.getName(), - serviceInstanceName, serviceBindingJob.getErrors()); + .error(buildErrorMessage(app, serviceInstance, serviceInstanceName, serviceBindingJob)); + + } + + private String buildErrorMessage(CloudApplication app, CloudServiceInstance serviceInstance, String serviceInstanceName, + CloudAsyncJob serviceBindingJob) { + + if (serviceInstance.isUserProvided()) { + return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_USER_PROVIDED_SERVICE_BINDING_FAILED_WITH, app.getName(), + serviceInstanceName, serviceBindingJob.getErrors()); + } else { + return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, + serviceInstance.getLabel(), serviceInstance.getPlan(), + serviceBindingJob.getErrors()); + } } @Override From 836c47940755fc6cb3d003396bd651e313e8a0d2 Mon Sep 17 00:00:00 2001 From: stiv03 Date: Fri, 19 Sep 2025 16:17:03 +0300 Subject: [PATCH 2/4] add null check --- .../cloudfoundry/multiapps/controller/process/Messages.java | 1 + .../PollServiceBindingUnbindingOperationBaseExecution.java | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java index b622d3d0ef..47ceabaf47 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java @@ -185,6 +185,7 @@ public class Messages { public static final String ERROR_WHILE_CHECKING_SERVICE_BINDING_OPERATIONS_0 = "Error while checking service binding operations for service binding: \"{0}\""; public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH = "Async operation for service binding between app \"{0}\" and service instance \"{1}\" with offering \"{2}\" and plan \"{3}\" failed with \"{4}\""; public static final String ASYNC_OPERATION_FOR_USER_PROVIDED_SERVICE_BINDING_FAILED_WITH = "Async operation for service binding between app \"{0}\" and user-provided service instance \"{1}\" failed with \"{2}\""; + public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_INSTANCE_MISSING = "Async operation for service binding between app \"{0}\" and service instance \"{1}\" failed: Instance not found. Cause: {2}"; public static final String ASYNC_OPERATION_FOR_SERVICE_KEY_FAILED_WITH = "Async operation for service key of service instance \"{0}\" failed with \"{1}\""; public static final String ASYNC_OPERATION_FOR_OPTIONAL_SERVICE_KEY_FAILED_WITH = "Async operation for service key of optional service instance \"{0}\" failed with \"{1}\""; public static final String ASYNC_OPERATION_FOR_SERVICE_BINDING_FOR_OPTIONAL_SERVICE_FAILED_WITH = "Async operation for service binding for optional service between app \"{0}\" and service instance \"{1}\" failed with \"{2}\""; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java index 0acdeac4c9..eea4e84422 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java @@ -50,7 +50,10 @@ protected Consumer getOnErrorHandler(ProcessContext context) { private String buildErrorMessage(CloudApplication app, CloudServiceInstance serviceInstance, String serviceInstanceName, CloudAsyncJob serviceBindingJob) { - if (serviceInstance.isUserProvided()) { + if (serviceInstance == null) { + return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_INSTANCE_MISSING, app.getName(), + serviceInstanceName, serviceBindingJob.getErrors()); + } else if (serviceInstance.isUserProvided()) { return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_USER_PROVIDED_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, serviceBindingJob.getErrors()); } else { From 18a6dceb53a365cb769f0711c74e591ad959964b Mon Sep 17 00:00:00 2001 From: stiv03 Date: Tue, 23 Sep 2025 10:13:13 +0300 Subject: [PATCH 3/4] add displayOrMissing helper for safe null handling --- ...indingUnbindingOperationBaseExecution.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java index eea4e84422..996f5d3c3f 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java @@ -2,6 +2,7 @@ import java.text.MessageFormat; import java.util.List; +import java.util.Optional; import java.util.function.Consumer; import org.cloudfoundry.multiapps.controller.client.facade.CloudControllerClient; @@ -14,6 +15,8 @@ public abstract class PollServiceBindingUnbindingOperationBaseExecution extends PollOperationBaseExecution { + private static final String MISSING_VALUE_PLACEHOLDER = "missing"; + @Override protected boolean isOptional(ProcessContext context) { List servicesToBind = context.getVariable(Variables.SERVICES_TO_BIND); @@ -53,14 +56,24 @@ private String buildErrorMessage(CloudApplication app, CloudServiceInstance serv if (serviceInstance == null) { return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_INSTANCE_MISSING, app.getName(), serviceInstanceName, serviceBindingJob.getErrors()); - } else if (serviceInstance.isUserProvided()) { + } + + if (serviceInstance.isUserProvided()) { return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_USER_PROVIDED_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, serviceBindingJob.getErrors()); - } else { - return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, - serviceInstance.getLabel(), serviceInstance.getPlan(), - serviceBindingJob.getErrors()); } + + String serviceOffering = displayOrMissing(serviceInstance.getLabel()); + String servicePlan = displayOrMissing(serviceInstance.getPlan()); + + return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, + serviceOffering, servicePlan, serviceBindingJob.getErrors()); + + } + + private String displayOrMissing(String value) { + return Optional.ofNullable(value) + .orElse(MISSING_VALUE_PLACEHOLDER); } @Override From 40f43d22f2465ee1eae9554b7d238d1d109eedd6 Mon Sep 17 00:00:00 2001 From: stiv03 Date: Tue, 23 Sep 2025 11:08:54 +0300 Subject: [PATCH 4/4] change method name --- .../PollServiceBindingUnbindingOperationBaseExecution.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java index 996f5d3c3f..853fd94bbb 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/PollServiceBindingUnbindingOperationBaseExecution.java @@ -63,15 +63,15 @@ private String buildErrorMessage(CloudApplication app, CloudServiceInstance serv serviceInstanceName, serviceBindingJob.getErrors()); } - String serviceOffering = displayOrMissing(serviceInstance.getLabel()); - String servicePlan = displayOrMissing(serviceInstance.getPlan()); + String serviceOffering = getValueOrMissing(serviceInstance.getLabel()); + String servicePlan = getValueOrMissing(serviceInstance.getPlan()); return MessageFormat.format(Messages.ASYNC_OPERATION_FOR_SERVICE_BINDING_FAILED_WITH, app.getName(), serviceInstanceName, serviceOffering, servicePlan, serviceBindingJob.getErrors()); } - private String displayOrMissing(String value) { + private String getValueOrMissing(String value) { return Optional.ofNullable(value) .orElse(MISSING_VALUE_PLACEHOLDER); }