diff options
Diffstat (limited to 'src/main/java/org')
12 files changed, 555 insertions, 194 deletions
diff --git a/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java b/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java index 3a98788f5..3dc807388 100644 --- a/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/CamelConfiguration.java @@ -22,11 +22,34 @@ package org.onap.clamp.clds.config; +import java.io.IOException; +import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.http4.HttpClientConfigurer; +import org.apache.camel.component.http4.HttpComponent; import org.apache.camel.model.rest.RestBindingMode; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.onap.clamp.clds.util.ClampVersioning; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; @Component @@ -35,15 +58,69 @@ public class CamelConfiguration extends RouteBuilder { @Autowired CamelContext camelContext; + @Autowired + private Environment env; + + private void configureDefaultSslProperties() { + if (env.getProperty("server.ssl.trust-store") != null) { + URL storeResource = CamelConfiguration.class + .getResource(env.getProperty("server.ssl.trust-store").replaceAll("classpath:", "")); + System.setProperty("javax.net.ssl.trustStore", storeResource.getPath()); + System.setProperty("javax.net.ssl.trustStorePassword", env.getProperty("server.ssl.trust-store-password")); + System.setProperty("javax.net.ssl.trustStoreType", "jks"); + System.setProperty("ssl.TrustManagerFactory.algorithm", "PKIX"); + storeResource = CamelConfiguration.class + .getResource(env.getProperty("server.ssl.key-store").replaceAll("classpath:", "")); + System.setProperty("javax.net.ssl.keyStore", storeResource.getPath()); + System.setProperty("javax.net.ssl.keyStorePassword", env.getProperty("server.ssl.key-store-password")); + System.setProperty("javax.net.ssl.keyStoreType", env.getProperty("server.ssl.key-store-type")); + } + } + + private void registerTrustStore() + throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException, CertificateException, IOException { + if (env.getProperty("server.ssl.trust-store") != null) { + KeyStore truststore = KeyStore.getInstance("JKS"); + truststore.load( + getClass().getClassLoader() + .getResourceAsStream(env.getProperty("server.ssl.trust-store").replaceAll("classpath:", "")), + env.getProperty("server.ssl.trust-store-password").toCharArray()); + + TrustManagerFactory trustFactory = TrustManagerFactory.getInstance("PKIX"); + trustFactory.init(truststore); + SSLContext sslcontext = SSLContext.getInstance("TLS"); + sslcontext.init(null, trustFactory.getTrustManagers(), null); + SSLSocketFactory factory = new SSLSocketFactory(sslcontext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); + SchemeRegistry registry = new SchemeRegistry(); + final Scheme scheme = new Scheme("https4", 443, factory); + registry.register(scheme); + ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory(); + HttpComponent http4 = camelContext.getComponent("https4", HttpComponent.class); + http4.setHttpClientConfigurer(new HttpClientConfigurer() { + + @Override + public void configureHttpClient(HttpClientBuilder builder) { + builder.setSSLSocketFactory(factory); + Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() + .register("https", factory).register("http", plainsf).build(); + builder.setConnectionManager(new BasicHttpClientConnectionManager(registry)); + } + }); + } + } + @Override - public void configure() { + public void configure() + throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { restConfiguration().component("servlet").bindingMode(RestBindingMode.json).jsonDataFormat("clamp-gson") .dataFormatProperty("prettyPrint", "true")// .enableCORS(true) // turn on swagger api-doc .apiContextPath("api-doc").apiVendorExtension(true).apiProperty("api.title", "Clamp Rest API") .apiProperty("api.version", ClampVersioning.getCldsVersionFromProps()) .apiProperty("base.path", "/restservices/clds/"); - // .apiProperty("cors", "true"); - camelContext.setTracing(true); + // camelContext.setTracing(true); + + configureDefaultSslProperties(); + registerTrustStore(); } } diff --git a/src/main/java/org/onap/clamp/clds/model/properties/Holmes.java b/src/main/java/org/onap/clamp/clds/model/properties/Holmes.java index a93b09cfa..a56c57d19 100644 --- a/src/main/java/org/onap/clamp/clds/model/properties/Holmes.java +++ b/src/main/java/org/onap/clamp/clds/model/properties/Holmes.java @@ -26,11 +26,11 @@ package org.onap.clamp.clds.model.properties; import com.google.gson.JsonObject; + import org.onap.clamp.clds.util.JsonUtils; /** - * Parse Holmes bpmn parameters json properties. - * Example json: + * Parse Holmes bpmn parameters json properties. Example json: * [{"name":"correlationalLogic","value":"vcwx"},{"name":"configPolicyName","value":"cccc"}] */ public class Holmes extends AbstractModelElement { @@ -43,14 +43,18 @@ public class Holmes extends AbstractModelElement { /** * Default constructor for Holmes Element. * - * @param modelBpmn The model bpmn - * @param modelJson The model json + * @param modelBpmn + * The model bpmn + * @param modelJson + * The model json */ public Holmes(ModelBpmn modelBpmn, JsonObject modelJson) { super(TYPE_HOLMES, modelBpmn, modelJson); - correlationLogic = JsonUtils.getStringValueByName(modelElementJsonNode, "correlationalLogic"); - configPolicyName = JsonUtils.getStringValueByName(modelElementJsonNode, "configPolicyName"); + if (modelElementJsonNode != null) { + correlationLogic = JsonUtils.getStringValueByName(modelElementJsonNode, "correlationalLogic"); + configPolicyName = JsonUtils.getStringValueByName(modelElementJsonNode, "configPolicyName"); + } } public static final String getType() { diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java index 809904f22..3792c1720 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java @@ -29,6 +29,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.util.AbstractMap; import java.util.Collections; import java.util.HashSet; import java.util.List; @@ -52,21 +53,23 @@ public class BlueprintParser { private static final String TYPE = "type"; private static final String PROPERTIES = "properties"; private static final String NAME = "name"; - private static final String POLICYID = "policy_id"; - private static final String POLICY_TYPEID = "policy_type_id"; + private static final String INPUT = "inputs"; + private static final String GET_INPUT = "get_input"; + private static final String POLICY_MODELID = "policy_model_id"; private static final String RELATIONSHIPS = "relationships"; private static final String CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM = "clamp_node.relationships.gets_input_from"; private static final String TARGET = "target"; public Set<MicroService> getMicroServices(String blueprintString) { Set<MicroService> microServices = new HashSet<>(); - JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString); - JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject(); + JsonObject blueprintJson = BlueprintParser.convertToJson(blueprintString); + JsonObject nodeTemplateList = blueprintJson.get(NODE_TEMPLATES).getAsJsonObject(); + JsonObject inputList = blueprintJson.get(INPUT).getAsJsonObject(); - for (Entry<String, JsonElement> entry : results.entrySet()) { + for (Entry<String, JsonElement> entry : nodeTemplateList.entrySet()) { JsonObject nodeTemplate = entry.getValue().getAsJsonObject(); if (nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES)) { - MicroService microService = getNodeRepresentation(entry); + MicroService microService = getNodeRepresentation(entry, nodeTemplateList, inputList); microServices.add(microService); } } @@ -89,7 +92,7 @@ public class BlueprintParser { } String msName = theBiggestMicroServiceKey.toLowerCase().contains(HOLMES_PREFIX) ? HOLMES : TCA; return Collections - .singletonList(new MicroService(msName, "onap.policies.monitoring.cdap.tca.hi.lo.app", "", "", "")); + .singletonList(new MicroService(msName, "onap.policies.monitoring.cdap.tca.hi.lo.app", "", "")); } String getName(Entry<String, JsonElement> entry) { @@ -118,30 +121,48 @@ public class BlueprintParser { return ""; } - String getModelType(Entry<String, JsonElement> entry) { + String findModelTypeInTargetArray(JsonArray jsonArray, JsonObject nodeTemplateList, JsonObject inputList) { + for (JsonElement elem : jsonArray) { + String modelType = getModelType( + new AbstractMap.SimpleEntry<String, JsonElement>(elem.getAsJsonObject().get(TARGET).getAsString(), + nodeTemplateList.get(elem.getAsJsonObject().get(TARGET).getAsString()).getAsJsonObject()), + nodeTemplateList, inputList); + if (!modelType.isEmpty()) { + return modelType; + } + } + return ""; + } + + String getModelType(Entry<String, JsonElement> entry, JsonObject nodeTemplateList, JsonObject inputList) { JsonObject ob = entry.getValue().getAsJsonObject(); + // Search first in this node template if (ob.has(PROPERTIES)) { JsonObject properties = ob.get(PROPERTIES).getAsJsonObject(); - if (properties.has(POLICYID)) { - JsonObject policyIdObj = properties.get(POLICYID).getAsJsonObject(); - if (policyIdObj.has(POLICY_TYPEID)) { - return policyIdObj.get(POLICY_TYPEID).getAsString(); + if (properties.has(POLICY_MODELID)) { + if (properties.get(POLICY_MODELID).isJsonObject()) { + // it's a blueprint parameter + return inputList.get(properties.get(POLICY_MODELID).getAsJsonObject().get(GET_INPUT).getAsString()) + .getAsJsonObject().get("default").getAsString(); + } else { + // It's a direct value + return properties.get(POLICY_MODELID).getAsString(); } } } + // Or it's may be defined in a relationship + if (ob.has(RELATIONSHIPS)) { + return findModelTypeInTargetArray(ob.get(RELATIONSHIPS).getAsJsonArray(), nodeTemplateList, inputList); + } return ""; } - String getBlueprintName(Entry<String, JsonElement> entry) { - return entry.getKey(); - } - - MicroService getNodeRepresentation(Entry<String, JsonElement> entry) { + MicroService getNodeRepresentation(Entry<String, JsonElement> entry, JsonObject nodeTemplateList, + JsonObject inputList) { String name = getName(entry); String getInputFrom = getInput(entry); - String modelType = getModelType(entry); - String blueprintName = getBlueprintName(entry); - return new MicroService(name, modelType, getInputFrom, "", blueprintName); + String modelType = getModelType(entry, nodeTemplateList, inputList); + return new MicroService(name, modelType, getInputFrom, ""); } private String getTarget(JsonObject elementObject) { diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java index ac4daeffb..9bc7a022a 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java @@ -29,16 +29,14 @@ import java.util.Objects; public class MicroService { private final String name; private final String modelType; - private final String blueprintName; private final String inputFrom; private String mappedNameJpa; - public MicroService(String name, String modelType, String inputFrom, String mappedNameJpa, String blueprintName) { + public MicroService(String name, String modelType, String inputFrom, String mappedNameJpa) { this.name = name; this.inputFrom = inputFrom; this.mappedNameJpa = mappedNameJpa; - this.modelType = modelType; - this.blueprintName = blueprintName; + this.modelType = modelType; } public String getName() { @@ -53,15 +51,10 @@ public class MicroService { return inputFrom; } - public String getBlueprintName() { - return blueprintName; - } - @Override public String toString() { return "MicroService{" + "name='" + name + '\'' + ", modelType='" + modelType + '\'' + ", inputFrom='" - + inputFrom + '\'' + ", mappedNameJpa='" + mappedNameJpa + '\'' + ", blueprintName='" - + blueprintName + '\'' + '}'; + + inputFrom + '\'' + ", mappedNameJpa='" + mappedNameJpa + '\'' + '}'; } public String getMappedNameJpa() { @@ -81,11 +74,12 @@ public class MicroService { return false; } MicroService that = (MicroService) o; - return name.equals(that.name) && modelType.equals(that.modelType) && inputFrom.equals(that.inputFrom) && mappedNameJpa.equals(that.mappedNameJpa) && blueprintName.equals(that.blueprintName); + return name.equals(that.name) && modelType.equals(that.modelType) && inputFrom.equals(that.inputFrom) + && mappedNameJpa.equals(that.mappedNameJpa); } @Override public int hashCode() { - return Objects.hash(name, modelType, inputFrom, mappedNameJpa, blueprintName); + return Objects.hash(name, modelType, inputFrom, mappedNameJpa); } } diff --git a/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java b/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java index fe2d5cb34..d88a17e86 100755 --- a/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java +++ b/src/main/java/org/onap/clamp/clds/util/drawing/Painter.java @@ -64,7 +64,7 @@ public class Painter { adjustGraphics2DProperties(); - Point origin = new Point(0, rectHeight / 2); + Point origin = new Point(1, rectHeight / 2); ImageBuilder ib = new ImageBuilder(g2d, documentBuilder, origin, baseLength, rectHeight); doTheActualDrawing(collector, microServices, policy, ib); diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java index 0041c589e..6de2863ea 100644 --- a/src/main/java/org/onap/clamp/loop/Loop.java +++ b/src/main/java/org/onap/clamp/loop/Loop.java @@ -23,6 +23,8 @@ package org.onap.clamp.loop; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -45,7 +47,9 @@ import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.OneToMany; +import javax.persistence.OrderBy; import javax.persistence.Table; +import javax.persistence.Transient; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -65,6 +69,9 @@ public class Loop implements Serializable { */ private static final long serialVersionUID = -286522707701388642L; + @Transient + private static final EELFLogger logger = EELFManager.getInstance().getLogger(Loop.class); + @Id @Expose @Column(nullable = false, name = "name", unique = true) @@ -114,6 +121,7 @@ public class Loop implements Serializable { @Expose @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "loop") + @OrderBy("id DESC") private Set<LoopLog> loopLogs = new HashSet<>(); public Loop() { @@ -277,7 +285,9 @@ public class Loop implements Serializable { jsonArray.add(policyNode); policyNode.addProperty("policy-id", policyName); } - return new GsonBuilder().setPrettyPrinting().create().toJson(jsonObject); + String payload = new GsonBuilder().setPrettyPrinting().create().toJson(jsonObject); + logger.info("PdpGroup policy payload: " + payload); + return payload; } /** diff --git a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java b/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java index 0124aa704..ad13ad34d 100644 --- a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java +++ b/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java @@ -25,7 +25,6 @@ package org.onap.clamp.loop; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import com.google.gson.Gson; import com.google.gson.JsonObject; import java.io.IOException; @@ -51,9 +50,13 @@ import org.onap.clamp.clds.util.drawing.SvgFacade; import org.onap.clamp.policy.Policy; import org.onap.clamp.policy.microservice.MicroServicePolicy; import org.onap.clamp.policy.operational.OperationalPolicy; -import org.onap.sdc.tosca.parser.api.ISdcCsarHelper; +import org.onap.sdc.tosca.parser.api.IEntityDetails; +import org.onap.sdc.tosca.parser.elements.queries.EntityQuery; +import org.onap.sdc.tosca.parser.elements.queries.TopologyTemplateQuery; +import org.onap.sdc.tosca.parser.enums.EntityTemplateType; import org.onap.sdc.tosca.parser.enums.SdcTypes; import org.onap.sdc.toscaparser.api.NodeTemplate; +import org.onap.sdc.toscaparser.api.Property; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @@ -183,22 +186,49 @@ public class LoopCsarInstaller implements CsarInstaller { return globalProperties; } - private JsonObject createModelPropertiesJson(CsarHandler csar) { - JsonObject modelProperties = new JsonObject(); - Gson gson = new Gson(); - ISdcCsarHelper csarHelper = csar.getSdcCsarHelper(); - modelProperties.add("serviceDetails", - gson.fromJson(gson.toJson(csarHelper.getServiceMetadataAllProperties()), JsonObject.class)); + private static JsonObject createVfModuleProperties(CsarHandler csar) { + JsonObject vfModuleProps = new JsonObject(); + // Loop on all Groups defined in the service (VFModule entries type: + // org.openecomp.groups.VfModule) + for (IEntityDetails entity : csar.getSdcCsarHelper().getEntity( + EntityQuery.newBuilder(EntityTemplateType.GROUP).build(), + TopologyTemplateQuery.newBuilder(SdcTypes.SERVICE).build(), false)) { + // Get all metadata info + JsonObject allVfProps = (JsonObject) JsonUtils.GSON.toJsonTree(entity.getMetadata().getAllProperties()); + vfModuleProps.add(entity.getMetadata().getAllProperties().get("vfModuleModelName"), allVfProps); + // now append the properties section so that we can also have isBase, + // volume_group, etc ... fields under the VFmodule name + for (Entry<String, Property> additionalProp : entity.getProperties().entrySet()) { + allVfProps.add(additionalProp.getValue().getName(), + JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue())); + } + } + return vfModuleProps; + } + private static JsonObject createServicePropertiesByType(CsarHandler csar) { JsonObject resourcesProp = new JsonObject(); + // Iterate on all types defined in the tosca lib for (SdcTypes type : SdcTypes.values()) { JsonObject resourcesPropByType = new JsonObject(); - for (NodeTemplate nodeTemplate : csarHelper.getServiceNodeTemplateBySdcType(type)) { - resourcesPropByType.add(nodeTemplate.getName(), JsonUtils.GSON_JPA_MODEL - .fromJson(new Gson().toJson(nodeTemplate.getMetaData().getAllProperties()), JsonObject.class)); + // For each type, get the metadata of each nodetemplate + for (NodeTemplate nodeTemplate : csar.getSdcCsarHelper().getServiceNodeTemplateBySdcType(type)) { + resourcesPropByType.add(nodeTemplate.getName(), + JsonUtils.GSON.toJsonTree(nodeTemplate.getMetaData().getAllProperties())); } resourcesProp.add(type.getValue(), resourcesPropByType); } + return resourcesProp; + } + + private static JsonObject createModelPropertiesJson(CsarHandler csar) { + JsonObject modelProperties = new JsonObject(); + // Add service details + modelProperties.add("serviceDetails", JsonUtils.GSON.fromJson( + JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class)); + // Add properties details for each type, VfModule, VF, VFC, .... + JsonObject resourcesProp = createServicePropertiesByType(csar); + resourcesProp.add("VFModule", createVfModuleProperties(csar)); modelProperties.add("resourceDetails", resourcesProp); return modelProperties; } diff --git a/src/main/java/org/onap/clamp/loop/LoopOperation.java b/src/main/java/org/onap/clamp/loop/LoopOperation.java index 3f4c52939..87effa5fd 100644 --- a/src/main/java/org/onap/clamp/loop/LoopOperation.java +++ b/src/main/java/org/onap/clamp/loop/LoopOperation.java @@ -25,31 +25,21 @@ package org.onap.clamp.loop; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonNull; import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Iterator; +import java.util.Set; +import java.util.UUID; import org.apache.camel.Exchange; -import org.onap.clamp.clds.client.DcaeDispatcherServices; -import org.onap.clamp.clds.config.ClampProperties; -import org.onap.clamp.clds.util.LoggingUtils; -import org.onap.clamp.clds.util.ONAPLogConstants; -import org.onap.clamp.exception.OperationException; -import org.onap.clamp.util.HttpConnectionManager; -import org.slf4j.event.Level; +import org.apache.camel.Message; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.onap.clamp.policy.operational.OperationalPolicy; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.yaml.snakeyaml.Yaml; /** * Closed loop operations. @@ -59,160 +49,217 @@ public class LoopOperation { protected static final EELFLogger logger = EELFManager.getInstance().getLogger(LoopOperation.class); protected static final EELFLogger auditLogger = EELFManager.getInstance().getMetricsLogger(); - private final DcaeDispatcherServices dcaeDispatcherServices; + private static final String DCAE_LINK_FIELD = "links"; + private static final String DCAE_STATUS_FIELD = "status"; + private static final String DCAE_SERVICETYPE_ID = "serviceTypeId"; + private static final String DCAE_INPUTS = "inputs"; + private static final String DCAE_DEPLOYMENT_PREFIX = "CLAMP_"; + private static final String DEPLOYMENT_PARA = "dcaeDeployParameters"; private final LoopService loopService; - private LoggingUtils util = new LoggingUtils(logger); - @Autowired - private HttpServletRequest request; + public enum TempLoopState { + NOT_SUBMITTED, SUBMITTED, DEPLOYED, NOT_DEPLOYED, PROCESSING, IN_ERROR; + } + /** + * The constructor. + * + * @param loopService + * The loop service + * @param refProp + * The clamp properties + */ @Autowired - public LoopOperation(LoopService loopService, DcaeDispatcherServices dcaeDispatcherServices, - ClampProperties refProp, HttpConnectionManager httpConnectionManager) { + public LoopOperation(LoopService loopService) { this.loopService = loopService; - this.dcaeDispatcherServices = dcaeDispatcherServices; } - + /** - * Deploy the closed loop. + * Get the payload used to send the deploy closed loop request. * - * @param loopName - * the loop name - * @return the updated loop - * @throws OperationException - * Exception during the operation + * @param loop + * The loop + * @return The payload used to send deploy closed loop request + * @throws IOException + * IOException */ - public Loop deployLoop(Exchange camelExchange, String loopName) throws OperationException { - util.entering(request, "CldsService: Deploy model"); - Date startTime = new Date(); - Loop loop = loopService.getLoop(loopName); - - if (loop == null) { - String msg = "Deploy loop exception: Not able to find closed loop:" + loopName; - util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), msg, Level.INFO, - ONAPLogConstants.ResponseStatus.ERROR); - throw new OperationException(msg); - } + public String getDeployPayload(Loop loop) throws IOException { + JsonObject globalProp = loop.getGlobalPropertiesJson(); + JsonObject deploymentProp = globalProp.getAsJsonObject(DEPLOYMENT_PARA); + + String serviceTypeId = loop.getDcaeBlueprintId(); - // verify the current closed loop state - if (loop.getLastComputedState() != LoopState.SUBMITTED) { - String msg = "Deploy loop exception: This closed loop is in state:" + loop.getLastComputedState() - + ". It could be deployed only when it is in SUBMITTED state."; - util.exiting(HttpStatus.CONFLICT.toString(), msg, Level.INFO, ONAPLogConstants.ResponseStatus.ERROR); - throw new OperationException(msg); + JsonObject rootObject = new JsonObject(); + rootObject.addProperty(DCAE_SERVICETYPE_ID, serviceTypeId); + if (deploymentProp != null) { + rootObject.add(DCAE_INPUTS, deploymentProp); } + String apiBodyString = rootObject.toString(); + logger.info("Dcae api Body String - " + apiBodyString); + return apiBodyString; + } + + /** + * Get the deployment id. + * + * @param loop + * The loop + * @return The deployment id + * @throws IOException + * IOException + */ + public String getDeploymentId(Loop loop) { // Set the deploymentId if not present yet String deploymentId = ""; // If model is already deployed then pass same deployment id if (loop.getDcaeDeploymentId() != null && !loop.getDcaeDeploymentId().isEmpty()) { deploymentId = loop.getDcaeDeploymentId(); } else { - loop.setDcaeDeploymentId(deploymentId = "closedLoop_" + loopName + "_deploymentId"); + deploymentId = DCAE_DEPLOYMENT_PREFIX + UUID.randomUUID(); } - - Yaml yaml = new Yaml(); - Map<String, Object> yamlMap = yaml.load(loop.getBlueprint()); - JsonObject bluePrint = wrapSnakeObject(yamlMap).getAsJsonObject(); - - loop.setDcaeDeploymentStatusUrl( - dcaeDispatcherServices.createNewDeployment(deploymentId, loop.getDcaeBlueprintId(), bluePrint)); - loop.setLastComputedState(LoopState.DEPLOYED); - // save the updated loop - loopService.saveOrUpdateLoop(loop); - - // audit log - LoggingUtils.setTimeContext(startTime, new Date()); - auditLogger.info("Deploy model completed"); - util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED); - return loop; + return deploymentId; } /** - * Un deploy closed loop. + * Update the loop info. * - * @param loopName - * the loop name - * @return the updated loop + * @param camelExchange + * The camel exchange + * @param loop + * The loop + * @param deploymentId + * The deployment id + * @throws ParseException + * The parse exception */ - public Loop unDeployLoop(String loopName) throws OperationException { - util.entering(request, "LoopOperation: Undeploy the closed loop"); - Date startTime = new Date(); - Loop loop = loopService.getLoop(loopName); - - if (loop == null) { - String msg = "Undeploy loop exception: Not able to find closed loop:" + loopName; - util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), msg, Level.INFO, - ONAPLogConstants.ResponseStatus.ERROR); - throw new OperationException(msg); - } - - // verify the current closed loop state - if (loop.getLastComputedState() != LoopState.DEPLOYED) { - String msg = "Unploy loop exception: This closed loop is in state:" + loop.getLastComputedState() - + ". It could be undeployed only when it is in DEPLOYED state."; - util.exiting(HttpStatus.CONFLICT.toString(), msg, Level.INFO, ONAPLogConstants.ResponseStatus.ERROR); - throw new OperationException(msg); - } + public void updateLoopInfo(Exchange camelExchange, Loop loop, String deploymentId) throws ParseException { + Message in = camelExchange.getIn(); + String msg = in.getBody(String.class); - loop.setDcaeDeploymentStatusUrl( - dcaeDispatcherServices.deleteExistingDeployment(loop.getDcaeDeploymentId(), loop.getDcaeBlueprintId())); + JSONParser parser = new JSONParser(); + Object obj0 = parser.parse(msg); + JSONObject jsonObj = (JSONObject) obj0; - // clean the deployment ID - loop.setDcaeDeploymentId(null); - loop.setLastComputedState(LoopState.SUBMITTED); + JSONObject linksObj = (JSONObject) jsonObj.get(DCAE_LINK_FIELD); + String statusUrl = (String) linksObj.get(DCAE_STATUS_FIELD); - // save the updated loop + if (deploymentId == null) { + loop.setDcaeDeploymentId(null); + loop.setDcaeDeploymentStatusUrl(null); + } else { + loop.setDcaeDeploymentId(deploymentId); + loop.setDcaeDeploymentStatusUrl(statusUrl.replaceAll("http:", "http4:").replaceAll("https:", "https4:")); + } loopService.saveOrUpdateLoop(loop); + } - // audit log - LoggingUtils.setTimeContext(startTime, new Date()); - auditLogger.info("Undeploy model completed"); - util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED); - return loop; + /** + * Get the Closed Loop status based on the reply from Policy. + * + * @param statusCode + * The status code + * @return The state based on policy response + * @throws ParseException + * The parse exception + */ + public String analysePolicyResponse(int statusCode) { + if (statusCode == 200) { + return TempLoopState.SUBMITTED.toString(); + } else if (statusCode == 404) { + return TempLoopState.NOT_SUBMITTED.toString(); + } + return TempLoopState.IN_ERROR.toString(); } - private JsonElement wrapSnakeObject(Object obj) { - // NULL => JsonNull - if (obj == null) { - return JsonNull.INSTANCE; + /** + * Get the name of the first Operational policy. + * + * @param loop + * The closed loop + * @return The name of the first operational policy + */ + public String getOperationalPolicyName(Loop loop) { + Set<OperationalPolicy> opSet = loop.getOperationalPolicies(); + Iterator<OperationalPolicy> iterator = opSet.iterator(); + while (iterator.hasNext()) { + OperationalPolicy policy = iterator.next(); + return policy.getName(); } + return null; + } - // Collection => JsonArray - if (obj instanceof Collection) { - JsonArray array = new JsonArray(); - for (Object childObj : (Collection<?>) obj) { - array.add(wrapSnakeObject(childObj)); - } - return array; + /** + * Get the Closed Loop status based on the reply from DCAE. + * + * @param camelExchange + * The camel exchange + * @return The state based on DCAE response + * @throws ParseException + * The parse exception + */ + public String analyseDcaeResponse(Exchange camelExchange, Integer statusCode) throws ParseException { + if (statusCode == null) { + return TempLoopState.NOT_DEPLOYED.toString(); } + if (statusCode == 200) { + Message in = camelExchange.getIn(); + String msg = in.getBody(String.class); + + JSONParser parser = new JSONParser(); + Object obj0 = parser.parse(msg); + JSONObject jsonObj = (JSONObject) obj0; - // Array => JsonArray - if (obj.getClass().isArray()) { - JsonArray array = new JsonArray(); + String opType = (String) jsonObj.get("operationType"); + String status = (String) jsonObj.get("status"); - int length = Array.getLength(array); - for (int i = 0; i < length; i++) { - array.add(wrapSnakeObject(Array.get(array, i))); + // status = processing/successded/failed + if (status.equals("succeeded")) { + if (opType.equals("install")) { + return TempLoopState.DEPLOYED.toString(); + } else if (opType.equals("uninstall")) { + return TempLoopState.NOT_DEPLOYED.toString(); + } + } else if (status.equals("processing")) { + return TempLoopState.PROCESSING.toString(); } - return array; + } else if (statusCode == 404) { + return TempLoopState.NOT_DEPLOYED.toString(); } + return TempLoopState.IN_ERROR.toString(); + } - // Map => JsonObject - if (obj instanceof Map) { - Map<?, ?> map = (Map<?, ?>) obj; - - JsonObject jsonObject = new JsonObject(); - for (final Map.Entry<?, ?> entry : map.entrySet()) { - final String name = String.valueOf(entry.getKey()); - final Object value = entry.getValue(); - jsonObject.add(name, wrapSnakeObject(value)); + /** + * Update the status of the closed loop based on the response from Policy and + * DCAE. + * + * @param loop + * The closed loop + * @param policyState + * The state get from Policy + * @param dcaeState + * The state get from DCAE + * @throws ParseException + * The parse exception + */ + public LoopState updateLoopStatus(Loop loop, TempLoopState policyState, TempLoopState dcaeState) { + LoopState clState = LoopState.IN_ERROR; + if (policyState == TempLoopState.SUBMITTED) { + if (dcaeState == TempLoopState.DEPLOYED) { + clState = LoopState.DEPLOYED; + } else if (dcaeState == TempLoopState.PROCESSING) { + clState = LoopState.WAITING; + } else if (dcaeState == TempLoopState.NOT_DEPLOYED) { + clState = LoopState.SUBMITTED; + } + } else if (policyState == TempLoopState.NOT_SUBMITTED) { + if (dcaeState == TempLoopState.NOT_DEPLOYED) { + clState = LoopState.DESIGN; } - return jsonObject; } - - // otherwise take it as a string - return new JsonPrimitive(String.valueOf(obj)); + loop.setLastComputedState(clState); + loopService.saveOrUpdateLoop(loop); + return clState; } } diff --git a/src/main/java/org/onap/clamp/loop/log/LoopLog.java b/src/main/java/org/onap/clamp/loop/log/LoopLog.java index 3edb2ee59..cea495712 100644 --- a/src/main/java/org/onap/clamp/loop/log/LoopLog.java +++ b/src/main/java/org/onap/clamp/loop/log/LoopLog.java @@ -69,7 +69,7 @@ public class LoopLog implements Serializable { private LogType logType; @Expose - @Column(name = "message", nullable = false) + @Column(name = "message", columnDefinition = "MEDIUMTEXT", nullable = false) private String message; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java index 2bbb91183..d8d15a5b2 100644 --- a/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java +++ b/src/main/java/org/onap/clamp/policy/microservice/MicroServicePolicy.java @@ -23,6 +23,8 @@ package org.onap.clamp.policy.microservice; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -40,6 +42,7 @@ import javax.persistence.FetchType; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; +import javax.persistence.Transient; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -61,6 +64,9 @@ public class MicroServicePolicy implements Serializable, Policy { */ private static final long serialVersionUID = 6271238288583332616L; + @Transient + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MicroServicePolicy.class); + @Expose @Id @Column(nullable = false, name = "name", unique = true) @@ -271,7 +277,9 @@ public class MicroServicePolicy implements Serializable, Policy { JsonObject policyProperties = new JsonObject(); policyDetails.add("properties", policyProperties); policyProperties.add(this.getMicroServicePropertyNameFromTosca(toscaJson), this.getProperties()); - return new GsonBuilder().setPrettyPrinting().create().toJson(policyPayloadResult); + String policyPayload = new GsonBuilder().setPrettyPrinting().create().toJson(policyPayloadResult); + logger.info("Micro service policy payload: " + policyPayload); + return policyPayload; } } diff --git a/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java b/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java new file mode 100644 index 000000000..33148f0b6 --- /dev/null +++ b/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java @@ -0,0 +1,150 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.clamp.policy.operational; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.apache.commons.lang3.math.NumberUtils; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.DumperOptions.ScalarStyle; +import org.yaml.snakeyaml.Yaml; + +/** + * + * This class contains the code required to support the sending of Legacy + * operational payload to policy engine. This will probably disappear in El + * Alto. + * + */ +public class LegacyOperationalPolicy { + + private LegacyOperationalPolicy() { + + } + + private static void translateStringValues(String jsonKey, String stringValue, JsonElement parentJsonElement) { + if (stringValue.equalsIgnoreCase("true") || stringValue.equalsIgnoreCase("false")) { + parentJsonElement.getAsJsonObject().addProperty(jsonKey, Boolean.valueOf(stringValue)); + + } else if (NumberUtils.isParsable(stringValue)) { + parentJsonElement.getAsJsonObject().addProperty(jsonKey, Long.parseLong(stringValue)); + } + } + + private static JsonElement removeAllQuotes(JsonElement jsonElement) { + if (jsonElement.isJsonArray()) { + for (JsonElement element : jsonElement.getAsJsonArray()) { + removeAllQuotes(element); + } + } else if (jsonElement.isJsonObject()) { + for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) { + if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) { + translateStringValues(entry.getKey(), entry.getValue().getAsString(), jsonElement); + } else { + removeAllQuotes(entry.getValue()); + } + } + } + return jsonElement; + } + + public static JsonElement reworkPayloadAttributes(JsonElement policyJson) { + for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) { + JsonElement payloadElem = policy.getAsJsonObject().get("payload"); + String payloadString = payloadElem != null ? payloadElem.getAsString() : ""; + if (!payloadString.isEmpty()) { + Map<String, String> testMap = new Yaml().load(payloadString); + String json = new GsonBuilder().create().toJson(testMap); + policy.getAsJsonObject().add("payload", new GsonBuilder().create().fromJson(json, JsonElement.class)); + } + } + return policyJson; + } + + private static void replacePropertiesIfEmpty(JsonElement policy, String key, String valueIfEmpty) { + JsonElement payloadElem = policy.getAsJsonObject().get(key); + String payloadString = payloadElem != null ? payloadElem.getAsString() : ""; + if (payloadString.isEmpty()) { + policy.getAsJsonObject().addProperty(key, valueIfEmpty); + } + } + + private static JsonElement fulfillPoliciesTreeField(JsonElement policyJson) { + for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) { + replacePropertiesIfEmpty(policy, "success", "final_success"); + replacePropertiesIfEmpty(policy, "failure", "final_failure"); + replacePropertiesIfEmpty(policy, "failure_timeout", "final_failure_timeout"); + replacePropertiesIfEmpty(policy, "failure_retries", "final_failure_retries"); + replacePropertiesIfEmpty(policy, "failure_exception", "final_failure_exception"); + replacePropertiesIfEmpty(policy, "failure_guard", "final_failure_guard"); + } + return policyJson; + } + + private static Map<String, Object> createMap(JsonElement jsonElement) { + Map<String, Object> mapResult = new TreeMap<>(); + + if (jsonElement.isJsonObject()) { + for (Entry<String, JsonElement> entry : jsonElement.getAsJsonObject().entrySet()) { + if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) { + mapResult.put(entry.getKey(), entry.getValue().getAsString()); + } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isBoolean()) { + mapResult.put(entry.getKey(), entry.getValue().getAsBoolean()); + } else if (entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isNumber()) { + // Only int ro long normally, we don't need float here + mapResult.put(entry.getKey(), entry.getValue().getAsLong()); + } else if (entry.getValue().isJsonArray()) { + List<Map<String, Object>> newArray = new ArrayList<>(); + mapResult.put(entry.getKey(), newArray); + for (JsonElement element : entry.getValue().getAsJsonArray()) { + newArray.add(createMap(element)); + } + } else if (entry.getValue().isJsonObject()) { + mapResult.put(entry.getKey(), createMap(entry.getValue())); + } + } + } + return mapResult; + } + + public static String createPolicyPayloadYamlLegacy(JsonElement operationalPolicyJsonElement) { + JsonElement opPolicy = fulfillPoliciesTreeField( + removeAllQuotes(reworkPayloadAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy()))); + Map<?, ?> jsonMap = createMap(opPolicy); + DumperOptions options = new DumperOptions(); + options.setDefaultScalarStyle(ScalarStyle.PLAIN); + options.setIndent(2); + options.setPrettyFlow(true); + // Policy can't support { } in the yaml + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + return (new Yaml(options)).dump(jsonMap); + } +} diff --git a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java index b2f6109f7..62c5a1e9f 100644 --- a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java +++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java @@ -23,6 +23,8 @@ package org.onap.clamp.policy.operational; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -45,6 +47,7 @@ import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import javax.persistence.Transient; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -52,6 +55,7 @@ import org.hibernate.annotations.TypeDefs; import org.onap.clamp.dao.model.jsontype.StringJsonUserType; import org.onap.clamp.loop.Loop; import org.onap.clamp.policy.Policy; +import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @Entity @@ -63,6 +67,9 @@ public class OperationalPolicy implements Serializable, Policy { */ private static final long serialVersionUID = 6117076450841538255L; + @Transient + private static final EELFLogger logger = EELFManager.getInstance().getLogger(OperationalPolicy.class); + @Id @Expose @Column(nullable = false, name = "name", unique = true) @@ -176,21 +183,33 @@ public class OperationalPolicy implements Serializable, Policy { operationalPolicyDetails.add("metadata", metadata); metadata.addProperty("policy-id", this.name); - operationalPolicyDetails.add("properties", this.configurationsJson.get("operational_policy")); + operationalPolicyDetails.add("properties", LegacyOperationalPolicy + .reworkPayloadAttributes(this.configurationsJson.get("operational_policy").deepCopy())); Gson gson = new GsonBuilder().create(); + Map<?, ?> jsonMap = gson.fromJson(gson.toJson(policyPayloadResult), Map.class); - return (new Yaml()).dump(jsonMap); + + DumperOptions options = new DumperOptions(); + options.setIndent(2); + options.setPrettyFlow(true); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + return (new Yaml(options)).dump(jsonMap); } @Override public String createPolicyPayload() throws UnsupportedEncodingException { - // Now the Yaml payload must be injected in a json ... + // Now using the legacy payload fo Dublin JsonObject payload = new JsonObject(); payload.addProperty("policy-id", this.getName()); - payload.addProperty("content", URLEncoder.encode(createPolicyPayloadYaml(), StandardCharsets.UTF_8.toString())); - return new GsonBuilder().setPrettyPrinting().create().toJson(payload); + payload.addProperty("content", URLEncoder.encode( + LegacyOperationalPolicy.createPolicyPayloadYamlLegacy(this.configurationsJson.get("operational_policy")), + StandardCharsets.UTF_8.toString())); + String opPayload = new GsonBuilder().setPrettyPrinting().create().toJson(payload); + logger.info("Operational policy payload: " + opPayload); + return opPayload; } /** @@ -206,10 +225,11 @@ public class OperationalPolicy implements Serializable, Policy { for (Entry<String, JsonElement> guardElem : guardsList.getAsJsonObject().entrySet()) { JsonObject guard = new JsonObject(); guard.addProperty("policy-id", guardElem.getKey()); - guard.add("contents", guardElem.getValue()); + guard.add("content", guardElem.getValue()); result.put(guardElem.getKey(), new GsonBuilder().create().toJson(guard)); } } + logger.info("Guard policy payload: " + result); return result; } |