From f9e2ceeae29504505f631086e612fad4e1e16979 Mon Sep 17 00:00:00 2001 From: sebdet Date: Fri, 9 Aug 2019 18:36:09 +0200 Subject: Draft of op policy First draft of the Operational policy based on JsonEditor, it's a wip code Issue-ID: CLAMP-430 Change-Id: I2c7970e94488f4020377fd9d4d00691a3590b13e Signed-off-by: sebdet --- src/main/java/org/onap/clamp/loop/Loop.java | 39 +- .../org/onap/clamp/loop/LoopCsarInstaller.java | 68 +-- .../operational/LegacyOperationalPolicy.java | 37 +- .../policy/operational/OperationalPolicy.java | 37 +- .../OperationalPolicyRepresentationBuilder.java | 146 ++++++ .../operational_policies/operational_policy.json | 362 +++++++++++++ .../microservice/OperationalPolicyPayloadTest.java | 20 +- ...OperationalPolicyRepresentationBuilderTest.java | 52 ++ ...OperationalPolicyRepresentationBuilderTest.java | 52 ++ .../resources/tosca/guard1-policy-payload.json | 19 +- .../resources/tosca/guard2-policy-payload.json | 20 +- .../tosca/operational-policy-json-schema.json | 574 +++++++++++++++++++++ .../tosca/operational-policy-payload-legacy.yaml | 52 +- .../tosca/operational-policy-payload.json | 2 +- .../tosca/operational-policy-payload.yaml | 60 ++- .../tosca/operational-policy-properties.json | 149 +++--- .../resources/tosca/pdp-group-policy-payload.json | 4 +- 17 files changed, 1472 insertions(+), 221 deletions(-) create mode 100644 src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java create mode 100644 src/main/resources/clds/json-schema/operational_policies/operational_policy.json create mode 100644 src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java create mode 100644 src/test/resources/clds/OperationalPolicyRepresentationBuilderTest.java create mode 100644 src/test/resources/tosca/operational-policy-json-schema.json (limited to 'src') diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java index 2393f2498..37d597eeb 100644 --- a/src/main/java/org/onap/clamp/loop/Loop.java +++ b/src/main/java/org/onap/clamp/loop/Loop.java @@ -23,9 +23,13 @@ package org.onap.clamp.loop; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.Expose; +import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; @@ -59,6 +63,7 @@ import org.onap.clamp.loop.components.external.PolicyComponent; import org.onap.clamp.loop.log.LoopLog; import org.onap.clamp.policy.microservice.MicroServicePolicy; import org.onap.clamp.policy.operational.OperationalPolicy; +import org.onap.clamp.policy.operational.OperationalPolicyRepresentationBuilder; @Entity @Table(name = "loops") @@ -70,6 +75,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) @@ -90,6 +98,11 @@ public class Loop implements Serializable { @Column(columnDefinition = "MEDIUMTEXT", name = "svg_representation") private String svgRepresentation; + @Expose + @Type(type = "json") + @Column(columnDefinition = "json", name = "operational_policy_schema") + private JsonObject operationalPolicySchema; + @Expose @Type(type = "json") @Column(columnDefinition = "json", name = "global_properties_json") @@ -131,6 +144,9 @@ public class Loop implements Serializable { this.addComponent(new DcaeComponent()); } + /** + * Public constructor. + */ public Loop() { initializeExternalComponents(); } @@ -256,6 +272,13 @@ public class Loop implements Serializable { void setModelPropertiesJson(JsonObject modelPropertiesJson) { this.modelPropertiesJson = modelPropertiesJson; + try { + this.operationalPolicySchema = OperationalPolicyRepresentationBuilder + .generateOperationalPolicySchema(this.getModelPropertiesJson()); + } catch (JsonSyntaxException | IOException | NullPointerException e) { + logger.error("Unable to generate the operational policy Schema ... ", e); + this.operationalPolicySchema = new JsonObject(); + } } public Map getComponents() { @@ -273,20 +296,16 @@ public class Loop implements Serializable { /** * Generate the loop name. * - * @param serviceName - * The service name - * @param serviceVersion - * The service version - * @param resourceName - * The resource name - * @param blueprintFileName - * The blueprint file name + * @param serviceName The service name + * @param serviceVersion The service version + * @param resourceName The resource name + * @param blueprintFileName The blueprint file name * @return The generated loop name */ static String generateLoopName(String serviceName, String serviceVersion, String resourceName, - String blueprintFilename) { + String blueprintFilename) { StringBuilder buffer = new StringBuilder("LOOP_").append(serviceName).append("_v").append(serviceVersion) - .append("_").append(resourceName).append("_").append(blueprintFilename.replaceAll(".yaml", "")); + .append("_").append(resourceName).append("_").append(blueprintFilename.replaceAll(".yaml", "")); return buffer.toString().replace('.', '_').replaceAll(" ", ""); } diff --git a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java b/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java index ad13ad34d..41d34a224 100644 --- a/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java +++ b/src/main/java/org/onap/clamp/loop/LoopCsarInstaller.java @@ -99,10 +99,10 @@ public class LoopCsarInstaller implements CsarInstaller { boolean alreadyInstalled = true; for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { alreadyInstalled = alreadyInstalled - && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprint.getValue().getResourceAttached().getResourceInstanceName(), - blueprint.getValue().getBlueprintArtifactName())); + && loopRepository.existsById(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), + csar.getSdcNotification().getServiceVersion(), + blueprint.getValue().getResourceAttached().getResourceInstanceName(), + blueprint.getValue().getBlueprintArtifactName())); } return alreadyInstalled; } @@ -110,7 +110,7 @@ public class LoopCsarInstaller implements CsarInstaller { @Override @Transactional(propagation = Propagation.REQUIRED) public void installTheCsar(CsarHandler csar) - throws SdcArtifactInstallerException, InterruptedException, PolicyModelException { + throws SdcArtifactInstallerException, InterruptedException, PolicyModelException { try { logger.info("Installing the CSAR " + csar.getFilePath()); for (Entry blueprint : csar.getMapOfBlueprints().entrySet()) { @@ -126,53 +126,53 @@ public class LoopCsarInstaller implements CsarInstaller { } private Loop createLoopFromBlueprint(CsarHandler csar, BlueprintArtifact blueprintArtifact) - throws IOException, ParseException, InterruptedException { + throws IOException, ParseException, InterruptedException { Loop newLoop = new Loop(); newLoop.setBlueprint(blueprintArtifact.getDcaeBlueprint()); newLoop.setName(Loop.generateLoopName(csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName())); + csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName())); newLoop.setLastComputedState(LoopState.DESIGN); List microServicesChain = chainGenerator - .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())); + .getChainOfMicroServices(blueprintParser.getMicroServices(blueprintArtifact.getDcaeBlueprint())); if (microServicesChain.isEmpty()) { microServicesChain = blueprintParser.fallbackToOneMicroService(blueprintArtifact.getDcaeBlueprint()); } - - newLoop - .setMicroServicePolicies(createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop)); + newLoop.setModelPropertiesJson(createModelPropertiesJson(csar)); + newLoop.setMicroServicePolicies( + createMicroServicePolicies(microServicesChain, csar, blueprintArtifact, newLoop)); newLoop.setOperationalPolicies(createOperationalPolicies(csar, blueprintArtifact, newLoop)); newLoop.setSvgRepresentation(svgFacade.getSvgImage(microServicesChain)); newLoop.setGlobalPropertiesJson(createGlobalPropertiesJson(blueprintArtifact, newLoop)); - newLoop.setModelPropertiesJson(createModelPropertiesJson(csar)); + DcaeInventoryResponse dcaeResponse = queryDcaeToGetServiceTypeId(blueprintArtifact); newLoop.setDcaeBlueprintId(dcaeResponse.getTypeId()); return newLoop; } private HashSet createOperationalPolicies(CsarHandler csar, BlueprintArtifact blueprintArtifact, - Loop newLoop) { + Loop newLoop) { return new HashSet<>(Arrays.asList(new OperationalPolicy(Policy.generatePolicyName("OPERATIONAL", - csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject()))); + csar.getSdcNotification().getServiceName(), csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName()), newLoop, new JsonObject()))); } private HashSet createMicroServicePolicies(List microServicesChain, - CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { + CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { HashSet newSet = new HashSet<>(); for (MicroService microService : microServicesChain) { MicroServicePolicy microServicePolicy = new MicroServicePolicy( - Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(), - csar.getSdcNotification().getServiceVersion(), - blueprintArtifact.getResourceAttached().getResourceInstanceName(), - blueprintArtifact.getBlueprintArtifactName()), - microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false, - new HashSet<>(Arrays.asList(newLoop))); + Policy.generatePolicyName(microService.getName(), csar.getSdcNotification().getServiceName(), + csar.getSdcNotification().getServiceVersion(), + blueprintArtifact.getResourceAttached().getResourceInstanceName(), + blueprintArtifact.getBlueprintArtifactName()), + microService.getModelType(), csar.getPolicyModelYaml().orElse(""), false, + new HashSet<>(Arrays.asList(newLoop))); newSet.add(microServicePolicy); microService.setMappedNameJpa(microServicePolicy.getName()); @@ -191,8 +191,8 @@ public class LoopCsarInstaller implements CsarInstaller { // 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)) { + 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); @@ -200,7 +200,7 @@ public class LoopCsarInstaller implements CsarInstaller { // volume_group, etc ... fields under the VFmodule name for (Entry additionalProp : entity.getProperties().entrySet()) { allVfProps.add(additionalProp.getValue().getName(), - JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue())); + JsonUtils.GSON.toJsonTree(additionalProp.getValue().getValue())); } } return vfModuleProps; @@ -214,7 +214,7 @@ public class LoopCsarInstaller implements CsarInstaller { // 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())); + JsonUtils.GSON.toJsonTree(nodeTemplate.getMetaData().getAllProperties())); } resourcesProp.add(type.getValue(), resourcesPropByType); } @@ -225,7 +225,7 @@ public class LoopCsarInstaller implements CsarInstaller { JsonObject modelProperties = new JsonObject(); // Add service details modelProperties.add("serviceDetails", JsonUtils.GSON.fromJson( - JsonUtils.GSON.toJson(csar.getSdcCsarHelper().getServiceMetadataAllProperties()), JsonObject.class)); + 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)); @@ -237,7 +237,7 @@ public class LoopCsarInstaller implements CsarInstaller { JsonObject node = new JsonObject(); Yaml yaml = new Yaml(); Map inputsNodes = ((Map) ((Map) yaml - .load(blueprintArtifact.getDcaeBlueprint())).get("inputs")); + .load(blueprintArtifact.getDcaeBlueprint())).get("inputs")); inputsNodes.entrySet().stream().filter(e -> !e.getKey().contains("policy_id")).forEach(elem -> { Object defaultValue = ((Map) elem.getValue()).get("default"); if (defaultValue != null) { @@ -258,10 +258,10 @@ public class LoopCsarInstaller implements CsarInstaller { * @return The DcaeInventoryResponse object containing the dcae values */ private DcaeInventoryResponse queryDcaeToGetServiceTypeId(BlueprintArtifact blueprintArtifact) - throws IOException, ParseException, InterruptedException { + throws IOException, ParseException, InterruptedException { return dcaeInventoryService.getDcaeInformation(blueprintArtifact.getBlueprintArtifactName(), - blueprintArtifact.getBlueprintInvariantServiceUuid(), - blueprintArtifact.getResourceAttached().getResourceInvariantUUID()); + blueprintArtifact.getBlueprintInvariantServiceUuid(), + blueprintArtifact.getResourceAttached().getResourceInvariantUUID()); } private void addPropertyToNode(JsonObject node, String key, Object value) { diff --git a/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java b/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java index 33148f0b6..dd156d8f3 100644 --- a/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java +++ b/src/main/java/org/onap/clamp/policy/operational/LegacyOperationalPolicy.java @@ -25,6 +25,7 @@ package org.onap.clamp.policy.operational; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import java.util.ArrayList; import java.util.List; @@ -33,16 +34,15 @@ import java.util.Map.Entry; import java.util.TreeMap; import org.apache.commons.lang3.math.NumberUtils; +import org.onap.clamp.loop.Loop; 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 { @@ -76,6 +76,13 @@ public class LegacyOperationalPolicy { return jsonElement; } + /** + * This method rework the payload attribute (yaml) that is normally wrapped in a + * string when coming from the UI. + * + * @param policyJson The operational policy json config + * @return The same object reference but modified + */ public static JsonElement reworkPayloadAttributes(JsonElement policyJson) { for (JsonElement policy : policyJson.getAsJsonObject().get("policies").getAsJsonArray()) { JsonElement payloadElem = policy.getAsJsonObject().get("payload"); @@ -135,9 +142,15 @@ public class LegacyOperationalPolicy { return mapResult; } + /** + * This method transforms the configuration json to a Yaml format. + * + * @param operationalPolicyJsonElement The operational policy json config + * @return The Yaml as string + */ public static String createPolicyPayloadYamlLegacy(JsonElement operationalPolicyJsonElement) { JsonElement opPolicy = fulfillPoliciesTreeField( - removeAllQuotes(reworkPayloadAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy()))); + removeAllQuotes(reworkPayloadAttributes(operationalPolicyJsonElement.getAsJsonObject().deepCopy()))); Map jsonMap = createMap(opPolicy); DumperOptions options = new DumperOptions(); options.setDefaultScalarStyle(ScalarStyle.PLAIN); @@ -147,4 +160,22 @@ public class LegacyOperationalPolicy { options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); return (new Yaml(options)).dump(jsonMap); } + + /** + * This method load mandatory field in the operational policy configuration + * JSON. + * + * @param configurationsJson The operational policy JSON + * @param loop The parent loop object + */ + public static void preloadConfiguration(JsonObject configurationsJson, Loop loop) { + if (configurationsJson.entrySet().isEmpty()) { + JsonObject controlLoopName = new JsonObject(); + controlLoopName.addProperty("controlLoopName", + loop != null ? loop.getName() : "Empty (NO loop loaded yet)"); + JsonObject controlLoop = new JsonObject(); + controlLoop.add("controlLoop", controlLoopName); + configurationsJson.add("operational_policy", controlLoop); + } + } } 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 62c5a1e9f..86f8ac391 100644 --- a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java +++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicy.java @@ -38,7 +38,6 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -import java.util.Map.Entry; import javax.persistence.Column; import javax.persistence.Entity; @@ -91,17 +90,16 @@ public class OperationalPolicy implements Serializable, Policy { /** * The constructor. * - * @param name - * The name of the operational policy - * @param loop - * The loop that uses this operational policy - * @param configurationsJson - * The operational policy property in the format of json + * @param name The name of the operational policy + * @param loop The loop that uses this operational policy + * @param configurationsJson The operational policy property in the format of + * json */ public OperationalPolicy(String name, Loop loop, JsonObject configurationsJson) { this.name = name; this.loop = loop; this.configurationsJson = configurationsJson; + LegacyOperationalPolicy.preloadConfiguration(this.configurationsJson, loop); } @Override @@ -117,11 +115,6 @@ public class OperationalPolicy implements Serializable, Policy { return loop; } - @Override - public JsonObject getJsonRepresentation() { - return configurationsJson; - } - public JsonObject getConfigurationsJson() { return configurationsJson; } @@ -130,6 +123,11 @@ public class OperationalPolicy implements Serializable, Policy { this.configurationsJson = configurationsJson; } + @Override + public JsonObject getJsonRepresentation() { + return null; + } + @Override public int hashCode() { final int prime = 31; @@ -184,7 +182,7 @@ public class OperationalPolicy implements Serializable, Policy { metadata.addProperty("policy-id", this.name); operationalPolicyDetails.add("properties", LegacyOperationalPolicy - .reworkPayloadAttributes(this.configurationsJson.get("operational_policy").deepCopy())); + .reworkPayloadAttributes(this.configurationsJson.get("operational_policy").deepCopy())); Gson gson = new GsonBuilder().create(); @@ -204,9 +202,8 @@ public class OperationalPolicy implements Serializable, Policy { // Now using the legacy payload fo Dublin JsonObject payload = new JsonObject(); payload.addProperty("policy-id", this.getName()); - payload.addProperty("content", URLEncoder.encode( - LegacyOperationalPolicy.createPolicyPayloadYamlLegacy(this.configurationsJson.get("operational_policy")), - StandardCharsets.UTF_8.toString())); + 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; @@ -222,11 +219,9 @@ public class OperationalPolicy implements Serializable, Policy { JsonElement guardsList = this.getConfigurationsJson().get("guard_policies"); if (guardsList != null) { - for (Entry guardElem : guardsList.getAsJsonObject().entrySet()) { - JsonObject guard = new JsonObject(); - guard.addProperty("policy-id", guardElem.getKey()); - guard.add("content", guardElem.getValue()); - result.put(guardElem.getKey(), new GsonBuilder().create().toJson(guard)); + for (JsonElement guardElem : guardsList.getAsJsonArray()) { + result.put(guardElem.getAsJsonObject().get("policy-id").getAsString(), + new GsonBuilder().create().toJson(guardElem)); } } logger.info("Guard policy payload: " + result); diff --git a/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java new file mode 100644 index 000000000..f6f3f498d --- /dev/null +++ b/src/main/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilder.java @@ -0,0 +1,146 @@ +/*- + * ============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.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; + +import java.io.IOException; +import java.util.Map.Entry; + +import org.onap.clamp.clds.util.JsonUtils; +import org.onap.clamp.clds.util.ResourceFileUtil; + +public class OperationalPolicyRepresentationBuilder { + + /** + * This method generates the operational policy json representation that will be + * used by ui for rendering. It uses the model (VF and VFModule) defined in the + * loop object to do so, so it's dynamic. It also uses the operational policy + * schema template defined in the resource folder. + * + * @param modelJson The loop model json + * @return The json representation + * @throws JsonSyntaxException If the schema template cannot be parsed + * @throws IOException In case of issue when opening the schema template + */ + public static JsonObject generateOperationalPolicySchema(JsonObject modelJson) + throws JsonSyntaxException, IOException { + JsonObject jsonSchema = JsonUtils.GSON.fromJson( + ResourceFileUtil.getResourceAsString("clds/json-schema/operational_policies/operational_policy.json"), + JsonObject.class); + jsonSchema.get("schema").getAsJsonObject().get("items").getAsJsonObject().get("properties").getAsJsonObject() + .get("configurationsJson").getAsJsonObject().get("properties").getAsJsonObject() + .get("operational_policy").getAsJsonObject().get("properties").getAsJsonObject().get("policies") + .getAsJsonObject().get("items").getAsJsonObject().get("properties").getAsJsonObject().get("target") + .getAsJsonObject().get("anyOf").getAsJsonArray().addAll(createAnyOfArray(modelJson)); + return jsonSchema; + } + + private static JsonObject createSchemaProperty(String title, String type, String defaultValue, String readOnlyFlag, + String[] enumArray) { + JsonObject property = new JsonObject(); + property.addProperty("title", title); + property.addProperty("type", type); + property.addProperty("default", defaultValue); + property.addProperty("readOnly", readOnlyFlag); + + if (enumArray != null) { + JsonArray jsonArray = new JsonArray(); + property.add("enum", jsonArray); + for (String val : enumArray) { + jsonArray.add(val); + } + } + return property; + } + + private static JsonArray createVnfSchema(JsonObject modelJson) { + JsonArray vnfSchemaArray = new JsonArray(); + JsonObject modelVnfs = modelJson.get("resourceDetails").getAsJsonObject().get("VF").getAsJsonObject(); + + for (Entry entry : modelVnfs.entrySet()) { + JsonObject vnfOneOfSchema = new JsonObject(); + vnfOneOfSchema.addProperty("title", "VNF" + "-" + entry.getKey()); + JsonObject properties = new JsonObject(); + properties.add("type", createSchemaProperty("Type", "string", "VNF", "True", null)); + properties.add("resourceID", createSchemaProperty("Resource ID", "string", + modelVnfs.get(entry.getKey()).getAsJsonObject().get("name").getAsString(), "True", null)); + + vnfOneOfSchema.add("properties", properties); + vnfSchemaArray.add(vnfOneOfSchema); + } + return vnfSchemaArray; + } + + private static JsonArray createVfModuleSchema(JsonObject modelJson) { + JsonArray vfModuleOneOfSchemaArray = new JsonArray(); + JsonObject modelVfModules = modelJson.get("resourceDetails").getAsJsonObject().get("VFModule") + .getAsJsonObject(); + + for (Entry entry : modelVfModules.entrySet()) { + JsonObject vfModuleOneOfSchema = new JsonObject(); + vfModuleOneOfSchema.addProperty("title", "VFMODULE" + "-" + entry.getKey()); + JsonObject properties = new JsonObject(); + properties.add("type", createSchemaProperty("Type", "string", "VFMODULE", "True", null)); + properties.add("resourceID", + createSchemaProperty("Resource ID", "string", + modelVfModules.get(entry.getKey()).getAsJsonObject().get("vfModuleModelName").getAsString(), + "True", null)); + properties.add("modelInvariantId", + createSchemaProperty("Model Invariant Id (ModelInvariantUUID)", "string", modelVfModules + .get(entry.getKey()).getAsJsonObject().get("vfModuleModelInvariantUUID").getAsString(), + "True", null)); + properties.add("modelVersionId", + createSchemaProperty("Model Version Id (ModelUUID)", "string", + modelVfModules.get(entry.getKey()).getAsJsonObject().get("vfModuleModelUUID").getAsString(), + "True", null)); + properties.add("modelName", + createSchemaProperty("Model Name", "string", + modelVfModules.get(entry.getKey()).getAsJsonObject().get("vfModuleModelName").getAsString(), + "True", null)); + properties.add("modelVersion", createSchemaProperty("Model Version", "string", + modelVfModules.get(entry.getKey()).getAsJsonObject().get("vfModuleModelVersion").getAsString(), + "True", null)); + properties + .add("modelCustomizationId", + createSchemaProperty("Customization ID", "string", modelVfModules.get(entry.getKey()) + .getAsJsonObject().get("vfModuleModelCustomizationUUID").getAsString(), "True", + null)); + + vfModuleOneOfSchema.add("properties", properties); + vfModuleOneOfSchemaArray.add(vfModuleOneOfSchema); + } + return vfModuleOneOfSchemaArray; + } + + private static JsonArray createAnyOfArray(JsonObject modelJson) { + JsonArray targetOneOfStructure = new JsonArray(); + targetOneOfStructure.addAll(createVnfSchema(modelJson)); + targetOneOfStructure.addAll(createVfModuleSchema(modelJson)); + return targetOneOfStructure; + } +} diff --git a/src/main/resources/clds/json-schema/operational_policies/operational_policy.json b/src/main/resources/clds/json-schema/operational_policies/operational_policy.json new file mode 100644 index 000000000..93738c809 --- /dev/null +++ b/src/main/resources/clds/json-schema/operational_policies/operational_policy.json @@ -0,0 +1,362 @@ +{ + "schema": { + "uniqueItems": "true", + "format": "tabs", + "type": "array", + "minItems": 1, + "maxItems": 1, + "title": "Operational policies", + "items": { + "type": "object", + "title": "Operational Policy Item", + "id": "operational_policy_item", + "headerTemplate": "{{self.name}}", + "required": [ + "name", + "configurationsJson" + ], + "properties": { + "name": { + "type": "string", + "title": "Operational policy name", + "readOnly": "True" + }, + "configurationsJson": { + "type": "object", + "title": "Configuration", + "required": [ + "operational_policy", + "guard_policies" + ], + "properties": { + "operational_policy": { + "type": "object", + "title": "Related Parameters", + "required": [ + "controlLoop", + "policies" + ], + "properties": { + "controlLoop": { + "type": "object", + "title": "Control Loop details", + "required": [ + "timeout", + "abatement", + "trigger_policy", + "controlLoopName" + ], + "properties": { + "timeout": { + "type": "string", + "title": "Overall Time Limit", + "default": "0", + "format": "number" + }, + "abatement": { + "type": "string", + "title": "Abatement", + "enum": [ + "True", + "False" + ] + }, + "trigger_policy": { + "type": "string", + "title": "Policy Decision Entry" + }, + "controlLoopName": { + "type": "string", + "title": "Control loop name", + "readOnly": "True" + } + } + }, + "policies": { + "uniqueItems": "true", + "id": "policies_array", + "type": "array", + "title": "Policy Decision Tree", + "format": "tabs-top", + "items": { + "title": "Policy Decision", + "type": "object", + "id": "policy_item", + "headerTemplate": "{{self.id}} - {{self.recipe}}", + "format": "categories", + "basicCategoryTitle": "recipe", + "required": [ + "id", + "recipe", + "retry", + "timeout", + "actor", + "success", + "failure", + "failure_timeout", + "failure_retries", + "failure_exception", + "failure_guard", + "target" + ], + "properties": { + "id": { + "default": "Policy 1", + "title": "Policy ID", + "type": "string" + }, + "recipe": { + "title": "Recipe", + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "retry": { + "default": "0", + "title": "Number of Retry", + "type": "string", + "format": "number" + }, + "timeout": { + "default": "0", + "title": "Timeout", + "type": "string", + "format": "number" + }, + "actor": { + "title": "Actor", + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "payload": { + "title": "Payload (YAML)", + "type": "string", + "format": "textarea" + }, + "success": { + "default": "final_success", + "title": "When Success", + "type": "string" + }, + "failure": { + "default": "final_failure", + "title": "When Failure", + "type": "string" + }, + "failure_timeout": { + "default": "final_failure_timeout", + "title": "When Failure Timeout", + "type": "string" + }, + "failure_retries": { + "default": "final_failure_retries", + "title": "When Failure Retries", + "type": "string" + }, + "failure_exception": { + "default": "final_failure_exception", + "title": "When Failure Exception", + "type": "string" + }, + "failure_guard": { + "default": "final_failure_guard", + "title": "When Failure Guard", + "type": "string" + }, + "target": { + "type": "object", + "required": [ + "type", + "resourceID" + ], + "anyOf": [ + { + "title": "User Defined", + "additionalProperties":"True", + "properties": { + "type": { + "title": "Target type", + "type": "string", + "default": "", + "enum": [ + "VNF", + "VFMODULE", + "VM" + ] + }, + "resourceID": { + "title": "Target type", + "type": "string", + "default": "" + } + } + } + ] + } + } + } + } + } + }, + "guard_policies": { + "type": "array", + "format": "tabs-top", + "title": "Associated Guard policies", + "items": { + "headerTemplate": "{{self.policy-id}} - {{self.content.recipe}}", + "anyOf": [ + { + "title": "Guard MinMax", + "type": "object", + "properties": { + "policy-id": { + "type": "string", + "default": "guard.minmax.new", + "pattern": "^(guard.minmax\\..*)$" + }, + "content": { + "properties": { + "actor": { + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "recipe": { + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "targets": { + "type": "string", + "default": ".*" + }, + "clname": { + "type": "string", + "template": "{{loopName}}", + "watch": { + "loopName": "operational_policy_item.configurationsJson.operational_policy.controlLoop.controlLoopName" + } + }, + "guardActiveStart": { + "type": "string", + "default": "00:00:00Z" + }, + "guardActiveEnd": { + "type": "string", + "default": "10:00:00Z" + }, + "min": { + "type": "string", + "default": "0" + }, + "max": { + "type": "string", + "default": "1" + } + } + } + } + }, + { + "title": "Guard Frequency", + "type": "object", + "properties": { + "policy-id": { + "type": "string", + "default": "guard.frequency.new", + "pattern": "^(guard.frequency\\..*)$" + }, + "content": { + "properties": { + "actor": { + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "recipe": { + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "targets": { + "type": "string", + "default": ".*" + }, + "clname": { + "type": "string", + "template": "{{loopName}}", + "watch": { + "loopName": "operational_policy_item.configurationsJson.operational_policy.controlLoop.controlLoopName" + } + }, + "guardActiveStart": { + "type": "string", + "default": "00:00:00Z" + }, + "guardActiveEnd": { + "type": "string", + "default": "10:00:00Z" + }, + "limit": { + "type": "string" + }, + "timeWindow": { + "type": "string" + }, + "timeUnits": { + "type": "string", + "enum":["minute","hour","day","week","month","year"] + } + } + } + } + } + ] + } + } + } + } + } + } + } +} diff --git a/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java b/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java index 8972e5117..728b61cc9 100644 --- a/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java +++ b/src/test/java/org/onap/clamp/policy/microservice/OperationalPolicyPayloadTest.java @@ -42,29 +42,29 @@ public class OperationalPolicyPayloadTest { @Test public void testOperationalPolicyPayloadConstruction() throws IOException { JsonObject jsonConfig = new GsonBuilder().create().fromJson( - ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); + ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig); assertThat(policy.createPolicyPayloadYaml()) - .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload.yaml")); + .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload.yaml")); assertThat(policy.createPolicyPayload()) - .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload.json")); + .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload.json")); } @Test public void testLegacyOperationalPolicyPayloadConstruction() throws IOException { JsonObject jsonConfig = new GsonBuilder().create().fromJson( - ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); + ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); assertThat(LegacyOperationalPolicy.createPolicyPayloadYamlLegacy(jsonConfig.get("operational_policy"))) - .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload-legacy.yaml")); + .isEqualTo(ResourceFileUtil.getResourceAsString("tosca/operational-policy-payload-legacy.yaml")); } @Test public void testGuardPolicyEmptyPayloadConstruction() throws IOException { JsonObject jsonConfig = new GsonBuilder().create().fromJson( - ResourceFileUtil.getResourceAsString("tosca/operational-policy-no-guard-properties.json"), - JsonObject.class); + ResourceFileUtil.getResourceAsString("tosca/operational-policy-no-guard-properties.json"), + JsonObject.class); OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig); Map guardsMap = policy.createGuardPolicyPayloads(); assertThat(guardsMap).isEmpty(); @@ -74,15 +74,15 @@ public class OperationalPolicyPayloadTest { @Test public void testGuardPolicyPayloadConstruction() throws IOException { JsonObject jsonConfig = new GsonBuilder().create().fromJson( - ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); + ResourceFileUtil.getResourceAsString("tosca/operational-policy-properties.json"), JsonObject.class); OperationalPolicy policy = new OperationalPolicy("testPolicy", null, jsonConfig); Map guardsMap = policy.createGuardPolicyPayloads(); JSONAssert.assertEquals(ResourceFileUtil.getResourceAsString("tosca/guard1-policy-payload.json"), - guardsMap.get("guard1"), false); + guardsMap.get("guard.minmax.new"), false); JSONAssert.assertEquals(ResourceFileUtil.getResourceAsString("tosca/guard2-policy-payload.json"), - guardsMap.get("guard2"), false); + guardsMap.get("guard.frequency.new"), false); } } diff --git a/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java b/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java new file mode 100644 index 000000000..904525bea --- /dev/null +++ b/src/test/java/org/onap/clamp/policy/operational/OperationalPolicyRepresentationBuilderTest.java @@ -0,0 +1,52 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThat; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; + +import java.io.IOException; + +import org.junit.Test; +import org.onap.clamp.clds.util.ResourceFileUtil; +import org.skyscreamer.jsonassert.JSONAssert; + +public class OperationalPolicyRepresentationBuilderTest { + + @Test + public void testOperationalPolicyPayloadConstruction() throws IOException { + JsonObject jsonModel = new GsonBuilder().create() + .fromJson(ResourceFileUtil.getResourceAsString("tosca/model-properties.json"), JsonObject.class); + + JsonObject jsonSchema = OperationalPolicyRepresentationBuilder.generateOperationalPolicySchema(jsonModel); + + assertThat(jsonSchema).isNotNull(); + + JSONAssert.assertEquals(ResourceFileUtil.getResourceAsString("tosca/operational-policy-json-schema.json"), + new GsonBuilder().create().toJson(jsonSchema), false); + } + +} diff --git a/src/test/resources/clds/OperationalPolicyRepresentationBuilderTest.java b/src/test/resources/clds/OperationalPolicyRepresentationBuilderTest.java new file mode 100644 index 000000000..904525bea --- /dev/null +++ b/src/test/resources/clds/OperationalPolicyRepresentationBuilderTest.java @@ -0,0 +1,52 @@ +/*- + * ============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 static org.assertj.core.api.Assertions.assertThat; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; + +import java.io.IOException; + +import org.junit.Test; +import org.onap.clamp.clds.util.ResourceFileUtil; +import org.skyscreamer.jsonassert.JSONAssert; + +public class OperationalPolicyRepresentationBuilderTest { + + @Test + public void testOperationalPolicyPayloadConstruction() throws IOException { + JsonObject jsonModel = new GsonBuilder().create() + .fromJson(ResourceFileUtil.getResourceAsString("tosca/model-properties.json"), JsonObject.class); + + JsonObject jsonSchema = OperationalPolicyRepresentationBuilder.generateOperationalPolicySchema(jsonModel); + + assertThat(jsonSchema).isNotNull(); + + JSONAssert.assertEquals(ResourceFileUtil.getResourceAsString("tosca/operational-policy-json-schema.json"), + new GsonBuilder().create().toJson(jsonSchema), false); + } + +} diff --git a/src/test/resources/tosca/guard1-policy-payload.json b/src/test/resources/tosca/guard1-policy-payload.json index b4e0809c9..1c03df306 100644 --- a/src/test/resources/tosca/guard1-policy-payload.json +++ b/src/test/resources/tosca/guard1-policy-payload.json @@ -1,16 +1,13 @@ { - "policy-id": "guard1", + "policy-id": "guard.minmax.new", "content": { - "recipe": "Rebuild", - "actor": "SO", - "clname": "testloop", + "actor": "APPC", + "recipe": "Restart", "targets": ".*", - "min": "3", - "max": "7", - "limit": "", - "timeUnits": "", - "timeWindow": "", - "guardActiveStart": "00:00:01-05:00", - "guardActiveEnd": "23:59:01-05:00" + "clname": "LOOP_ASJOy_v1_0_ResourceInstanceName1_tca", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "10:00:00Z", + "min": "0", + "max": "1" } } \ No newline at end of file diff --git a/src/test/resources/tosca/guard2-policy-payload.json b/src/test/resources/tosca/guard2-policy-payload.json index 29beb6b98..559a56840 100644 --- a/src/test/resources/tosca/guard2-policy-payload.json +++ b/src/test/resources/tosca/guard2-policy-payload.json @@ -1,16 +1,14 @@ { - "policy-id": "guard2", + "policy-id": "guard.frequency.new", "content": { - "recipe": "Migrate", - "actor": "SO", - "clname": "testloop", + "actor": "APPC", + "recipe": "Rebuild", "targets": ".*", - "min": "1", - "max": "2", - "limit": "", - "timeUnits": "", - "timeWindow": "", - "guardActiveStart": "00:00:01-05:00", - "guardActiveEnd": "23:59:01-05:00" + "clname": "LOOP_ASJOy_v1_0_ResourceInstanceName1_tca", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "10:00:00Z", + "limit": "1", + "timeWindow": "2", + "timeUnits": "minute" } } \ No newline at end of file diff --git a/src/test/resources/tosca/operational-policy-json-schema.json b/src/test/resources/tosca/operational-policy-json-schema.json new file mode 100644 index 000000000..d6870dc9d --- /dev/null +++ b/src/test/resources/tosca/operational-policy-json-schema.json @@ -0,0 +1,574 @@ +{ + "schema": { + "uniqueItems": "true", + "format": "tabs", + "type": "array", + "minItems": 1, + "maxItems": 1, + "title": "Operational policies", + "items": { + "type": "object", + "title": "Operational Policy Item", + "id": "operational_policy_item", + "headerTemplate": "{{self.name}}", + "required": [ + "name", + "configurationsJson" + ], + "properties": { + "name": { + "type": "string", + "title": "Operational policy name", + "readOnly": "True" + }, + "configurationsJson": { + "type": "object", + "title": "Configuration", + "required": [ + "operational_policy", + "guard_policies" + ], + "properties": { + "operational_policy": { + "type": "object", + "title": "Related Parameters", + "required": [ + "controlLoop", + "policies" + ], + "properties": { + "controlLoop": { + "type": "object", + "title": "Control Loop details", + "required": [ + "timeout", + "abatement", + "trigger_policy", + "controlLoopName" + ], + "properties": { + "timeout": { + "type": "string", + "title": "Overall Time Limit", + "default": "0", + "format": "number" + }, + "abatement": { + "type": "string", + "title": "Abatement", + "enum": [ + "True", + "False" + ] + }, + "trigger_policy": { + "type": "string", + "title": "Policy Decision Entry" + }, + "controlLoopName": { + "type": "string", + "title": "Control loop name", + "readOnly": "True" + } + } + }, + "policies": { + "uniqueItems": "true", + "id": "policies_array", + "type": "array", + "title": "Policy Decision Tree", + "format": "tabs-top", + "items": { + "title": "Policy Decision", + "type": "object", + "id": "policy_item", + "headerTemplate": "{{self.id}} - {{self.recipe}}", + "format": "categories", + "basicCategoryTitle": "recipe", + "required": [ + "id", + "recipe", + "retry", + "timeout", + "actor", + "success", + "failure", + "failure_timeout", + "failure_retries", + "failure_exception", + "failure_guard", + "target" + ], + "properties": { + "id": { + "default": "Policy 1", + "title": "Policy ID", + "type": "string" + }, + "recipe": { + "title": "Recipe", + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "retry": { + "default": "0", + "title": "Number of Retry", + "type": "string", + "format": "number" + }, + "timeout": { + "default": "0", + "title": "Timeout", + "type": "string", + "format": "number" + }, + "actor": { + "title": "Actor", + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "payload": { + "title": "Payload (YAML)", + "type": "string", + "format": "textarea" + }, + "success": { + "default": "final_success", + "title": "When Success", + "type": "string" + }, + "failure": { + "default": "final_failure", + "title": "When Failure", + "type": "string" + }, + "failure_timeout": { + "default": "final_failure_timeout", + "title": "When Failure Timeout", + "type": "string" + }, + "failure_retries": { + "default": "final_failure_retries", + "title": "When Failure Retries", + "type": "string" + }, + "failure_exception": { + "default": "final_failure_exception", + "title": "When Failure Exception", + "type": "string" + }, + "failure_guard": { + "default": "final_failure_guard", + "title": "When Failure Guard", + "type": "string" + }, + "target": { + "type": "object", + "required": [ + "type", + "resourceID" + ], + "anyOf": [ + { + "title": "User Defined", + "additionalProperties": "True", + "properties": { + "type": { + "title": "Target type", + "type": "string", + "default": "", + "enum": [ + "VNF", + "VFMODULE", + "VM" + ] + }, + "resourceID": { + "title": "Target type", + "type": "string", + "default": "" + } + } + }, + { + "title": "VNF-vLoadBalancerMS 0", + "properties": { + "type": { + "title": "Type", + "type": "string", + "default": "VNF", + "readOnly": "True" + }, + "resourceID": { + "title": "Resource ID", + "type": "string", + "default": "vLoadBalancerMS", + "readOnly": "True" + } + } + }, + { + "title": "VFMODULE-Vloadbalancerms..vpkg..module-1", + "properties": { + "type": { + "title": "Type", + "type": "string", + "default": "VFMODULE", + "readOnly": "True" + }, + "resourceID": { + "title": "Resource ID", + "type": "string", + "default": "Vloadbalancerms..vpkg..module-1", + "readOnly": "True" + }, + "modelInvariantId": { + "title": "Model Invariant Id (ModelInvariantUUID)", + "type": "string", + "default": "ca052563-eb92-4b5b-ad41-9111768ce043", + "readOnly": "True" + }, + "modelVersionId": { + "title": "Model Version Id (ModelUUID)", + "type": "string", + "default": "1e725ccc-b823-4f67-82b9-4f4367070dbc", + "readOnly": "True" + }, + "modelName": { + "title": "Model Name", + "type": "string", + "default": "Vloadbalancerms..vpkg..module-1", + "readOnly": "True" + }, + "modelVersion": { + "title": "Model Version", + "type": "string", + "default": "1", + "readOnly": "True" + }, + "modelCustomizationId": { + "title": "Customization ID", + "type": "string", + "default": "1bffdc31-a37d-4dee-b65c-dde623a76e52", + "readOnly": "True" + } + } + }, + { + "title": "VFMODULE-Vloadbalancerms..vdns..module-3", + "properties": { + "type": { + "title": "Type", + "type": "string", + "default": "VFMODULE", + "readOnly": "True" + }, + "resourceID": { + "title": "Resource ID", + "type": "string", + "default": "Vloadbalancerms..vdns..module-3", + "readOnly": "True" + }, + "modelInvariantId": { + "title": "Model Invariant Id (ModelInvariantUUID)", + "type": "string", + "default": "4c10ba9b-f88f-415e-9de3-5d33336047fa", + "readOnly": "True" + }, + "modelVersionId": { + "title": "Model Version Id (ModelUUID)", + "type": "string", + "default": "4fa73b49-8a6c-493e-816b-eb401567b720", + "readOnly": "True" + }, + "modelName": { + "title": "Model Name", + "type": "string", + "default": "Vloadbalancerms..vdns..module-3", + "readOnly": "True" + }, + "modelVersion": { + "title": "Model Version", + "type": "string", + "default": "1", + "readOnly": "True" + }, + "modelCustomizationId": { + "title": "Customization ID", + "type": "string", + "default": "bafcdab0-801d-4d81-9ead-f464640a38b1", + "readOnly": "True" + } + } + }, + { + "title": "VFMODULE-Vloadbalancerms..base_template..module-0", + "properties": { + "type": { + "title": "Type", + "type": "string", + "default": "VFMODULE", + "readOnly": "True" + }, + "resourceID": { + "title": "Resource ID", + "type": "string", + "default": "Vloadbalancerms..base_template..module-0", + "readOnly": "True" + }, + "modelInvariantId": { + "title": "Model Invariant Id (ModelInvariantUUID)", + "type": "string", + "default": "921f7c96-ebdd-42e6-81b9-1cfc0c9796f3", + "readOnly": "True" + }, + "modelVersionId": { + "title": "Model Version Id (ModelUUID)", + "type": "string", + "default": "63734409-f745-4e4d-a38b-131638a0edce", + "readOnly": "True" + }, + "modelName": { + "title": "Model Name", + "type": "string", + "default": "Vloadbalancerms..base_template..module-0", + "readOnly": "True" + }, + "modelVersion": { + "title": "Model Version", + "type": "string", + "default": "1", + "readOnly": "True" + }, + "modelCustomizationId": { + "title": "Customization ID", + "type": "string", + "default": "86baddea-c730-4fb8-9410-cd2e17fd7f27", + "readOnly": "True" + } + } + }, + { + "title": "VFMODULE-Vloadbalancerms..vlb..module-2", + "properties": { + "type": { + "title": "Type", + "type": "string", + "default": "VFMODULE", + "readOnly": "True" + }, + "resourceID": { + "title": "Resource ID", + "type": "string", + "default": "Vloadbalancerms..vlb..module-2", + "readOnly": "True" + }, + "modelInvariantId": { + "title": "Model Invariant Id (ModelInvariantUUID)", + "type": "string", + "default": "a772a1f4-0064-412c-833d-4749b15828dd", + "readOnly": "True" + }, + "modelVersionId": { + "title": "Model Version Id (ModelUUID)", + "type": "string", + "default": "0f5c3f6a-650a-4303-abb6-fff3e573a07a", + "readOnly": "True" + }, + "modelName": { + "title": "Model Name", + "type": "string", + "default": "Vloadbalancerms..vlb..module-2", + "readOnly": "True" + }, + "modelVersion": { + "title": "Model Version", + "type": "string", + "default": "1", + "readOnly": "True" + }, + "modelCustomizationId": { + "title": "Customization ID", + "type": "string", + "default": "96a78aad-4ffb-4ef0-9c4f-deb03bf1d806", + "readOnly": "True" + } + } + } + ] + } + } + } + } + } + }, + "guard_policies": { + "type": "array", + "format": "tabs-top", + "title": "Associated Guard policies", + "items": { + "headerTemplate": "{{self.policy-id}} - {{self.content.recipe}}", + "anyOf": [ + { + "title": "Guard MinMax", + "type": "object", + "properties": { + "policy-id": { + "type": "string", + "default": "guard.minmax.new", + "pattern": "^(guard.minmax\\..*)$" + }, + "content": { + "properties": { + "actor": { + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "recipe": { + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "targets": { + "type": "string", + "default": ".*" + }, + "clname": { + "type": "string", + "template": "{{loopName}}", + "watch": { + "loopName": "operational_policy_item.configurationsJson.operational_policy.controlLoop.controlLoopName" + } + }, + "guardActiveStart": { + "type": "string", + "default": "00:00:00Z" + }, + "guardActiveEnd": { + "type": "string", + "default": "10:00:00Z" + }, + "min": { + "type": "string", + "default": "0" + }, + "max": { + "type": "string", + "default": "1" + } + } + } + } + }, + { + "title": "Guard Frequency", + "type": "object", + "properties": { + "policy-id": { + "type": "string", + "default": "guard.frequency.new", + "pattern": "^(guard.frequency\\..*)$" + }, + "content": { + "properties": { + "actor": { + "type": "string", + "enum": [ + "APPC", + "SO", + "VFC", + "SDNC", + "SDNR" + ] + }, + "recipe": { + "type": "string", + "enum": [ + "Restart", + "Rebuild", + "Migrate", + "Health-Check", + "ModifyConfig", + "VF Module Create", + "VF Module Delete", + "Reroute" + ] + }, + "targets": { + "type": "string", + "default": ".*" + }, + "clname": { + "type": "string", + "template": "{{loopName}}", + "watch": { + "loopName": "operational_policy_item.configurationsJson.operational_policy.controlLoop.controlLoopName" + } + }, + "guardActiveStart": { + "type": "string", + "default": "00:00:00Z" + }, + "guardActiveEnd": { + "type": "string", + "default": "10:00:00Z" + }, + "limit": { + "type": "string" + }, + "timeWindow": { + "type": "string" + }, + "timeUnits": { + "type": "string", + "enum": [ + "minute", + "hour", + "day", + "week", + "month", + "year" + ] + } + } + } + } + } + ] + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/tosca/operational-policy-payload-legacy.yaml b/src/test/resources/tosca/operational-policy-payload-legacy.yaml index 41184c9c9..4d2b9f361 100644 --- a/src/test/resources/tosca/operational-policy-payload-legacy.yaml +++ b/src/test/resources/tosca/operational-policy-payload-legacy.yaml @@ -1,39 +1,43 @@ controlLoop: abatement: true - controlLoopName: control loop - timeout: 30 - trigger_policy: new1 - version: 2.0.0 + controlLoopName: LOOP_ASJOy_v1_0_ResourceInstanceName1_tca + timeout: 0 + trigger_policy: policy1 policies: -- actor: SO - failure: new2 - failure_exception: new2 - failure_guard: new2 - failure_retries: new2 - failure_timeout: new2 - id: new1 +- actor: APPC + failure: policy2 + failure_exception: final_failure_exception + failure_guard: final_failure_guard + failure_retries: final_failure_retries + failure_timeout: final_failure_timeout + id: policy1 payload: configurationParameters: '[{"ip-addr":"$.vf-module-topology.vf-module-parameters.param[10].value","oam-ip-addr":"$.vf-module-topology.vf-module-parameters.param[15].value","enabled":"$.vf-module-topology.vf-module-parameters.param[22].value"}]' requestParameters: '{"usePreload":true,"userParams":[]}' - recipe: Rebuild - retry: 10 - success: new2 + recipe: Restart + retry: 0 + success: final_success target: - resourceTargetId: test - type: VFC - timeout: 20 -- actor: SDNC + resourceID: vLoadBalancerMS + type: VNF + timeout: 0 +- actor: SO failure: final_failure failure_exception: final_failure_exception failure_guard: final_failure_guard failure_retries: final_failure_retries failure_timeout: final_failure_timeout - id: new2 + id: policy2 payload: '' - recipe: Migrate - retry: 30 + recipe: VF Module Create + retry: 0 success: final_success target: - resourceTargetId: test - type: VFC - timeout: 40 + modelCustomizationId: 1bffdc31-a37d-4dee-b65c-dde623a76e52 + modelInvariantId: ca052563-eb92-4b5b-ad41-9111768ce043 + modelName: Vloadbalancerms..vpkg..module-1 + modelVersion: 1 + modelVersionId: 1e725ccc-b823-4f67-82b9-4f4367070dbc + resourceID: Vloadbalancerms..vpkg..module-1 + type: VFMODULE + timeout: 0 diff --git a/src/test/resources/tosca/operational-policy-payload.json b/src/test/resources/tosca/operational-policy-payload.json index 5097654da..ed0197606 100644 --- a/src/test/resources/tosca/operational-policy-payload.json +++ b/src/test/resources/tosca/operational-policy-payload.json @@ -1,4 +1,4 @@ { "policy-id": "testPolicy", - "content": "controlLoop%3A%0A++abatement%3A+true%0A++controlLoopName%3A+control+loop%0A++timeout%3A+30%0A++trigger_policy%3A+new1%0A++version%3A+2.0.0%0Apolicies%3A%0A-+actor%3A+SO%0A++failure%3A+new2%0A++failure_exception%3A+new2%0A++failure_guard%3A+new2%0A++failure_retries%3A+new2%0A++failure_timeout%3A+new2%0A++id%3A+new1%0A++payload%3A%0A++++configurationParameters%3A+%27%5B%7B%22ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B10%5D.value%22%2C%22oam-ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B15%5D.value%22%2C%22enabled%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B22%5D.value%22%7D%5D%27%0A++++requestParameters%3A+%27%7B%22usePreload%22%3Atrue%2C%22userParams%22%3A%5B%5D%7D%27%0A++recipe%3A+Rebuild%0A++retry%3A+10%0A++success%3A+new2%0A++target%3A%0A++++resourceTargetId%3A+test%0A++++type%3A+VFC%0A++timeout%3A+20%0A-+actor%3A+SDNC%0A++failure%3A+final_failure%0A++failure_exception%3A+final_failure_exception%0A++failure_guard%3A+final_failure_guard%0A++failure_retries%3A+final_failure_retries%0A++failure_timeout%3A+final_failure_timeout%0A++id%3A+new2%0A++payload%3A+%27%27%0A++recipe%3A+Migrate%0A++retry%3A+30%0A++success%3A+final_success%0A++target%3A%0A++++resourceTargetId%3A+test%0A++++type%3A+VFC%0A++timeout%3A+40%0A" + "content": "controlLoop%3A%0A++abatement%3A+true%0A++controlLoopName%3A+LOOP_ASJOy_v1_0_ResourceInstanceName1_tca%0A++timeout%3A+0%0A++trigger_policy%3A+policy1%0Apolicies%3A%0A-+actor%3A+APPC%0A++failure%3A+policy2%0A++failure_exception%3A+final_failure_exception%0A++failure_guard%3A+final_failure_guard%0A++failure_retries%3A+final_failure_retries%0A++failure_timeout%3A+final_failure_timeout%0A++id%3A+policy1%0A++payload%3A%0A++++configurationParameters%3A+%27%5B%7B%22ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B10%5D.value%22%2C%22oam-ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B15%5D.value%22%2C%22enabled%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B22%5D.value%22%7D%5D%27%0A++++requestParameters%3A+%27%7B%22usePreload%22%3Atrue%2C%22userParams%22%3A%5B%5D%7D%27%0A++recipe%3A+Restart%0A++retry%3A+0%0A++success%3A+final_success%0A++target%3A%0A++++resourceID%3A+vLoadBalancerMS%0A++++type%3A+VNF%0A++timeout%3A+0%0A-+actor%3A+SO%0A++failure%3A+final_failure%0A++failure_exception%3A+final_failure_exception%0A++failure_guard%3A+final_failure_guard%0A++failure_retries%3A+final_failure_retries%0A++failure_timeout%3A+final_failure_timeout%0A++id%3A+policy2%0A++payload%3A+%27%27%0A++recipe%3A+VF+Module+Create%0A++retry%3A+0%0A++success%3A+final_success%0A++target%3A%0A++++modelCustomizationId%3A+1bffdc31-a37d-4dee-b65c-dde623a76e52%0A++++modelInvariantId%3A+ca052563-eb92-4b5b-ad41-9111768ce043%0A++++modelName%3A+Vloadbalancerms..vpkg..module-1%0A++++modelVersion%3A+1%0A++++modelVersionId%3A+1e725ccc-b823-4f67-82b9-4f4367070dbc%0A++++resourceID%3A+Vloadbalancerms..vpkg..module-1%0A++++type%3A+VFMODULE%0A++timeout%3A+0%0A" } \ No newline at end of file diff --git a/src/test/resources/tosca/operational-policy-payload.yaml b/src/test/resources/tosca/operational-policy-payload.yaml index c3a6b5c23..ed03842f5 100644 --- a/src/test/resources/tosca/operational-policy-payload.yaml +++ b/src/test/resources/tosca/operational-policy-payload.yaml @@ -8,35 +8,45 @@ topology_template: policy-id: testPolicy properties: controlLoop: - controlLoopName: control loop - version: 2.0.0 - trigger_policy: new1 - timeout: '30' - abatement: 'true' + timeout: '0' + abatement: 'True' + trigger_policy: policy1 + controlLoopName: LOOP_ASJOy_v1_0_ResourceInstanceName1_tca policies: - - id: new1 - recipe: Rebuild - retry: '10' - timeout: '20' - actor: SO + - id: policy1 + recipe: Restart + retry: '0' + timeout: '0' + actor: APPC payload: requestParameters: '{"usePreload":true,"userParams":[]}' configurationParameters: '[{"ip-addr":"$.vf-module-topology.vf-module-parameters.param[10].value","oam-ip-addr":"$.vf-module-topology.vf-module-parameters.param[15].value","enabled":"$.vf-module-topology.vf-module-parameters.param[22].value"}]' - success: new2 - failure: new2 - failure_timeout: new2 - failure_retries: new2 - failure_exception: new2 - failure_guard: new2 + success: final_success + failure: policy2 + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard target: - type: VFC - resourceTargetId: test - - id: new2 - recipe: Migrate - retry: '30' - timeout: '40' - actor: SDNC + type: VNF + resourceID: vLoadBalancerMS + - id: policy2 + recipe: VF Module Create + retry: '0' + timeout: '0' + actor: SO payload: '' + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard target: - type: VFC - resourceTargetId: test + type: VFMODULE + resourceID: Vloadbalancerms..vpkg..module-1 + modelInvariantId: ca052563-eb92-4b5b-ad41-9111768ce043 + modelVersionId: 1e725ccc-b823-4f67-82b9-4f4367070dbc + modelName: Vloadbalancerms..vpkg..module-1 + modelVersion: '1' + modelCustomizationId: 1bffdc31-a37d-4dee-b65c-dde623a76e52 diff --git a/src/test/resources/tosca/operational-policy-properties.json b/src/test/resources/tosca/operational-policy-properties.json index bfce6b331..ac1314ecb 100644 --- a/src/test/resources/tosca/operational-policy-properties.json +++ b/src/test/resources/tosca/operational-policy-properties.json @@ -1,71 +1,82 @@ { - "guard_policies": { - "guard1":{ - "recipe": "Rebuild", - "actor": "SO", - "clname": "testloop", - "targets": ".*", - "min": "3", - "max": "7", - "limit": "", - "timeUnits": "", - "timeWindow": "", - "guardActiveStart": "00:00:01-05:00", - "guardActiveEnd": "23:59:01-05:00" - }, - "guard2":{ - "recipe": "Migrate", - "actor": "SO", - "clname": "testloop", - "targets": ".*", - "min": "1", - "max": "2", - "limit": "", - "timeUnits": "", - "timeWindow": "", - "guardActiveStart": "00:00:01-05:00", - "guardActiveEnd": "23:59:01-05:00" - } - }, - "operational_policy": { - "controlLoop": { - "controlLoopName": "control loop", - "version": "2.0.0", - "trigger_policy": "new1", - "timeout": "30", - "abatement": "true" - }, - "policies": [ - { - "id": "new1", - "recipe": "Rebuild", - "retry": "10", - "timeout": "20", - "actor": "SO", - "payload": "requestParameters: '{\"usePreload\":true,\"userParams\":[]}'\r\nconfigurationParameters: '[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[10].value\",\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[15].value\",\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[22].value\"}]'", - "success": "new2", - "failure": "new2", - "failure_timeout": "new2", - "failure_retries": "new2", - "failure_exception": "new2", - "failure_guard": "new2", - "target": { - "type": "VFC", - "resourceTargetId": "test" - } - }, - { - "id": "new2", - "recipe": "Migrate", - "retry": "30", - "timeout": "40", - "actor": "SDNC", - "payload": "", - "target": { - "type": "VFC", - "resourceTargetId": "test" - } - } - ] - } + "operational_policy": { + "controlLoop": { + "timeout": "0", + "abatement": "True", + "trigger_policy": "policy1", + "controlLoopName": "LOOP_ASJOy_v1_0_ResourceInstanceName1_tca" + }, + "policies": [ + { + "id": "policy1", + "recipe": "Restart", + "retry": "0", + "timeout": "0", + "actor": "APPC", + "payload": "requestParameters: '{\"usePreload\":true,\"userParams\":[]}'\r\nconfigurationParameters: '[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[10].value\",\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[15].value\",\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[22].value\"}]'", + "success": "final_success", + "failure": "policy2", + "failure_timeout": "final_failure_timeout", + "failure_retries": "final_failure_retries", + "failure_exception": "final_failure_exception", + "failure_guard": "final_failure_guard", + "target": { + "type": "VNF", + "resourceID": "vLoadBalancerMS" + } + }, + { + "id": "policy2", + "recipe": "VF Module Create", + "retry": "0", + "timeout": "0", + "actor": "SO", + "payload": "", + "success": "final_success", + "failure": "final_failure", + "failure_timeout": "final_failure_timeout", + "failure_retries": "final_failure_retries", + "failure_exception": "final_failure_exception", + "failure_guard": "final_failure_guard", + "target": { + "type": "VFMODULE", + "resourceID": "Vloadbalancerms..vpkg..module-1", + "modelInvariantId": "ca052563-eb92-4b5b-ad41-9111768ce043", + "modelVersionId": "1e725ccc-b823-4f67-82b9-4f4367070dbc", + "modelName": "Vloadbalancerms..vpkg..module-1", + "modelVersion": "1", + "modelCustomizationId": "1bffdc31-a37d-4dee-b65c-dde623a76e52" + } + } + ] + }, + "guard_policies": [ + { + "policy-id": "guard.minmax.new", + "content": { + "actor": "APPC", + "recipe": "Restart", + "targets": ".*", + "clname": "LOOP_ASJOy_v1_0_ResourceInstanceName1_tca", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "10:00:00Z", + "min": "0", + "max": "1" + } + }, + { + "policy-id": "guard.frequency.new", + "content": { + "actor": "APPC", + "recipe": "Rebuild", + "targets": ".*", + "clname": "LOOP_ASJOy_v1_0_ResourceInstanceName1_tca", + "guardActiveStart": "00:00:00Z", + "guardActiveEnd": "10:00:00Z", + "limit": "1", + "timeWindow": "2", + "timeUnits": "minute" + } + } + ] } diff --git a/src/test/resources/tosca/pdp-group-policy-payload.json b/src/test/resources/tosca/pdp-group-policy-payload.json index bf941e516..ad3a5b4c3 100644 --- a/src/test/resources/tosca/pdp-group-policy-payload.json +++ b/src/test/resources/tosca/pdp-group-policy-payload.json @@ -4,10 +4,10 @@ "policy-id": "GuardOpPolicyTest" }, { - "policy-id": "guard2" + "policy-id": "guard.minmax.new" }, { - "policy-id": "guard1" + "policy-id": "guard.frequency.new" }, { "policy-id": "configPolicyTest" -- cgit 1.2.3-korg