diff options
14 files changed, 577 insertions, 217 deletions
diff --git a/INFO.yaml b/INFO.yaml new file mode 100644 index 000000000..345217e0f --- /dev/null +++ b/INFO.yaml @@ -0,0 +1,51 @@ +--- +project: 'clamp' +project_creation_date: '2017-06-15' +lifecycle_state: 'Incubation' +project_lead: &onap_releng_ptl + name: 'Gervais-Martial Ngueko' + email: 'gn422w@intl.att.com' + id: 'osgn422w' + company: 'ATT' + timezone: 'Belgium/Namur' +primary_contact: *onap_releng_ptl +issue_tracking: + type: 'jira' + url: 'https://jira.onap.org/projects/CLAMP' + key: 'CLAMP' +meetings: + - type: 'zoom' + agenda: 'https://wiki.onap.org/pages/viewpage.action?pageId=6593117' + url: 'https://wiki.onap.org/pages/viewpage.action?pageId=6593117' + server: 'n/a' + channel: 'n/a' + repeats: 'weekly' + time: '13:00 UTC' +committers: + - name: 'Christophe Closset' + email: 'cc697w@intl.att.com' + company: 'ATT' + id: 'ChrisC' + timezone: 'Belgium/Namur' + - name: 'Eddy Hautot' + email: 'eh552t@intl.att.com' + company: 'ATT' + id: 'ehautot' + timezone: 'Belgium/Namur' + - name: 'Pierre Close' + email: 'pc457b@intl.att.com' + company: 'ATT' + id: 'piclose' + timezone: 'Belgium/Namur' + - name: 'Sébastien Determe' + email: 'sd378r@intl.att.com' + company: 'ATT' + id: 'sebdet' + timezone: 'Belgium/Namur' + - name: 'Xinyuan Wang' + email: 'wang.xinyuan1@zte.com.cn' + company: 'ZTE' + id: 'Xinyuan' + timezone: 'Belgium/Namur' +tsc: + approval: 'https://lists.onap.org/pipermail/onap-tsc' @@ -502,8 +502,15 @@ <dependency> <groupId>org.openecomp.sdc.sdc-distribution-client</groupId> <artifactId>sdc-distribution-client</artifactId> - <version>1.2.3</version> + <version>1.2.2</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc.sdc-tosca</groupId> + <artifactId>sdc-tosca</artifactId> + <version>1.2.2</version> </dependency> + + </dependencies> <build> @@ -514,6 +521,7 @@ <directory>src/test/resources</directory> <excludes> <exclude>**/*.jks</exclude> + <exclude>**/*.csar</exclude> </excludes> <filtering>true</filtering> </testResource> @@ -525,6 +533,14 @@ <filtering>false</filtering> <targetPath>https</targetPath> </testResource> + <testResource> + <directory>src/test/resources/example/sdc</directory> + <includes> + <include>**.csar</include> + </includes> + <filtering>false</filtering> + <targetPath>example/sdc</targetPath> + </testResource> </testResources> <resources> <resource> diff --git a/src/main/java/org/onap/clamp/clds/client/req/policy/PolicyClient.java b/src/main/java/org/onap/clamp/clds/client/req/policy/PolicyClient.java index 144a48c92..8caac0c7d 100644 --- a/src/main/java/org/onap/clamp/clds/client/req/policy/PolicyClient.java +++ b/src/main/java/org/onap/clamp/clds/client/req/policy/PolicyClient.java @@ -125,7 +125,7 @@ public class PolicyClient { PolicyParameters policyParameters = new PolicyParameters(); // Set Policy Type policyParameters.setPolicyConfigType(PolicyConfigType.MicroService); - policyParameters.setEcompName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); + policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName()); policyParameters.setConfigBody(policyJson); policyParameters.setConfigBodyType(PolicyType.JSON); @@ -159,7 +159,7 @@ public class PolicyClient { PolicyParameters policyParameters = new PolicyParameters(); // Set Policy Type policyParameters.setPolicyConfigType(PolicyConfigType.Base); - policyParameters.setEcompName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); + policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName()); policyParameters.setConfigBody(configBody); policyParameters.setConfigBodyType(PolicyType.OTHER); @@ -187,7 +187,7 @@ public class PolicyClient { PolicyParameters policyParameters = new PolicyParameters(); // Set Policy Type policyParameters.setPolicyConfigType(PolicyConfigType.MicroService); - policyParameters.setEcompName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); + policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME)); policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName()); policyParameters.setConfigBody(configBody); String policyNamePrefix = refProp.getStringValue("policy.ms.policyNamePrefix"); diff --git a/src/main/java/org/onap/clamp/clds/config/sdc/SdcControllersConfiguration.java b/src/main/java/org/onap/clamp/clds/config/sdc/SdcControllersConfiguration.java index 5b5490426..f1a961840 100644 --- a/src/main/java/org/onap/clamp/clds/config/sdc/SdcControllersConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/sdc/SdcControllersConfiguration.java @@ -71,8 +71,7 @@ public class SdcControllersConfiguration { } public SdcSingleControllerConfiguration getSdcSingleControllerConfiguration(String controllerName) { - Map<String, SdcSingleControllerConfiguration> controllerMap = getAllDefinedControllers(); - return controllerMap.get(controllerName); + return getAllDefinedControllers().get(controllerName); } /** diff --git a/src/main/java/org/onap/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java b/src/main/java/org/onap/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java index c97beb08d..d8bd992e9 100644 --- a/src/main/java/org/onap/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java +++ b/src/main/java/org/onap/clamp/clds/config/sdc/SdcSingleControllerConfiguration.java @@ -56,14 +56,14 @@ public class SdcSingleControllerConfiguration implements IConfiguration { public static final String CONSUMER_GROUP_ATTRIBUTE_NAME = "consumerGroup"; public static final String CONSUMER_ID_ATTRIBUTE_NAME = "consumerId"; public static final String ENVIRONMENT_NAME_ATTRIBUTE_NAME = "environmentName"; - public static final String PASSWORD_ATTRIBUTE_NAME = "password"; + public static final String SDC_KEY_ATTRIBUTE_NAME = "password"; public static final String POLLING_INTERVAL_ATTRIBUTE_NAME = "pollingInterval"; public static final String RELEVANT_ARTIFACT_TYPES_ATTRIBUTE_NAME = "relevantArtifactTypes"; public static final String USER_ATTRIBUTE_NAME = "user"; public static final String SDC_ADDRESS_ATTRIBUTE_NAME = "sdcAddress"; public static final String POLLING_TIMEOUT_ATTRIBUTE_NAME = "pollingTimeout"; public static final String ACTIVATE_SERVER_TLS_AUTH = "activateServerTLSAuth"; - public static final String KEY_STORE_PASSWORD = "keyStorePassword"; + public static final String KEY_STORE_KEY = "keyStorePassword"; public static final String KEY_STORE_PATH = "keyStorePath"; private String errorMessageKeyNotFound; /** @@ -109,6 +109,30 @@ public class SdcSingleControllerConfiguration implements IConfiguration { testAllRequiredParameters(); } + private String getStringConfig(String key) { + if (jsonRootNode != null && jsonRootNode.get(key) != null) { + String config = jsonRootNode.get(key).asText(); + return config.isEmpty() ? null : config; + } + return null; + } + + private Integer getIntConfig(String key) { + if (jsonRootNode != null && jsonRootNode.get(key) != null) { + return jsonRootNode.get(key).asInt(); + } else { + return 0; + } + } + + private String getEncryptedStringConfig(String key) throws GeneralSecurityException, DecoderException { + if (jsonRootNode != null && jsonRootNode.get(key) != null) { + String config = CryptoUtils.decrypt(jsonRootNode.get(key).asText()); + return config.isEmpty() ? null : config; + } + return null; + } + @Override public java.lang.Boolean isUseHttpsWithDmaap() { return false; @@ -125,42 +149,27 @@ public class SdcSingleControllerConfiguration implements IConfiguration { @Override public String getConsumerID() { - if (jsonRootNode != null && jsonRootNode.get(CONSUMER_ID_ATTRIBUTE_NAME) != null) { - String config = jsonRootNode.get(CONSUMER_ID_ATTRIBUTE_NAME).asText(); - return config.isEmpty() ? null : config; - } - return null; + return getStringConfig(CONSUMER_ID_ATTRIBUTE_NAME); } @Override public String getEnvironmentName() { - if (jsonRootNode != null && jsonRootNode.get(ENVIRONMENT_NAME_ATTRIBUTE_NAME) != null) { - String config = jsonRootNode.get(ENVIRONMENT_NAME_ATTRIBUTE_NAME).asText(); - return config.isEmpty() ? null : config; - } - return null; + return getStringConfig(ENVIRONMENT_NAME_ATTRIBUTE_NAME); } @Override public String getPassword() { try { - if (jsonRootNode != null && jsonRootNode.get(PASSWORD_ATTRIBUTE_NAME) != null) { - String config = CryptoUtils.decrypt(jsonRootNode.get(PASSWORD_ATTRIBUTE_NAME).asText()); - return config.isEmpty() ? null : config; - } + return getEncryptedStringConfig(SDC_KEY_ATTRIBUTE_NAME); } catch (GeneralSecurityException | DecoderException e) { logger.error("Unable to decrypt the SDC password", e); + return null; } - return null; } @Override public int getPollingInterval() { - if (jsonRootNode != null && jsonRootNode.get(POLLING_INTERVAL_ATTRIBUTE_NAME) != null) { - return jsonRootNode.get(POLLING_INTERVAL_ATTRIBUTE_NAME).asInt(); - } else { - return 0; - } + return getIntConfig(POLLING_INTERVAL_ATTRIBUTE_NAME); } @Override @@ -172,29 +181,17 @@ public class SdcSingleControllerConfiguration implements IConfiguration { @Override public String getUser() { - if (jsonRootNode != null && jsonRootNode.get(USER_ATTRIBUTE_NAME) != null) { - String config = jsonRootNode.get(USER_ATTRIBUTE_NAME).asText(); - return config.isEmpty() ? null : config; - } - return null; + return getStringConfig(USER_ATTRIBUTE_NAME); } @Override public String getAsdcAddress() { - if (jsonRootNode != null && jsonRootNode.get(SDC_ADDRESS_ATTRIBUTE_NAME) != null) { - String config = jsonRootNode.get(SDC_ADDRESS_ATTRIBUTE_NAME).asText(); - return config.isEmpty() ? null : config; - } - return null; + return getStringConfig(SDC_ADDRESS_ATTRIBUTE_NAME); } @Override public int getPollingTimeout() { - if (jsonRootNode != null && jsonRootNode.get(POLLING_TIMEOUT_ATTRIBUTE_NAME) != null) { - return jsonRootNode.get(POLLING_TIMEOUT_ATTRIBUTE_NAME).asInt(); - } else { - return 0; - } + return getIntConfig(POLLING_TIMEOUT_ATTRIBUTE_NAME); } @Override @@ -209,23 +206,16 @@ public class SdcSingleControllerConfiguration implements IConfiguration { @Override public String getKeyStorePassword() { try { - if (jsonRootNode != null && jsonRootNode.get(KEY_STORE_PASSWORD) != null) { - String config = CryptoUtils.decrypt(jsonRootNode.get(KEY_STORE_PASSWORD).asText()); - return config.isEmpty() ? null : config; - } + return getEncryptedStringConfig(KEY_STORE_KEY); } catch (GeneralSecurityException | DecoderException e) { logger.error("Unable to decrypt the SDC password", e); + return null; } - return null; } @Override public String getKeyStorePath() { - if (jsonRootNode != null && jsonRootNode.get(KEY_STORE_PATH) != null) { - String config = jsonRootNode.get(KEY_STORE_PATH).asText(); - return config.isEmpty() ? null : config; - } - return null; + return getStringConfig(KEY_STORE_PATH); } /** @@ -252,7 +242,7 @@ public class SdcSingleControllerConfiguration implements IConfiguration { throw new SdcParametersException(SDC_ADDRESS_ATTRIBUTE_NAME + errorMessageKeyNotFound); } if (this.getPassword() == null || this.getPassword().isEmpty()) { - throw new SdcParametersException(PASSWORD_ATTRIBUTE_NAME + errorMessageKeyNotFound); + throw new SdcParametersException(SDC_KEY_ATTRIBUTE_NAME + errorMessageKeyNotFound); } if (this.getPollingInterval() == 0) { throw new SdcParametersException(POLLING_INTERVAL_ATTRIBUTE_NAME + errorMessageKeyNotFound); diff --git a/src/main/java/org/onap/clamp/clds/exception/sdc/controller/CsarHandlerException.java b/src/main/java/org/onap/clamp/clds/exception/sdc/controller/CsarHandlerException.java new file mode 100644 index 000000000..16fd77984 --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/exception/sdc/controller/CsarHandlerException.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2018 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============================================ + * =================================================================== + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ + +package org.onap.clamp.clds.exception.sdc.controller; + +/** + * Exception during Csar operations. + */ +public class CsarHandlerException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -7628640776124409155L; + + /** + * @param message + * The message to dump + * @param cause + * The Throwable cause object + */ + public CsarHandlerException(final String message) { + super(message); + } + + /** + * @param message + * The message to dump + * @param cause + * The Throwable cause object + */ + public CsarHandlerException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java new file mode 100644 index 000000000..270286bcb --- /dev/null +++ b/src/main/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandler.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2018 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============================================ + * =================================================================== + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ + +package org.onap.clamp.clds.sdc.controller.installer; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException; +import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.results.IDistributionClientDownloadResult; +import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper; +import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException; +import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory; + +/** + * CsarDescriptor that will be used to deploy in CLAMP. + */ +public class CsarHandler { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CsarHandler.class); + private IArtifactInfo artifactElement; + private String filePath; + private String controllerName; + private SdcToscaParserFactory factory = SdcToscaParserFactory.getInstance(); + private ISdcCsarHelper sdcCsarHelper; + public static final String CSAR_TYPE = "TOSCA_CSAR"; + private String csarPath; + + public CsarHandler(INotificationData iNotif, String controller, String sdcCsarPath) throws CsarHandlerException { + this.csarPath = sdcCsarPath; + this.controllerName = controller; + this.artifactElement = searchForUniqueCsar(iNotif); + this.filePath = buildFilePathForCsar(artifactElement); + } + + private String buildFilePathForCsar(IArtifactInfo artifactElement) { + return csarPath + "/" + controllerName + "/" + artifactElement.getArtifactName(); + } + + private IArtifactInfo searchForUniqueCsar(INotificationData iNotif) throws CsarHandlerException { + List<IArtifactInfo> serviceArtifacts = iNotif.getServiceArtifacts(); + for (IArtifactInfo artifact : serviceArtifacts) { + if (artifact.getArtifactType().equals(CSAR_TYPE)) { + return artifact; + } + } + throw new CsarHandlerException("Unable to find a CSAR in the Sdc Notification"); + } + + public void save(IDistributionClientDownloadResult resultArtifact) + throws SdcArtifactInstallerException, SdcToscaParserException { + try { + logger.info("Writing CSAR file : " + artifactElement.getArtifactURL() + " UUID " + + artifactElement.getArtifactUUID() + ")"); + Path path = Paths.get(filePath); + Files.createDirectories(path.getParent()); + Files.createFile(path); + try (FileOutputStream outFile = new FileOutputStream(filePath)) { + outFile.write(resultArtifact.getArtifactPayload(), 0, resultArtifact.getArtifactPayload().length); + } + sdcCsarHelper = factory.getSdcCsarHelper(filePath); + } catch (IOException e) { + throw new SdcArtifactInstallerException( + "Exception caught when trying to write the CSAR on the file system to " + filePath, e); + } + } + + public IArtifactInfo getArtifactElement() { + return artifactElement; + } + + public String getFilePath() { + return filePath; + } + + public ISdcCsarHelper getSdcCsarHelper() { + return sdcCsarHelper; + } +} diff --git a/src/main/java/org/onap/clamp/clds/service/CldsService.java b/src/main/java/org/onap/clamp/clds/service/CldsService.java index 9bd9c4173..d22a5188b 100644 --- a/src/main/java/org/onap/clamp/clds/service/CldsService.java +++ b/src/main/java/org/onap/clamp/clds/service/CldsService.java @@ -52,6 +52,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import javax.xml.transform.TransformerException; import org.apache.camel.Produce; @@ -207,7 +208,7 @@ public class CldsService extends SecureServiceBase { /** * REST service that retrieves clds healthcheck information. - * + * * @return CldsHealthCheck class containing healthcheck info */ @GET @@ -396,95 +397,106 @@ public class CldsService extends SecureServiceBase { @Path("/action/{action}/{modelName}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public CldsModel putModelAndProcessAction(@PathParam("action") String action, + public Response putModelAndProcessAction(@PathParam("action") String action, @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model) throws TransformerException, ParseException, GeneralSecurityException, DecoderException { Date startTime = new Date(); - LoggingUtils.setRequestContext("CldsService: Process model action", getPrincipalName()); - String actionCd = action.toUpperCase(); - SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage, - cldsPermissionInstance, actionCd); - isAuthorized(permisionManage); - isAuthorizedForVf(model); - String userId = getUserId(); - String actionStateCd = CldsEvent.ACTION_STATE_INITIATED; - String processDefinitionKey = "clds-process-action-wf"; - logger.info("PUT actionCd={}", actionCd); - logger.info("PUT actionStateCd={}", actionStateCd); - logger.info("PUT processDefinitionKey={}", processDefinitionKey); - logger.info("PUT modelName={}", modelName); - logger.info("PUT test={}", test); - logger.info("PUT bpmnText={}", model.getBpmnText()); - logger.info("PUT propText={}", model.getPropText()); - logger.info("PUT userId={}", userId); - logger.info("PUT getTypeId={}", model.getTypeId()); - logger.info("PUT deploymentId={}", model.getDeploymentId()); - if (model.getTemplateName() != null) { - CldsTemplate template = cldsDao.getTemplate(model.getTemplateName()); - if (template != null) { - model.setTemplateId(template.getId()); - model.setDocText(template.getPropText()); - // This is to provide the Bpmn XML when Template part in UI is - // disabled - model.setBpmnText(template.getBpmnText()); + CldsModel retrievedModel = null; + Boolean errorCase = false; + try { + LoggingUtils.setRequestContext("CldsService: Process model action", getPrincipalName()); + String actionCd = action.toUpperCase(); + SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage, + cldsPermissionInstance, actionCd); + isAuthorized(permisionManage); + isAuthorizedForVf(model); + String userId = getUserId(); + String actionStateCd = CldsEvent.ACTION_STATE_INITIATED; + String processDefinitionKey = "clds-process-action-wf"; + logger.info("PUT actionCd={}", actionCd); + logger.info("PUT actionStateCd={}", actionStateCd); + logger.info("PUT processDefinitionKey={}", processDefinitionKey); + logger.info("PUT modelName={}", modelName); + logger.info("PUT test={}", test); + logger.info("PUT bpmnText={}", model.getBpmnText()); + logger.info("PUT propText={}", model.getPropText()); + logger.info("PUT userId={}", userId); + logger.info("PUT getTypeId={}", model.getTypeId()); + logger.info("PUT deploymentId={}", model.getDeploymentId()); + if (model.getTemplateName() != null) { + CldsTemplate template = cldsDao.getTemplate(model.getTemplateName()); + if (template != null) { + model.setTemplateId(template.getId()); + model.setDocText(template.getPropText()); + // This is to provide the Bpmn XML when Template part in UI is + // disabled + model.setBpmnText(template.getBpmnText()); + } } - } - // save model to db - model.setName(modelName); - model.save(cldsDao, getUserId()); - // get vars and format if necessary - String prop = model.getPropText(); - String bpmn = model.getBpmnText(); - String docText = model.getDocText(); - String controlName = model.getControlName(); - String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn); - logger.info("PUT bpmnJson={}", bpmnJson); - // Flag indicates whether it is triggered by Validation Test button from - // UI - boolean isTest = false; - if (test != null && test.equalsIgnoreCase("true")) { - isTest = true; - } else { - String actionTestOverride = refProp.getStringValue("action.test.override"); - if (actionTestOverride != null && actionTestOverride.equalsIgnoreCase("true")) { - logger.info("PUT actionTestOverride={}", actionTestOverride); - logger.info("PUT override test indicator and setting it to true"); + // save model to db + model.setName(modelName); + model.save(cldsDao, getUserId()); + // get vars and format if necessary + String prop = model.getPropText(); + String bpmn = model.getBpmnText(); + String docText = model.getDocText(); + String controlName = model.getControlName(); + String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn); + logger.info("PUT bpmnJson={}", bpmnJson); + // Flag indicates whether it is triggered by Validation Test button from + // UI + boolean isTest = false; + if (test != null && test.equalsIgnoreCase("true")) { isTest = true; + } else { + String actionTestOverride = refProp.getStringValue("action.test.override"); + if (actionTestOverride != null && actionTestOverride.equalsIgnoreCase("true")) { + logger.info("PUT actionTestOverride={}", actionTestOverride); + logger.info("PUT override test indicator and setting it to true"); + isTest = true; + } } + logger.info("PUT isTest={}", isTest); + boolean isInsertTestEvent = false; + String insertTestEvent = refProp.getStringValue("action.insert.test.event"); + if (insertTestEvent != null && insertTestEvent.equalsIgnoreCase("true")) { + isInsertTestEvent = true; + } + logger.info("PUT isInsertTestEvent={}", isInsertTestEvent); + // determine if requested action is permitted + model.validateAction(actionCd); + logger.info("modelProp - " + prop); + logger.info("docText - " + docText); + try { + String result = camelProxy.submit(actionCd, prop, bpmnJson, modelName, controlName, docText, isTest, userId, + isInsertTestEvent); + logger.info("Starting Camel flow on request, result is: ", result); + } catch (SdcCommunicationException | PolicyClientException | BadRequestException e) { + errorCase = true; + logger.error("Exception occured during invoking Camel process", e); + } + // refresh model info from db (get fresh event info) + retrievedModel = CldsModel.retrieve(cldsDao, modelName, false); + if (!isTest && (actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMIT) + || actionCd.equalsIgnoreCase(CldsEvent.ACTION_RESUBMIT) + || actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMITDCAE))) { + // To verify inventory status and modify model status to distribute + dcaeInventoryServices.setEventInventory(retrievedModel, getUserId()); + retrievedModel.save(cldsDao, getUserId()); + } + // audit log + LoggingUtils.setTimeContext(startTime, new Date()); + LoggingUtils.setResponseContext("0", "Process model action success", this.getClass().getName()); + auditLogger.info("Process model action completed"); + } catch (Exception e) { + errorCase = true; + logger.error("Exception occured during putModelAndProcessAction", e); } - logger.info("PUT isTest={}", isTest); - boolean isInsertTestEvent = false; - String insertTestEvent = refProp.getStringValue("action.insert.test.event"); - if (insertTestEvent != null && insertTestEvent.equalsIgnoreCase("true")) { - isInsertTestEvent = true; - } - logger.info("PUT isInsertTestEvent={}", isInsertTestEvent); - // determine if requested action is permitted - model.validateAction(actionCd); - logger.info("modelProp - " + prop); - logger.info("docText - " + docText); - try { - String result = camelProxy.submit(actionCd, prop, bpmnJson, modelName, controlName, docText, isTest, userId, - isInsertTestEvent); - logger.info("Starting Camel flow on request, result is: ", result); - } catch (SdcCommunicationException | PolicyClientException | BadRequestException e) { - logger.error("Exception occured during invoking Camel process", e); - throw new CldsConfigException(e.getMessage(), e); - } - // refresh model info from db (get fresh event info) - CldsModel retrievedModel = CldsModel.retrieve(cldsDao, modelName, false); - if (!isTest && (actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMIT) - || actionCd.equalsIgnoreCase(CldsEvent.ACTION_RESUBMIT) - || actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMITDCAE))) { - // To verify inventory status and modify model status to distribute - dcaeInventoryServices.setEventInventory(retrievedModel, getUserId()); - retrievedModel.save(cldsDao, getUserId()); + + if (errorCase) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(retrievedModel).build(); } - // audit log - LoggingUtils.setTimeContext(startTime, new Date()); - LoggingUtils.setResponseContext("0", "Process model action success", this.getClass().getName()); - auditLogger.info("Process model action completed"); - return retrievedModel; + return Response.status(Response.Status.OK).entity(retrievedModel).build(); } /** @@ -542,7 +554,7 @@ public class CldsService extends SecureServiceBase { /** * REST service that retrieves sdc services - * + * * @throws GeneralSecurityException * In case of issue when decryting the SDC password * @throws DecoderException @@ -572,7 +584,7 @@ public class CldsService extends SecureServiceBase { /** * REST service that retrieves total properties required by UI - * + * * @throws IOException * In case of issues */ @@ -586,7 +598,7 @@ public class CldsService extends SecureServiceBase { /** * REST service that retrieves total properties by using invariantUUID based * on refresh and non refresh - * + * * @throws GeneralSecurityException * In case of issues with the decryting the encrypted password * @throws DecoderException @@ -794,102 +806,123 @@ public class CldsService extends SecureServiceBase { @Path("/deploy/{modelName}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public CldsModel deployModel(@PathParam("action") String action, @PathParam("modelName") String modelName, + public Response deployModel(@PathParam("action") String action, @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model) { Date startTime = new Date(); LoggingUtils.setRequestContext("CldsService: Deploy model", getPrincipalName()); + Boolean errorCase = false; try { - checkForDuplicateServiceVf(modelName, model.getPropText()); - } catch (IOException | BadRequestException e) { - logger.error("Exception occured during duplicate check for service and VF", e); - throw new CldsConfigException(e.getMessage(), e); - } - String deploymentId = ""; - // If model is already deployed then pass same deployment id - if (model.getDeploymentId() != null && !model.getDeploymentId().isEmpty()) { - deploymentId = model.getDeploymentId(); - } else { - deploymentId = "closedLoop_" + UUID.randomUUID() + "_deploymentId"; - } - String createNewDeploymentStatusUrl = dcaeDispatcherServices.createNewDeployment(deploymentId, - model.getTypeId()); - String operationStatus = "processing"; - long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10); - while ("processing".equalsIgnoreCase(operationStatus)) { - // Break the loop if waiting for more than 10 mins - if (waitingTime < System.nanoTime()) { - break; + try { + checkForDuplicateServiceVf(modelName, model.getPropText()); + } catch (IOException | BadRequestException e) { + errorCase = true; + logger.error("Exception occured during duplicate check for service and VF", e); } - operationStatus = dcaeDispatcherServices.getOperationStatus(createNewDeploymentStatusUrl); - } - if ("succeeded".equalsIgnoreCase(operationStatus)) { - String artifactName = model.getControlName(); - if (artifactName != null) { - artifactName = artifactName + ".yml"; + String deploymentId = ""; + // If model is already deployed then pass same deployment id + if (model.getDeploymentId() != null && !model.getDeploymentId().isEmpty()) { + deploymentId = model.getDeploymentId(); + } else { + deploymentId = "closedLoop_" + UUID.randomUUID() + "_deploymentId"; } - DcaeEvent dcaeEvent = new DcaeEvent(); - /* set dcae events */ - dcaeEvent.setArtifactName(artifactName); - dcaeEvent.setEvent(DcaeEvent.EVENT_DEPLOYMENT); - CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(), - CldsEvent.ACTION_STATE_RECEIVED, null); - model.setDeploymentId(deploymentId); - model.save(cldsDao, getUserId()); - } else { - logger.info("Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); - throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, - "Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); + String createNewDeploymentStatusUrl = dcaeDispatcherServices.createNewDeployment(deploymentId, + model.getTypeId()); + String operationStatus = "processing"; + long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10); + while ("processing".equalsIgnoreCase(operationStatus)) { + // Break the loop if waiting for more than 10 mins + if (waitingTime < System.nanoTime()) { + break; + } + operationStatus = dcaeDispatcherServices.getOperationStatus(createNewDeploymentStatusUrl); + } + if ("succeeded".equalsIgnoreCase(operationStatus)) { + String artifactName = model.getControlName(); + if (artifactName != null) { + artifactName = artifactName + ".yml"; + } + DcaeEvent dcaeEvent = new DcaeEvent(); + /* set dcae events */ + dcaeEvent.setArtifactName(artifactName); + dcaeEvent.setEvent(DcaeEvent.EVENT_DEPLOYMENT); + CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(), + CldsEvent.ACTION_STATE_RECEIVED, null); + model.setDeploymentId(deploymentId); + model.save(cldsDao, getUserId()); + } else { + logger.info("Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); + throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, + "Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); + } + logger.info("Deploy model (" + modelName + ") succeeded...Deployment Id is - " + deploymentId); + // audit log + LoggingUtils.setTimeContext(startTime, new Date()); + LoggingUtils.setResponseContext("0", "Deploy model success", this.getClass().getName()); + auditLogger.info("Deploy model completed"); + } catch (Exception e) { + errorCase = true; + logger.error("Exception occured during deployModel", e); } - logger.info("Deploy model (" + modelName + ") succeeded...Deployment Id is - " + deploymentId); - // audit log - LoggingUtils.setTimeContext(startTime, new Date()); - LoggingUtils.setResponseContext("0", "Deploy model success", this.getClass().getName()); - auditLogger.info("Deploy model completed"); - return model; + + if (errorCase) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(model).build(); + } + return Response.status(Response.Status.OK).entity(model).build(); } @PUT @Path("/undeploy/{modelName}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public CldsModel unDeployModel(@PathParam("action") String action, @PathParam("modelName") String modelName, + public Response unDeployModel(@PathParam("action") String action, @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model) { Date startTime = new Date(); LoggingUtils.setRequestContext("CldsService: Undeploy model", getPrincipalName()); - String operationStatusUndeployUrl = dcaeDispatcherServices.deleteExistingDeployment(model.getDeploymentId(), - model.getTypeId()); - String operationStatus = "processing"; - long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10); - while ("processing".equalsIgnoreCase(operationStatus)) { - if (waitingTime < System.nanoTime()) { - break; + + Boolean errorCase = false; + try { + String operationStatusUndeployUrl = dcaeDispatcherServices.deleteExistingDeployment(model.getDeploymentId(), + model.getTypeId()); + String operationStatus = "processing"; + long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10); + while ("processing".equalsIgnoreCase(operationStatus)) { + if (waitingTime < System.nanoTime()) { + break; + } + operationStatus = dcaeDispatcherServices.getOperationStatus(operationStatusUndeployUrl); } - operationStatus = dcaeDispatcherServices.getOperationStatus(operationStatusUndeployUrl); - } - if ("succeeded".equalsIgnoreCase(operationStatus)) { - String artifactName = model.getControlName(); - if (artifactName != null) { - artifactName = artifactName + ".yml"; + if ("succeeded".equalsIgnoreCase(operationStatus)) { + String artifactName = model.getControlName(); + if (artifactName != null) { + artifactName = artifactName + ".yml"; + } + DcaeEvent dcaeEvent = new DcaeEvent(); + // set dcae events + dcaeEvent.setArtifactName(artifactName); + dcaeEvent.setEvent(DcaeEvent.EVENT_UNDEPLOYMENT); + CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(), + CldsEvent.ACTION_STATE_RECEIVED, null); + model.setDeploymentId(null); + model.save(cldsDao, getUserId()); + } else { + logger.info("Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); + throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, + "Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); } - DcaeEvent dcaeEvent = new DcaeEvent(); - // set dcae events - dcaeEvent.setArtifactName(artifactName); - dcaeEvent.setEvent(DcaeEvent.EVENT_UNDEPLOYMENT); - CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(), - CldsEvent.ACTION_STATE_RECEIVED, null); - model.setDeploymentId(null); - model.save(cldsDao, getUserId()); - } else { - logger.info("Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); - throw new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, - "Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus); + logger.info("Undeploy model (" + modelName + ") succeeded."); + // audit log + LoggingUtils.setTimeContext(startTime, new Date()); + LoggingUtils.setResponseContext("0", "Undeploy model success", this.getClass().getName()); + auditLogger.info("Undeploy model completed"); + } catch (Exception e) { + errorCase = true; + logger.error("Exception occured during unDeployModel", e); } - logger.info("Undeploy model (" + modelName + ") succeeded."); - // audit log - LoggingUtils.setTimeContext(startTime, new Date()); - LoggingUtils.setResponseContext("0", "Undeploy model success", this.getClass().getName()); - auditLogger.info("Undeploy model completed"); - return model; + + if (errorCase) { + return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(model).build(); + } + return Response.status(Response.Status.OK).entity(model).build(); } private void checkForDuplicateServiceVf(String modelName, String modelPropText) throws IOException { diff --git a/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java b/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java index 720576c47..0402754ac 100644 --- a/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java +++ b/src/main/java/org/onap/clamp/clds/util/ResourceFileUtil.java @@ -52,7 +52,7 @@ public final class ResourceFileUtil { } /** - * Return resource as a Stream. + * Return resource as a String. */ public static String getResourceAsString(String name) throws IOException { InputStream is = getResourceAsStream(name); diff --git a/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js b/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js index f6092b8f2..0887550e1 100644 --- a/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js +++ b/src/main/resources/META-INF/resources/designer/scripts/CldsModelService.js @@ -214,6 +214,7 @@ app.service('cldsModelService', ['alertService', '$http', '$q', function(alertSe }) .error(function(data) { + def.resolve(data); alertService.alertMessage("Action Failure:" + uiAction, 2); //def alertService.alertMessage("Action Successful:"+uiAction,1); def.reject(svcAction + " not successful"); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3d56725d6..f626e1af1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -177,6 +177,7 @@ clamp.config.sdc.locationArtifactType=DCAE_INVENTORY_JSON clamp.config.sdc.InstanceID=X-ECOMP-InstanceID
clamp.config.sdc.header.requestId = X-ECOMP-RequestID
#
+clamp.config.sdc.csarFolder = /tmp/sdc-controllers
#
clamp.config.ui.location.default=classpath:/clds/templates/ui-location-default.json
clamp.config.ui.alarm.default=classpath:/clds/templates/ui-alarm-default.json
diff --git a/src/test/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandlerTest.java b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandlerTest.java new file mode 100644 index 000000000..4c3ab86b7 --- /dev/null +++ b/src/test/java/org/onap/clamp/clds/sdc/controller/installer/CsarHandlerTest.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2018 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============================================ + * =================================================================== + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ + +package org.onap.clamp.clds.sdc.controller.installer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.att.aft.dme2.internal.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import org.junit.AfterClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.clamp.clds.exception.sdc.controller.CsarHandlerException; +import org.onap.clamp.clds.exception.sdc.controller.SdcArtifactInstallerException; +import org.onap.clamp.clds.util.ResourceFileUtil; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.results.IDistributionClientDownloadResult; +import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException; + +public class CsarHandlerTest { + + private static final String sdcFolder = "/tmp/csar-handler-tests"; + private static final String csarArtifactName = "testArtifact.csar"; + + @AfterClass + public static void removeAllFiles() throws IOException { + // Do some cleanup + Path path = Paths.get(sdcFolder + "/test-controller/" + csarArtifactName); + Files.deleteIfExists(path); + } + + @Test + public void testConstructor() throws CsarHandlerException { + IArtifactInfo serviceArtifact = Mockito.mock(IArtifactInfo.class); + Mockito.when(serviceArtifact.getArtifactType()).thenReturn(CsarHandler.CSAR_TYPE); + Mockito.when(serviceArtifact.getArtifactName()).thenReturn(csarArtifactName); + List<IArtifactInfo> servicesList = new ArrayList<>(); + servicesList.add(serviceArtifact); + INotificationData iNotifData = Mockito.mock(INotificationData.class); + Mockito.when(iNotifData.getServiceArtifacts()).thenReturn(servicesList); + CsarHandler csar = new CsarHandler(iNotifData, "test-controller", sdcFolder); + assertEquals(sdcFolder + "/test-controller" + "/" + csarArtifactName, csar.getFilePath()); + } + + @Test(expected = CsarHandlerException.class) + public void testFailingConstructor() throws CsarHandlerException { + INotificationData iNotifData = Mockito.mock(INotificationData.class); + Mockito.when(iNotifData.getServiceArtifacts()).thenReturn(new ArrayList<>()); + new CsarHandler(iNotifData, "test-controller", "/tmp/csar-handler-tests"); + fail("Exception should have been raised"); + } + + @Test + public void testSave() + throws SdcArtifactInstallerException, SdcToscaParserException, CsarHandlerException, IOException { + IArtifactInfo serviceArtifact = Mockito.mock(IArtifactInfo.class); + Mockito.when(serviceArtifact.getArtifactType()).thenReturn(CsarHandler.CSAR_TYPE); + Mockito.when(serviceArtifact.getArtifactName()).thenReturn(csarArtifactName); + List<IArtifactInfo> servicesList = new ArrayList<>(); + servicesList.add(serviceArtifact); + INotificationData iNotifData = Mockito.mock(INotificationData.class); + Mockito.when(iNotifData.getServiceArtifacts()).thenReturn(servicesList); + CsarHandler csar = new CsarHandler(iNotifData, "test-controller", "/tmp/csar-handler-tests"); + IDistributionClientDownloadResult resultArtifact = Mockito.mock(IDistributionClientDownloadResult.class); + Mockito.when(resultArtifact.getArtifactPayload()).thenReturn( + IOUtils.toByteArray(ResourceFileUtil.getResourceAsStream("example/sdc/service-Simsfoimap0112.csar"))); + csar.save(resultArtifact); + assertTrue((new File(sdcFolder + "/test-controller/" + csarArtifactName)).exists()); + assertEquals(csarArtifactName, csar.getArtifactElement().getArtifactName()); + assertNotNull(csar.getSdcCsarHelper()); + } +} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index adcd4d98b..413cfe7a1 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -177,6 +177,7 @@ clamp.config.sdc.locationArtifactType=DCAE_INVENTORY_JSON clamp.config.sdc.InstanceID=X-ECOMP-InstanceID
clamp.config.sdc.header.requestId = X-ECOMP-RequestID
#
+clamp.config.sdc.csarFolder = /tmp/sdc-tests
#
clamp.config.ui.location.default=classpath:/clds/templates/ui-location-default.json
clamp.config.ui.alarm.default=classpath:/clds/templates/ui-alarm-default.json
diff --git a/src/test/resources/example/sdc/service-Simsfoimap0112.csar b/src/test/resources/example/sdc/service-Simsfoimap0112.csar Binary files differnew file mode 100644 index 000000000..160c8f2cc --- /dev/null +++ b/src/test/resources/example/sdc/service-Simsfoimap0112.csar |