diff options
author | Patrick Brady <pb071s@att.com> | 2017-02-15 23:11:26 -0800 |
---|---|---|
committer | Patrick Brady <pb071s@att.com> | 2017-02-15 23:13:06 -0800 |
commit | 1c192d2dd68724e292b6a30f463085a262e1e813 (patch) | |
tree | d0e2b3a396e169863cd0efaa835c8675e9d5aaac /appc-dispatcher/appc-request-handler | |
parent | c69ba05c7508aa7d7f675189a45c8c87569369ef (diff) |
Moving all files to root directory
Change-Id: Ica5535fd6ec85f350fe1640b42137b49f83f10f0
Signed-off-by: Patrick Brady <pb071s@att.com>
Diffstat (limited to 'appc-dispatcher/appc-request-handler')
44 files changed, 5115 insertions, 0 deletions
diff --git a/appc-dispatcher/appc-request-handler/.gitignore b/appc-dispatcher/appc-request-handler/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml new file mode 100644 index 000000000..b24c10797 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml @@ -0,0 +1,59 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler-api</artifactId> + <packaging>bundle</packaging> + + <name>appc-request-handler-api</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> +<!-- <version>${jackson.version}</version> --> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.message</Export-Package> + <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Import-Package>com.fasterxml.jackson.annotation,org.apache.commons.lang3,!groovy.lang,!javax.*,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java new file mode 100644 index 000000000..c397f09cd --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/message/RequestHandlerMessages.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.message; + + +public class RequestHandlerMessages { + public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; + public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java new file mode 100644 index 000000000..d0d54c9db --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/RequestHandler.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; + +/** + * This class provides application logic for the Request/Response Handler Component. + * + */ +public interface RequestHandler { + /** + * It receives requests from the north-bound REST API (Communication) Layer and + * performs following validations. + * 1. VNF exists in A&AI for the given targetID (VnfID) + * 2. For the current VNF Orchestration Status, the command can be executed + * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database + * If any of the validation fails, it returns appropriate response + * + * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc. + * @return response for request as enum with Return code and message. + */ + RequestHandlerOutput handleRequest(RequestHandlerInput input); + + /** + * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI. + * @param vnf_id vnf id or target Id on which updates required + * @param requestIdentifierString - string contains id uniquely represents the request + * @param forceFlag + * @return true in case AAI updates are successful. false for any error or exception. + */ + void onRequestExecutionStart(String vnf_id, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException; + + /** + * This method perform following operations required after execution of workflow. + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * Generate audit logs. + * Adds transaction record to database id if transaction logging is enabled. + * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I + * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion. + */ + void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated); + + /** + * This method perform following operations required if TTL ends when request still waiting in execution queue . + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * @param runtimeContext RuntimeContext object which contains all parameters from request, response and few parameters from AA&I; + * @param updateAAI boolean flag which indicate AAI upodate status after request completion. + */ + void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI); +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java new file mode 100644 index 000000000..70d9b84e8 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerInput.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.objects; + +import org.openecomp.appc.domainmodel.lcm.RequestContext; + +public class RequestHandlerInput { + + + private RequestContext requestContext; + private String rpcName; + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public RequestContext getRequestContext() { + return requestContext; + } + + public RequestHandlerInput(){ + } + + + public void setRequestContext(RequestContext requestContext) { + this.requestContext = requestContext; + } + + @Override + public String toString() { + return "RequestHandlerInput{" + + "requestContext=" + requestContext + + '}'; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java new file mode 100644 index 000000000..051c02708 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/objects/RequestHandlerOutput.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.objects; + +import org.openecomp.appc.domainmodel.lcm.ResponseContext; + +public class RequestHandlerOutput { + + private ResponseContext responseContext; + + public RequestHandlerOutput(){ + + } + + public ResponseContext getResponseContext() { + return responseContext; + } + + public void setResponseContext(ResponseContext responseContext) { + this.responseContext = responseContext; + } + + @Override + public String toString() { + return "RequestHandlerOutput{" + + "responseContext=" + responseContext + + '}'; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <installed facet="java" version="1.8"/> +</faceted-project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml new file mode 100644 index 000000000..d2f469bbc --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <!-- Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with this + work for additional information regarding copyright ownership. The ASF licenses + this file to You 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. --> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler-core</artifactId> + <packaging>bundle</packaging> + + <name>appc-request-handler-core Bundle</name> + <description>appc-request-handler-core OSGi bundle project.</description> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-workflow-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>execution-queue-management-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-lifecycle-management-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-data-access-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>lock-manager-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>transaction-recorder</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Embed-Dependency>appc-provider-model,appc-dmaap-adapter-bundle,appc-metric-bundle,appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Export-Service>org.openecomp.appc.requesthandler.RequestHandler</Export-Service> + <Import-Package>org.openecomp.appc.lockmanager.api.*,org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder,org.openecomp.appc.transactionrecorder.objects,!groovy.lang,!org.apache.log,!org.apache.log4j.*,!org.codehaus.jackson.*,!org.codehaus.jackson.map.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.apache.commons.lang3,!org.codehaus.janino,!org.jasypt.*,!com.ibm.icu.*,!com.sun.faces.*,*</Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java new file mode 100644 index 000000000..e516f4991 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/common/constant/Constants.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.common.constant; + +import java.util.concurrent.TimeUnit; + +public class Constants { + + public static final int DEFAULT_TTL = 30; + public static final String SUCCESS_MSG="SUCCESS"; + public static final String FAILURE_MSG="FAILURE"; + public static final String DEFAULT_LOGGING_FLAG="true"; + public static final long DEFAULT_IDLE_TIMEOUT = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES); +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java new file mode 100644 index 000000000..e24237fcb --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/MessageAdapter.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.messageadapter; + +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; + +public interface MessageAdapter { + /** + * Initialize dmaapProducer client to post messages using configuration properties + */ + void init(); + + /** + * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP. + * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel). + * @return True if message is postes successfully else False + */ + boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse); + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java new file mode 100644 index 000000000..9f74ad438 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/messageadapter/impl/MessageAdapterDmaapImpl.java @@ -0,0 +1,127 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.messageadapter.impl; + +import java.util.HashSet; +import java.util.Properties; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.adapter.dmaap.Producer; +import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.requesthandler.conv.Converter; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.core.JsonProcessingException; + +public class MessageAdapterDmaapImpl implements MessageAdapter{ + + private Producer dmaapProducer; + private String partition ; + private Configuration configuration; + private HashSet<String> pool; + private String writeTopic; + private String apiKey; + private String apiSecret; + + private Integer READ_TIMEOUT; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapterDmaapImpl.class); + + /** + * Initialize dmaapProducer client to post messages using configuration properties + */ + @Override + public void init(){ + this.dmaapProducer = getDmaapProducer(); + } + private Producer getDmaapProducer() { + configuration = ConfigurationFactory.getConfiguration(); + Properties properties=configuration.getProperties(); + updateProperties(properties); + Producer producer=new DmaapProducer(pool,writeTopic); + producer.updateCredentials(apiKey, apiSecret); + return producer; + } + + + private void updateProperties(Properties props) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to updateProperties with Properties = "+ ObjectUtils.toString(props)); + } + pool = new HashSet<>(); + if (props != null) { + // readTopic = props.getProperty("dmaap.topic.read"); + writeTopic = props.getProperty("dmaap.topic.write"); + apiKey = props.getProperty("dmaap.client.key"); + apiSecret = props.getProperty("dmaap.client.secret"); + /* clientName = props.getProperty("dmaap.client.name", "APP-C"); + clientId = props.getProperty("dmaap.client.name.id", "0"); + filter_json = props.getProperty("dmaap.topic.read.filter"); + */ + // READ_TIMEOUT = Integer.valueOf(props.getProperty("dmaap.topic.read.timeout", String.valueOf(READ_TIMEOUT))); + String hostnames = props.getProperty("dmaap.poolMembers"); + if (hostnames != null && !hostnames.isEmpty()) { + for (String name : hostnames.split(",")) { + pool.add(name); + } + } + } + } + + /** + * Posts message to DMaaP. As DMaaP accepts only json messages this method first convert dmaapMessage to json format and post it to DMaaP. + * @param asyncResponse response data that based on it a message will be send to DMaaP (the format of the message that will be sent to DMaaP based on the action and its YANG domainmodel). + * @return True if message is postes successfully else False + */ + @Override + public boolean post(VNFOperation operation, String rpcName, ResponseContext asyncResponse){ + boolean success; + if (logger.isTraceEnabled()) { + logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(asyncResponse)); + } + + String jsonMessage; + try { + jsonMessage = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(operation, rpcName, asyncResponse); + if (logger.isDebugEnabled()) { + logger.debug("DMaaP Response = " + jsonMessage); + } + success = dmaapProducer.post(this.partition, jsonMessage); + } catch (JsonProcessingException e1) { + logger.error("Error generating Jason from DMaaP message "+ e1.getMessage()); + success= false; + }catch (Exception e){ + logger.error("Error sending message to DMaaP "+e.getMessage()); + success= false; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from post with (success = "+ ObjectUtils.toString(success)+")"); + } + return success; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java new file mode 100644 index 000000000..50c18d661 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/conv/Converter.java @@ -0,0 +1,341 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.conv; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Payload; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutputBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ZULU; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.FlagsBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.status.StatusBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.openecomp.appc.domainmodel.lcm.ResponseContext; +import org.openecomp.appc.domainmodel.lcm.VNFOperation; +import org.openecomp.appc.requesthandler.impl.DmaapOutgoingMessage; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationFeature; + + +public class Converter { + public static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + public static final String MODE_FLAG = "MODE"; + public static final String FORCE_FLAG = "FORCE"; + public static final String TTL_FLAG = "TTL"; + public final static String DMaaP_ROOT_VALUE = "output"; + private static final SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(Converter.class); + static { + isoFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + public static Builder<?> convAsyncResponseToBuilder(VNFOperation vnfOperation, String rpcName, ResponseContext response) { + Builder<?> outObj = null; + if(response == null){ + throw new IllegalArgumentException("empty asyncResponse"); + } + if(vnfOperation == null){ + throw new IllegalArgumentException("empty asyncResponse.action"); + } + Action action = Action.valueOf(vnfOperation.name()); + CommonHeader commonHeader = convAsyncResponseTorev160108CommonHeader(response); + Status status = convAsyncResponseTorev160108Status(response); +// Payload payload = convAsyncResponseTorev160108Payload(inObj); + switch (action){ + case Rollback: + outObj = new RollbackOutputBuilder(); + ((RollbackOutputBuilder)outObj).setCommonHeader(commonHeader); + ((RollbackOutputBuilder)outObj).setStatus(status); + return outObj; + case Snapshot: + outObj = new SnapshotOutputBuilder(); + ((SnapshotOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SnapshotOutputBuilder)outObj).setStatus(status); + try { + ((SnapshotOutputBuilder) outObj).setSnapshotId(response.getAdditionalContext().get("output.snapshot-id")); + } catch (NullPointerException ignored) { + // in case of negative response, snapshotID does not populated, so just ignore NPL + } + return outObj; + case Audit: + outObj = new AuditOutputBuilder(); + ((AuditOutputBuilder)outObj).setCommonHeader(commonHeader); + ((AuditOutputBuilder)outObj).setStatus(status); + return outObj; + case HealthCheck: + outObj = new HealthCheckOutputBuilder(); + ((HealthCheckOutputBuilder)outObj).setCommonHeader(commonHeader); + ((HealthCheckOutputBuilder)outObj).setStatus(status); + return outObj; + case LiveUpgrade: + outObj = new LiveUpgradeOutputBuilder(); + ((LiveUpgradeOutputBuilder)outObj).setCommonHeader(commonHeader); + ((LiveUpgradeOutputBuilder)outObj).setStatus(status); + return outObj; + case Lock: + outObj = new LockOutputBuilder(); + ((LockOutputBuilder)outObj).setCommonHeader(commonHeader); + ((LockOutputBuilder)outObj).setStatus(status); + return outObj; + case ModifyConfig: + outObj = new ModifyConfigOutputBuilder(); + ((ModifyConfigOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ModifyConfigOutputBuilder)outObj).setStatus(status); + return outObj; + case SoftwareUpload: + outObj = new SoftwareUploadOutputBuilder(); + ((SoftwareUploadOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SoftwareUploadOutputBuilder)outObj).setStatus(status); + return outObj; + case Stop: + outObj = new StopOutputBuilder(); + ((StopOutputBuilder)outObj).setCommonHeader(commonHeader); + ((StopOutputBuilder)outObj).setStatus(status); + return outObj; + case Sync: + outObj = new SyncOutputBuilder(); + ((SyncOutputBuilder)outObj).setCommonHeader(commonHeader); + ((SyncOutputBuilder)outObj).setStatus(status); + return outObj; + case Terminate: + outObj = new TerminateOutputBuilder(); + ((TerminateOutputBuilder)outObj).setCommonHeader(commonHeader); + ((TerminateOutputBuilder)outObj).setStatus(status); + return outObj; + case Test: + outObj = new TestOutputBuilder(); + ((TestOutputBuilder)outObj).setCommonHeader(commonHeader); + ((TestOutputBuilder)outObj).setStatus(status); + return outObj; + case Unlock: + outObj = new UnlockOutputBuilder(); + ((UnlockOutputBuilder)outObj).setCommonHeader(commonHeader); + ((UnlockOutputBuilder)outObj).setStatus(status); + return outObj; + default: + throw new IllegalArgumentException(action+" action is not supported"); + } + } + + public static Payload convAsyncResponseTorev160108Payload(ResponseContext inObj) throws ParseException { + Payload payload = null; + if(inObj.getPayload() != null) { + payload = new Payload(inObj.getPayload()); + } + return payload; + } + + public static String convPayloadObjectToJsonString(Object inObj) throws ParseException { + String payloadAsString = null; + if(inObj != null) { + + if(inObj instanceof String){ + payloadAsString = (String)inObj; + }else { + try { + ObjectMapper objectMapper = new ObjectMapper(); + payloadAsString = objectMapper.writeValueAsString(inObj); +// payloadAsString = objectMapper.writeValueAsString(payloadAsString); + } catch (JsonProcessingException e) { + String errMsg = "Error serialize payload json to string"; + throw new ParseException(errMsg + "-" + e.toString(), 0); + } + } + } + return payloadAsString; + } + + public static Status convAsyncResponseTorev160108Status(ResponseContext inObj) { + StatusBuilder statusBuilder = new StatusBuilder(); + statusBuilder.setCode(inObj.getStatus().getCode()); + statusBuilder.setMessage(inObj.getStatus().getMessage()); + return statusBuilder.build(); + } + + public static CommonHeader convAsyncResponseTorev160108CommonHeader(ResponseContext inObj) { + CommonHeader outObj = null; + if(inObj == null){ + throw new IllegalArgumentException("empty asyncResponse"); + } + + CommonHeaderBuilder commonHeaderBuilder = new CommonHeaderBuilder(); + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags commonHeaderFlags = null; + if(inObj.getCommonHeader().getFlags() != null){ + commonHeaderFlags = Converter.convFlagsMapTorev160108Flags(inObj.getCommonHeader().getFlags()); + commonHeaderBuilder.setFlags(commonHeaderFlags); + } + + + commonHeaderBuilder.setApiVer(inObj.getCommonHeader().getApiVer()); + commonHeaderBuilder.setRequestId(inObj.getCommonHeader().getRequestId()); + if(inObj.getCommonHeader().getSubRequestId() != null){ + commonHeaderBuilder.setSubRequestId(inObj.getCommonHeader().getSubRequestId()); + } + + if(inObj.getCommonHeader().getOriginatorId() != null){ + commonHeaderBuilder.setOriginatorId(inObj.getCommonHeader().getOriginatorId()); + } + + if(inObj.getCommonHeader().getTimeStamp() != null){ + String zuluTimestampStr = Converter.convDateToZuluString(inObj.getCommonHeader().getTimeStamp()); + ZULU zuluTimestamp = new ZULU(zuluTimestampStr); + commonHeaderBuilder.setTimestamp(zuluTimestamp); + } + outObj = commonHeaderBuilder.build(); + return outObj; + + } + + public static String convDateToZuluString(Date timeStamp) { + return isoFormatter.format(timeStamp); + } + + public static org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags + convFlagsMapTorev160108Flags(org.openecomp.appc.domainmodel.lcm.Flags flags) { + Flags rev160108flags = null; + boolean anyFlag = false; + FlagsBuilder flagsBuilder = new FlagsBuilder(); + /* + * TODO: The below flags are related to APP-C request and should not be sent back - uncomment when response flags are introduced. + */ + /* + if(flags.containsKey(FORCE_FLAG)){ + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force force = + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Force.valueOf(flags.get(FORCE_FLAG).toString()); + flagsBuilder.setForce(force); + anyFlag = true; + } + if(flags.containsKey(MODE_FLAG)){ + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode mode = + org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags.Mode.valueOf(flags.get(MODE_FLAG).toString()); + flagsBuilder.setMode(mode); + anyFlag = true; + } + if(flags.containsKey(TTL_FLAG)){ + flagsBuilder.setTtl(Integer.valueOf(flags.get(TTL_FLAG).toString())); + anyFlag = true; + } + if(anyFlag){ + rev160108flags = flagsBuilder.build(); + } + */ + + rev160108flags = flagsBuilder.build(); + return rev160108flags; + } + + public static String convAsyncResponseToJsonStringBody(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse); + Object message = builder.build(); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(message.getClass(), MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + objectMapper.addMixInAnnotations(Flags.class, MixIn.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(Payload.class, MixIn.class); + objectMapper.addMixInAnnotations(ZULU.class, MixIn.class); + +// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true) + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true) + .writer(SerializationFeature.WRAP_ROOT_VALUE).withRootName(DMaaP_ROOT_VALUE).withoutFeatures(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); + return writer.writeValueAsString(message); + } + + public static String convAsyncResponseToDmaapOutgoingMessageJsonString(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToDmaapOutgoingMessage(vnfOperation, rpcName, asyncResponse); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + objectMapper.addMixInAnnotations(Flags.class, MixIn.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(Payload.class, MixIn.class); + objectMapper.addMixInAnnotations(ZULU.class, MixIn.class); + +// .configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY,true) + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true).writer(); + return writer.writeValueAsString(dmaapOutgoingMessage); + } + + public static DmaapOutgoingMessage convAsyncResponseToDmaapOutgoingMessage(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + outObj.setRpcName(rpcName); + Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse); + Object messageBody = builder.build(); + DmaapOutgoingMessage.Body body = new DmaapOutgoingMessage.Body(messageBody); + outObj.setBody(body); + return outObj; + } + + abstract class MixIn { + @JsonIgnore + abstract Class<? extends DataContainer> getImplementedInterface(); // to be removed during serialization + + @JsonValue + abstract java.lang.String getValue(); + } + abstract class MixInCommonHeader extends MixIn { + @JsonProperty("api-ver") + abstract java.lang.String getApiVer(); + @JsonProperty("originator-id") + abstract java.lang.String getOriginatorId(); + @JsonProperty("request-id") + abstract java.lang.String getRequestId(); + @JsonProperty("sub-request-id") + abstract java.lang.String getSubRequestId(); + + } + abstract class MixInFlagsMessage extends MixIn { + @JsonProperty("common-header") + abstract CommonHeader getCommonHeader(); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java new file mode 100644 index 000000000..c41f42ed6 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DGWorkflowNotFoundException.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class DGWorkflowNotFoundException extends Exception { + public final String workflowModule; + public final String workflowName; + public final String workflowVersion; + public DGWorkflowNotFoundException(String message,String workflowModule,String workflowName,String workflowVersion){ + super(message); + this.workflowModule = workflowModule; + this.workflowName = workflowName; + this.workflowVersion = workflowVersion; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java new file mode 100644 index 000000000..a9c1c0000 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/DuplicateRequestException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class DuplicateRequestException extends Exception { + public DuplicateRequestException(String message){ + super(message); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java new file mode 100644 index 000000000..a70b6f14a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/InvalidInputException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class InvalidInputException extends Exception { + public InvalidInputException(String message){ + super(message); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java new file mode 100644 index 000000000..44b0869a9 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/RequestExpiredException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class RequestExpiredException extends Exception { + public RequestExpiredException(String message){ + super(message); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java new file mode 100644 index 000000000..16a9e5e6e --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/VNFNotFoundException.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class VNFNotFoundException extends Exception { + public VNFNotFoundException(String message){ + super(message); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java new file mode 100644 index 000000000..97dabe869 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/WorkflowNotFoundException.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.exceptions; + + +public class WorkflowNotFoundException extends Exception { + public final String vnfTypeVersion; + public final String command; + public WorkflowNotFoundException(String message,String vnfTypeVersion,String command){ + super(message); + this.vnfTypeVersion = vnfTypeVersion; + this.command = command; + } + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java new file mode 100644 index 000000000..874626c78 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestRegistry.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.helper; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * + * This class serves as Request Registry, which holds the + * request unique parameters (originatorId,requestId,subRequestId) + * in memory. + */ +public class RequestRegistry { + + static Set<UniqueRequestIdentifier> set = Collections.newSetFromMap(new ConcurrentHashMap<UniqueRequestIdentifier, Boolean>()); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestRegistry.class); + public RequestRegistry(){ + + } + + /** + * This method accepts unique request parameters and adds it to Request Registry + * if Registry already contains same parameters it returns false, + * else returns true. + * @param requestIdentifier + * @return + */ + public boolean registerRequest(UniqueRequestIdentifier requestIdentifier){ + + if (logger.isTraceEnabled()) { + logger.trace("Entering to registerRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier)); + } + boolean output = set.add(requestIdentifier); + logger.debug(" Output = " + output); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from registerRequest with (output = "+ ObjectUtils.toString(output)+")"); + } + return output; + } + + /** + * This method accepts unique request parameters and removes request + * from the Request Registry + * @param requestIdentifier + */ + public void removeRequest(UniqueRequestIdentifier requestIdentifier){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to removeRequest with UniqueRequestIdentifier = "+ ObjectUtils.toString(requestIdentifier)); + } + set.remove(requestIdentifier); + } + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java new file mode 100644 index 000000000..4f2986d74 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/helper/RequestValidator.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.helper; + +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.requesthandler.exceptions.DGWorkflowNotFoundException; +import org.openecomp.appc.requesthandler.exceptions.DuplicateRequestException; +import org.openecomp.appc.requesthandler.exceptions.InvalidInputException; +import org.openecomp.appc.requesthandler.exceptions.RequestExpiredException; +import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException; +import org.openecomp.appc.requesthandler.exceptions.WorkflowNotFoundException; + +public interface RequestValidator { + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException; +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java new file mode 100644 index 000000000..4546726e9 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/DmaapOutgoingMessage.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.impl; + + + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * This class represents a message being sent out to DMaaP by APPC as async response. + * note the structure of this class must be adapted to the sync message sent to DMaaP represened in org.openecomp.appc.listener.LCM.domainmodel.DmaapOutgoingMessage + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapOutgoingMessage { + + private final static String defaultCambriaPartition = "MSO"; + @JsonProperty("cambria.partition") + private String cambriaPartition = defaultCambriaPartition; + + @JsonProperty("rpc-name") + private String rpcName; + + @JsonProperty("body") + private Body body; + + public DmaapOutgoingMessage() { + } + + public String getCambriaPartition() { + return cambriaPartition; + } + + public void setCambriaPartition(String cambriaPartition) { + this.cambriaPartition = cambriaPartition; + } + + public String getRpcName() { + return rpcName; + } + + public void setRpcName(String rpcName) { + this.rpcName = rpcName; + } + + public Body getBody() { + return body; + } + + public void setBody(Body body) { + this.body = body; + } + + @Override + public String toString() { + return "DmaapOutgoingMessage{" + + "cambriaPartition='" + cambriaPartition + '\'' + + ", rpcName='" + rpcName + '\'' + + ", body=" + body + + '}'; + } + + @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Body { + public Body() { + } + + public Body(Object output) { + this.output = output; + } + + @JsonProperty("output") + private Object output; + + public Object getOutput() { + return output; + } + + public void setOutput(Object body) { + this.output = body; + } + + @Override + public String toString() { + return "Body{" + + "output=" + output + + '}'; + } + } +} + diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java new file mode 100644 index 000000000..d1303605d --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestHandlerImpl.java @@ -0,0 +1,839 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.impl; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.common.constant.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executor.CommandExecutor; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.messageadapter.impl.MessageAdapterDmaapImpl; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.publisher.LogPublisher; +import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.helper.RequestRegistry; +import org.openecomp.appc.requesthandler.helper.RequestValidator; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource.QueryStatus; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.MDC; + +import static com.att.eelf.configuration.Configuration.*; + +import java.net.InetAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * This class provides application logic for the Request/Response Handler Component. + * + */ +public class RequestHandlerImpl implements RequestHandler { + + /** + * APP-C VNF lock idle timeout in milliseconds. Applied only when locking VNF using northbound API "lock" + */ + private static final String PROP_IDLE_TIMEOUT = "org.openecomp.appc.lock.idleTimeout"; + + private CommandExecutor commandExecutor; + + private TransactionRecorder transactionRecorder; + private MessageAdapter messageAdapter; + private RequestValidator requestValidator; + private static MetricRegistry metricRegistry; + private boolean isMetricEnabled = false; + private RequestRegistry requestRegistry; + private LockManager lockManager; + private WorkingStateManager workingStateManager; + private AAIService aaiService; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RequestHandlerImpl.class); + + public void setAaiService(AAIService aaiService) { + this.aaiService = aaiService; + } + + public void setTransactionRecorder(TransactionRecorder transactionRecorder) { + this.transactionRecorder = transactionRecorder; + } + + public void setLockManager(LockManager lockManager) { + this.lockManager = lockManager; + } + + public void setRequestValidator(RequestValidator requestValidator) { + this.requestValidator = requestValidator; + } + + public void setMessageAdapter(MessageAdapter messageAdapter) { + this.messageAdapter = messageAdapter; + } + + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public void setWorkingStateManager(WorkingStateManager workingStateManager) { + this.workingStateManager = workingStateManager; + } + + public RequestHandlerImpl() { + requestRegistry = new RequestRegistry(); + messageAdapter = new MessageAdapterDmaapImpl(); + messageAdapter.init(); + Properties properties = configuration.getProperties(); + if (properties != null && properties.getProperty("metric.enabled") != null) { + isMetricEnabled = Boolean.valueOf(properties.getProperty("metric.enabled")); + } + if (isMetricEnabled) { + initMetric(); + } + } + + public void setCommandExecutor(CommandExecutor commandExecutor) { + this.commandExecutor = commandExecutor; + } + + + /** + * It receives requests from the north-bound REST API (Communication) Layer and + * performs following validations. + * 1. VNF exists in A&AI for the given targetID (VnfID) + * 2. For the current VNF Orchestration Status, the command can be executed + * 3. For the given VNF type and Operation, there exists work-flow definition in the APPC database + * If any of the validation fails, it returns appropriate response + * + * @param input RequestHandlerInput object which contains request header and other request parameters like command , target Id , payload etc. + * @return response for request as enum with Return code and message. + */ + @Override + public RequestHandlerOutput handleRequest(RequestHandlerInput input) { + if (logger.isTraceEnabled()) + logger.trace("Entering to handleRequest with RequestHandlerInput = " + ObjectUtils.toString(input) + ")"); + Params params = null; + String vnfId = null, vnfType = null, errorMessage = null; + Date startTime = new Date(System.currentTimeMillis()); + RequestHandlerOutput output = null; + setInitialLogProperties(input.getRequestContext()); + + RuntimeContext runtimeContext = new RuntimeContext(); + runtimeContext.setRequestContext(input.getRequestContext()); + runtimeContext.setTimeStart(startTime); + runtimeContext.setRpcName(input.getRpcName()); + + final ResponseContext responseContext = new ResponseContext(); + responseContext.setStatus(new Status()); + responseContext.setAdditionalContext(new HashMap<String, String>(4)); + responseContext.setCommonHeader(input.getRequestContext().getCommonHeader()); + runtimeContext.setResponseContext(responseContext); + runtimeContext.getResponseContext().setStatus(new Status()); + + vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + + try { + + requestValidator.validateRequest(runtimeContext); + + handleRequest(runtimeContext); + + final int statusCode = runtimeContext.getResponseContext().getStatus().getCode(); + if (statusCode % 100 == 2 || statusCode % 100 == 3) { + createTransactionRecord(runtimeContext); + } + output = new RequestHandlerOutput(); + output.setResponseContext(runtimeContext.getResponseContext()); + + } catch (VNFNotFoundException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.APPC_NO_RESOURCE_FOUND, vnfId); + storeErrorMessageToLog(runtimeContext, LoggingConstants.TargetNames.AAI, "", logMessage); + params = new Params().addParam("vnfId", vnfId); + output = buildRequestHandlerOutput(LCMCommandStatus.VNF_NOT_FOUND, params); + } catch (NoTransitionDefinedException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.VF_UNDEFINED_STATE, input.getRequestContext().getCommonHeader().getOriginatorId(), input.getRequestContext().getAction().name()); + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState); + output = buildRequestHandlerOutput(LCMCommandStatus.NO_TRANSITION_DEFINE, params); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.STATE_MACHINE, + logMessage); + } catch (LifecycleException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("currentState", e.currentState); + output = buildRequestHandlerOutput(LCMCommandStatus.ACTION_NOT_SUPPORTED, params); + } catch (UnstableVNFException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("vnfId", vnfId); + output = buildRequestHandlerOutput(LCMCommandStatus.UNSTABLE_VNF, params); + } catch (WorkflowNotFoundException e) { + errorMessage = e.getMessage(); + String vnfTypeVersion = e.vnfTypeVersion; + params = new Params().addParam("actionName", input.getRequestContext().getAction()).addParam("vnfTypeVersion", vnfTypeVersion); + output = buildRequestHandlerOutput(LCMCommandStatus.WORKFLOW_NOT_FOUND, params); + } catch (DGWorkflowNotFoundException e) { + errorMessage = e.getMessage(); + String logMessage = EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfType, input.getRequestContext().getAction().name()); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + logMessage); + params = new Params().addParam("actionName", input.getRequestContext().getAction().name()) + .addParam("dgModule", e.workflowModule).addParam("dgName", e.workflowName).addParam("dgVersion", e.workflowVersion); + output = buildRequestHandlerOutput(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND, params); + } catch (RequestExpiredException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("actionName", input.getRequestContext().getAction().name()); + output = buildRequestHandlerOutput(LCMCommandStatus.EXPIRED_REQUEST, params); + } catch (InvalidInputException e) { + errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + params = new Params().addParam("errorMsg", errorMessage); + output = buildRequestHandlerOutput(LCMCommandStatus.INVALID_INPUT_PARAMETER, params); + } catch (DuplicateRequestException e) { + errorMessage = e.getMessage(); + output = buildRequestHandlerOutput(LCMCommandStatus.DUPLICATE_REQUEST, null); + } catch (Exception e) { + storeErrorMessageToLog(runtimeContext, "", "", "Exception = " + e.getMessage()); + errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + params = new Params().addParam("errorMsg", errorMessage); + output = buildRequestHandlerOutput(LCMCommandStatus.UNEXPECTED_ERROR, params); + } finally { + try { + if (logger.isDebugEnabled() && errorMessage != null) + logger.debug("error occurred in handleRequest " + errorMessage); + logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.ACCEPTED.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())); + logger.debug("output.getResponse().getResponseCode().equals(LCMCommandStatus.SUCCESS.getResponseCode(): " + (output.getResponseContext().getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode())); + + runtimeContext.setResponseContext(output.getResponseContext()); + if ((null == output) || !(output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())) { + if (isMetricEnabled) { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementRejectedRequest(); + } + removeRequestFromRegistry(input.getRequestContext().getCommonHeader()); + } + } finally { + storeAuditLogRecord(runtimeContext); + storeMetricLogRecord(runtimeContext); + clearRequestLogProperties(); + } + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from handleRequest with (RequestHandlerOutput = " + ObjectUtils.toString(output.getResponseContext()) + ")"); + } + return output; + } + + private void storeErrorMessageToLog(RuntimeContext runtimeContext, String targetEntity, String targetServiceName, String additionalMessage) { + LoggingUtils.logErrorMessage(runtimeContext.getResponseContext().getStatus() != null ? + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()) : "", + runtimeContext.getResponseContext().getStatus() != null ? + String.valueOf(runtimeContext.getResponseContext().getStatus().getMessage()) : "", + targetEntity, + targetServiceName, + additionalMessage, + this.getClass().getCanonicalName()); + } + + private void createTransactionRecord(RuntimeContext runtimeContext) { + TransactionRecord transactionRecord = new TransactionRecord(); + transactionRecord.setTimeStamp(runtimeContext.getResponseContext().getCommonHeader().getTimeStamp()); + transactionRecord.setRequestID(runtimeContext.getResponseContext().getCommonHeader().getRequestId()); + transactionRecord.setStartTime(runtimeContext.getTimeStart()); + transactionRecord.setEndTime(new Date(System.currentTimeMillis())); + transactionRecord.setTargetID(runtimeContext.getVnfContext().getId()); + transactionRecord.setTargetType(runtimeContext.getVnfContext().getType()); + transactionRecord.setOperation(runtimeContext.getRequestContext().getAction().name()); + transactionRecord.setResultCode(String.valueOf(runtimeContext.getResponseContext().getStatus().getCode())); + transactionRecord.setDescription(runtimeContext.getResponseContext().getStatus().getMessage()); + transactionRecorder.store(transactionRecord); + } + + private void handleRequest(RuntimeContext runtimeContext) { + + switch (runtimeContext.getRequestContext().getAction()) { + case Lock: + try { + lockWithTimeout(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + } catch (LockException e) { + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.LOCK_MANAGER, + EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId())); + } + + break; + + case Unlock: + try { + releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + } catch (LockException e) { + //TODO add proper error code and message + // logger.error(EELFResourceManager.format(Msg.VF_SERVER_BUSY, runtimeContext.getVnfContext().getId())); + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + } + break; + + case CheckLock: + boolean isLocked = lockManager.isLocked(runtimeContext.getVnfContext().getId()); + fillStatus(runtimeContext,LCMCommandStatus.SUCCESS, null); + runtimeContext.getResponseContext().addKeyValueToAdditionalContext("locked", String.valueOf(isLocked).toUpperCase()); + break; + default: + try { + boolean lockAcquired = acquireVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId(), 0); + runtimeContext.setIsLockAcquired(lockAcquired); + callWfOperation(runtimeContext); + } catch (LockException e) { + Params params = new Params().addParam("errorMsg", e.getMessage()); + fillStatus(runtimeContext, LCMCommandStatus.LOCKING_FAILURE, params); + } finally { + if (runtimeContext.isLockAcquired()) { + final int statusCode = runtimeContext.getResponseContext().getStatus().getCode(); + if (statusCode % 100 == 2 || statusCode % 100 == 3) { + try { + releaseVNFLock(runtimeContext.getVnfContext().getId(), runtimeContext.getRequestContext().getCommonHeader().getRequestId()); + //TODO add logger call + } catch (LockException e) { + //ignore + } + } + } + } + } + + } + + private void callWfOperation(RuntimeContext runtimeContext) { + int remainingTTL = calculateRemainingTTL(runtimeContext.getRequestContext().getCommonHeader()); + if (remainingTTL > 0) { + if (logger.isDebugEnabled()) { + logger.debug("Calling command Executor with remaining TTL value: " + remainingTTL); + } + + RuntimeContext clonedContext = cloneContext(runtimeContext); + + CommandExecutorInput commandExecutorInput = new CommandExecutorInput(); + commandExecutorInput.setRuntimeContext(clonedContext); + commandExecutorInput.setTtl(remainingTTL); + + try { + commandExecutor.executeCommand(commandExecutorInput); + if(logger.isTraceEnabled()) { + logger.trace("Command was added to queue successfully for vnfID = " + ObjectUtils.toString(runtimeContext.getRequestContext().getActionIdentifiers().getVnfId())); + } + fillStatus(runtimeContext, LCMCommandStatus.ACCEPTED, null); + if (isMetricEnabled) { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementAcceptedRequest(); + } + } catch (APPCException e) { + String errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); + Params params = new Params().addParam("errorMsg", errorMessage); + fillStatus(runtimeContext, LCMCommandStatus.UNEXPECTED_ERROR, params); + } + + } else { + fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST, null); + storeErrorMessageToLog(runtimeContext, + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.REQUEST_HANDLER, + EELFResourceManager.format(Msg.APPC_EXPIRED_REQUEST, + runtimeContext.getRequestContext().getCommonHeader().getOriginatorId(), + runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(), + String.valueOf(runtimeContext.getRequestContext().getCommonHeader().getFlags().getTtl()))); + } + } + + private void fillStatus(RuntimeContext runtimeContext, LCMCommandStatus lcmCommandStatus, Params params) { + runtimeContext.getResponseContext().getStatus().setCode(lcmCommandStatus.getResponseCode()); + runtimeContext.getResponseContext().getStatus().setMessage(lcmCommandStatus.getFormattedMessage(params)); + } + + /* + * Workaround to clone context in order to prevent sharing of ResponseContext by two threads (one to set Accepted + * status code and other - depending on DG status). Other properties should not be a problem + */ + private RuntimeContext cloneContext(RuntimeContext runtimeContext) { + RuntimeContext other = new RuntimeContext(); + other.setRequestContext(runtimeContext.getRequestContext()); + other.setResponseContext(new ResponseContext()); + other.getResponseContext().setStatus(new Status()); + other.getResponseContext().setCommonHeader(runtimeContext.getRequestContext().getCommonHeader()); + other.setVnfContext(runtimeContext.getVnfContext()); + other.setRpcName(runtimeContext.getRpcName()); + other.setTimeStart(runtimeContext.getTimeStart()); + other.setIsLockAcquired(runtimeContext.isLockAcquired()); + return other; + } + + + private void clearRequestLogProperties() { + try { + MDC.remove(MDC_KEY_REQUEST_ID); + MDC.remove(MDC_SERVICE_INSTANCE_ID); + MDC.remove(MDC_SERVICE_NAME); + MDC.remove(LoggingConstants.MDCKeys.PARTNER_NAME); + MDC.remove(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY); + } catch (Exception e) { + + } + } + + private void removeRequestFromRegistry(CommonHeader commonHeader) { + if (logger.isTraceEnabled()) + logger.trace("Entering to removeRequestFromRegistry with RequestHeader = " + ObjectUtils.toString(commonHeader)); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(commonHeader.getOriginatorId(), + commonHeader.getRequestId(), + commonHeader.getSubRequestId())); + } + + private boolean acquireVNFLock(String vnfID, String requestId, long timeout) throws LockException { + if (logger.isTraceEnabled()) + logger.trace("Entering to acquireVNFLock with vnfID = " + vnfID); + boolean lockAcquired = lockManager.acquireLock(vnfID, requestId, timeout); + if (lockAcquired) { + logger.info("Lock acquired for vnfID = " + vnfID); + } else { + logger.info("vnfID = " + vnfID + " was already locked"); + } + return lockAcquired; + } + + private void lockWithTimeout(String vnfId, String requestId) throws LockException { + long timeout = configuration.getLongProperty(PROP_IDLE_TIMEOUT, Constants.DEFAULT_IDLE_TIMEOUT); + acquireVNFLock(vnfId, requestId, timeout); + } + + private void resetLock(String vnfId, String requestId, boolean lockAcquired, boolean resetLockTimeout) { + if (lockAcquired) { + try { + releaseVNFLock(vnfId, requestId); + } catch (LockException e) { + logger.error("Unlock VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e); + + + } + } else if (resetLockTimeout) { + try { + // reset timeout to previous value + lockWithTimeout(vnfId, requestId); + } catch (LockException e) { + logger.error("Reset lock idle timeout for VNF [" + vnfId + "] failed. Request id: [" + requestId + "]", e); + } + } + } + + private void releaseVNFLock(String vnfId, String transactionId) throws LockException { + lockManager.releaseLock(vnfId, transactionId); + logger.info("Lock released for vnfID = " + vnfId); + } + + private void setInitialLogProperties(RequestContext requestContext) { + + try { + MDC.put(MDC_KEY_REQUEST_ID, requestContext.getCommonHeader().getRequestId()); + if (requestContext.getActionIdentifiers().getServiceInstanceId() != null) { + MDC.put(MDC_SERVICE_INSTANCE_ID, requestContext.getActionIdentifiers().getServiceInstanceId()); + } + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, requestContext.getCommonHeader().getOriginatorId()); + MDC.put(MDC_INSTANCE_UUID, ""); // value should be created in the future + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getHostName() again please. It's wrong! + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + MDC.put(LoggingConstants.MDCKeys.SERVER_NAME, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVICE_NAME, requestContext.getAction().name()); + MDC.put(LoggingConstants.MDCKeys.TARGET_VIRTUAL_ENTITY, requestContext.getActionIdentifiers().getVnfId()); + + } catch (Exception e) { + logger.debug(e.getMessage()); + } + } catch (RuntimeException e) { + //ignore + } + } + + + private int calculateRemainingTTL(CommonHeader commonHeader) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to calculateRemainingTTL with RequestHeader = " + ObjectUtils.toString(commonHeader)); + } + long usedTimeInMillis = (System.currentTimeMillis() - commonHeader.getTimeStamp().getTime()); + logger.debug("usedTimeInMillis = " + usedTimeInMillis); + int usedTimeInSeconds = Math.round(usedTimeInMillis / 1000); + logger.debug("usedTimeInSeconds = " + usedTimeInSeconds); + Integer inputTTL = this.getInputTTL(commonHeader); + logger.debug("inputTTL = " + inputTTL); + Integer remainingTTL = inputTTL - usedTimeInSeconds; + logger.debug("Remaining TTL = " + remainingTTL); + if (logger.isTraceEnabled()) + logger.trace("Exiting from calculateRemainingTTL with (remainingTTL = " + ObjectUtils.toString(remainingTTL) + ")"); + return remainingTTL; + } + + private Integer getInputTTL(CommonHeader header) { + if (logger.isTraceEnabled()) + logger.trace("Entering in getInputTTL with RequestHeader = " + ObjectUtils.toString(header)); + if (!isValidTTL(String.valueOf(header.getFlags().getTtl()))) { + String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL)); + Integer defaultTTL = Integer.parseInt(defaultTTLStr); + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (defaultTTL = " + ObjectUtils.toString(defaultTTL) + ")"); + return defaultTTL; + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (inputTTL = " + ObjectUtils.toString(header.getFlags().getTtl()) + ")"); + + return header.getFlags().getTtl(); + } + + private boolean isValidTTL(String ttl) { + if (ttl == null || ttl.length() == 0) { + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (result = false)"); + return false; + } + try { + Integer i = Integer.parseInt(ttl); + return (i > 0); + } catch (NumberFormatException e) { + if (logger.isTraceEnabled()) + logger.trace("Exiting from getInputTTL with (result = false)"); + return false; + } + } + + private Boolean isLoggingEnabled() { + String defaultFlagStr = configuration.getProperty("org.openecomp.appc.localTransactionRecorder.enable", String.valueOf(Constants.DEFAULT_LOGGING_FLAG)); + Boolean defaultFlag = Boolean.parseBoolean(defaultFlagStr); + return defaultFlag; + } + + private static RequestHandlerOutput buildRequestHandlerOutput(LCMCommandStatus response, Params params) { + RequestHandlerOutput output = new RequestHandlerOutput(); + ResponseContext responseContext = new ResponseContext(); + org.openecomp.appc.domainmodel.lcm.Status status = new org.openecomp.appc.domainmodel.lcm.Status(); + status.setCode(response.getResponseCode()); + status.setMessage(response.getFormattedMessage(params)); + responseContext.setStatus(status); + output.setResponseContext(responseContext); + return output; + } + + /** + * This method perform operations required before execution of workflow starts. It retrieves next state for current operation from Lifecycle manager and update it in AAI. + * + * @return true in case AAI updates are successful. false for any error or exception. + */ + @Override + public void onRequestExecutionStart(String vnfId, boolean readOnlyActivity, String requestIdentifierString, boolean forceFlag) throws UnstableVNFException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestExecutionStart with vnfId = " + vnfId + "and requestIdentifierString = " + requestIdentifierString); + } + try { + boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, requestIdentifierString, forceFlag); + if (!updated) { + throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId); + } + } catch (Exception e) { + logger.error("Error updating working state for vnf " + vnfId + e); + throw new RuntimeException(e); + } + + if (logger.isTraceEnabled()) + logger.trace("Exiting from onRequestExecutionStart "); + } + + /** + * This method perform following operations required after execution of workflow. + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * Generate audit logs. + * Adds transaction record to database id if transaction logging is enabled. + * + * @param isAAIUpdated boolean flag which indicate AAI upodate status after request completion. + */ + @Override + public void onRequestExecutionEnd(RuntimeContext runtimeContext, boolean isAAIUpdated) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestExecutionEnd with runtimeContext = " + ObjectUtils.toString(runtimeContext)); + } + + postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext()); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId())); + resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true); + Status status = runtimeContext.getResponseContext().getStatus(); + + VNFWorkingState workingState; + if (status.getCode() == LCMCommandStatus.SUCCESS.getResponseCode() || isReadOnlyAction(runtimeContext.getRequestContext().getAction())) { + workingState = VNFWorkingState.STABLE; + } else { + workingState = VNFWorkingState.UNKNOWN; + } + + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId()); + + String requestIdentifierString = requestIdentifier.toIdentifierString(); + workingStateManager.setWorkingState(runtimeContext.getVnfContext().getId(), workingState, requestIdentifierString, false); + + + storeAuditLogRecord(runtimeContext); + + if (isLoggingEnabled()) { + createTransactionRecord(runtimeContext); + } + } + + private void storeAuditLogRecord(RuntimeContext runtimeContext) { + LoggingUtils.logAuditMessage(runtimeContext.getTimeStart(), + new Date(System.currentTimeMillis()), + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()), + runtimeContext.getResponseContext().getStatus().getMessage(), + this.getClass().getCanonicalName()); + } + + private void storeMetricLogRecord(RuntimeContext runtimeContext) { + LoggingUtils.logMetricsMessage(runtimeContext.getTimeStart(), + new Date(System.currentTimeMillis()), + LoggingConstants.TargetNames.APPC, + runtimeContext.getRequestContext().getAction().name(), + runtimeContext.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode() ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR, + String.valueOf(runtimeContext.getResponseContext().getStatus().getCode()), + runtimeContext.getResponseContext().getStatus().getMessage(), + this.getClass().getCanonicalName()); + } + + private boolean isReadOnlyAction(VNFOperation action) { + return VNFOperation.Sync == action + || VNFOperation.Audit == action; + } + + + //returns null if asyncResponse was not modified otherwise reutrns the updated asyncResponse + private void postMessageToDMaaP(VNFOperation operation, String rpcName, ResponseContext responseContext/*, boolean isTTLEnd, boolean aaiUpdateSuccess*/) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to postMessageToDMaaP with AsyncResponse = " + ObjectUtils.toString(responseContext)); + } + /*boolean updated = updateAsyncResponseStatus(responseContext, isTTLEnd, aaiUpdateSuccess); + */ + boolean callbackResponse = messageAdapter.post(operation, rpcName, responseContext); + if (!callbackResponse) { + logger.error("DMaaP posting status: " + callbackResponse, "dmaapMessage: " + responseContext); + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from postMessageToDMaaP with (callbackResponse = " + ObjectUtils.toString(callbackResponse) + ")"); + } + + //returns true if asyncResponse was modified + /* private boolean updateAsyncResponseStatus(ResponseContext asyncResponse, boolean isTTLEnd, boolean aaiUpdateSuccess) { + boolean updated = false; + if (logger.isTraceEnabled()) + logger.trace("Entering to updateAsyncResponseStatus with AsyncResponse = "+ObjectUtils.toString(asyncResponse)+ ", isTTLEnd = "+ ObjectUtils.toString(isTTLEnd)+ ", aaiUpdateSuccess = "+ ObjectUtils.toString(aaiUpdateSuccess)); + if(!aaiUpdateSuccess){ + if (asyncResponse.getStatus().getCode() == 0 || asyncResponse.getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode()) { + asyncResponse.getStatus().setCode(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.UPDATE_AAI_FAILURE.getResponseMessage()); + updated = true; + } + }else if(isTTLEnd){ + asyncResponse.getStatus().setCode(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage()); + updated = true; + } + if (logger.isTraceEnabled()) + logger.trace("Exiting from updateAsyncResponseStatus with (asyncResponse = "+ ObjectUtils.toString(asyncResponse)+")"); + return updated; + }*/ + + + /** + * This method perform following operations required if TTL ends when request still waiting in execution queue . + * It posts asynchronous response to message bus (DMaaP). + * Unlock VNF Id + * Removes request from request registry. + * + * @param runtimeContext AsyncResponse object which contains VNF Id , timestamp , apiVersion, responseId, executionSuccess, payload, isExpired, action, startTime, vnfType, originatorId, subResponseId; + * @param updateAAI boolean flag which indicate AAI upodate status after request completion. + */ + @Override + public void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to onRequestTTLEnd with " + + "AsyncResponse = " + ObjectUtils.toString(runtimeContext) + + ", updateAAI = " + ObjectUtils.toString(updateAAI)); + } + logger.error(LCMCommandStatus.EXPIRED_REQUEST_FAILURE.getResponseMessage()); + fillStatus(runtimeContext, LCMCommandStatus.EXPIRED_REQUEST_FAILURE, null); + postMessageToDMaaP(runtimeContext.getRequestContext().getAction(), runtimeContext.getRpcName(), runtimeContext.getResponseContext()); + resetLock(runtimeContext.getVnfContext().getId(), runtimeContext.getResponseContext().getCommonHeader().getRequestId(), runtimeContext.isLockAcquired(), true); + requestRegistry.removeRequest( + new UniqueRequestIdentifier(runtimeContext.getResponseContext().getCommonHeader().getOriginatorId(), + runtimeContext.getResponseContext().getCommonHeader().getRequestId(), + runtimeContext.getResponseContext().getCommonHeader().getSubRequestId())); + } + + private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + String key = "vnf-id = '" + vnf_id + "'"; + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfdata with " + + "vnfId = " + vnf_id + + ", prefix = " + prefix + + ", SvcLogicContex = " + ObjectUtils.toString(ctx)); + } + try { + QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx); + if (QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } else if (QueryStatus.FAILURE.equals(response)) { + throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + logger.error("Error in getVnfdata " + e); + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getVnfdata with (SvcLogicContext = " + ObjectUtils.toString(ctx) + ")"); + } + return ctx; + } + + private boolean postVnfdata(String vnf_id, String status, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to postVnfdata with " + + "vnfId = " + vnf_id + + ", status = " + status + + ", prefix = " + prefix + + ", SvcLogicContext = " + ObjectUtils.toString(ctx)); + } + String key = "vnf-id = '" + vnf_id + "'"; + Map<String, String> data = new HashMap<>(); + data.put("orchestration-status", status); + try { + QueryStatus response = aaiService.update("generic-vnf", key, data, prefix, ctx); + if (QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + if (response.toString().equals("SUCCESS")) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(true) + ")"); + } + return true; + } + + } catch (SvcLogicException e) { + logger.error("Error in postVnfdata " + e); + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from postVnfdata with (Result = " + ObjectUtils.toString(false) + ")"); + } + return false; + } + + private void initMetric() { + if (logger.isDebugEnabled()) + logger.debug("Metric getting initialized"); + MetricService metricService = getMetricservice(); + metricRegistry = metricService.createRegistry("APPC"); + DispatchingFuntionMetric dispatchingFuntionMetric = metricRegistry.metricBuilderFactory(). + dispatchingFunctionCounterBuilder(). + withName("DISPATCH_FUNCTION").withType(MetricType.COUNTER). + withAcceptRequestValue(0) + .withRejectRequestValue(0) + .build(); + if (metricRegistry.register(dispatchingFuntionMetric)) { + Metric[] metrics = new Metric[]{dispatchingFuntionMetric}; + LogPublisher logPublisher = new LogPublisher(metricRegistry, metrics); + LogPublisher[] logPublishers = new LogPublisher[1]; + logPublishers[0] = logPublisher; + PublishingPolicy manuallyScheduledPublishingPolicy = metricRegistry.policyBuilderFactory(). + scheduledPolicyBuilder().withPublishers(logPublishers). + withMetrics(metrics). + build(); + if (logger.isDebugEnabled()) + logger.debug("Policy getting initialized"); + manuallyScheduledPublishingPolicy.init(); + if (logger.isDebugEnabled()) + logger.debug("Metric initialized"); + } + } + + + private MetricService getMetricservice() { + BundleContext bctx = FrameworkUtil.getBundle(MetricService.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(MetricService.class.getName()); + if (sref != null) { + logger.info("Metric Service from bundlecontext"); + return (MetricService) bctx.getService(sref); + } else { + logger.info("Metric Service error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.appc.metricservice.MetricService"); + return null; + } + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java new file mode 100644 index 000000000..0871a8f97 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/RequestValidatorImpl.java @@ -0,0 +1,382 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler.impl; + +import org.apache.commons.lang.ObjectUtils; +import org.openecomp.appc.common.constant.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.UniqueRequestIdentifier; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.helper.RequestRegistry; +import org.openecomp.appc.requesthandler.helper.RequestValidator; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicException; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.Calendar; +import java.util.Date; + + +public class RequestValidatorImpl implements RequestValidator { + + private AAIService aaiService; + + private LifecycleManager lifecyclemanager; + + private WorkFlowManager workflowManager; + + private WorkingStateManager workingStateManager; + + private final RequestRegistry requestRegistry = new RequestRegistry(); + + private final Configuration configuration = ConfigurationFactory.getConfiguration(); + private final EELFLogger logger = EELFManager.getInstance().getLogger(RequestValidatorImpl.class); + private final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + public void setLifecyclemanager(LifecycleManager lifecyclemanager) { + this.lifecyclemanager = lifecyclemanager; + } + + public void setWorkflowManager(WorkFlowManager workflowManager) { + this.workflowManager = workflowManager; + } + + public void setWorkingStateManager(WorkingStateManager workingStateManager) { + this.workingStateManager = workingStateManager; + } + + public RequestValidatorImpl() { + } + + @Override + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException { + if (logger.isTraceEnabled()){ + logger.trace("Entering to validateRequest with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext)); + } + getAAIservice(); + validateInput(runtimeContext.getRequestContext()); + checkVNFWorkingState(runtimeContext); + String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + VNFContext vnfContext = queryAAI(vnfId); + runtimeContext.setVnfContext(vnfContext); + + queryLCM(runtimeContext.getVnfContext().getStatus(), runtimeContext.getRequestContext().getAction()); + VNFOperation operation = runtimeContext.getRequestContext().getAction(); + if(!operation.isBuiltIn()) { + // for built-in operations skip WF presence check + queryWFM(vnfContext, runtimeContext.getRequestContext()); + } + } + + private boolean isValidTTL(String ttl) { + if (logger.isTraceEnabled()){ + logger.trace("Entering to isValidTTL where ttl = "+ ObjectUtils.toString(ttl)); + } + if (ttl == null || ttl.length() == 0) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTT with (result = "+ ObjectUtils.toString(false)+")"); + } + return false; + } + try { + Integer i = Integer.parseInt(ttl); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(i > 0)+")"); + } + return (i > 0); + } catch (NumberFormatException e) { + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isValidTTL with (result = "+ ObjectUtils.toString(false)+")"); + } + return false; + } + } + + private void validateInput(RequestContext requestContext) throws RequestExpiredException, InvalidInputException, DuplicateRequestException { + if (logger.isTraceEnabled()){ + logger.trace("Entering to validateInput with RequestHandlerInput = "+ ObjectUtils.toString(requestContext)); + } + if (requestContext.getActionIdentifiers().getVnfId() == null || requestContext.getAction() == null + || requestContext.getActionIdentifiers().getVnfId().length() == 0 || requestContext.getAction().name().length() == 0 || + null == requestContext.getCommonHeader().getApiVer()) { + if (logger.isDebugEnabled()) { + logger.debug("vnfID = " + requestContext.getActionIdentifiers().getVnfId() + ", action = " + requestContext.getAction().name()); + } + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.REQUEST_VALIDATOR, + EELFResourceManager.format(Msg.APPC_INVALID_INPUT), + this.getClass().getCanonicalName()); + + throw new InvalidInputException("vnfID or command is null"); + } + CommonHeader commonHeader = requestContext.getCommonHeader(); + + checkForDuplicateRequest(commonHeader); + + Calendar inputTimeStamp = DateToCalendar(commonHeader.getTimeStamp()); + Calendar currentTime = Calendar.getInstance(); + + // If input timestamp is of future, we reject the request + if (inputTimeStamp.getTime().getTime() > currentTime.getTime().getTime()) { + if (logger.isDebugEnabled()) { + logger.debug("Input Timestamp is of future = " + inputTimeStamp.getTime()); + } + throw new InvalidInputException("Input Timestamp is of future = " + inputTimeStamp.getTime()); + } + Integer ttl = readTTL(commonHeader); + logger.debug("TTL value set to (seconds) : " + ttl); + inputTimeStamp.add(Calendar.SECOND, ttl); + if (currentTime.getTime().getTime() >= inputTimeStamp.getTime().getTime()) { + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.REQUEST_VALIDATOR, + "TTL Expired: Current time - " + currentTime.getTime().getTime() + " Request time: " + inputTimeStamp.getTime().getTime() + " with TTL value: " + ttl, + this.getClass().getCanonicalName()); + + throw new RequestExpiredException("TTL Expired"); + } + if (logger.isDebugEnabled()) { + logger.debug("Validation of the request is successful"); + } + } + + + private static Calendar DateToCalendar(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + // TODO: Get reference once via Blueprint and get rid of this method + private void getAAIservice() { + BundleContext bctx = FrameworkUtil.getBundle(AAIService.class).getBundleContext(); + // Get AAIadapter reference + ServiceReference sref = bctx.getServiceReference(AAIService.class.getName()); + if (sref != null) { + logger.info("AAIService from bundlecontext"); + aaiService = (AAIService) bctx.getService(sref); + + } else { + logger.info("AAIService error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.sdnc.sli.aai.AAIService"); + + } + } + + private VNFContext queryAAI(String vnfId) throws VNFNotFoundException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx = getVnfdata(vnfId, "vnf", ctx); + + VNFContext vnfContext = new VNFContext(); + populateVnfContext(vnfContext, ctx); + + return vnfContext; + } + + private String queryLCM(String orchestrationStatus, VNFOperation action) throws LifecycleException, NoTransitionDefinedException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to queryLCM with Orchestration Status = "+ ObjectUtils.toString(orchestrationStatus)+ + ", command = "+ ObjectUtils.toString(action)); + } + + String nextState = lifecyclemanager.getNextState(null, orchestrationStatus, action.name()); + if (logger.isDebugEnabled()) { + logger.trace("Exiting from queryLCM with (LCMResponse = "+ ObjectUtils.toString(nextState)+")"); + } + return nextState; + } + + private void queryWFM(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException { + + checkWorkflowExists(vnfContext, requestContext); + } + + private void checkWorkflowExists(VNFContext vnfContext, RequestContext requestContext) throws WorkflowNotFoundException,DGWorkflowNotFoundException { + + WorkflowExistsOutput workflowExistsOutput = workflowManager.workflowExists(getWorkflowQueryParams(vnfContext, requestContext)); + if (!workflowExistsOutput.isMappingExist()) { + if (logger.isDebugEnabled()) { + logger.debug("WorkflowManager : Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()); + } + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()), + this.getClass().getCanonicalName()); + + + throw new WorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(),vnfContext.getType(),requestContext.getAction().name()); + } + if (!workflowExistsOutput.isDgExist()) { + if (logger.isDebugEnabled()) { + logger.debug("WorkflowManager : DG Workflow not found for vnfType = " + vnfContext.getType() + ", version = " + vnfContext.getVersion() + ", command = " + requestContext.getAction().name()+" "+workflowExistsOutput); + } + + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.WORKFLOW_MANAGER, + EELFResourceManager.format(Msg.APPC_WORKFLOW_NOT_FOUND, vnfContext.getType(), requestContext.getAction().name()), + this.getClass().getCanonicalName()); + + + throw new DGWorkflowNotFoundException("Workflow not found for vnfType = " + vnfContext.getType() + ", command = " + requestContext.getAction().name(), + workflowExistsOutput.getWorkflowModule(),workflowExistsOutput.getWorkflowName(),workflowExistsOutput.getWorkflowVersion()); + } + } + + private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) { + vnfContext.setType(ctx.getAttribute("vnf.vnf-type")); + vnfContext.setStatus(ctx.getAttribute("vnf.orchestration-status")); + vnfContext.setId(ctx.getAttribute("vnf.vnf-id")); + // TODO: Uncomment once A&AI supports VNF version + //vnfContext.setVersion(ctx.getAttribute("vnf.vnf-version")); + } + + private WorkflowRequest getWorkflowQueryParams(VNFContext vnfContext, RequestContext requestContext) { + + WorkflowRequest workflowRequest = new WorkflowRequest(); + workflowRequest.setVnfContext(vnfContext); + workflowRequest.setRequestContext(requestContext); + if (logger.isTraceEnabled()) { + logger.trace("Exiting from etWorkflowQueryParams with (WorkflowRequest = "+ ObjectUtils.toString(workflowRequest)+")"); + } + return workflowRequest; + } + + + private void checkForDuplicateRequest(CommonHeader header) throws DuplicateRequestException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to checkForDuplicateRequest with RequestHeader = "+ ObjectUtils.toString(header)); + } + + UniqueRequestIdentifier requestIdentifier = new UniqueRequestIdentifier(header.getOriginatorId(), header.getRequestId(), header.getSubRequestId()); + boolean requestAccepted = requestRegistry.registerRequest(requestIdentifier); + if (!requestAccepted) { + if (logger.isDebugEnabled()) { + logger.debug("Duplicate Request with " + requestIdentifier); + } + throw new DuplicateRequestException("Duplicate Request with " + requestIdentifier); + } + } + + private void checkVNFWorkingState(RuntimeContext runtimeContext) throws UnstableVNFException { + + if (logger.isTraceEnabled()) { + logger.trace("Entering to checkVNFWorkingState with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext.getRequestContext())); + } + boolean forceFlag = runtimeContext.getRequestContext().getCommonHeader().getFlags() != null ? runtimeContext.getRequestContext().getCommonHeader().getFlags().isForce() : false; + String vnfId = runtimeContext.getRequestContext().getActionIdentifiers().getVnfId(); + + if (logger.isDebugEnabled()) { + logger.debug("forceFlag = " + forceFlag); + } + boolean isVNFStable = workingStateManager.isVNFStable(vnfId); + if (!isVNFStable && !forceFlag) { + if (logger.isDebugEnabled()) { + logger.debug("VNF is not stable for VNF ID = " + vnfId); + } + throw new UnstableVNFException("VNF is not stable for vnfID = " + vnfId); + } + + } + + + private Integer readTTL(CommonHeader header) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to readTTL with RequestHandlerInput = "+ ObjectUtils.toString(header)); + } + if (header.getFlags()== null || !isValidTTL(String.valueOf(header.getFlags().getTtl()))) { + String defaultTTLStr = configuration.getProperty("org.openecomp.appc.workflow.default.ttl", String.valueOf(Constants.DEFAULT_TTL)); + Integer defaultTTL = Integer.parseInt(defaultTTLStr); + return defaultTTL; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from readTTL with (TTL = "+ ObjectUtils.toString(header.getFlags().getTtl())+")"); + } + return header.getFlags().getTtl(); + } + + + private SvcLogicContext getVnfdata(String vnf_id, String prefix, SvcLogicContext ctx) throws VNFNotFoundException { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfdata with vnfid = "+ ObjectUtils.toString(vnf_id) + ", prefix = "+ ObjectUtils.toString(prefix)+ ", SvcLogicContext"+ ObjectUtils.toString(ctx)); + } + + String key = "vnf-id = '" + vnf_id + "'"; + logger.debug("inside getVnfdata=== " + key); + try { + Date beginTimestamp = new Date(); + SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key, prefix, null, ctx); + Date endTimestamp = new Date(); + String status = SvcLogicResource.QueryStatus.SUCCESS.equals(response) ? LoggingConstants.StatusCodes.COMPLETE : LoggingConstants.StatusCodes.ERROR; + LoggingUtils.logMetricsMessage( + beginTimestamp, + endTimestamp, + LoggingConstants.TargetNames.AAI, + LoggingConstants.TargetServiceNames.AAIServiceNames.QUERY, + status, + "", + response.name(), + this.getClass().getCanonicalName()); + if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { + throw new VNFNotFoundException("VNF not found for vnf_id = " + vnf_id); + } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { + throw new RuntimeException("Error Querying AAI with vnfID = " + vnf_id); + } + logger.info("AAIResponse: " + response.toString()); + } catch (SvcLogicException e) { + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetServiceNames.AAIServiceNames.GET_VNF_DATA, + "Error in getVnfdata" + e, + this.getClass().getCanonicalName()); + + throw new RuntimeException(e); + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getVnfdata with (SvcLogicContext = "+ ObjectUtils.toString(ctx)+")"); + } + return ctx; + } + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java new file mode 100644 index 000000000..8755ad3f5 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/WorkingStateManager.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager; + +import org.openecomp.appc.requesthandler.exceptions.VNFNotFoundException; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; + + +public interface WorkingStateManager { + + /** + * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception. + * @param vnfId vnf Id to be verified for stable state + * @return True if vnf Exists and state is STABLE else False. + */ + public boolean isVNFStable(String vnfId); + + /** + * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or + * if the registered ownerId is equal to the given ownerId or if the forceFlag is true. + * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store. + * @param vnfId vnf Id to be updated + * @param workingState new working state + * @param ownerId + * @param forceFlag - force to update also on case given onwerId is different then the registered one + */ + public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag); + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java new file mode 100644 index 000000000..07d97739a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/JdbcWorkingStateManager.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager.impl; + +import java.sql.Connection; + +import org.openecomp.appc.dao.util.JdbcConnectionFactory; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; + +public abstract class JdbcWorkingStateManager implements WorkingStateManager { + + private JdbcConnectionFactory connectionFactory; + + public void setConnectionFactory(JdbcConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + protected Connection openDbConnection() { + return connectionFactory.openDbConnection(); + } + + protected void closeDbConnection(Connection connection) { + connectionFactory.closeDbConnection(connection); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java new file mode 100644 index 000000000..1de81606e --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/RequestHandlerMessages.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager.impl; + + +public class RequestHandlerMessages { + public final static String VNF_WORKING_STATE_UPDATED = "VNF WorkingState for vnfId ${vnfId} was updated to ${workingState} at attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; + public final static String VNF_WORKING_STATE_WAS_NOT_UPDATED = "VNF WorkingState for vnfId ${vnfId} was not updated to ${workingState} attempt ${attempt} out of ${maxAttempts} with ownerId = ${ownerId} and forceFlag = ${forceFlag}"; +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java new file mode 100644 index 000000000..732a41304 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/impl/WorkingStateManagerImpl.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.message.RequestHandlerMessages; +import org.openecomp.appc.util.MessageFormatter; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import org.openecomp.appc.workingstatemanager.objects.VnfWorkingStateDto; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.apache.commons.lang3.StringUtils; + + +public class WorkingStateManagerImpl extends JdbcWorkingStateManager { + + private static final String SQL_RETRIEVE_VNF_STATE_MANAGEMENT = "SELECT VNF_ID,STATE,OWNER_ID,UPDATED,VER FROM VNF_STATE_MANAGEMENT WHERE VNF_ID=?"; + private static final String SQL_INSERT_VNF_STATE_MANAGEMENT = "INSERT IGNORE INTO VNF_STATE_MANAGEMENT (VNF_ID,STATE,OWNER_ID,UPDATED,VER) VALUES (?, ?, ?, ?, ?)"; + private static final String SQL_UPDATE_VNF_STATE_MANAGEMENT = "UPDATE VNF_STATE_MANAGEMENT SET OWNER_ID=?, UPDATED=?, STATE=?, VER=? WHERE VNF_ID=? AND VER=?"; + private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + private static int maxAttempts = ConfigurationFactory.getConfiguration().getIntegerProperty("org.openecomp.appc.workingstatemanager.maxAttempts",20); + + private static Map<String,VNFWorkingState> workingStateMap = new ConcurrentHashMap<>(); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(WorkingStateManagerImpl.class); + + + /** + * Return true if vnf state exists in working state map and state is STABLE else return false. If vnf does not exists in working state map throws vnf not found exception. + * @param vnfId vnf Id to be verified for stable state + * @return True if vnf Exists and state is STABLE else False. + */ + @Override + public boolean isVNFStable(String vnfId){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to isVNFStable with vnfId = "+ vnfId); + } + Connection connection = null; + boolean vnfStable = false; + try { + connection = openDbConnection(); + VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId); + vnfStable = isVNFStable(vnfWorkingStateDto); + } catch (SQLException e) { + String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage(); + throw new RuntimeException(errMsg); + } finally { + if(connection != null) { + closeDbConnection(connection); + } + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from isVNFStable for vnfId = "+ vnfId+" with Result = "+vnfStable); + } + return vnfStable; + } + + /** + * Updates working state for given vnf Id. Returns true if update was allowed and succeeded. Update will success only if the existing vnf state is 'STABLE' or + * if the registered ownerId is equal to the given ownerId or if the forceFlag is true. + * Note on case of simultaneously updates the latest updates will be failed, and another attempts will be done after refetching the updated data from persistent store. + * @param vnfId vnf Id to be updated + * @param workingState new working state + * @param ownerId + * @param forceFlag - force to update also on case given onwerId is different then the registered one + */ + @Override + public boolean setWorkingState(String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag){ + boolean updated = false; + if (logger.isTraceEnabled()) { + logger.trace("Entering to setWorkingState with vnfId = "+ ObjectUtils.toString(vnfId)+ ", VNFWorkingState = " + workingState.name() + ", ownerId = "+ownerId+", forceFlag = "+forceFlag); + } + Connection connection = null; + try { + connection = openDbConnection(); + updated = setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag, maxAttempts); + } catch (SQLException e) { + String errMsg = StringUtils.isEmpty(e.getMessage())? e.toString() :e.getMessage(); + throw new RuntimeException(errMsg); + } finally { + if(connection != null) { + closeDbConnection(connection); + } + } + + logger.trace("setWorkingState exit with output updated = "+updated); + return updated; + } + + public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag, int maxAttempts) throws SQLException { + return setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,1,maxAttempts); + } + public boolean setWorkingStateIfStableOrSameOwnerIdOrForce(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, boolean forceFlag,int attempt, int maxAttempts) throws SQLException { + boolean updated = false; + VnfWorkingStateDto vnfWorkingStateDto = retrieveVnfWorkingState(connection, vnfId); + Long currentVersion = vnfWorkingStateDto != null ? vnfWorkingStateDto.getVer() : null; + if(forceFlag || isVNFStable(vnfWorkingStateDto) || vnfWorkingStateDto.getOwnerId().equals(ownerId)){ + updated = storeWorkingStateIfSameVersion(connection, vnfId, workingState, ownerId, currentVersion); + + Params params = new Params().addParam("vnfId", vnfId).addParam("workingState",workingState.name()) + .addParam("attempt",attempt).addParam("maxAttempts",maxAttempts).addParam("ownerId",ownerId).addParam("forceFlag",forceFlag); + String logMessage; + if(updated) { + logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_UPDATED, params.getParams()); + }else { + logMessage = MessageFormatter.format(RequestHandlerMessages.VNF_WORKING_STATE_WAS_NOT_UPDATED, params.getParams()); + } + logger.debug(logMessage); + if(!updated && attempt<maxAttempts){ + setWorkingStateIfStableOrSameOwnerIdOrForce(connection, vnfId, workingState, ownerId, forceFlag,++attempt,maxAttempts); + } + + } + return updated; + } + + + public boolean storeWorkingStateIfSameVersion(Connection connection, String vnfId, VNFWorkingState workingState, String ownerId, Long currentVersion) throws SQLException { + boolean stored = false; + if (currentVersion != null) { + stored = updateStateIfSameVersion(connection, vnfId, ownerId, workingState.name(), currentVersion); + } else { + stored = addVnfWorkingStateIfNotExists(connection, vnfId, ownerId, workingState.name()); + } + + return stored; + } + + private boolean isVNFStable(VnfWorkingStateDto vnfWorkingStateDto) { + if( vnfWorkingStateDto == null || vnfWorkingStateDto.getState() ==VNFWorkingState.STABLE){ + return true; + } + return false; + } + + public boolean updateStateIfSameVersion(Connection connection, String vnfId, String ownerId, String state, long currentVer) throws SQLException { + try(PreparedStatement statement = connection.prepareStatement(SQL_UPDATE_VNF_STATE_MANAGEMENT)) { + long newVer = (currentVer >= Long.MAX_VALUE) ? 1 : (currentVer + 1); + statement.setString(1, ownerId); + statement.setLong(2, getCurrentTime(connection)); + statement.setString(3, state); + statement.setLong(4, newVer); + statement.setString(5, vnfId); + statement.setLong(6, currentVer); + return (statement.executeUpdate() != 0); + } + } + + protected VnfWorkingStateDto retrieveVnfWorkingState(Connection connection, String vnfId) throws SQLException { + VnfWorkingStateDto res = null; + + try(PreparedStatement statement = connection.prepareStatement(SQL_RETRIEVE_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER + statement.setString(1, vnfId); + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = new VnfWorkingStateDto(vnfId); + String stateString = resultSet.getString(2); + VNFWorkingState vnfWorkingState = VNFWorkingState.valueOf(stateString); + res.setState(vnfWorkingState); + res.setOwnerId(resultSet.getString(3)); + res.setUpdated(resultSet.getLong(4)); + res.setVer(resultSet.getLong(5)); + } + } + } + return res; + } + + private long getCurrentTime(Connection connection) throws SQLException { + long res = -1; + if(connection != null) { + try(PreparedStatement statement = connection.prepareStatement(SQL_CURRENT_TIMESTAMP)) { + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = resultSet.getTimestamp(1).getTime(); + } + } + } + } + if(res == -1) { + res = System.currentTimeMillis(); + } + return res; + } + + protected boolean addVnfWorkingStateIfNotExists(Connection connection, String vnfId, String ownerId, String state) throws SQLException { + boolean added = false; + try(PreparedStatement statement = connection.prepareStatement(SQL_INSERT_VNF_STATE_MANAGEMENT)) { //VNF_ID,STATE,OWNER_ID,UPDATED,VER + statement.setString(1, vnfId); + statement.setString(2, state); + statement.setString(3, ownerId); + statement.setLong(4, getCurrentTime(connection)); + statement.setLong(5, 1L); + int rowCount = statement.executeUpdate(); + added = rowCount != 0 ? true : false; + } + return added; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java new file mode 100644 index 000000000..ad6973712 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VNFWorkingState.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager.objects; + + +public enum VNFWorkingState { + STABLE,UNSTABLE,UNKNOWN; + public String toString(){ + return this.name(); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java new file mode 100644 index 000000000..ed840f480 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/workingstatemanager/objects/VnfWorkingStateDto.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager.objects; + + +public class VnfWorkingStateDto { + private String vnfId; + private VNFWorkingState state; + private String ownerId; + private long updated; + private long ver; + + public VnfWorkingStateDto() { + } + + public VnfWorkingStateDto(String vnfId) { + this.vnfId = vnfId; + } + + public String getVnfId() { + return vnfId; + } + + public void setVnfId(String vnfId) { + this.vnfId = vnfId; + } + + public VNFWorkingState getState() { + return state; + } + + public void setState(VNFWorkingState state) { + this.state = state; + } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } + + public long getVer() { + return ver; + } + + public void setVer(long ver) { + this.ver = ver; + } + + + @Override + public String toString() { + return "VnfWorkingStateDto{" + + "vnfId='" + vnfId + '\'' + + ", state=" + state + + ", ownerId='" + ownerId + '\'' + + ", updated=" + updated + + ", ver=" + ver + + '}'; + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..785b6cb04 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 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========================================================= + --> + +<!-- + Starter Blueprint Camel Definition appc-aai-adapter-blueprint +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> + <bean id="requestHandlerBean" class="org.openecomp.appc.requesthandler.impl.RequestHandlerImpl" scope="singleton" > + <property name="commandExecutor" ref="commandExecutorRef" /> + <property name="requestValidator" ref="requestValidatorBean" /> + <property name="lockManager" ref="lockManagerRef" /> + <property name="workingStateManager" ref="workingStateManagerBean"/> + <property name="transactionRecorder" ref="transactionRecorderRef" /> + <property name="aaiService" ref="aaiServiceRef" /> + </bean> + + <bean id="requestValidatorBean" class="org.openecomp.appc.requesthandler.impl.RequestValidatorImpl" scope="singleton" > + <property name="lifecyclemanager" ref="lifecyclemanagerRef" /> + <property name="workflowManager" ref="workflowManagerRef" /> + <property name="workingStateManager" ref="workingStateManagerBean" /> + </bean> + + <service id="requestHandlerService" interface="org.openecomp.appc.requesthandler.RequestHandler" ref="requestHandlerBean"/> + <reference id="lifecyclemanagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lifecyclemanager.LifecycleManager" /> + <reference id="workflowManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.workflow.WorkFlowManager" /> + <reference id="commandExecutorRef" availability="optional" activation="eager" interface="org.openecomp.appc.executor.CommandExecutor" /> + <reference id="lockManagerRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.lockmanager.api.LockManager" /> + <reference id="transactionRecorderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.transactionrecorder.TransactionRecorder" /> + <reference xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" ext:proxy-method="classes" id="aaiServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.aai.AAIService" /> + + <bean id="workingStateManagerBean" class="org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl" scope="singleton" > + <property name="connectionFactory"> + <bean class="org.openecomp.appc.dao.util.AppcJdbcConnectionFactory"> + <property name="schema" value="sdnctl"/> + </bean> + </property> + </bean> + +</blueprint> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2e2763f9a --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,53 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 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========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded +# to supply configuration options +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-MAIN +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +org.openecomp.appc.db.url.sdnctl=jdbc:mysql://127.0.0.1:3306/test +org.openecomp.appc.db.user.sdnctl=test +org.openecomp.appc.db.pass.sdnctl=123456 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: +org.openecomp.appc.workingstatemanager.maxAttempts=20 diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java new file mode 100644 index 000000000..46875a269 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestConverter.java @@ -0,0 +1,360 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.requesthandler.conv.Converter; + +import javax.ws.rs.container.AsyncResponse; +import java.text.ParseException; +import java.util.Date; +import java.util.HashMap; + + +public class TestConverter { + private String expectedJsonBodyStr ="{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}}"; + private String expectedDmaapOutgoingMessageJsonStringTest ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"test\"}"; + private String expectedDmaapOutgoingMessageJsonStringRollback ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"rollback\"}"; + private String expectedDmaapOutgoingMessageJsonStringSnapshot ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"snapshot\"}"; + private String expectedDmaapOutgoingMessageJsonStringAudit ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"audit\"}"; + private String expectedDmaapOutgoingMessageJsonStringHealthCheck ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"health-check\"}"; + private String expectedDmaapOutgoingMessageJsonStringLiveUpgrade ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"live-upgrade\"}"; + private String expectedDmaapOutgoingMessageJsonStringLock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"lock\"}"; + private String expectedDmaapOutgoingMessageJsonStringModifyConfig ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"modify-config\"}"; + private String expectedDmaapOutgoingMessageJsonStringSoftwareUpload ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"software-upload\"}"; + private String expectedDmaapOutgoingMessageJsonStringStop ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"stop\"}"; + private String expectedDmaapOutgoingMessageJsonStringSync ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"sync\"}"; + private String expectedDmaapOutgoingMessageJsonStringTerminate ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"terminate\"}"; + private String expectedDmaapOutgoingMessageJsonStringUnlock ="{\"body\":{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"rpc-name\":\"unlock\"}"; + + @Test + public void convDateToZuluStringTest(){ + String dateToZuluString = Converter.convDateToZuluString(new Date(0L)); + Assert.assertEquals("1970-01-01T00:00:00.000Z", dateToZuluString); + } + + @Test + public void convAsyncResponseToBuilderTestTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Test; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTestTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Test; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTest,jsonStr); + } + + @Test + public void convPayloadObjectToJsonStringTest() throws JsonProcessingException, ParseException { + String jsonString = Converter.convPayloadObjectToJsonString("any valid JSON string value"); + Assert.assertEquals("any valid JSON string value", jsonString); + + HashMap<String, String> hashMap = new HashMap<>(); + hashMap.put("key","value"); + jsonString = Converter.convPayloadObjectToJsonString(hashMap); + Assert.assertEquals("{\"key\":\"value\"}", jsonString); + } + + @Test + public void convAsyncResponseToBuilderRollbackTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Rollback; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringRollbackTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Rollback; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringRollback,jsonStr); + } + + @Test + public void convAsyncResponseToBuilderSnapshotTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Snapshot; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSnapshotTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Snapshot; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSnapshot,jsonStr); + } + @Test + public void convAsyncResponseToBuilderAuditTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Audit; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringAuditTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Audit; + String rpcName = action.name().toLowerCase(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringAudit,jsonStr); + } + @Test + public void convAsyncResponseToBuilderHealthCheckTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.HealthCheck; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringHealthCheckTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.HealthCheck; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringHealthCheck,jsonStr); + } + @Test + public void convAsyncResponseToBuilderLiveUpgradeTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.LiveUpgrade; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringLiveUpgradeTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.LiveUpgrade; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLiveUpgrade,jsonStr); + } + @Test + public void convAsyncResponseToBuilderLockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Lock; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringLockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Lock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringLock,jsonStr); + } + @Test + public void convAsyncResponseToBuilderModifyConfigTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.ModifyConfig; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringModifyConfigTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.ModifyConfig; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringModifyConfig,jsonStr); + } + @Test + public void convAsyncResponseToBuilderSoftwareUploadTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.SoftwareUpload; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSoftwareUploadTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.SoftwareUpload; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSoftwareUpload,jsonStr); + } + @Test + public void convAsyncResponseToBuilderStopTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Stop; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringStopTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Stop; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringStop,jsonStr); + } + @Test + public void convAsyncResponseToBuilderSync() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringSync() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringSync,jsonStr); + } + @Test + public void convAsyncResponseToBuilderTerminateTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Sync; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTerminateTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Terminate; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringTerminate,jsonStr); + } + @Test + public void convAsyncResponseToBuilderUnlockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Unlock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringUnlockTest() throws JsonProcessingException { + ResponseContext asyncResponse = buildAsyncResponse(); + VNFOperation action = VNFOperation.Unlock; + String rpcName = convertActionNameToUrl(action.name()); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonStringUnlock,jsonStr); + } + /*@Test + public void convAsyncResponseToBuilderTest() throws JsonProcessingException { + AsyncResponse asyncResponse = buildAsyncResponse(); + String jsonStr = Converter.convAsyncResponseToJsonStringBody(asyncResponse); + Assert.assertEquals(expectedJsonBodyStr,jsonStr); + } + + @Test + public void convAsyncResponseToDmaapOutgoingMessageJsonStringTest() throws JsonProcessingException { + AsyncResponse asyncResponse = buildAsyncResponse(); + String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(asyncResponse); + System.out.println("jsonStr = " + jsonStr); + Assert.assertEquals(expectedDmaapOutgoingMessageJsonString,jsonStr); + }*/ + + + private ResponseContext buildAsyncResponse() { + ResponseContext asyncResponse = createResponseContextWithSubObjects(); + asyncResponse.getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode()); + asyncResponse.getStatus().setMessage(LCMCommandStatus.SUCCESS.getResponseMessage()); + asyncResponse.getCommonHeader().setOriginatorId("oid"); + asyncResponse.getCommonHeader().setApiVer("2.0.0"); + asyncResponse.getCommonHeader().setRequestId("reqid"); + asyncResponse.getCommonHeader().setTimestamp(new Date(1000L)); + asyncResponse.setPayload("any valid JSON string value. Json escape characters need to be added to make it a valid json string value"); + return asyncResponse; + } + + private ResponseContext createResponseContextWithSubObjects() { + + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } + + +} + + + diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java new file mode 100644 index 000000000..e4c1e92d3 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestHandler.java @@ -0,0 +1,583 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.CommandExecutor; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.executor.objects.CommandExecutorInput; +import org.openecomp.appc.executor.objects.LCMCommandStatus; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockManager; +import org.openecomp.appc.messageadapter.MessageAdapter; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl; +import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.requesthandler.objects.RequestHandlerOutput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.transactionrecorder.objects.TransactionRecord; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.FrameworkUtil; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.*; +import static org.mockito.Matchers.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) +public class TestRequestHandler { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); + + private RequestHandlerImpl requestHandler; + private RequestValidatorImpl requestValidator; + private WorkFlowManager workflowManager; + private WorkingStateManager workingStateManager ; + private LockManager lockManager; + + @Before + public void init() throws Exception { + + requestHandler = new RequestHandlerImpl(); + LifecycleManager lifecyclemanager= mock(LifecycleManager.class); + workflowManager= mock(WorkFlowManager.class); + CommandExecutor commandExecutor= mock(CommandExecutor.class); + MessageAdapter messageAdapter = mock(MessageAdapter.class); + workingStateManager = mock(WorkingStateManager.class); + lockManager = mock(LockManager.class); + TransactionRecorder transactionRecorder= mock(TransactionRecorder.class); + + requestHandler.setWorkingStateManager(workingStateManager); + requestHandler.setMessageAdapter(messageAdapter); + requestValidator = mock(RequestValidatorImpl.class); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestValidator.setWorkingStateManager(workingStateManager); + requestValidator.setWorkflowManager(workflowManager); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestHandler.setCommandExecutor(commandExecutor); + requestHandler.setRequestValidator(requestValidator); + requestHandler.setLockManager(lockManager); + requestHandler.setTransactionRecorder(transactionRecorder); + + doNothing().when(transactionRecorder).store((TransactionRecord) anyObject()); +// Mockito.when(commandExecutor.executeCommand((CommandExecutorInput)anyObject())).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + for(Integer i=130; i<=140 ; i++) + { + Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true); + } + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false); + Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true); + } + + private void threadSleep(){ + try { + Thread.sleep(5); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Test + public void testNegativeFlowWithRequestingUsedVnfId() throws Exception { + logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("131", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + threadSleep (); + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + logger.debug("testNegativeFlowWithRequestingUsedVnfId"); + logger.debug("=====================testNegativeFlowWithRequestingUsedVnfId============================="); + } + + @Test + public void testInvalidVNFExceptionRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testLifecycleException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new LifecycleException(new Exception(),"Configured","test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACTION_NOT_SUPPORTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + + @Test + public void testRequestExpiredException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new RequestExpiredException("")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.EXPIRED_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testWorkflowNotFoundException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new WorkflowNotFoundException("Unable to find the DG","VNF-2.0.0.0", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode());} + + @Test + public void testDGWorkflowNotFoundException() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest) anyObject())).thenReturn(new WorkflowExistsOutput(true, true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure, 0, false, originatorID, requestID, subRequestID, new Date()); + PowerMockito.doThrow(new DGWorkflowNotFoundException("Unable to find the DG", "VNF-2.0.0.0", "temp", "Test")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.DG_WORKFLOW_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testInvalidInputException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID1 = UUID.randomUUID().toString(); + String requestID1 = UUID.randomUUID().toString(); + String subRequestID1 = UUID.randomUUID().toString(); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID1, requestID1, subRequestID1,new Date()); + PowerMockito.doThrow(new InvalidInputException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.INVALID_INPUT_PARAMETER.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + } + + @Test + public void testNoTransitionDefinedException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3010", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new NoTransitionDefinedException("Invalid VNF State","Unstable","Test event")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.NO_TRANSITION_DEFINE.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void rejectInvalidRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + PowerMockito.doThrow(new VNFNotFoundException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.VNF_NOT_FOUND.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testUnstableWorkingState() throws Exception { + logger.debug("=====================testUnstableWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("37")).thenReturn(true,false); + RequestHandlerInput input = this.getRequestHandlerInput("37", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input); + RequestHandlerOutput output = requestHandler.handleRequest(input); + + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RequestHandlerInput input1 = this.getRequestHandlerInput("37", VNFOperation.Configure,1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output1 = requestHandler.handleRequest(input1); + + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(), output1.getResponseContext().getStatus().getCode()); + logger.debug("=====================testUnstableWorkingState============================="); + } + + @Test + public void testOnRequestExecutionEndSuccessForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"137", "", "", ""),true); + + input1 = this.getRequestHandlerInput("137", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestExecutionEndSuccessForWorkingState============================="); + } + + private void mockRuntimeContextAndVnfContext(RequestHandlerInput input1) throws Exception { + RuntimeContext runtimeContext = PowerMockito.mock(RuntimeContext.class); + VNFContext vnfContext = new VNFContext(); + vnfContext.setType("SCP"); + vnfContext.setId("137"); + when(runtimeContext.getVnfContext()).thenReturn(vnfContext); + when(runtimeContext.getRequestContext()).thenReturn(input1.getRequestContext()); + when(runtimeContext.getRpcName()).thenReturn(input1.getRpcName()); + + + ResponseContext responseContext = new ResponseContext(); + responseContext.setStatus(new Status()); + responseContext.setAdditionalContext(new HashMap<String, String>(4)); + responseContext.setCommonHeader(input1.getRequestContext().getCommonHeader()); + runtimeContext.setResponseContext(responseContext); + when(runtimeContext.getResponseContext()).thenReturn(responseContext); + responseContext.setStatus(new Status()); + runtimeContext.setResponseContext(responseContext); + PowerMockito.whenNew(RuntimeContext.class).withAnyArguments().thenReturn(runtimeContext); + + } + + + @Test + public void testOnRequestExecutionEndFailureForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.NO_TRANSITION_DEFINE,"38", "", "", ""),true); + + input1 = this.getRequestHandlerInput("38", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode()); + + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + } + + @Test + public void testOnRequestExecutionEndTTLExpiredForWorkingState() throws Exception { + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + mockRuntimeContextAndVnfContext(input1); + + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + input1 = this.getRequestHandlerInput("39", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new LockException(" ")).when(lockManager).acquireLock(Matchers.anyString(), Matchers.anyString(), Matchers.anyByte()); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.LOCKING_FAILURE.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); + } + + @Test + public void testOnRequestTTLEndForWorkingState() throws Exception { + logger.debug("=====================testOnRequestTTLEndForWorkingState============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + RequestHandlerInput input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.EXPIRED_REQUEST_FAILURE,"40", "", "", ""); + requestHandler.onRequestTTLEnd(response,true); + input1 = this.getRequestHandlerInput("40", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + PowerMockito.doThrow(new UnstableVNFException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.UNSTABLE_VNF.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testOnRequestTTLEndForWorkingState============================="); + } + + @Test + public void testForceCommandExecution() throws Exception { + logger.debug("=====================testForceCommandExecution============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + mockRuntimeContextAndVnfContext(input1); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + threadSleep(); + RuntimeContext response = this.getAsyncResponse(false,LCMCommandStatus.ACCEPTED,"138", "", "", ""); + requestHandler.onRequestTTLEnd(response,true); + input1 = this.getRequestHandlerInput("138", VNFOperation.Configure, 1200, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + input1.getRequestContext().getCommonHeader().getFlags().setForce(true); + mockRuntimeContextAndVnfContext(input1); + output = requestHandler.handleRequest(input1); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(),output.getResponseContext().getStatus().getCode()); + logger.debug("=====================testForceCommandExecution============================="); + } + + @Test + public void testOnRequestExecutionEndSuccess() throws VNFNotFoundException { + logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Starts ============================="); + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"201", "", "", ""),true); + logger.debug("=====================Positive TEST - On Request Execution End SUCCESS- Ends ============================="); + } + + @Test + public void testOnRequestExecutionEndFailure() throws VNFNotFoundException { + logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Starts ============================="); + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionEnd(this.getAsyncResponse(false,LCMCommandStatus.DG_FAILURE,"202", "", "", ""),true); + logger.debug("=====================Positive TEST - On Request Execution End FAILURE- Ends ============================="); + } + + private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force,String originatorId, String requestId, String subRequestId,Date timeStamp){ + String API_VERSION= "2.0.0"; + RequestHandlerInput input = new RequestHandlerInput(); + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + RequestContext requestContext = runtimeContext.getRequestContext(); + input.setRequestContext(requestContext); + requestContext.getActionIdentifiers().setVnfId(vnfID); + requestContext.setAction(action); + input.setRpcName(convertActionNameToUrl(action.name())); + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestId); + requestContext.getCommonHeader().setOriginatorId(originatorId); + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().getFlags().setForce(force); + requestContext.getCommonHeader().setTimestamp(timeStamp); + requestContext.getCommonHeader().setApiVer(API_VERSION); + return input; + } + + private RuntimeContext getAsyncResponse(boolean wfStatus, LCMCommandStatus commandStatus, String vnfId, String originatorId, String requestId, String subRequestId) + { + RuntimeContext output = createRuntimeContextWithSubObjects(); + + + output.getRequestContext().getActionIdentifiers().setVnfId(vnfId); + output.getVnfContext().setId(vnfId); + output.getResponseContext().getCommonHeader().setApiVer("2.0.0"); + output.getResponseContext().getCommonHeader().setTimestamp(new Date()); + output.getResponseContext().getStatus().setCode(LCMCommandStatus.SUCCESS.getResponseCode()); + output.setTimeStart(new Date()); + output.getResponseContext().getCommonHeader().setOriginatorId(originatorId); + output.getResponseContext().getCommonHeader().setRequestId(requestId); + output.getResponseContext().getCommonHeader().setSubRequestId(subRequestId); + + output.getVnfContext().setType("FIREWALL"); + output.getRequestContext().setAction(VNFOperation.Configure); + output.setRpcName("configure"); + output.getResponseContext().setPayload(""); + return output; + } + + @Test + public void rejectDuplicateRequest() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + input = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + + PowerMockito.doThrow(new DuplicateRequestException(" ")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.DUPLICATE_REQUEST.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void removeRequestFromRegistryOnRequestCompletion() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("302", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.SUCCESS,"302",originatorID,requestID,subRequestID); + requestHandler.onRequestExecutionEnd(asyncResponse,true); + + input = this.getRequestHandlerInput("310", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void removeRequestFromRegistryOnTTLExpiration() throws Exception { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + PowerMockito.doNothing().when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("303", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + mockRuntimeContextAndVnfContext(input); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + + RuntimeContext asyncResponse = this.getAsyncResponse(true,LCMCommandStatus.ACCEPTED,"303",originatorID,requestID,subRequestID); + requestHandler.onRequestTTLEnd(asyncResponse,false); + + output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.ACCEPTED.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + /*@Test + public void getMetricserviceTest() throws Exception{ + Method method = RequestHandlerImpl.class.getDeclaredMethod("getMetricservice", null); + method.setAccessible(true); + method.invoke(null, null); + + }*/ + @Test + public void onRequestExecutionStartTest() throws Exception{ + Mockito.doReturn(true).when(workingStateManager).setWorkingState(anyString(),(VNFWorkingState) anyObject(), anyString(),anyBoolean()); + requestHandler.onRequestExecutionStart("303",false, null, true); + Assert.assertNotNull(requestHandler); + } + + + private RuntimeContext createRuntimeContextWithSubObjects() { + RuntimeContext runtimeContext = new RuntimeContext(); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + ResponseContext responseContext = createResponseContextWithSuObjects(); + runtimeContext.setResponseContext(responseContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return runtimeContext; + + } + + private ResponseContext createResponseContextWithSuObjects(){ + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } +} + diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java new file mode 100644 index 000000000..6c287a580 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/TestRequestValidator.java @@ -0,0 +1,626 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.requesthandler; + + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.executor.UnstableVNFException; +import org.openecomp.appc.lifecyclemanager.LifecycleManager; +import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; +import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; +import org.openecomp.appc.requesthandler.exceptions.*; +import org.openecomp.appc.requesthandler.impl.RequestHandlerImpl; +import org.openecomp.appc.requesthandler.impl.RequestValidatorImpl; +import org.openecomp.appc.requesthandler.objects.RequestHandlerInput; +import org.openecomp.appc.transactionrecorder.TransactionRecorder; +import org.openecomp.appc.workflow.WorkFlowManager; +import org.openecomp.appc.workflow.objects.WorkflowExistsOutput; +import org.openecomp.appc.workflow.objects.WorkflowRequest; +import org.openecomp.appc.workingstatemanager.WorkingStateManager; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicResource; +import org.openecomp.sdnc.sli.aai.AAIService; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.Date; +import java.util.Map; +import java.util.UUID; + +import static junit.framework.TestCase.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.*; + + +@RunWith(PowerMockRunner.class) +@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) +public class TestRequestValidator { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); + + private static final String TTL_FLAG= "TTL"; + + private RequestValidatorImpl requestValidator; + + AAIService aaiAdapter ; + LifecycleManager lifecyclemanager; + WorkFlowManager workflowManager; + WorkingStateManager workingStateManager ; +// AppcDAOImpl dao ; + + private final BundleContext bundleContext= Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + + + + @Before + public void init() throws Exception { + +// dao = Mockito.mock(AppcDAOImpl.class); +// PowerMockito.whenNew(AppcDAOImpl.class).withNoArguments().thenReturn(dao); +// Mockito.doNothing().when(dao).storeTransactionRecord((TransactionRecord)anyObject()); + // PowerMockito.when(dao.queryWorkflow(anyString(),anyString())).thenReturn(true); + + // *** + AAIService aaiService = Mockito.mock(AAIService.class);; + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(AAIService.class)).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(AAIService.class.getName())).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(aaiService); + PowerMockito.when(aaiService.query(anyString(),anyBoolean(),anyString(),anyString(),anyString(),anyString(),(SvcLogicContext)anyObject())).thenAnswer(new Answer<SvcLogicResource.QueryStatus>() { + @Override + public SvcLogicResource.QueryStatus answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + SvcLogicContext ctx =(SvcLogicContext)args[6]; + String prefix = (String)args[4]; + String key = (String)args[3]; + if(key.contains("'28'")){ + return SvcLogicResource.QueryStatus.FAILURE ; + }else if ( key.contains("'8'")) { + return SvcLogicResource.QueryStatus.NOT_FOUND ; + }else { + ctx.setAttribute(prefix + ".vnf-type", "FIREWALL"); + ctx.setAttribute(prefix + ".orchestration-status", "Instantiated"); + } + return SvcLogicResource.QueryStatus.SUCCESS ; + } + }); + PowerMockito.when(aaiService.update(anyString(),anyString(),(Map)anyObject(),anyString(),(SvcLogicContext)anyObject())).thenReturn(SvcLogicResource.QueryStatus.SUCCESS); + //PowerMockito.when(requestHandler.getVnfdata(anyString(), anyString(), (SvcLogicContext)anyObject())).thenReturn() + // *** + + + aaiAdapter = Mockito.mock(AAIService.class); + lifecyclemanager= Mockito.mock(LifecycleManager.class); + workflowManager= Mockito.mock(WorkFlowManager.class); + workingStateManager = Mockito.mock(WorkingStateManager.class); + + // transactionRecorder= spy(TransactionRecorder.class); + requestValidator = new RequestValidatorImpl(); +// requestValidator = Mockito.mock(RequestValidator.class); + requestValidator.setWorkflowManager(workflowManager); + requestValidator.setLifecyclemanager(lifecyclemanager); + requestValidator.setWorkingStateManager(workingStateManager); + + + /* Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true); + Mockito.when(aaiAdapter.requestGenericVnfData("1")).thenReturn(getGenericVnf("FIREWALL","INSTNATIATED"));*/ + // Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(true); + + /*PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("8")).thenThrow(new AAIAdapterException("404")); + Mockito.when(workingStateManager.isVNFStable("8")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("9")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("9")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("10")).thenReturn(getGenericVnf("WrongRouter","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("10")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("11")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("11")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("12")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("12")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("13")).thenReturn(getGenericVnf("FIREWALL","TESTING")); + Mockito.when(workingStateManager.isVNFStable("13")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("14")).thenReturn(getGenericVnf("FIREWALL","REBUILDING")); + Mockito.when(workingStateManager.isVNFStable("14")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("26")).thenReturn(getGenericVnf("FIREWALL","NOT_INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("26")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("27")).thenReturn(getGenericVnf("FIREWALL","RESTARTING")); + Mockito.when(workingStateManager.isVNFStable("27")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("28")).thenThrow(new RuntimeException("AAI Down Excpetion")); + Mockito.when(workingStateManager.isVNFStable("28")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("35")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("35")).thenReturn(true);*/ + + /*for(Integer i=130; i<=140 ; i++) + { + PowerMockito.when(getAaiadapter().requestGenericVnfData(i.toString())).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable(i.toString())).thenReturn(true); + } + PowerMockito.when(getAaiadapter().requestGenericVnfData("39")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("39")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("40")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("40")).thenReturn(true).thenReturn(false); + + + PowerMockito.when(getAaiadapter().requestGenericVnfData("38")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("38")).thenReturn(true).thenReturn(false); + + + PowerMockito.when(getAaiadapter().requestGenericVnfData("201")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","CONFIGURED")); + Mockito.when(workingStateManager.isVNFStable("201")).thenReturn(true); + PowerMockito.when(getAaiadapter().requestGenericVnfData("202")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")).thenReturn(getGenericVnf("FIREWALL","ERROR")); + Mockito.when(workingStateManager.isVNFStable("202")).thenReturn(true).thenReturn(false); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("301")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true).thenReturn(false); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("302")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("302")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("303")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("303")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("309")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true).thenReturn(true); + + PowerMockito.when(getAaiadapter().requestGenericVnfData("310")).thenReturn(getGenericVnf("FIREWALL","INSTANTIATED")); + Mockito.when(workingStateManager.isVNFStable("310")).thenReturn(true).thenReturn(true);*/ + } + public AAIService getAaiadapter() { + return this.aaiAdapter; + } +/* public GenericVnf getGenericVnf(String vnfType, String operationalState) { + GenericVnf genericVnf = new GenericVnf(); + genericVnf.setVnfType(vnfType); + // genericVnf.setOperationalState(operationalState); + genericVnf.setOrchestrationStatus(operationalState); + return genericVnf; + }*/ + private RequestHandlerInput getRequestHandlerInput(String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp){ + String API_VERSION= "2.0.0"; + RequestHandlerInput input = new RequestHandlerInput(); + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + RequestContext requestContext = runtimeContext.getRequestContext(); + input.setRequestContext(requestContext); + requestContext.getActionIdentifiers().setVnfId(vnfID); + requestContext.setAction(action); + if (action != null) { + input.setRpcName(convertActionNameToUrl(action.name())); + } + else{ + input.setRpcName(null); + } + requestContext.getCommonHeader().setRequestId(requestId); + requestContext.getCommonHeader().setSubRequestId(subRequestId); + requestContext.getCommonHeader().setOriginatorId(originatorId); + requestContext.getCommonHeader().getFlags().setTtl(ttl); + requestContext.getCommonHeader().getFlags().setForce(force); + requestContext.getCommonHeader().getTimeStamp(); + requestContext.getCommonHeader().setApiVer(API_VERSION); + requestContext.getCommonHeader().setTimestamp(timeStamp); + return input; + } + @Test + public void testNullVnfID() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullVnfID============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput(null, VNFOperation.Configure, 30, + false, UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } +// assertEquals(new InvalidInputException("vnfID or command is null") ,ex); + assertNotNull(ex); + logger.debug("=====================testNullVnfID============================="); + } + + @Test + public void testPositiveFlowWithConfigure() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testPositiveFlowWithConfigure============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true); + RequestHandlerInput input = this.getRequestHandlerInput("1", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNull(ex); + logger.debug("testPositiveFlowWithConfigure"); + logger.debug("=====================testPositiveFlowWithConfigure============================="); + } + + @Test + public void testVnfNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testVnfNotFound============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("8", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testVnfNotFound============================="); + } + + + + @Test + public void testNullCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullCommand============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput("7", null,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testNullCommand============================="); + } + + @Test + public void testNullVnfIDAndCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNullVnfIDAndCommand============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + RequestHandlerInput input = this.getRequestHandlerInput(null, null,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(InvalidInputException e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testNullVnfIDAndCommand============================="); + } + + @Test + public void testWorkflowNotFound() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testWorkflowNotFound============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(false,false)); + RequestHandlerInput input = this.getRequestHandlerInput("10", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testWorkflowNotFound============================="); + } + + @Test + public void testUnstableVnfWithConfigure() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithConfigure============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("11", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithConfigure============================="); + } + + @Test + public void testUnstableVnfWithTest() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithTest============================="); + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + RequestHandlerInput input = this.getRequestHandlerInput("12", VNFOperation.Test,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithTest============================="); + } + + @Test + public void testUnstableVnfWithStart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithStart============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("13", VNFOperation.Start,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithStart============================="); + } + + @Test + public void testUnstableVnfWithTerminate() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithTerminate============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + RequestHandlerInput input = this.getRequestHandlerInput("14", VNFOperation.Terminate,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithTerminate============================="); + } + + @Test + public void testUnstableVnfWithRestart() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithRestart============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + RequestHandlerInput input = this.getRequestHandlerInput("26", VNFOperation.Restart,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithRestart============================="); + } + + @Test + public void testUnstableVnfWithRebuild() throws LifecycleException, NoTransitionDefinedException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testUnstableVnfWithRebuild============================="); + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(),anyString())).thenThrow( new NoTransitionDefinedException("","","")); + + // Mockito.doReturn(this.getGenericVnf("Firewall", "NOT_INSTANTIATED")).when(getAaiadapter()).requestGenericVnfData("8"); + RequestHandlerInput input = this.getRequestHandlerInput("27", VNFOperation.Rebuild,30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testUnstableVnfWithRebuild============================="); + } + + + + + @Test + public void testAAIDown() throws Exception { + logger.debug("=====================testAAIDown============================="); + // AAIAdapter aaiAdapter = Mockito.mock(AAIAdapterImpl.class); + // RequestHandler requestHandler=RequestHandlerSingleton.getRequestHandler(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl()); + // RequestHandler requestHandler = new RequestHandlerImpl(new WorkFlowManagerImpl(),aaiAdapter,new LifecycleManagerImpl()); + RequestHandlerInput input = this.getRequestHandlerInput("28", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + try { + requestValidator.validateRequest(runtimeContext); + + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("=====================testAAIDown============================="); + } + + @Test + public void testNegativeFlowWithTimeStamp() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + logger.debug("=====================testNegativeFlowWithTimeStamp============================="); + Date now = new Date(); + Date past = new Date(); + past.setTime(now.getTime() -1000000 ); + RequestHandlerInput input = this.getRequestHandlerInput("35", VNFOperation.Configure, 30, + false,UUID.randomUUID().toString(),UUID.randomUUID().toString(),UUID.randomUUID().toString(),past); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + logger.debug("testNegativeFlowWithTimeStamp"); + logger.debug("=====================testNegativeFlowWithTimeStamp============================="); + } + + + @Test + public void rejectDuplicateRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); + Mockito.when(workingStateManager.isVNFStable("301")).thenReturn(true); + Mockito.when(workingStateManager.isVNFStable("309")).thenReturn(true); + RequestHandlerInput input = this.getRequestHandlerInput("301", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + + RequestHandlerInput input1 = this.getRequestHandlerInput("309", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,new Date()); + Exception ex =null; + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + RuntimeContext runtimeContext1 = putInputToRuntimeContext(input1); + + try { + requestValidator.validateRequest(runtimeContext); + }catch(Exception e ) { + ex = e; + } + assertNull(ex); + + try { + requestValidator.validateRequest(runtimeContext1); + }catch(Exception e ) { + ex = e; + } + assertNotNull(ex); + } + + @Test + public void testLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Lock); + } + + @Test + public void testUnlockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Unlock); + } + + @Test + public void testCheckLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.CheckLock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Lock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Lock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testUnlockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.Unlock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.Unlock); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testCheckLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + Mockito.when(lifecyclemanager.getNextState(anyString(), anyString(), eq(VNFOperation.CheckLock.toString()))).thenThrow(new NoTransitionDefinedException("", "", "")); + Mockito.when(workingStateManager.isVNFStable("no-matter")).thenReturn(true); + testOperation("no-matter", VNFOperation.CheckLock); + } + + private void testOperation(String resource, VNFOperation operation) throws WorkflowNotFoundException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, InvalidInputException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, RequestExpiredException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + RequestHandlerInput input = this.getRequestHandlerInput(resource, operation, 0, false, originatorID, requestID, subRequestID, new Date()); + RuntimeContext runtimeContext = putInputToRuntimeContext(input); + requestValidator.validateRequest(runtimeContext); + } + + + private RuntimeContext createRuntimeContextWithSubObjects() { + RuntimeContext runtimeContext = new RuntimeContext(); + RequestContext requestContext = new RequestContext(); + runtimeContext.setRequestContext(requestContext); + ResponseContext responseContext = createResponseContextWithSuObjects(); + runtimeContext.setResponseContext(responseContext); + CommonHeader commonHeader = new CommonHeader(); + requestContext.setCommonHeader(commonHeader); + Flags flags = new Flags(); + commonHeader.setFlags(flags); + ActionIdentifiers actionIdentifiers = new ActionIdentifiers(); + requestContext.setActionIdentifiers(actionIdentifiers); + VNFContext vnfContext = new VNFContext(); + runtimeContext.setVnfContext(vnfContext); + return runtimeContext; + + } + + private ResponseContext createResponseContextWithSuObjects(){ + ResponseContext responseContext = new ResponseContext(); + CommonHeader commonHeader = new CommonHeader(); + Flags flags = new Flags(); + Status status = new Status(); + responseContext.setCommonHeader(commonHeader); + responseContext.setStatus(status); + commonHeader.setFlags(flags); + return responseContext; + } + + private String convertActionNameToUrl(String action) { + String regex = "([a-z])([A-Z]+)"; + String replacement = "$1-$2"; + return action.replaceAll(regex, replacement) + .toLowerCase(); + } + + private RuntimeContext putInputToRuntimeContext(RequestHandlerInput input) { + RuntimeContext runtimeContext = createRuntimeContextWithSubObjects(); + runtimeContext.setRequestContext(input.getRequestContext()); + runtimeContext.setRpcName(input.getRpcName()); + runtimeContext.getVnfContext().setId(input.getRequestContext().getActionIdentifiers().getVnfId()); + //runtimeContext.getRequestContext().getActionIdentifiers().setVnfId(input.getRequestContext().getActionIdentifiers().getVnfId()); + return runtimeContext; + + //String vnfID, VNFOperation action, int ttl, boolean force, String originatorId, String requestId, String subRequestId, Date timeStamp + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java new file mode 100644 index 000000000..33028465b --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/workingstatemanager/TestWorkingStateManager.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * openECOMP : APP-C + * ================================================================================ + * Copyright (C) 2017 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.openecomp.appc.workingstatemanager; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.dao.util.AppcJdbcConnectionFactory; +import org.openecomp.appc.workingstatemanager.impl.WorkingStateManagerImpl; +import org.openecomp.appc.workingstatemanager.objects.VNFWorkingState; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.UUID; + + + +public class TestWorkingStateManager { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestWorkingStateManager.class); + WorkingStateManagerImpl workingStateManager; + + @Before + public void init() throws Exception { + workingStateManager = new WorkingStateManagerImpl(); + AppcJdbcConnectionFactory appcJdbcConnectionFactory = new AppcJdbcConnectionFactory(); + String schema = "sdnctl"; + appcJdbcConnectionFactory.setSchema(schema); + workingStateManager.setConnectionFactory(appcJdbcConnectionFactory); + String property = ConfigurationFactory.getConfiguration().getProperty(String.format("org.openecomp.appc.db.url.%s", schema)); + logger.info(property+" will be used as connection URL to mySQL."); + logger.warn("you can set connection URL to other IP by adding -DmysqlIp=<MYSQL_IP> in VM Option"); +// System.getProperties().getProperty("mys") + } + + @Test + // this test run on mysql you need to uncomment Ignore and to add -DmysqlIp=<MYSQL_IP> in VM Option, to make that test pass successfully. + @Ignore + public void testUpdateWorkingState() { + String vnfId = UUID.randomUUID().toString(); + String myOwnerId = "myOwnerId"; + String otherOwnerId = "otherOwnerId"; + boolean vnfStable = workingStateManager.isVNFStable(vnfId); + logger.info("isVNFStable returns "+vnfStable+" for vnfId "+vnfId); + + //set to unstable with force true + boolean updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + + //negative test - try to set to any value by other ownerId when vnf state is UNSTABLE + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, otherOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, otherOwnerId, false); + Assert.assertFalse(updated); + + //positive test - set with same ownerId and force false + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false); + Assert.assertTrue(updated); + Assert.assertTrue(workingStateManager.isVNFStable(vnfId)); + + //positive test - set with otherOwnerId and force false when VNF is stable + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, otherOwnerId, false); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + + //negative test - try to set to any value by myOwnerId when vnf state is UNKNOWN + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNKNOWN, myOwnerId, false); + Assert.assertFalse(updated); + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.STABLE, myOwnerId, false); + Assert.assertFalse(updated); + + //positive test - try to set to any value by myOwnerId when vnf state is UNKNOWN but with force + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, myOwnerId, true); + Assert.assertTrue(updated); + Assert.assertFalse(workingStateManager.isVNFStable(vnfId)); + } + + +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..2d75df419 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,107 @@ +### +# ============LICENSE_START======================================================= +# openECOMP : APP-C +# ================================================================================ +# Copyright (C) 2017 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========================================================= +### + +# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded to supply configuration options +#org.openecomp.appc.bootstrap.file=executor-test.properties +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. + +# +# Certificate keystore and truststore +# +#org.openecomp.sdnc.sli.aai.ssl.trust=<jks_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.trust.psswd=adminadmin +#org.openecomp.sdnc.sli.aai.ssl.key=<p12_FILE_HERE> +#org.openecomp.sdnc.sli.aai.ssl.key.psswd=adminadmin +org.openecomp.sdnc.sli.aai.host.certificate.ignore=true +org.openecomp.sdnc.sli.aai.certificate.trust.all=true + +# +# Configuration file for A&AI Adapter +# + +# OPEN SOURCE - EXTERNAL A&AI INSTANCE IN TEST ENVIRONMENT +org.openecomp.sdnc.sli.aai.uri=https://10.0.1.1:8443 + +org.openecomp.sdnc.sli.aai.path.query=/aai/v8/search/sdn-zone-query + +# service instance +org.openecomp.sdnc.sli.aai.path.svcinst=/aai/v8/business/customers/customer/{customer-id}/service-subscriptions/service-subscription/{service-type}/service-instances +org.openecomp.sdnc.sli.aai.path.svcinst.query=/aai/v8/search/generic-query?key=service-instance.service-instance-id:{svc-instance-id}&start-node-type=service-instance&include=service-instance + +# complex +org.openecomp.sdnc.sli.aai.path.complexes=/aai/v8/cloud-infrastructure/complexes +org.openecomp.sdnc.sli.aai.path.complex=/aai/v8/cloud-infrastructure/complexes/complex/{physical-location-id} + +# vservers +org.openecomp.sdnc.sli.aai.path.vservers=/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers +org.openecomp.sdnc.sli.aai.path.vserver =/aai/v8/cloud-infrastructure/tenants/tenant/{tenant-id}/vservers/vserver/{vserver-id} + +# generic-vnf +org.openecomp.sdnc.sli.aai.path.generic.vnfs=/aai/v8/network/generic-vnfs/generic-vnf/ +org.openecomp.sdnc.sli.aai.path.generic.vnf=/aai/v8/network/generic-vnfs/generic-vnf/{vnf-id} + +# +# Formatting +# +org.openecomp.sdnc.sli.aai.param.format=filter=%s:%s +org.openecomp.sdnc.sli.aai.param.vnf_type=vnf-type +org.openecomp.sdnc.sli.aai.param.physical.location.id=physical-location-id +org.openecomp.sdnc.sli.aai.param.service.type=service-type + + +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + +org.openecomp.appc.db.url.%s", schema), ""); +org.openecomp.appc.db.user.%s", schema), ""); +org.openecomp.appc.db.pass.%s", schema), ""); + + +#Property below provided by appc.properties +#dmaap.poolMembers=<DMAAP_IP>:3904 + +dmaap.topic.read=APPC-TEST2 +dmaap.topic.write=APPC-TEST2 +#dmaap.topic.read.filter={"class":"Assigned","field":"request"} +dmaap.topic.read.filter={"class": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} +dmaap.client.name=APPC-TEST-CLIENT-REQ-HDLR-TEST +dmaap.client.name.id=0 +#dmaap.client.key=random +#dmaap.client.secret=random + +dmaap.threads.queuesize.min=1 +dmaap.threads.queuesize.max=1000 +dmaap.threads.poolsize.min=1 +dmaap.threads.poolsize.max=2 + +# +# This needs to be changed so that the action can be appended to the end of the URL path +# +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider:topology-service +#provider.urls.topology=https://admin:password@<IP_ADDRESS>:8443/restconf/operations/appc-provider: + +mysqlIp=127.0.0.1 +org.openecomp.appc.db.url.sdnctl=jdbc:mysql://${mysqlIp}:3306/test +org.openecomp.appc.db.user.sdnctl=test +org.openecomp.appc.db.pass.sdnctl=123456 + +org.openecomp.appc.workingstatemanager.maxAttempts=2 diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore b/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-features/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml new file mode 100644 index 000000000..453a8e62f --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-features/pom.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <artifactId>appc-request-handler</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.0.0</version> + </parent> + <name>appc-request-handler-features</name> + <artifactId>appc-request-handler-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-core</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <filtering>true</filtering> + <directory>src/main/resources</directory> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>filter</id> + <goals> + <goal>resources</goal> + </goals> + <phase>generate-resources</phase> + </execution> + </executions> + </plugin> + <!--<plugin> + <!– launches the feature test, which validates that your karaf feature + can be installed inside of a karaf container. It doesn't validate that your + functionality works correctly, just that you have all of the dependent bundles + defined correctly. –> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.16</version> + <configuration> + <systemPropertyVariables> + <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId> + <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId> + <karaf.distro.version>${odl.karaf.empty.distro.version}</karaf.distro.version> + </systemPropertyVariables> + <dependenciesToScan> + <dependency>org.opendaylight.yangtools:features-test</dependency> + </dependenciesToScan> + <classpathDependencyExcludes> + <!– The dependencies which bring in AbstractDataBrokerTest class + brings in a second PaxExam container which results in the feature tests failing + with a message similar to: "ERROR o.ops4j.pax.exam.spi.PaxExamRuntime - Ambiguous + TestContainer ..." This excludes the container we don't want to use. –> + <classpathDependencyExcludes>org.ops4j.pax.exam:pax-exam-container-native</classpathDependencyExcludes> + </classpathDependencyExcludes> + </configuration> + </plugin>--> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>attach-artifacts</id> + <goals> + <goal>attach-artifact</goal> + </goals> + <phase>package</phase> + <configuration> + <artifacts> + <artifact> + <file>${project.build.directory}/classes/${features.file}</file> + <type>xml</type> + <classifier>features</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + + <!-- Skipping ODL feature test --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml b/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml new file mode 100644 index 000000000..cc8fe1192 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-features/src/main/resources/features.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : APP-C + ================================================================================ + Copyright (C) 2017 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========================================================= + --> + + +<features name="appc-request-handler-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + + <feature name='appc-request-handler' description="appc-request-handler" version='${project.version}'> + <bundle>mvn:org.openecomp.appc/transaction-recorder/${project.version}</bundle> + <bundle dependency="true">mvn:org.openecomp.appc/domain-model-lib/${project.version}</bundle> + <bundle start-level="75" start="true">mvn:org.openecomp.appc/appc-command-executor-api/${project.version}</bundle> + <bundle start-level="80" start="true">mvn:org.openecomp.appc/appc-request-handler-api/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-request-handler-core/${project.version}</bundle> + </feature> + +</features> diff --git a/appc-dispatcher/appc-request-handler/pom.xml b/appc-dispatcher/appc-request-handler/pom.xml new file mode 100644 index 000000000..9f06a54dd --- /dev/null +++ b/appc-dispatcher/appc-request-handler/pom.xml @@ -0,0 +1,22 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dispatcher</artifactId> + <version>1.0.0</version> + </parent> + <artifactId>appc-request-handler</artifactId> + <packaging>pom</packaging> + <name>APPC Request Handler</name> + <description>APPC Request Handler</description> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-request-handler-api</module> + <module>appc-request-handler-core</module> + <module>appc-request-handler-features</module> + </modules> + +</project>
\ No newline at end of file |