Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ public class Messages {
public static final String SERVICE_INSTANCE_0_PLAN_UPDATE_FAILED_IGNORING_FAILURE = "Service instance: \"{0}\" plan update failed, ignoring failure...";
public static final String SERVICE_INSTANCE_0_PARAMETERS_UPDATE_FAILED_IGNORING_FAILURE = "Service instance: \"{0}\" parameters update failed, ignoring failure...";
public static final String SERVICE_INSTANCE_0_TAGS_UPDATE_FAILED_IGNORING_FAILURE = "Service instance: \"{0}\" tags update failed, ignoring failure...";
public static final String ONLY_FIRST_SERVICE_WILL_BE_CREATED = "Only the first service will be created because the provided 'service-name' fields are duplicated! All other services with the same 'service-name' will be ignored! Duplicated names: {0}";

// INFO log messages
public static final String ACQUIRING_LOCK = "Process \"{0}\" attempting to acquire lock for operation on MTA \"{1}\"";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package org.cloudfoundry.multiapps.controller.process.steps;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.sap.cloudfoundry.client.facade.CloudControllerClient;
import com.sap.cloudfoundry.client.facade.domain.CloudEntity;
import jakarta.inject.Named;

import org.cloudfoundry.multiapps.common.util.MiscUtil;
import org.cloudfoundry.multiapps.controller.client.lib.domain.CloudServiceInstanceExtended;
import org.cloudfoundry.multiapps.controller.client.lib.domain.ImmutableCloudServiceInstanceExtended;
Expand All @@ -23,8 +25,6 @@
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;

import com.sap.cloudfoundry.client.facade.CloudControllerClient;

@Named("extractBatchedServicesWithResolvedDynamicParametersStep")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ExtractBatchedServicesWithResolvedDynamicParametersStep extends SyncFlowableStep {
Expand All @@ -34,16 +34,21 @@ protected StepPhase executeStep(ProcessContext context) {
getStepLogger().debug(Messages.EXTRACT_SERVICES_AND_RESOLVE_DYNAMIC_PARAMETERS_FROM_BATCH);

Set<DynamicResolvableParameter> dynamicResolvableParameters = context.getVariable(Variables.DYNAMIC_RESOLVABLE_PARAMETERS);
List<CloudServiceInstanceExtended> servicesCalculatedForDeployment = context.getVariableBackwardsCompatible(Variables.BATCH_TO_PROCESS);
Set<DynamicResolvableParameter> dynamicParametersWithResolvedExistingInstances = resolveDynamicPramatersWithExistingInstances(context.getControllerClient(),
dynamicResolvableParameters,
servicesCalculatedForDeployment);
List<CloudServiceInstanceExtended> servicesCalculatedForDeployment = context.getVariableBackwardsCompatible(
Variables.BATCH_TO_PROCESS);
Set<DynamicResolvableParameter> dynamicParametersWithResolvedExistingInstances = resolveDynamicPramatersWithExistingInstances(
context.getControllerClient(),
dynamicResolvableParameters,
servicesCalculatedForDeployment);

List<CloudServiceInstanceExtended> resolvedServiceInstances = servicesCalculatedForDeployment.stream()
.map(service -> resolveDynamicParametersOfServiceInstance(service,
dynamicParametersWithResolvedExistingInstances))
.map(
service -> resolveDynamicParametersOfServiceInstance(
service,
dynamicParametersWithResolvedExistingInstances))
.collect(Collectors.toList());

checkForDuplicatedServiceNameFields(resolvedServiceInstances);
setServicesToCreate(context, resolvedServiceInstances);
context.setVariable(Variables.DYNAMIC_RESOLVABLE_PARAMETERS, dynamicParametersWithResolvedExistingInstances);
return StepPhase.DONE;
Expand All @@ -55,17 +60,18 @@ protected String getStepErrorMessage(ProcessContext context) {
}

private Set<DynamicResolvableParameter>
resolveDynamicPramatersWithExistingInstances(CloudControllerClient client,
Set<DynamicResolvableParameter> dynamicResolvableParameters,
List<CloudServiceInstanceExtended> servicesCalculatedForDeployment) {
resolveDynamicPramatersWithExistingInstances(CloudControllerClient client,
Set<DynamicResolvableParameter> dynamicResolvableParameters,
List<CloudServiceInstanceExtended> servicesCalculatedForDeployment) {
Map<String, String> existingServiceGuids = getExistingServiceGuidsIfNeeded(client, dynamicResolvableParameters,
servicesCalculatedForDeployment);
Set<DynamicResolvableParameter> resolvedDynamicParameters = new HashSet<>(dynamicResolvableParameters);
for (var dynamicParameter : dynamicResolvableParameters) {
if (existingServiceGuids.containsKey(dynamicParameter.getRelationshipEntityName())) {
resolvedDynamicParameters.remove(dynamicParameter);
resolvedDynamicParameters.add(ImmutableDynamicResolvableParameter.copyOf(dynamicParameter)
.withValue(existingServiceGuids.get(dynamicParameter.getRelationshipEntityName())));
.withValue(existingServiceGuids.get(
dynamicParameter.getRelationshipEntityName())));
}
}
return resolvedDynamicParameters;
Expand All @@ -92,14 +98,16 @@ private boolean isServiceInstanceGuidRequired(Set<DynamicResolvableParameter> dy
CloudServiceInstanceExtended serviceCalculatedForDeployment) {
return dynamicResolvableParameters.stream()
.anyMatch(dynamicParameter -> dynamicParameter.getRelationshipEntityName()
.equals(serviceCalculatedForDeployment.getResourceName()));
.equals(
serviceCalculatedForDeployment.getResourceName()));
}

private CloudServiceInstanceExtended
resolveDynamicParametersOfServiceInstance(CloudServiceInstanceExtended service,
Set<DynamicResolvableParameter> dynamicResolvableParameters) {
resolveDynamicParametersOfServiceInstance(CloudServiceInstanceExtended service,
Set<DynamicResolvableParameter> dynamicResolvableParameters) {
DynamicParametersResolver resolver = new DynamicParametersResolver(service.getResourceName(),
new DynamicResolvableParametersHelper(dynamicResolvableParameters));
new DynamicResolvableParametersHelper(
dynamicResolvableParameters));
Map<String, Object> resolvedServiceParameters = MiscUtil.cast(new VisitableObject(service.getCredentials()).accept(resolver));
return ImmutableCloudServiceInstanceExtended.copyOf(service)
.withCredentials(resolvedServiceParameters);
Expand All @@ -109,11 +117,39 @@ private boolean isServiceInstanceGuidRequired(Set<DynamicResolvableParameter> dy
private void setServicesToCreate(ProcessContext context, List<CloudServiceInstanceExtended> servicesCalculatedForDeployment) {

List<CloudServiceInstanceExtended> servicesToCreate = servicesCalculatedForDeployment.stream()
.filter(CloudServiceInstanceExtended::isManaged)
.filter(
CloudServiceInstanceExtended::isManaged)
.collect(Collectors.toList());
getStepLogger().debug(Messages.SERVICES_TO_CREATE, SecureSerialization.toJson(servicesToCreate));
context.setVariable(Variables.SERVICES_TO_CREATE, servicesToCreate);
context.setVariable(Variables.SERVICES_TO_CREATE_COUNT, servicesToCreate.size());
}

private void checkForDuplicatedServiceNameFields(List<CloudServiceInstanceExtended> resolvedServiceInstances) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is only in the 'batchedServices...' step - is there an alternative flow in the diagram that doesn't split the service in batches and will it not validate in that case?

List<String> resolvedServiceInstancesNames = resolvedServiceInstances.stream()
.map(CloudEntity::getName)
.toList();

List<String> duplicatedNames = getDuplicatedNames(resolvedServiceInstancesNames);
if (!duplicatedNames.isEmpty()) {
getStepLogger().warn(
Messages.ONLY_FIRST_SERVICE_WILL_BE_CREATED, String.join(" ", duplicatedNames));
}
}

private List<String> getDuplicatedNames(List<String> resolvedServiceInstancesNames) {
List<String> duplicatedNames = new ArrayList<>();
Map<String, Integer> frequencyOfNamesMap = new HashMap<>();
for (String name : resolvedServiceInstancesNames) {
frequencyOfNamesMap.merge(name, 1, Integer::sum);
}

for (String name : frequencyOfNamesMap.keySet()) {
if (frequencyOfNamesMap.get(name) > 1) {
duplicatedNames.add(name);
}
}
return duplicatedNames;
}

}
Loading
Loading