diff options
Diffstat (limited to 'src/main/java')
10 files changed, 408 insertions, 116 deletions
diff --git a/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java b/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java index a8ff1206..9d4e7d0c 100644 --- a/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/DefaultUserConfiguration.java @@ -75,8 +75,10 @@ public class DefaultUserConfiguration extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) { try { http.csrf().disable().httpBasic().and().authorizeRequests().antMatchers("/restservices/clds/v1/user/**") - .authenticated().anyRequest().permitAll().and().logout().and().sessionManagement().maximumSessions(1) - .and().invalidSessionUrl("/designer/timeout.html"); + .authenticated().anyRequest().permitAll().and().logout() + .logoutUrl("/restservices/clds/v1/user/logout").logoutSuccessUrl("/index.html") + .invalidateHttpSession(true).deleteCookies("JSESSIONID").and().sessionManagement() + .maximumSessions(1); } catch (Exception e) { logger.error(SETUP_WEB_USERS_EXCEPTION_MSG, e); @@ -105,7 +107,7 @@ public class DefaultUserConfiguration extends WebSecurityConfigurerAdapter { } for (CldsUser user : usersList) { auth.inMemoryAuthentication().withUser(user.getUser()).password(user.getPassword()) - .authorities(user.getPermissionsString()).and().passwordEncoder(passwordEncoder); + .authorities(user.getPermissionsString()).and().passwordEncoder(passwordEncoder); } } catch (Exception e) { logger.error(SETUP_WEB_USERS_EXCEPTION_MSG, e); @@ -118,8 +120,7 @@ public class DefaultUserConfiguration extends WebSecurityConfigurerAdapter { * CldsUser. * * @return The array of CldsUser - * @throws IOException - * In case of the file is not found + * @throws IOException In case of the file is not found */ private CldsUser[] loadUsers() throws IOException { logger.info("Load from clds-users.properties"); @@ -134,7 +135,7 @@ public class DefaultUserConfiguration extends WebSecurityConfigurerAdapter { return new BCryptPasswordEncoder(cldsBcryptEncoderStrength); } else { throw new CldsConfigException( - "Invalid clamp.config.security.encoder value. 'bcrypt' is the only option at this time."); + "Invalid clamp.config.security.encoder value. 'bcrypt' is the only option at this time."); } } }
\ No newline at end of file diff --git a/src/main/java/org/onap/clamp/clds/service/CldsDictionaryService.java b/src/main/java/org/onap/clamp/clds/service/CldsDictionaryService.java index c228e171..454056cd 100644 --- a/src/main/java/org/onap/clamp/clds/service/CldsDictionaryService.java +++ b/src/main/java/org/onap/clamp/clds/service/CldsDictionaryService.java @@ -60,47 +60,73 @@ public class CldsDictionaryService extends SecureServiceBase { @PostConstruct - private final void initConstruct() { + private void initConstruct() { permissionReadTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "read"); permissionUpdateTosca = SecureServicePermission.create(cldsPermissionTypeTosca, cldsPermissionInstance, "update"); } /** - * REST Service that creates or Updates a Dictionary. - * + * REST Service that creates a Dictionary. + * * @param dictionaryName dictionary name - * @param cldsDictionary clds dictionary * @return CldsDictionary that was created in DB. */ + public CldsDictionary createDictionary(String dictionaryName) { + CldsDictionary cldsDictionary = new CldsDictionary(); + cldsDictionary.setDictionaryName(dictionaryName); + cldsDictionary.save(cldsDictionary.getDictionaryName(), cldsDao, getUserId()); + return cldsDictionary; + } + + /** + * REST Service that creates or Updates a Dictionary. + * Used in clds-services.xml + * + * @param cldsDictionary clds dictionary + * @return ResponseEntity with CldsDictionary that was created in DB. + */ public ResponseEntity<CldsDictionary> createOrUpdateDictionary(String dictionaryName, - CldsDictionary cldsDictionary) { - final Date startTime = new Date(); + CldsDictionary cldsDictionary) { + + Date startTime = new Date(); LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionary", getPrincipalName()); // TODO revisit based on new permissions isAuthorized(permissionUpdateTosca); + if (cldsDictionary == null) { - cldsDictionary = new CldsDictionary(); - cldsDictionary.setDictionaryName(dictionaryName); + + cldsDictionary = createDictionary(dictionaryName); + } else { + + if (cldsDictionary.getDictionaryName() == null) { + cldsDictionary.setDictionaryName(dictionaryName); + } + + cldsDictionary.save(cldsDictionary.getDictionaryName(), cldsDao, getUserId()); } - cldsDictionary.save(dictionaryName, cldsDao, getUserId()); - auditLogInfo("createOrUpdateDictionary", startTime); + + LoggingUtils.setTimeContext(startTime, new Date()); + LoggingUtils.setResponseContext("0", "createOrUpdateDictionary success", this.getClass().getName()); + auditLogger.info("createOrUpdateDictionary completed"); + return new ResponseEntity<>(cldsDictionary, HttpStatus.OK); } /** * REST Service that creates or Updates a Dictionary Elements for dictionary * in DB. - * + * * @param dictionaryName dictionary name * @param dictionaryItem dictionary item * @return CldsDictionaryItem A dictionary items that was created or updated * in DB */ public ResponseEntity<CldsDictionaryItem> createOrUpdateDictionaryElements(String dictionaryName, - CldsDictionaryItem dictionaryItem) { + CldsDictionaryItem dictionaryItem) { final Date startTime = new Date(); - LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionaryElements", getPrincipalName()); + LoggingUtils.setRequestContext("CldsDictionaryService: createOrUpdateDictionaryElements", + getPrincipalName()); // TODO revisit based on new permissions isAuthorized(permissionUpdateTosca); dictionaryItem.save(dictionaryName, cldsDao, getUserId()); @@ -110,7 +136,7 @@ public class CldsDictionaryService extends SecureServiceBase { /** * Rest Service that retrieves all CLDS dictionary in DB. - * + * * @return CldsDictionary List List of CldsDictionary available in DB */ public ResponseEntity<List<CldsDictionary>> getAllDictionaryNames() { @@ -126,7 +152,7 @@ public class CldsDictionaryService extends SecureServiceBase { /** * Rest Service that retrieves all CLDS dictionary items in DB for a give * dictionary name. - * + * * @param dictionaryName dictionary name * @return CldsDictionaryItem list List of CLDS Dictionary items for a given * dictionary name @@ -150,4 +176,4 @@ public class CldsDictionaryService extends SecureServiceBase { util = utilP; } -} +}
\ No newline at end of file diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java index 2393f249..37d597ee 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) @@ -92,6 +100,11 @@ public class Loop implements Serializable { @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") private JsonObject globalPropertiesJson; @@ -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<String, ExternalComponent> 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 ad13ad34..41d34a22 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<String, BlueprintArtifact> 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<String, BlueprintArtifact> 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<MicroService> 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<OperationalPolicy> 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<MicroServicePolicy> createMicroServicePolicies(List<MicroService> microServicesChain, - CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { + CsarHandler csar, BlueprintArtifact blueprintArtifact, Loop newLoop) throws IOException { HashSet<MicroServicePolicy> 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<String, Property> 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<String, Object> inputsNodes = ((Map<String, Object>) ((Map<String, Object>) 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<String, Object>) 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/loop/components/external/ExternalComponent.java b/src/main/java/org/onap/clamp/loop/components/external/ExternalComponent.java index a8aae203..2be707fe 100644 --- a/src/main/java/org/onap/clamp/loop/components/external/ExternalComponent.java +++ b/src/main/java/org/onap/clamp/loop/components/external/ExternalComponent.java @@ -28,9 +28,7 @@ import com.google.gson.annotations.Expose; import org.apache.camel.Exchange; /** - * - * SHould be abstract but Gson can't instantiate it if it's an abstract - * + * Should be abstract but Gson can't instantiate it if it's an abstract. */ public class ExternalComponent { @Expose @@ -49,7 +47,7 @@ public class ExternalComponent { } public ExternalComponentState computeState(Exchange camelExchange) { - return new ExternalComponentState("INIT", "no desc"); + return new ExternalComponentState("INIT", "no desc", 0); } public ExternalComponent(ExternalComponentState initialState) { diff --git a/src/main/java/org/onap/clamp/loop/components/external/ExternalComponentState.java b/src/main/java/org/onap/clamp/loop/components/external/ExternalComponentState.java index 6a723c24..a220ee1d 100644 --- a/src/main/java/org/onap/clamp/loop/components/external/ExternalComponentState.java +++ b/src/main/java/org/onap/clamp/loop/components/external/ExternalComponentState.java @@ -29,18 +29,26 @@ import com.google.gson.annotations.Expose; * This is a transient state reflecting the deployment status of a component. It * can be Policy, DCAE, or whatever... This is object is generic. Clamp is now * stateless, so it triggers the different components at runtime, the status per - * component is stored here. + * component is stored here. The state level is used to re-compute the global + * state when multiple sub states are required for that computation (generally + * provided sequentially to the method computeState from the camel routes. * */ -public class ExternalComponentState { +public class ExternalComponentState implements Comparable<ExternalComponentState> { @Expose private String stateName; @Expose private String description; + private int stateLevel; - public ExternalComponentState(String stateName, String description) { + public ExternalComponentState(String stateName, String description, int level) { this.stateName = stateName; this.description = description; + this.stateLevel = level; + } + + public ExternalComponentState(String stateName, String description) { + this(stateName, description, 0); } public ExternalComponentState() { @@ -58,4 +66,50 @@ public class ExternalComponentState { public String toString() { return stateName; } + + public int getLevel() { + return stateLevel; + } + + public void setLevel(int priority) { + this.stateLevel = priority; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((stateName == null) ? 0 : stateName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ExternalComponentState other = (ExternalComponentState) obj; + if (stateName == null) { + if (other.stateName != null) + return false; + } else if (!stateName.equals(other.stateName)) + return false; + return true; + } + + /** + * This method compares this object by using the level of them. + * + * @param stateToCompare The state to compare to the current object + * @return If the one given in input has a higher level than the current object + * it returns -1, 1 otherwise and 0 if equals. + */ + @Override + public int compareTo(ExternalComponentState stateToCompare) { + return Integer.compare(this.getLevel(), stateToCompare.getLevel()); + } + } diff --git a/src/main/java/org/onap/clamp/loop/components/external/PolicyComponent.java b/src/main/java/org/onap/clamp/loop/components/external/PolicyComponent.java index acd6115f..68d598b5 100644 --- a/src/main/java/org/onap/clamp/loop/components/external/PolicyComponent.java +++ b/src/main/java/org/onap/clamp/loop/components/external/PolicyComponent.java @@ -44,17 +44,22 @@ public class PolicyComponent extends ExternalComponent { @Transient private static final EELFLogger logger = EELFManager.getInstance().getLogger(PolicyComponent.class); + public static final ExternalComponentState IN_ERROR = new ExternalComponentState("IN_ERROR", + "There was an error during the sending to policy, the policy engine may be corrupted or inconsistent", 100); public static final ExternalComponentState NOT_SENT = new ExternalComponentState("NOT_SENT", - "The policies defined have NOT yet been created on the policy engine"); + "The policies defined have NOT yet been created on the policy engine", 90); public static final ExternalComponentState SENT = new ExternalComponentState("SENT", - "The policies defined have been created but NOT deployed on the policy engine"); + "The policies defined have been created but NOT deployed on the policy engine", 50); public static final ExternalComponentState SENT_AND_DEPLOYED = new ExternalComponentState("SENT_AND_DEPLOYED", - "The policies defined have been created and deployed on the policy engine"); - public static final ExternalComponentState IN_ERROR = new ExternalComponentState("IN_ERROR", - "There was an error during the sending to policy, the policy engine may be corrupted or inconsistent"); + "The policies defined have been created and deployed on the policy engine", 10); public PolicyComponent() { - super(NOT_SENT); + /* + * We assume it's good by default as we will receive the state for each policy + * on by one, each time we increase the level we can't decrease it anymore. + * That's why it starts with the lowest one SENT_AND_DEPLOYED. + */ + super(SENT_AND_DEPLOYED); } @Override @@ -103,21 +108,38 @@ public class PolicyComponent extends ExternalComponent { return policyNamesList; } + private static ExternalComponentState findNewState(boolean found, boolean deployed) { + + ExternalComponentState newState = NOT_SENT; + if (found && deployed) { + newState = SENT_AND_DEPLOYED; + } else if (found) { + newState = SENT; + } else if (deployed) { + newState = IN_ERROR; + } + return newState; + } + + private static ExternalComponentState mergeStates(ExternalComponentState oldState, + ExternalComponentState newState) { + return (oldState.compareTo(newState) < 0) ? newState : oldState; + } + + /** + * This is a method that expect the results of the queries getPolicy and + * getPolicyDeployed for a unique policy (op,guard, config, etc ...). It + * re-computes the global policy state for each policy results given. Therefore + * this method is called multiple times from the camel route and must be reset + * for a new global policy state retrieval. The state to compute the global + * policy state is stored in this class. + * + */ @Override public ExternalComponentState computeState(Exchange camelExchange) { - boolean oneNotFound = (boolean) camelExchange.getIn().getExchange().getProperty("atLeastOnePolicyNotFound"); - boolean oneNotDeployed = (boolean) camelExchange.getIn().getExchange() - .getProperty("atLeastOnePolicyNotDeployed"); - - if (oneNotFound && oneNotDeployed) { - this.setState(NOT_SENT); - } else if (!oneNotFound && oneNotDeployed) { - this.setState(SENT); - } else if (!oneNotFound && !oneNotDeployed) { - this.setState(SENT_AND_DEPLOYED); - } else { - this.setState(IN_ERROR); - } + this.setState(mergeStates(this.getState(), + findNewState((boolean) camelExchange.getIn().getExchange().getProperty("policyFound"), + (boolean) camelExchange.getIn().getExchange().getProperty("policyDeployed")))); return this.getState(); } } 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 33148f0b..dd156d8f 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 62c5a1e9..86f8ac39 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; } @@ -131,6 +124,11 @@ public class OperationalPolicy implements Serializable, Policy { } @Override + public JsonObject getJsonRepresentation() { + return null; + } + + @Override public int hashCode() { final int prime = 31; int result = 1; @@ -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<String, JsonElement> 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 00000000..f6f3f498 --- /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<String, JsonElement> 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<String, JsonElement> 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; + } +} |