/**
* Copyright (C) 2015 Orange
* 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 com.francetelecom.clara.cloud.paas.projection.cf;
import com.francetelecom.clara.cloud.coremodel.ApplicationRelease;
import com.francetelecom.clara.cloud.coremodel.ConfigRole;
import com.francetelecom.clara.cloud.coremodel.ConfigRoleHelper;
import com.francetelecom.clara.cloud.coremodel.ConfigValue;
import com.francetelecom.clara.cloud.logicalmodel.InvalidConfigServiceException;
import com.francetelecom.clara.cloud.logicalmodel.LogicalConfigService;
import com.francetelecom.clara.cloud.logicalmodel.LogicalDeployment;
import com.francetelecom.clara.cloud.logicalmodel.ProcessingNode;
import com.francetelecom.clara.cloud.model.TechnicalDeploymentInstance;
import com.francetelecom.clara.cloud.techmodel.cf.App;
import com.francetelecom.clara.cloud.techmodel.cf.EnvVariable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
public class ConfigOverrideProjectionRule {
private static Logger logger = LoggerFactory.getLogger(ConfigOverrideProjectionRule.class.getName());
public void updateDeploymentTemplateInstance(TechnicalDeploymentInstance tdi, ApplicationRelease applicationRelease, List<ConfigRole> configRoles) {
//Q: how to extract this into a dedicated class ? Too early ?
//Wait for other overides ? Sizing (nb instances) ?
Set<ProcessingNode> impactedProcessingServices = identifyImpactedProcessingNodes(applicationRelease, configRoles);
for (ProcessingNode impactedProcessingService : impactedProcessingServices) {
Properties mergedConfigServicesProperties;
try {
mergedConfigServicesProperties = ConfigRoleHelper.getMergedConfigServicesProperties(impactedProcessingService, configRoles);
} catch (InvalidConfigServiceException e) {
String msg = "expected LogicalDeployment to be checked prior to projection being called. Caught: " + e;
logger.error(msg, e);
throw new IllegalArgumentException(msg);
}
Set<App> impactedApps = tdi.getTechnicalDeployment().listXaasSubscriptionTemplates(App.class, impactedProcessingService.getName());
for (App impactedApp : impactedApps) { //Usually a single app, but we never know
for (Map.Entry<Object, Object> potentiallyOverridenEnvEntries : mergedConfigServicesProperties.entrySet()) {
String key = (String) potentiallyOverridenEnvEntries.getKey();
String value = (String) potentiallyOverridenEnvEntries.getValue();
impactedApp.setEnvVariable(key, value);
}
//Q: do we need to capture this so that we can also reuse the code to modify an existing implemented app ?
}
}
}
protected Set<ProcessingNode> identifyImpactedProcessingNodes(ApplicationRelease applicationRelease, List<ConfigRole> configRoles) {
Set<ProcessingNode> impactedProcessingServices = new HashSet<ProcessingNode>();
LogicalDeployment architecture = applicationRelease.getLogicalDeployment();
for (ConfigRole configRole : configRoles) {
List<ConfigValue> configValues = configRole.listValues();
for (ConfigValue configValue : configValues) {
String configServiceName = configValue.getConfigSet();
Set<LogicalConfigService> logicalConfigServices = architecture.listLogicalServices(LogicalConfigService.class, configServiceName);
LogicalConfigService configService = logicalConfigServices.iterator().next();
impactedProcessingServices.addAll(configService.listDependentProcessingNodes());
}
}
return impactedProcessingServices;
}
}