From c2ac232af66853dc6bc06f6cf4b03e5319eceb85 Mon Sep 17 00:00:00 2001 From: Piotr Darosz Date: Thu, 7 Mar 2019 13:04:52 +0100 Subject: [PATCH] Extract modules names and relations Extract modules names and relations from DCAE_INVENTORY_BLUEPRINT Change-Id: Ia419b946e15f399d3c4e8c75f836fde6b4b3dbed Issue-ID: CLAMP-283 Signed-off-by: Piotr Darosz --- .../sdc/controller/installer/BlueprintParser.java | 138 +++++++++++++++ .../sdc/controller/installer/ChainGenerator.java | 82 +++++++++ .../controller/installer/CsarInstallerImpl.java | 15 ++ .../sdc/controller/installer/MicroService.java | 68 ++++++++ .../controller/installer/BlueprintParserTest.java | 190 +++++++++++++++++++++ .../controller/installer/ChainGeneratorTest.java | 75 ++++++++ .../clds/blueprint-with-microservice-chain.yaml | 92 ++++++++++ src/test/resources/clds/holmes-old-style-ms.yaml | 117 +++++++++++++ .../clds/single-microservice-fragment-valid.yaml | 23 +++ .../single-microservice-fragment-without-name.yaml | 22 +++ ...e-microservice-fragment-without-properties.yaml | 18 ++ ...icroservice-fragment-without-relationships.yaml | 18 ++ src/test/resources/clds/tca-old-style-ms.yaml | 169 ++++++++++++++++++ 13 files changed, 1027 insertions(+) create mode 100644 src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java create mode 100644 src/main/java/org/onap/clamp/clds/sdc/controller/installer/ChainGenerator.java create mode 100644 src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java create mode 100644 src/test/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParserTest.java create mode 100644 src/test/java/org/onap/clamp/clds/sdc/controller/installer/ChainGeneratorTest.java create mode 100644 src/test/resources/clds/blueprint-with-microservice-chain.yaml create mode 100644 src/test/resources/clds/holmes-old-style-ms.yaml create mode 100644 src/test/resources/clds/single-microservice-fragment-valid.yaml create mode 100644 src/test/resources/clds/single-microservice-fragment-without-name.yaml create mode 100644 src/test/resources/clds/single-microservice-fragment-without-properties.yaml create mode 100644 src/test/resources/clds/single-microservice-fragment-without-relationships.yaml create mode 100644 src/test/resources/clds/tca-old-style-ms.yaml 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 new file mode 100644 index 00000000..16aee277 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParser.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 Nokia 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.clds.sdc.controller.installer; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.json.JSONObject; +import org.springframework.stereotype.Component; +import org.yaml.snakeyaml.Yaml; + +@Component +public class BlueprintParser { + + static final String TCA = "TCA"; + static final String HOLMES = "Holmes"; + private static final String TCA_POLICY = "tca_policy"; + private static final String HOLMES_PREFIX = "holmes"; + private static final String NODE_TEMPLATES = "node_templates"; + private static final String DCAE_NODES = "dcae.nodes."; + private static final String TYPE = "type"; + private static final String PROPERTIES = "properties"; + private static final String NAME = "name"; + 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"; + + BlueprintParser() {} + + Set getMicroServices(String blueprintString) { + Set microServices = new HashSet<>(); + JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString); + JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject(); + + for (Entry entry : results.entrySet()) { + JsonObject nodeTemplate = entry.getValue().getAsJsonObject(); + if (nodeTemplate.get(TYPE).getAsString().contains(DCAE_NODES)) { + MicroService microService = getNodeRepresentation(entry); + microServices.add(microService); + } + } + microServices.removeIf(ms -> TCA_POLICY.equals(ms.getName())); + return microServices; + } + + List fallbackToOneMicroService(String blueprintString) { + JsonObject jsonObject = BlueprintParser.convertToJson(blueprintString); + JsonObject results = jsonObject.get(NODE_TEMPLATES).getAsJsonObject(); + String theBiggestMicroServiceContent = ""; + String theBiggestMicroServiceKey = ""; + for (Entry entry : results.entrySet()) { + String msAsString = entry.getValue().toString(); + int len =msAsString.length(); + if(len > theBiggestMicroServiceContent.length()) { + theBiggestMicroServiceContent = msAsString; + theBiggestMicroServiceKey = entry.getKey(); + } + } + String msName = theBiggestMicroServiceKey.toLowerCase().contains(HOLMES_PREFIX) ? HOLMES : TCA; + return Collections.singletonList(new MicroService(msName, "")); + } + + String getName(Entry entry) { + String microServiceYamlName = entry.getKey(); + JsonObject ob = entry.getValue().getAsJsonObject(); + if (ob.has(PROPERTIES)) { + JsonObject properties = ob.get(PROPERTIES).getAsJsonObject(); + if (properties.has(NAME)) { + return properties.get(NAME).getAsString(); + } + } + return microServiceYamlName; + } + + String getInput(Entry entry) { + JsonObject ob = entry.getValue().getAsJsonObject(); + if (ob.has(RELATIONSHIPS)) { + JsonArray relationships = ob.getAsJsonArray(RELATIONSHIPS); + for (JsonElement element : relationships) { + String target = getTarget(element.getAsJsonObject()); + if(!target.isEmpty()) { + return target; + } + } + } + return ""; + } + + MicroService getNodeRepresentation(Entry entry) { + String name = getName(entry); + String getInputFrom = getInput(entry); + return new MicroService(name, getInputFrom); + } + + private String getTarget(JsonObject elementObject) { + if (elementObject.has(TYPE) && + elementObject.has(TARGET) && + elementObject.get(TYPE).getAsString().equals(CLAMP_NODE_RELATIONSHIPS_GETS_INPUT_FROM)) { + return elementObject.get(TARGET).getAsString(); + } + return ""; + } + + private static JsonObject convertToJson(String yamlString) { + Yaml yaml = new Yaml(); + Map map = yaml.load(yamlString); + + JSONObject jsonObject = new JSONObject(map); + return new Gson().fromJson(jsonObject.toString(), JsonObject.class); + } +} diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/ChainGenerator.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/ChainGenerator.java new file mode 100644 index 00000000..b05b80f0 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/ChainGenerator.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 Nokia 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.clds.sdc.controller.installer; + +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class ChainGenerator { + + ChainGenerator() {} + + List getChainOfMicroServices(Set input) { + LinkedList returnList = new LinkedList<>(); + if(preValidate(input)) { + LinkedList theList = new LinkedList<>(); + for (MicroService ms : input) { + insertNodeTemplateIntoChain(ms, theList); + } + if(postValidate(theList)) { + returnList = theList; + } + } + return returnList; + } + + private boolean preValidate(Set input) { + List noInputs = + input.stream().filter(ms -> "".equals(ms.getInputFrom())).collect(Collectors.toList()); + return noInputs.size() == 1; + } + + private boolean postValidate(LinkedList microServices) { + for (int i = 1; i < microServices.size() - 1; i++) { + MicroService prev = microServices.get(i-1); + MicroService current = microServices.get(i); + if(!current.getInputFrom().equals(prev.getName())) { + return false; + } + } + return true; + } + + private void insertNodeTemplateIntoChain(MicroService microServicetoInsert, + LinkedList chainOfMicroServices) { + int insertIndex = 0; + for (int i = 0; i < chainOfMicroServices.size(); i++) { + MicroService current = chainOfMicroServices.get(i); + if (microServicetoInsert.getName().equals(current.getInputFrom())) { + insertIndex = i; + break; + } else if (current.getName().equals(microServicetoInsert.getInputFrom())) { + insertIndex = i + 1; + break; + } + } + chainOfMicroServices.add(insertIndex, microServicetoInsert); + } +} diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImpl.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImpl.java index 6841b87b..1303f2ab 100644 --- a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImpl.java +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarInstallerImpl.java @@ -35,6 +35,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import java.util.Set; import javax.annotation.PostConstruct; import javax.xml.transform.TransformerException; @@ -92,6 +93,12 @@ public class CsarInstallerImpl implements CsarInstaller { @Autowired private XslTransformer cldsBpmnTransformer; + @Autowired + private BlueprintParser blueprintParser; + + @Autowired + private ChainGenerator chainGenerator; + @PostConstruct public void loadConfiguration() throws IOException { BlueprintParserMappingConfiguration @@ -242,6 +249,14 @@ public class CsarInstallerImpl implements CsarInstaller { private CldsTemplate createFakeCldsTemplate(CsarHandler csar, BlueprintArtifact blueprintArtifact, BlueprintParserFilesConfiguration configFiles) throws IOException, SdcArtifactInstallerException { + + Set microServicesFromBlueprint = blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint()) ; + List microServicesChain = chainGenerator.getChainOfMicroServices(microServicesFromBlueprint); + if(microServicesChain.isEmpty()) { + microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint()); + } + //place where SVG text will be generated + CldsTemplate template = new CldsTemplate(); template.setBpmnId("Sdc-Generated"); template 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 new file mode 100644 index 00000000..287ac9a9 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/MicroService.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 Nokia 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.clds.sdc.controller.installer; + +import java.util.Objects; + +public class MicroService { + private final String name; + private final String inputFrom; + + public MicroService(String name, String inputFrom) { + this.name = name; + this.inputFrom = inputFrom; + } + public String getName() { + return name; + } + + public String getInputFrom() { + return inputFrom; + } + + @Override + public String toString() { + return "MicroService{" + + "name='" + name + '\'' + + ", inputFrom='" + inputFrom + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MicroService that = (MicroService) o; + return name.equals(that.name) && + inputFrom.equals(that.inputFrom); + } + + @Override + public int hashCode() { + return Objects.hash(name, inputFrom); + } +} diff --git a/src/test/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParserTest.java b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParserTest.java new file mode 100644 index 00000000..2a2ab94e --- /dev/null +++ b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/BlueprintParserTest.java @@ -0,0 +1,190 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 Nokia 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.clds.sdc.controller.installer; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.json.JSONObject; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.clamp.clds.util.ResourceFileUtil; +import org.yaml.snakeyaml.Yaml; + +public class BlueprintParserTest { + private static final Gson GSON = new Gson(); + private static final String FIRST_APPP = "first_app"; + private static final String SECOND_APPP = "second_app"; + private static final String THIRD_APPP = "third_app"; + + private static String microServiceTheWholeBlueprintValid; + private static String microServiceBlueprintOldStyleTCA; + private static String microServiceBlueprintOldStyleHolmes; + + private static JsonObject jsonObjectBlueprintValid; + private static JsonObject jsonObjectBlueprintWithoutName; + private static JsonObject jsonObjectBlueprintWithoutProperties; + private static JsonObject jsonObjectBlueprintWithoutRelationships; + + @BeforeClass + public static void loadBlueprints() throws IOException { + microServiceTheWholeBlueprintValid = ResourceFileUtil + .getResourceAsString("clds/blueprint-with-microservice-chain.yaml"); + microServiceBlueprintOldStyleTCA = ResourceFileUtil + .getResourceAsString("clds/tca-old-style-ms.yaml"); + microServiceBlueprintOldStyleHolmes = ResourceFileUtil + .getResourceAsString("clds/holmes-old-style-ms.yaml"); + + String microServiceBlueprintValid = ResourceFileUtil + .getResourceAsString("clds/single-microservice-fragment-valid.yaml"); + String microServiceBlueprintWithoutName = ResourceFileUtil + .getResourceAsString("clds/single-microservice-fragment-without-name.yaml"); + String microServiceBlueprintWithoutProperties = ResourceFileUtil + .getResourceAsString("clds/single-microservice-fragment-without-properties.yaml"); + String microServiceBlueprintWithoutRelationships = ResourceFileUtil + .getResourceAsString("clds/single-microservice-fragment-without-relationships.yaml"); + + jsonObjectBlueprintValid = yamlToJson(microServiceBlueprintValid); + jsonObjectBlueprintWithoutName = yamlToJson(microServiceBlueprintWithoutName); + jsonObjectBlueprintWithoutProperties = yamlToJson(microServiceBlueprintWithoutProperties); + jsonObjectBlueprintWithoutRelationships = yamlToJson(microServiceBlueprintWithoutRelationships); + + } + + @Test + public void getNameShouldReturnDefinedName() { + final JsonObject jsonObject = jsonObjectBlueprintValid; + String expectedName = jsonObject.get(jsonObject.keySet().iterator().next()) + .getAsJsonObject().get("properties") + .getAsJsonObject().get("name") + .getAsString(); + Entry entry = jsonObject.entrySet().iterator().next(); + String actualName = new BlueprintParser().getName(entry); + + Assert.assertEquals(expectedName, actualName); + } + + @Test + public void getNameShouldReturnServiceNameWhenNoNameDefined() { + final JsonObject jsonObject = jsonObjectBlueprintWithoutName; + + String expectedName = jsonObject.keySet().iterator().next(); + Entry entry = jsonObject.entrySet().iterator().next(); + String actualName = new BlueprintParser().getName(entry); + + Assert.assertEquals(expectedName, actualName); + } + + @Test + public void getNameShouldReturnServiceNameWhenNoPropertiesDefined() { + final JsonObject jsonObject = jsonObjectBlueprintWithoutProperties; + + String expectedName = jsonObject.keySet().iterator().next(); + Entry entry = jsonObject.entrySet().iterator().next(); + String actualName = new BlueprintParser().getName(entry); + + Assert.assertEquals(expectedName, actualName); + } + + @Test + public void getInputShouldReturnInputWhenPresent() { + final JsonObject jsonObject = jsonObjectBlueprintValid; + + String expected = FIRST_APPP; + Entry entry = jsonObject.entrySet().iterator().next(); + String actual = new BlueprintParser().getInput(entry); + + Assert.assertEquals(expected, actual); + } + + @Test + public void getInputShouldReturnEmptyStringWhenAbsent() { + final JsonObject jsonObject = jsonObjectBlueprintWithoutRelationships; + + String expected = ""; + Entry entry = jsonObject.entrySet().iterator().next(); + String actual = new BlueprintParser().getInput(entry); + + Assert.assertEquals(expected, actual); + } + + @Test + public void getNodeRepresentationFromCompleteYaml() { + final JsonObject jsonObject = jsonObjectBlueprintValid; + + MicroService expected = new MicroService(SECOND_APPP, FIRST_APPP); + Entry entry = jsonObject.entrySet().iterator().next(); + MicroService actual = new BlueprintParser().getNodeRepresentation(entry); + + Assert.assertEquals(expected, actual); + } + + @Test + public void getMicroServicesFromBlueprintTest() { + MicroService thirdApp = new MicroService(THIRD_APPP, ""); + MicroService firstApp = new MicroService(FIRST_APPP, THIRD_APPP); + MicroService secondApp = new MicroService(SECOND_APPP, FIRST_APPP); + + Set expected = new HashSet<>(Arrays.asList(firstApp, secondApp, thirdApp)); + Set actual = new BlueprintParser().getMicroServices(microServiceTheWholeBlueprintValid); + + Assert.assertEquals(expected, actual); + } + + @Test + public void fallBackToOneMicroServiceTCATest() { + MicroService tcaMS = new MicroService(BlueprintParser.TCA, ""); + + List expected = Collections.singletonList(tcaMS); + List actual = new BlueprintParser().fallbackToOneMicroService(microServiceBlueprintOldStyleTCA); + + Assert.assertEquals(expected, actual); + } + + @Test + public void fallBackToOneMicroServiceHolmesTest() { + MicroService holmesMS = new MicroService(BlueprintParser.HOLMES, ""); + + List expected = Collections.singletonList(holmesMS); + List actual = + new BlueprintParser().fallbackToOneMicroService(microServiceBlueprintOldStyleHolmes); + + Assert.assertEquals(expected, actual); + } + + private static JsonObject yamlToJson(String yamlString) { + Yaml yaml = new Yaml(); + Map map = yaml.load(yamlString); + JSONObject jsonObject = new JSONObject(map); + return GSON.fromJson(jsonObject.toString(), JsonObject.class); + } +} diff --git a/src/test/java/org/onap/clamp/clds/sdc/controller/installer/ChainGeneratorTest.java b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/ChainGeneratorTest.java new file mode 100644 index 00000000..9573515d --- /dev/null +++ b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/ChainGeneratorTest.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2019 Nokia 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.clds.sdc.controller.installer; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.junit.Assert; +import org.junit.Test; + +public class ChainGeneratorTest { + private static final String FIRST_APPP = "first_app"; + private static final String SECOND_APPP = "second_app"; + private static final String THIRD_APPP = "third_app"; + private static final String FOURTH_APPP = "fourth_app"; + + @Test + public void getChainOfMicroServicesTest() { + MicroService ms1 = new MicroService(FIRST_APPP, ""); + MicroService ms2 = new MicroService(SECOND_APPP, FIRST_APPP); + MicroService ms3 = new MicroService(THIRD_APPP, SECOND_APPP); + MicroService ms4 = new MicroService(FOURTH_APPP, THIRD_APPP); + + List expectedList = Arrays.asList(ms1, ms2, ms3, ms4); + Set inputSet = new HashSet<>(expectedList); + + List actualList = new ChainGenerator().getChainOfMicroServices(inputSet); + Assert.assertEquals(expectedList, actualList); + } + + @Test + public void getChainOfMicroServicesTwiceNoInputTest() { + MicroService ms1 = new MicroService(FIRST_APPP, ""); + MicroService ms2 = new MicroService(SECOND_APPP, ""); + MicroService ms3 = new MicroService(THIRD_APPP, SECOND_APPP); + MicroService ms4 = new MicroService(FOURTH_APPP, FIRST_APPP); + + Set inputSet = new HashSet<>(Arrays.asList(ms1, ms2, ms3, ms4)); + List actualList = new ChainGenerator().getChainOfMicroServices(inputSet); + Assert.assertTrue(actualList.isEmpty()); + } + + @Test + public void getChainOfMicroServicesBranchingTest() { + MicroService ms1 = new MicroService(FIRST_APPP, ""); + MicroService ms2 = new MicroService(SECOND_APPP, FIRST_APPP); + MicroService ms3 = new MicroService(THIRD_APPP, FIRST_APPP); + MicroService ms4 = new MicroService(FOURTH_APPP, FIRST_APPP); + + Set inputSet = new HashSet<>(Arrays.asList(ms1, ms2, ms3, ms4)); + List actualList = new ChainGenerator().getChainOfMicroServices(inputSet); + Assert.assertTrue(actualList.isEmpty()); + } +} \ No newline at end of file diff --git a/src/test/resources/clds/blueprint-with-microservice-chain.yaml b/src/test/resources/clds/blueprint-with-microservice-chain.yaml new file mode 100644 index 00000000..7b7148d5 --- /dev/null +++ b/src/test/resources/clds/blueprint-with-microservice-chain.yaml @@ -0,0 +1,92 @@ +tosca_definitions_version: cloudify_dsl_1_3 + +imports: + - http://www.getcloudify.org/spec/cloudify/3.4/types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R4/k8splugin/1.4.4/k8splugin_types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R4/dcaepolicyplugin/2.3.0/dcaepolicyplugin_types.yaml +inputs: + first_app_docker_image: + type: string + default: "image1" + second_app_docker_image: + type: string + default: "image2" + third_app_docker_image: + type: string + default: "image3" + dmaap_ip: + type: string + default: "message-router:3904" + dmaap_topic: + type: string + default: "/events/unauthenticated.DCAE_CL_OUTPUT" + policy_id: + type: string + default: "policy_id" +node_templates: + second_app: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + properties: + service_component_type: dcaegen2-analytics-tca + service_component_name_override: second_app + image: { get_input: second_app_docker_image } + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + grpc_server.host: "first_app.onap" + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8080:8080 + relationships: + - type: cloudify.relationships.connected_to + target: first_app + - type: clamp_node.relationships.gets_input_from + target: first_app + first_app: + type: dcae.nodes.ContainerizedPlatformComponent + properties: + name: first_app + dns_name: "first_app" + image: { get_input: first_app_docker_image } + container_port: 6565 + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8081:8081 + relationships: + - type: cloudify.relationships.connected_to + target: third_app + - type: clamp_node.relationships.gets_input_from + target: third_app + + third_app: + type: dcae.nodes.ContainerizedPlatformComponent + properties: + name: third_app + dns_name: "third_app" + image: { get_input: third_app_docker_image } + container_port: 443 + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8082:8082 + tca_policy: + type: dcae.nodes.policy + properties: + policy_id: { get_input: policy_id } \ No newline at end of file diff --git a/src/test/resources/clds/holmes-old-style-ms.yaml b/src/test/resources/clds/holmes-old-style-ms.yaml new file mode 100644 index 00000000..3f0c9a60 --- /dev/null +++ b/src/test/resources/clds/holmes-old-style-ms.yaml @@ -0,0 +1,117 @@ +tosca_definitions_version: cloudify_dsl_1_3 +imports: + - http://www.getcloudify.org/spec/cloudify/3.4/types.yaml + - https://nexus01.research.att.com:8443/repository/solutioning01-mte2-raw/type_files/docker/2.3.0+t.0.4/node-type.yaml + - https://nexus01.research.att.com:8443/repository/solutioning01-mte2-raw/type_files/relationship/1.0.0/node-type.yaml + - http://nexus01.research.att.com:8081/repository/solutioning01-mte2-raw/type_files/dmaap/1.2.0/dmaap.yaml +inputs: + dcae_service_location: + type: string + docker_host_override: + type: string + topic0_aaf_password: + type: string + topic0_aaf_username: + type: string + topic0_client_role: + type: string + topic1_aaf_password: + type: string + topic1_aaf_username: + type: string + topic1_client_role: + type: string + location_id: + type: string + service_id: + type: string + policy_id: + type: string + default: "CLAMPPolicyTriggerNoaapp_v1_0_29b0578b_dcee_472c_8cdd0.ClosedLoop_860ee9f2_ba64_11e8_a16b_02bd571477fe_TCA_1d13unw" +node_templates: + policy_0: + type: dcae.nodes.policy + properties: + policy_model: policy.nodes.holmes + policy_filter: "DCAE.Config_Holmes.*" + policy_id: + get_input: policy_id + docker_host_host: + type: dcae.nodes.SelectedDockerHost + properties: + docker_host_override: + get_input: docker_host_override + location_id: + get_input: dcae_service_location + holmes_rule_homes-rule: + type: dcae.nodes.DockerContainerForComponentsUsingDmaap + properties: + application_config: + services_calls: + - msb_config: + concat: + - '{{' + - get_property: + - SELF + - msb_config + - node_name + - '}}' + streams_publishes: [] + streams_subscribes: + - sec_measurement_unsecure: + aaf_password: + get_input: topic0_aaf_password + aaf_username: + get_input: topic0_aaf_username + dmaap_info: <> + type: message_router + - sec_measurement: + aaf_password: + get_input: topic1_aaf_password + aaf_username: + get_input: topic1_aaf_username + dmaap_info: <> + type: message_router + docker_config: + healthcheck: + endpoint: api/holmes-rule-mgmt/v1/healthcheck + interval: 15s + timeout: 1s + type: http + ports: + - 9101:9101 + image: nexus3.onap.org:10001/onap/holmes/rule-manamgement:latest + location_id: + get_input: dcae_service_location + service_component_type: dcae-analytics-holmes-rule-manamgement + streams_publishes: [] + streams_subscribes: + - client_role: + get_input: topic0_client_role + location: + get_input: dcae_service_location + name: topic0 + type: message_router + - client_role: + get_input: topic1_client_role + location: + get_input: dcae_service_location + name: topic1 + type: message_router + relationships: + - target: docker_host_host + type: dcae.relationships.component_contained_in + - target: topic0 + type: dcae.relationships.subscribe_to_events + - target: topic1 + type: dcae.relationships.subscribe_to_events + - target: policy_0 + type: dcae.relationships.depends_on + topic0: + type: dcae.nodes.Topic + properties: + topic_name: '' + topic1: + type: dcae.nodes.Topic + properties: + topic_name: '' diff --git a/src/test/resources/clds/single-microservice-fragment-valid.yaml b/src/test/resources/clds/single-microservice-fragment-valid.yaml new file mode 100644 index 00000000..abaae20b --- /dev/null +++ b/src/test/resources/clds/single-microservice-fragment-valid.yaml @@ -0,0 +1,23 @@ +second_app: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + properties: + service_component_type: dcaegen2-analytics-tca + service_component_name_override: second_app + image: { get_input: second_app_docker_image } + name: second_app + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + grpc_server.host: "first_app.onap" + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8080:8080 + relationships: + - type: cloudify.relationships.connected_to + target: first_app + - type: clamp_node.relationships.gets_input_from + target: first_app \ No newline at end of file diff --git a/src/test/resources/clds/single-microservice-fragment-without-name.yaml b/src/test/resources/clds/single-microservice-fragment-without-name.yaml new file mode 100644 index 00000000..f9ac53ca --- /dev/null +++ b/src/test/resources/clds/single-microservice-fragment-without-name.yaml @@ -0,0 +1,22 @@ +second_app: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + properties: + service_component_type: dcaegen2-analytics-tca + service_component_name_override: second_app + image: { get_input: second_app_docker_image } + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + grpc_server.host: "first_app.onap" + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8080:8080 + relationships: + - type: cloudify.relationships.connected_to + target: first_app + - type: clamp_node.relationships.gets_input_from + target: first_app \ No newline at end of file diff --git a/src/test/resources/clds/single-microservice-fragment-without-properties.yaml b/src/test/resources/clds/single-microservice-fragment-without-properties.yaml new file mode 100644 index 00000000..a34ccc6d --- /dev/null +++ b/src/test/resources/clds/single-microservice-fragment-without-properties.yaml @@ -0,0 +1,18 @@ +second_app: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + grpc_server.host: "first_app.onap" + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8080:8080 + relationships: + - type: cloudify.relationships.connected_to + target: first_app + - type: clamp_node.relationships.gets_input_from + target: first_app \ No newline at end of file diff --git a/src/test/resources/clds/single-microservice-fragment-without-relationships.yaml b/src/test/resources/clds/single-microservice-fragment-without-relationships.yaml new file mode 100644 index 00000000..0354acd6 --- /dev/null +++ b/src/test/resources/clds/single-microservice-fragment-without-relationships.yaml @@ -0,0 +1,18 @@ +second_app: + type: dcae.nodes.ContainerizedServiceComponentUsingDmaap + properties: + service_component_type: dcaegen2-analytics-tca + service_component_name_override: second_app + image: { get_input: second_app_docker_image } + name: second_app + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + grpc_server.host: "first_app.onap" + dmaap_ip: {get_input: dmaap_ip} + dmapp_topic: {get_input: dmaap_topic} + policy_id: {get_input: policy_id} + ports: + - 8080:8080 \ No newline at end of file diff --git a/src/test/resources/clds/tca-old-style-ms.yaml b/src/test/resources/clds/tca-old-style-ms.yaml new file mode 100644 index 00000000..b976190a --- /dev/null +++ b/src/test/resources/clds/tca-old-style-ms.yaml @@ -0,0 +1,169 @@ +tosca_definitions_version: cloudify_dsl_1_3 +imports: + - "http://www.getcloudify.org/spec/cloudify/3.4/types.yaml" + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R2/dockerplugin/3.2.0/dockerplugin_types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R2/relationshipplugin/1.0.0/relationshipplugin_types.yaml + - https://nexus.onap.org/service/local/repositories/raw/content/org.onap.dcaegen2.platform.plugins/R2/dcaepolicyplugin/2.3.0/dcaepolicyplugin_types.yaml + +inputs: + dh_override: + type: string + default: "component_dockerhost" + dh_location_id: + type: string + default: "zone1" + aaiEnrichmentHost: + type: string + default: "none" + aaiEnrichmentPort: + type: string + default: 8443 + enableAAIEnrichment: + type: string + default: false + dmaap_host: + type: string + default: dmaap.onap-message-router + dmaap_port: + type: string + default: 3904 + enableRedisCaching: + type: string + default: false + redisHosts: + type: string + tag_version: + type: string + default: "nexus3.onap.org:10001/onap//onap/org.onap.dcaegen2.deployments.tca-cdap-container:1.0.0" + consul_host: + type: string + default: consul-server.onap-consul + consul_port: + type: string + default: "8500" + cbs_host: + type: string + default: "config-binding-service.dcae" + cbs_port: + type: string + default: "10000" + policy_id: + type: string + default: "none" + external_port: + type: string + description: "Port for CDAPgui to be exposed" + default: "32010" + +node_templates: + docker_service_host: + properties: + docker_host_override: + get_input: dh_override + location_id: + get_input: dh_location_id + type: dcae.nodes.SelectedDockerHost + tca_docker: + relationships: + - type: dcae.relationships.component_contained_in + target: docker_service_host + - target: tca_policy + type: cloudify.relationships.depends_on + type: dcae.nodes.DockerContainerForComponentsUsingDmaap + properties: + application_config: + app_config: + appDescription: DCAE Analytics Threshold Crossing Alert Application + appName: dcae-tca + tcaAlertsAbatementTableName: TCAAlertsAbatementTable + tcaAlertsAbatementTableTTLSeconds: '1728000' + tcaSubscriberOutputStreamName: TCASubscriberOutputStream + tcaVESAlertsTableName: TCAVESAlertsTable + tcaVESAlertsTableTTLSeconds: '1728000' + tcaVESMessageStatusTableName: TCAVESMessageStatusTable + tcaVESMessageStatusTableTTLSeconds: '86400' + thresholdCalculatorFlowletInstances: '2' + app_preferences: + aaiEnrichmentHost: + get_input: aaiEnrichmentHost + aaiEnrichmentIgnoreSSLCertificateErrors: 'true' + aaiEnrichmentPortNumber: '8443' + aaiEnrichmentProtocol: https + aaiEnrichmentUserName: DCAE + aaiEnrichmentUserPassword: DCAE + aaiVMEnrichmentAPIPath: /aai/v11/search/nodes-query + aaiVNFEnrichmentAPIPath: /aai/v11/network/generic-vnfs/generic-vnf + enableAAIEnrichment: + get_input: enableAAIEnrichment + enableRedisCaching: + get_input: enableRedisCaching + redisHosts: + get_input: redisHosts + enableAlertCEFFormat: 'false' + publisherContentType: application/json + publisherHostName: + get_input: dmaap_host + publisherHostPort: + get_input: dmaap_port + publisherMaxBatchSize: '1' + publisherMaxRecoveryQueueSize: '100000' + publisherPollingInterval: '20000' + publisherProtocol: http + publisherTopicName: unauthenticated.DCAE_CL_OUTPUT + subscriberConsumerGroup: OpenDCAE-c12 + subscriberConsumerId: c12 + subscriberContentType: application/json + subscriberHostName: + get_input: dmaap_host + subscriberHostPort: + get_input: dmaap_port + subscriberMessageLimit: '-1' + subscriberPollingInterval: '30000' + subscriberProtocol: http + subscriberTimeoutMS: '-1' + subscriberTopicName: unauthenticated.SEC_MEASUREMENT_OUTPUT + tca_policy_default: '{"domain":"measurementsForVfScaling","metricsPerEventName":[{"eventName":"vFirewallBroadcastPackets","controlLoopSchemaType":"VNF","policyScope":"DCAE","policyName":"DCAE.Config_tca-hi-lo","policyVersion":"v0.0.1","thresholds":[{"closedLoopControlName":"ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a","version":"1.0.2","fieldPath":"$.event.measurementsForVfScalingFields.vNicUsageArray[*].receivedTotalPacketsDelta","thresholdValue":300,"direction":"LESS_OR_EQUAL","severity":"MAJOR","closedLoopEventStatus":"ONSET"},{"closedLoopControlName":"ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a","version":"1.0.2","fieldPath":"$.event.measurementsForVfScalingFields.vNicUsageArray[*].receivedTotalPacketsDelta","thresholdValue":700,"direction":"GREATER_OR_EQUAL","severity":"CRITICAL","closedLoopEventStatus":"ONSET"}]},{"eventName":"vLoadBalancer","controlLoopSchemaType":"VM","policyScope":"DCAE","policyName":"DCAE.Config_tca-hi-lo","policyVersion":"v0.0.1","thresholds":[{"closedLoopControlName":"ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3","version":"1.0.2","fieldPath":"$.event.measurementsForVfScalingFields.vNicUsageArray[*].receivedTotalPacketsDelta","thresholdValue":300,"direction":"GREATER_OR_EQUAL","severity":"CRITICAL","closedLoopEventStatus":"ONSET"}]},{"eventName":"Measurement_vGMUX","controlLoopSchemaType":"VNF","policyScope":"DCAE","policyName":"DCAE.Config_tca-hi-lo","policyVersion":"v0.0.1","thresholds":[{"closedLoopControlName":"ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","version":"1.0.2","fieldPath":"$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value","thresholdValue":0,"direction":"EQUAL","severity":"MAJOR","closedLoopEventStatus":"ABATED"},{"closedLoopControlName":"ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","version":"1.0.2","fieldPath":"$.event.measurementsForVfScalingFields.additionalMeasurements[*].arrayOfFields[0].value","thresholdValue":0,"direction":"GREATER","severity":"CRITICAL","closedLoopEventStatus":"ONSET"}]}]}' + service_component_type: dcaegen2-analytics_tca + docker_config: + healthcheck: + endpoint: /healthcheck + interval: 15s + timeout: 1s + type: http + image: + get_input: tag_version + interfaces: + cloudify.interfaces.lifecycle: + start: + inputs: + envs: + DMAAPHOST: + { get_input: dmaap_host } + DMAAPPORT: + { get_input: dmaap_port } + DMAAPPUBTOPIC: "unauthenticated.DCAE_CL_OUTPUT" + DMAAPSUBTOPIC: "unauthenticated.SEC_MEASUREMENT_OUTPUT" + AAIHOST: + { get_input: aaiEnrichmentHost } + AAIPORT: + { get_input: aaiEnrichmentPort } + CONSUL_HOST: + { get_input: consul_host } + CONSUL_PORT: + { get_input: consul_port } + CBS_HOST: + { get_input: cbs_host } + CBS_PORT: + { get_input: cbs_port } + CONFIG_BINDING_SERVICE: "config_binding_service" + ports: + - concat: ["11011:", { get_input: external_port }] + stop: + inputs: + cleanup_image: true + tca_policy: + type: dcae.nodes.policy + properties: + policy_id: + get_input: policy_id + -- 2.16.6