diff options
412 files changed, 25642 insertions, 7355 deletions
diff --git a/.gitignore b/.gitignore index 4b6cd2584..954077ca1 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ # Generated models and features **/bin/* +# Checkstyle files +**/.checkstyle + # MANIFEST.MF is updated on every clean install **/src/main/resources/META-INF/ diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml index 1ef168a24..2ccf432f5 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/pom.xml @@ -12,6 +12,11 @@ <name>chef Adapter - bundle</name> <dependencies> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + <version>20160810</version> + </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> @@ -29,33 +34,33 @@ <version>4.4.4</version> </dependency> - <dependency> + <!-- <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.1</version> - </dependency> + </dependency> --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> - <version>1.47</version> + <version>1.55</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> - <version>1.47</version> + <version>1.55</version> </dependency> <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> - <classifier>jar-with-dependencies</classifier> - <scope>compile</scope> +<!-- <classifier>jar-with-dependencies</classifier> --> + <scope>test</scope> </dependency> <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> - <scope>test</scope> + </dependency> <dependency> <groupId>javax</groupId> @@ -216,11 +221,11 @@ <Bundle-Activator>org.openecomp.appc.adapter.chef.ChefActivator</Bundle-Activator> <Export-Package>org.openecomp.appc.adapter.chef</Export-Package> <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*</Import-Package> - <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|!appc-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> - <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> </configuration> </plugin> </plugins> diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java index 907ded5d2..7859d6bbc 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/ChefAdapter.java @@ -199,5 +199,19 @@ public interface ChefAdapter extends SvcLogicJavaPlugin { void chefGet(Map<String, String> params, SvcLogicContext ctx) ; void chefPut(Map<String, String> params, SvcLogicContext ctx) ; + +void chefPost(Map<String, String> params, SvcLogicContext ctx) ; + + void chefDelete(Map<String, String> params, SvcLogicContext ctx) ; + + void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) ; + + void checkPushJob(Map<String, String> params, SvcLogicContext ctx) ; + + void pushJob(Map<String, String> params, SvcLogicContext ctx) ; + + void retrieveData (Map<String, String> params, SvcLogicContext ctx) ; + + void combineStrings (Map<String, String> params, SvcLogicContext ctx) ; } diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Delete.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Delete.java new file mode 100644 index 000000000..410f00a94 --- /dev/null +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Delete.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.adapter.chef.chefapi; + +import org.apache.http.client.methods.HttpDelete; + +public class Delete extends ApiMethod{ + + public Delete(HttpDelete method) { + super("DELETE"); + this.method = method; + } + +} diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Post.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Post.java new file mode 100644 index 000000000..7dc8baa40 --- /dev/null +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefapi/Post.java @@ -0,0 +1,43 @@ +/*- + * ============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.adapter.chef.chefapi; + +import org.apache.http.client.methods.*; +import org.apache.http.entity.StringEntity; + +public class Post extends ApiMethod{ + + public Post(HttpRequestBase method) { + super("POST"); + this.method = method; + } + + public ApiMethod body(String body){ + this.reqBody = body; + StringEntity params =new StringEntity (body,"UTF-8"); + params.setContentType("application/json"); + HttpPost post = (HttpPost) method; + post.setEntity(params); + return this; + } + +} diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java index 743fe8456..ca36aa4b6 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/ChefApiClient.java @@ -67,4 +67,28 @@ public class ChefApiClient { put.setChefPath(path); return put; } + public Post post(String path){ + Post post = new Post(new HttpPost(endpoint+path)); + post.setPemPath(pemPath); + post.setUserId(userId); + post.setOrganizations(organizations); + post.setChefPath(path); + return post; + } + + public Delete delete(String path){ + Delete del = new Delete(new HttpDelete(endpoint+path)); + del.setPemPath(pemPath); + del.setUserId(userId); + del.setOrganizations(organizations); + del.setChefPath(path); + return del; + } + + +/* public Header[] buildHeaders(){ + + return null; + } +*/ } diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java index d814762f8..cb479fc2e 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/chefclient/Utils.java @@ -35,8 +35,10 @@ import java.security.Signature; import java.security.SignatureException; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMReader; +import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.PEMKeyPair; public class Utils { private Utils(){} @@ -66,7 +68,10 @@ public class Utils { Security.addProvider(new BouncyCastleProvider()); try { - KeyPair kp = (KeyPair) new PEMReader(br).readObject(); + PEMParser pemParser = new PEMParser(br); + JcaPEMKeyConverter converter = new JcaPEMKeyConverter(); + Object object = pemParser.readObject(); + KeyPair kp = converter.getKeyPair((PEMKeyPair) object);; PrivateKey privateKey = kp.getPrivate(); Signature instance = Signature.getInstance("RSA"); instance.initSign(privateKey); diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java index 5985bcfd1..01e256d08 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/ChefAdapterImpl.java @@ -78,6 +78,23 @@ import static com.att.eelf.configuration.Configuration.*; import java.io.IOException; import java.net.InetAddress; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Properties; +//chef +import org.openecomp.appc.adapter.chef.chefapi.*; +import org.openecomp.appc.adapter.chef.chefclient.*; + +//json +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; /** * This class implements the {@link ChefAdapter} interface. This interface * defines the behaviors that our service provides. @@ -279,6 +296,94 @@ public class ChefAdapterImpl implements ChefAdapter { * org.openecomp.sdnc.sli.SvcLogicContext) */ + + /** + * build node object + */ + + @SuppressWarnings("nls") + @Override + public void nodeObejctBuilder(Map<String, String> params, SvcLogicContext ctx) { + logger.info("nodeObejctBuilder"); + String name = params.get("org.openecomp.appc.instance.nodeobject.name"); + String normal = params.get("org.openecomp.appc.instance.nodeobject.normal"); + String overrides = params.get("org.openecomp.appc.instance.nodeobject.overrides"); + String defaults = params.get("org.openecomp.appc.instance.nodeobject.defaults"); + String run_list = params.get("org.openecomp.appc.instance.nodeobject.run_list"); + String chef_environment = params.get("org.openecomp.appc.instance.nodeobject.chef_environment"); + String nodeObject = "{\"json_class\":\"Chef::Node\",\"default\":{" + defaults + + "},\"chef_type\":\"node\",\"run_list\":[" + run_list + "],\"override\":{" + overrides + + "},\"normal\": {" + normal + "},\"automatic\":{},\"name\":\"" + name + "\",\"chef_environment\":\"" + + chef_environment + "\"}"; + logger.info(nodeObject); + + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setAttribute("org.openecomp.appc.chef.nodeObject", nodeObject); + + } + + /** + * Send get request to chef server + */ + + public void chefInfo(Map<String, String> params) { + clientName = params.get("org.openecomp.appc.instance.username"); + serverAddress = params.get("org.openecomp.appc.instance.serverAddress"); + organizations = params.get("org.openecomp.appc.instance.organizations"); + chefserver = "https://" + serverAddress + "/organizations/" + organizations; + clientPrivatekey = "/opt/openecomp/appc/chef/" + serverAddress + "/" + organizations + "/" + clientName + ".pem"; + } + + public Boolean privateKeyCheck() { + File f = new File(clientPrivatekey); + if (f.exists()) { + return true; + } else { + return false; + } + } + + @SuppressWarnings("nls") + @Override + public void retrieveData(Map<String, String> params, SvcLogicContext ctx) { + String contextData = "someValue"; + String allConfigData = params.get("org.openecomp.appc.instance.allConfig"); + String key = params.get("org.openecomp.appc.instance.key"); + String dgContext = params.get("org.openecomp.appc.instance.dgContext"); + JSONObject josnConfig = new JSONObject(allConfigData); + try { + contextData = josnConfig.getString(key); + } catch (Exception ex) { + try { + contextData = josnConfig.getJSONObject(key).toString(); + } catch (Exception exc) { + contextData = josnConfig.getJSONArray(key).toString(); + } + } + + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setAttribute(dgContext, contextData); + } + + @SuppressWarnings("nls") + @Override + public void combineStrings(Map<String, String> params, SvcLogicContext ctx) { + + String String1 = params.get("org.openecomp.appc.instance.String1"); + String String2 = params.get("org.openecomp.appc.instance.String2"); + String dgContext = params.get("org.openecomp.appc.instance.dgContext"); + String contextData = String1 + String2; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setAttribute(dgContext, contextData); + } + + /** * Send GET request to chef server */ @@ -287,19 +392,25 @@ public class ChefAdapterImpl implements ChefAdapter { @Override public void chefGet(Map<String, String> params, SvcLogicContext ctx) { logger.info("chef get method"); - String chefAction= params.get("org.openecomp.appc.instance.chefAction"); + chefInfo(params); + String chefAction = params.get("org.openecomp.appc.instance.chefAction"); RequestContext rc = new RequestContext(ctx); rc.isAlive(); - //should load pem from somewhere else - ChefApiClient cac = new ChefApiClient(clientName,clientPrivatekey,chefserver,organizations); - // need pass path into it - //"/nodes" - ApiMethod am = cac.get(chefAction); - am.execute(); - int code = am.getReturnCode(); - String message = am.getResponseBodyAsString(); - logger.info(code + " " + message); - chefServerResult(rc,Integer.toString(code),message); + int code; + String message = null; + if (privateKeyCheck()) { + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + ApiMethod am = cac.get(chefAction); + am.execute(); + code = am.getReturnCode(); + message = am.getResponseBodyAsString(); + } else { + code = 500; + message = "Cannot find the private key in the APPC file system, please load the private key to " + + clientPrivatekey; + } + chefServerResult(rc, Integer.toString(code), message); + } /** @@ -309,29 +420,93 @@ public class ChefAdapterImpl implements ChefAdapter { @SuppressWarnings("nls") @Override public void chefPut(Map<String, String> params, SvcLogicContext ctx) { - - logger.info("chef PUT method"); - logger.info(clientName+" "+clientPrivatekey+" "+chefserver+" "+organizations); - String chefAction= params.get("org.openecomp.appc.instance.chefAction"); - String runList= params.get("org.openecomp.appc.instance.runList"); - String attributes= params.get("org.openecomp.appc.instance.attributes"); - logger.info(attributes); - String CHEF_NODE_STR = "{\"json_class\":\"Chef::Node\",\"default\":{},\"chef_type\":\"node\",\"run_list\":[\""+runList+"\"],\"override\":{},\"automatic\":{},\"normal\":{"+attributes+"},\"name\":\"testnode\",\"chef_environment\":\"_default\"}"; + chefInfo(params); + String chefAction = params.get("org.openecomp.appc.instance.chefAction"); + String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody"); RequestContext rc = new RequestContext(ctx); rc.isAlive(); - //should load pem from somewhere else - ChefApiClient cac = new ChefApiClient(clientName,clientPrivatekey,chefserver,organizations); - - // need pass path into it - //"/nodes/testnode" - ApiMethod am = cac.put(chefAction).body(CHEF_NODE_STR); - am.execute(); - int code = am.getReturnCode(); - String message = am.getResponseBodyAsString(); + int code; + String message = null; + if (privateKeyCheck()) { + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + + ApiMethod am = cac.put(chefAction).body(CHEF_NODE_STR); + am.execute(); + code = am.getReturnCode(); + message = am.getResponseBodyAsString(); + } else { + code = 500; + message = "Cannot find the private key in the APPC file system, please load the private key to " + + clientPrivatekey; + } logger.info(code + " " + message); - chefServerResult(rc,Integer.toString(code),message); + chefServerResult(rc, Integer.toString(code), message); + } + /** + * Send Post request to chef server + */ + + @SuppressWarnings("nls") + @Override + public void chefPost(Map<String, String> params, SvcLogicContext ctx) { + chefInfo(params); + logger.info("chef Post method"); + logger.info(clientName + " " + clientPrivatekey + " " + chefserver + " " + organizations); + String CHEF_NODE_STR = params.get("org.openecomp.appc.instance.chefRequestBody"); + String chefAction = params.get("org.openecomp.appc.instance.chefAction"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + int code; + String message = null; + // should load pem from somewhere else + if (privateKeyCheck()) { + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + + // need pass path into it + // "/nodes/testnode" + ApiMethod am = cac.post(chefAction).body(CHEF_NODE_STR); + am.execute(); + code = am.getReturnCode(); + message = am.getResponseBodyAsString(); + } else { + code = 500; + message = "Cannot find the private key in the APPC file system, please load the private key to " + + clientPrivatekey; + } + logger.info(code + " " + message); + chefServerResult(rc, Integer.toString(code), message); + } + + /** + * Send delete request to chef server + */ + + @SuppressWarnings("nls") + @Override + public void chefDelete(Map<String, String> params, SvcLogicContext ctx) { + logger.info("chef delete method"); + chefInfo(params); + String chefAction = params.get("org.openecomp.appc.instance.chefAction"); + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + int code; + String message = null; + if (privateKeyCheck()) { + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + ApiMethod am = cac.delete(chefAction); + am.execute(); + code = am.getReturnCode(); + message = am.getResponseBodyAsString(); + } else { + code = 500; + message = "Cannot find the private key in the APPC file system, please load the private key to " + + clientPrivatekey; + } + logger.info(code + " " + message); + chefServerResult(rc, Integer.toString(code), message); + } /** @@ -362,6 +537,78 @@ public class ChefAdapterImpl implements ChefAdapter { } + @SuppressWarnings("nls") + @Override + public void checkPushJob(Map<String, String> params, SvcLogicContext ctx) { + chefInfo(params); + String jobID = params.get("org.openecomp.appc.instance.jobid"); + int retryTimes = Integer.parseInt(params.get("org.openecomp.appc.instance.retryTimes")); + int retryInterval = Integer.parseInt(params.get("org.openecomp.appc.instance.retryInterval")); + String chefAction = "/pushy/jobs/" + jobID; + + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String message = ""; + String status = ""; + for (int i = 0; i < retryTimes; i++) { + try { + Thread.sleep(retryInterval); // 1000 milliseconds is one second. + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + ApiMethod am = cac.get(chefAction); + am.execute(); + int code = am.getReturnCode(); + message = am.getResponseBodyAsString(); + JSONObject obj = new JSONObject(message); + status = obj.getString("status"); + if (!status.equals("running")) { + logger.info(i + " time " + code + " " + status); + break; + } + + } + if (status.equals("complete")) { + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "200"); + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message); + } else { + if (status.equals("running")) { + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "202"); + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", "chef client runtime out"); + } else { + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.code", "500"); + svcLogic.setAttribute("org.openecomp.appc.chefServerResult.message", message); + } + } + } + + + @SuppressWarnings("nls") + @Override + public void pushJob(Map<String, String> params, SvcLogicContext ctx) { + chefInfo(params); + String pushRequest = params.get("org.openecomp.appc.instance.pushRequest"); + String chefAction = "/pushy/jobs"; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + ChefApiClient cac = new ChefApiClient(clientName, clientPrivatekey, chefserver, organizations); + ApiMethod am = cac.post(chefAction).body(pushRequest); + ; + am.execute(); + int code = am.getReturnCode(); + String message = am.getResponseBodyAsString(); + if (code == 201) { + int startIndex = message.indexOf("jobs") + 6; + int endIndex = message.length() - 2; + String jobID = message.substring(startIndex, endIndex); + svcLogic.setAttribute("org.openecomp.appc.jobID", jobID); + logger.info(jobID); + } + chefServerResult(rc, Integer.toString(code), message); + } @SuppressWarnings("static-method") diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml index 85b7941d8..8235f2b03 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml +++ b/appc-adapters/appc-chef-adapter/appc-chef-adapter-features/src/main/resources/features.xml @@ -31,6 +31,7 @@ <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> <feature>sdnc-sli</feature> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-chef-adapter-bundle/${project.version}</bundle> </feature> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml index 44ca150d1..449ce92d2 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/pom.xml @@ -14,13 +14,17 @@ <dependencies> <dependency> <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> <artifactId>appc-metric-bundle</artifactId> - <version>1.1.0-SNAPSHOT</version> + <version>${project.version}</version> </dependency> <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> - <classifier>jar-with-dependencies</classifier> <version>${project.version}</version> </dependency> @@ -65,7 +69,6 @@ <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> - <version>1.6.2</version> <scope>test</scope> </dependency> <dependency> @@ -85,10 +88,17 @@ <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> - <version>1.6.2</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> <dependency> <groupId>org.openecomp.sdnc.core</groupId> <artifactId>sli-common</artifactId> @@ -119,6 +129,14 @@ </exclusions> </dependency> + <!-- DMaaP Client --> + <dependency> + <groupId>com.att.nsa</groupId> + <artifactId>dmaapClient</artifactId> + <version>0.2.12</version> +<!-- <version>${dmaap.client.version}</version> --> + </dependency> + <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> @@ -129,8 +147,6 @@ </dependency> </dependencies> - - <build> <plugins> <plugin> @@ -139,12 +155,13 @@ <extensions>true</extensions> <configuration> <instructions> - <Bundle-SymbolicName>org.openecomp.appc.adapter.dmaap</Bundle-SymbolicName> - <Bundle-Activator>org.openecomp.appc.adapter.dmaap.AppcDmaapAdapterActivator</Bundle-Activator> - <Export-Package>org.openecomp.appc.adapter.dmaap.*</Export-Package> - <Export-Serice>org.openecomp.appc.adapter.dmaap.EventSender</Export-Serice> - <Import-Package>org.openecomp.appc.metricservice.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,!org.osgi.service.event.*,org.osgi.service.*,org.osgi.util.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.*,javax.naming.*,javax.crypto.*, com.sun.jersey.spi.container.servlet,org.eclipse.jetty.servlets</Import-Package> - <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <!--<Bundle-SymbolicName>org.openecomp.appc.adapter.messaging.dmaap</Bundle-SymbolicName>--> + <Bundle-Activator>org.openecomp.appc.adapter.messaging.dmaap.AppcDmaapAdapterActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.messaging.*</Export-Package> + <Import-Package>!org.slf4j.event,org.openecomp.appc.adapter.message.*,org.openecomp.appc.metricservice.*,com.att.nsa.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,!org.osgi.service.event.*,org.osgi.service.*,org.osgi.util.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.*,javax.naming.*,javax.crypto.*, com.sun.jersey.spi.container.servlet,org.eclipse.jetty.servlets</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|appc-message-adapter-api|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Bundle-Blueprint>OSGI-INF/blueprint/blueprint.xml</Bundle-Blueprint> </instructions> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/AppcDmaapAdapterActivator.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/AppcDmaapAdapterActivator.java index c02553dfe..c7be330cf 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/AppcDmaapAdapterActivator.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/AppcDmaapAdapterActivator.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.messaging.dmaap; import org.openecomp.appc.configuration.ConfigurationFactory; import com.att.eelf.configuration.EELFLogger; diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CommonHttpClient.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/CommonHttpClient.java index 654ec6f7f..0d0450681 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CommonHttpClient.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/CommonHttpClient.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.messaging.dmaap.http; import java.net.URI; diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapConsumer.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/HttpDmaapConsumerImpl.java index 6e16d896b..2145eaa70 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapConsumer.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/HttpDmaapConsumerImpl.java @@ -19,14 +19,13 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.messaging.dmaap.http; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; - import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; @@ -38,10 +37,11 @@ import org.apache.http.client.utils.URIBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.json.JSONArray; +import org.openecomp.appc.adapter.message.Consumer; -public class DmaapConsumer extends CommonHttpClient implements Consumer { +public class HttpDmaapConsumerImpl extends CommonHttpClient implements Consumer { - private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapConsumer.class); + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(HttpDmaapConsumerImpl.class); // Default values private static final int DEFAULT_TIMEOUT_MS = 15000; @@ -54,17 +54,17 @@ public class DmaapConsumer extends CommonHttpClient implements Consumer { private boolean useHttps = false; - public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId) { + public HttpDmaapConsumerImpl(Collection<String> hosts, String topicName, String consumerName, String consumerId) { this(hosts, topicName, consumerName, consumerId, null); } - public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId, - String filter) { + public HttpDmaapConsumerImpl(Collection<String> hosts, String topicName, String consumerName, String consumerId, + String filter) { this(hosts, topicName, consumerName, consumerId, filter, null, null); } - public DmaapConsumer(Collection<String> hosts, String topicName, String consumerName, String consumerId, - String filter, String user, String password) { + public HttpDmaapConsumerImpl(Collection<String> hosts, String topicName, String consumerName, String consumerId, + String filter, String user, String password) { urls = new ArrayList<String>(); for (String host : hosts) { urls.add(String.format(URL_TEMPLATE, formatHostString(host), topicName, consumerName, consumerId)); @@ -155,9 +155,10 @@ public class DmaapConsumer extends CommonHttpClient implements Consumer { LOG.error("Interrupted while sleeping"); } } - - public void close(){ - //not used yet - } + + @Override + public void close() { + // Nothing to do + } } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapProducer.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/HttpDmaapProducerImpl.java index 6845177b1..85e446dca 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapProducer.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/http/HttpDmaapProducerImpl.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.messaging.dmaap.http; import java.net.URI; import java.util.ArrayList; @@ -34,10 +34,11 @@ import com.att.eelf.configuration.EELFManager; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; +import org.openecomp.appc.adapter.message.Producer; -public class DmaapProducer extends CommonHttpClient implements Producer { +public class HttpDmaapProducerImpl extends CommonHttpClient implements Producer { - private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapProducer.class); + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(HttpDmaapProducerImpl.class); private static final String CONTENT_TYPE = "application/cambria"; private static final String URL_TEMPLATE = "%s/events/%s"; @@ -47,7 +48,7 @@ public class DmaapProducer extends CommonHttpClient implements Producer { private boolean useHttps = false; - public DmaapProducer(Collection<String> urls, String topicName) { + public HttpDmaapProducerImpl(Collection<String> urls, String topicName) { hosts = new ArrayList<String>(); topics = new HashSet<String>(); topics.add(topicName); @@ -57,7 +58,7 @@ public class DmaapProducer extends CommonHttpClient implements Producer { } } - public DmaapProducer(Collection<String> urls, Set<String> topicNames) { + public HttpDmaapProducerImpl(Collection<String> urls, Set<String> topicNames) { hosts = new ArrayList<String>(); topics = topicNames; @@ -126,8 +127,9 @@ public class DmaapProducer extends CommonHttpClient implements Producer { String m = (msg == null) ? "" : msg; return String.format("%d.%d.%s%s", p.length(), m.length(), p, m); } - - public void close(){ - //not used yet - } + + @Override + public void close() { + // Nothing to do + } } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapConsumerImpl.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapConsumerImpl.java new file mode 100644 index 000000000..342d52448 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapConsumerImpl.java @@ -0,0 +1,231 @@ +/*- + * ============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.adapter.messaging.dmaap.impl; + +import java.io.IOException; +import java.util.*; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +//import com.att.nsa.cambria.client.CambriaClientBuilders; +//import com.att.nsa.cambria.client.CambriaClientBuilders.ConsumerBuilder; +//import com.att.nsa.cambria.client.CambriaConsumer; + +import com.att.nsa.mr.client.MRClientFactory; +import com.att.nsa.mr.client.MRConsumer; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.impl.MetricServiceImpl; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterMetric; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.publisher.LogPublisher; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +public class DmaapConsumerImpl implements Consumer { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapConsumerImpl.class); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + // Default values + private static final int DEFAULT_TIMEOUT_MS = 60000; + private static final int DEFAULT_LIMIT = 1000; + private static MetricRegistry metricRegistry; + private String topic; + private DmaapRequestCounterMetric dmaapKpiMetric; + private boolean isMetricEnabled=false; + private boolean useHttps = false; + private MRConsumer client = null; + private Properties props = null; + + + public DmaapConsumerImpl(Collection<String> urls, String topicName, String consumerGroupName, String consumerId,String user, String password) { + this(urls, topicName, consumerGroupName, consumerId,user, password,null); + + } + + public DmaapConsumerImpl(Collection<String> urls, String topicName, String consumerGroupName, String consumerId,String user, String password,String filter) { + this.topic = topicName; + this.props = new Properties(); + String urlsStr = StringUtils.join(urls, ','); + props.setProperty("host",urlsStr); + props.setProperty("group",consumerGroupName); + props.setProperty("id",consumerId); + props.setProperty("username",user); + props.setProperty("password",password); + if(filter != null) { + props.setProperty("filter", filter); + } + } + + + private void initMetric() { + LOG.debug("Metric getting initialized"); + MetricService metricService = getMetricservice(); + metricRegistry = metricService.createRegistry("APPC"); + dmaapKpiMetric = metricRegistry.metricBuilderFactory(). + dmaapRequestCounterBuilder(). + withName("DMAAP_KPI").withType(MetricType.COUNTER). + withRecievedMessage(0) + .withPublishedMessage(0) + .build(); + if (metricRegistry.register(dmaapKpiMetric)) { + Metric[] metrics = new Metric[]{dmaapKpiMetric}; + LogPublisher logPublisher = new LogPublisher(metricRegistry, metrics); + LogPublisher[] logPublishers = new LogPublisher[1]; + logPublishers[0] = logPublisher; + PublishingPolicy manuallyScheduledPublishingPolicy = metricRegistry.policyBuilderFactory(). + scheduledPolicyBuilder().withPublishers(logPublishers). + withMetrics(metrics). + build(); + LOG.debug("Policy getting initialized"); + manuallyScheduledPublishingPolicy.init(); + LOG.debug("Metric initialized"); + } + } + private MRConsumer getClient() { + return getClient(DEFAULT_TIMEOUT_MS, DEFAULT_LIMIT); + } + + /** + * @return An instance of MRConsumer created from our class variables + */ + private synchronized MRConsumer getClient(int waitMs, int limit) { + try { + props.setProperty("timeout",String.valueOf(waitMs)); + props.setProperty("limit",String.valueOf(limit)); + String topicProducerPropFileName = DmaapUtil.createConsumerPropFile(topic,props); + return MRClientFactory.createConsumer ( topicProducerPropFileName); + } catch (IOException e1) { + LOG.error("failed to createConsumer",e1); + return null; + } + } + + @Override + public synchronized void updateCredentials(String key, String secret) { + LOG.info(String.format("Setting auth to %s for %s", key, this.toString())); + String user = key; + String password = secret; + props.setProperty("user",String.valueOf(user)); + props.setProperty("password",String.valueOf(password)); + client = null; + } + + @Override + public List<String> fetch(int waitMs, int limit) { + Properties properties=configuration.getProperties(); + if(properties!=null && properties.getProperty("metric.enabled")!=null ){ + isMetricEnabled=Boolean.valueOf(properties.getProperty("metric.enabled")); + } + if(isMetricEnabled){ + initMetric(); + } + LOG.debug(String.format("Fetching up to %d records with %dms wait on %s", limit, waitMs, this.toString())); + List<String> out = new ArrayList<String>(); + + // Create client once and reuse it on subsequent fetches. This is + // to support failover to other servers in the DMaaP cluster. + if (client == null) { + LOG.info("Getting DMaaP Client ..."); + client = getClient(waitMs, limit); + } + try { + for (String s : client.fetch(waitMs, limit)) { + out.add(s); + if(isMetricEnabled){ + ((DmaapRequestCounterMetric)metricRegistry.metric("DMAAP_KPI")).incrementRecievedMessage(); + } + } + LOG.debug(String.format("Got %d records from %s", out.size(), this.toString())); + } catch (Exception e) { + // Connection exception + LOG.error(String.format("Dmaap Connection Issue Detected. %s", e.getMessage())); + e.printStackTrace(); + try { + LOG.warn(String.format("Sleeping for %dms to compensate for connection failure", waitMs)); + Thread.sleep(waitMs); + } catch (InterruptedException e2) { + LOG.warn(String.format("Failed to wait for %dms after bad fetch", waitMs)); + } + } + + + return out; + } + + /** + * Close consumer Dmaap client + */ + @Override + public void close() { + LOG.debug("Closing Dmaap consumer client...."); + if (client != null) { + client.close(); + } + } + + @Override + public List<String> fetch() { + return fetch(DEFAULT_TIMEOUT_MS, DEFAULT_LIMIT); + } + + @Override + public String toString() { + String hostStr = (props == null || props.getProperty("host") == null? "N/A" : props.getProperty("host")); + String group = (props == null || props.getProperty("group") == null? "N/A" : props.getProperty("group")); + String id = (props == null || props.getProperty("id") == null? "N/A" : props.getProperty("id")); + return String.format("Consumer %s/%s listening to %s on [%s]", group, id, topic, hostStr); + } + + @Override + public void useHttps(boolean yes) { + useHttps = yes; + } + + + private MetricService getMetricservice() { + BundleContext bctx = FrameworkUtil.getBundle(MetricService.class).getBundleContext(); + // Get AAIadapter reference + ServiceReference sref = bctx.getServiceReference(MetricService.class.getName()); + if (sref != null) { + LOG.info("Metric Service from bundlecontext"); + return (MetricServiceImpl) bctx.getService(sref); + + } else { + LOG.info("Metric Service error from bundlecontext"); + LOG.warn("Cannot find service reference for org.openecomp.appc.metricservice.MetricService"); + return null; + + } + } + + public Metric getMetric(String name){ + return metricRegistry.metric(name); + } +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapProducerImpl.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapProducerImpl.java new file mode 100644 index 000000000..79d6b3db7 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapProducerImpl.java @@ -0,0 +1,220 @@ +/*- + * ============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.adapter.messaging.dmaap.impl; + +import java.io.*; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +//import com.att.nsa.cambria.client.CambriaBatchingPublisher; +//import com.att.nsa.cambria.client.CambriaClientBuilders; +//import com.att.nsa.cambria.client.CambriaClientBuilders.PublisherBuilder; + +import com.att.nsa.mr.client.MRBatchingPublisher; +import com.att.nsa.mr.client.MRClientFactory; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapUtil; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.metricservice.metric.MetricType; +import org.openecomp.appc.metricservice.metric.DmaapRequestCounterMetric; +import org.openecomp.appc.metricservice.policy.PublishingPolicy; +import org.openecomp.appc.metricservice.publisher.LogPublisher; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +public class DmaapProducerImpl implements Producer { + + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(DmaapProducerImpl.class); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + private Set<String> topics = new HashSet<String>(); + + private Properties props = null; + private static MetricRegistry metricRegistry; + private boolean useHttps = false; + private DmaapRequestCounterMetric dmaapKpiMetric; + private boolean isMetricEnabled=false; + + private Set<MRBatchingPublisher> clients; + + + public DmaapProducerImpl(Collection<String> urls, String topicName, String user, String password) { + this(urls, (Set<String>)null, user, password); + this.topics = new HashSet<>(); + if (topicName != null) { + for (String topic : topicName.split(",")) { + topics.add(topic); + } + } + } + + public DmaapProducerImpl(Collection<String> urls, Set<String> topicNames, String user, String password) { + topics = topicNames; + if(urls == null || user == null || password == null){ + throw new IllegalArgumentException("one of these mandaory argument is null: urls, user, password" ); + } + this.props = new Properties(); + String urlsStr = StringUtils.join(urls, ','); + props.setProperty("host",urlsStr); + props.setProperty("id", UUID.randomUUID().toString()); + props.setProperty("username",user); + props.setProperty("password",password); + } + private void initMetric() { + LOG.debug("Metric getting initialized"); + MetricService metricService = getMetricservice(); + metricRegistry=metricService.createRegistry("APPC"); + dmaapKpiMetric = metricRegistry.metricBuilderFactory(). + dmaapRequestCounterBuilder(). + withName("DMAAP_KPI").withType(MetricType.COUNTER). + withRecievedMessage(0) + .withPublishedMessage(0) + .build(); + if(metricRegistry.register(dmaapKpiMetric)) { + Metric[] metrics = new Metric[]{dmaapKpiMetric}; + LogPublisher logPublisher = new LogPublisher(metricRegistry, metrics); + LogPublisher[] logPublishers = new LogPublisher[1]; + logPublishers[0] = logPublisher; + PublishingPolicy manuallyScheduledPublishingPolicy = metricRegistry.policyBuilderFactory(). + scheduledPolicyBuilder().withPublishers(logPublishers). + withMetrics(metrics). + build(); + LOG.debug("Policy getting initialized"); + manuallyScheduledPublishingPolicy.init(); + LOG.debug("Metric initialized"); + } + + } + private Set<MRBatchingPublisher> getClients() { + Set<MRBatchingPublisher> out = new HashSet<MRBatchingPublisher>(); + for (String topic : topics) { + try { + String topicProducerPropFileName = DmaapUtil.createProducerPropFile(topic,props); + final MRBatchingPublisher client = MRClientFactory.createBatchingPublisher (topicProducerPropFileName); + out.add(client); + } catch (Exception e) { + e.printStackTrace(); + } + } + + return out; + } + + @Override + public synchronized void updateCredentials(String key, String secret) { + LOG.info(String.format("Setting auth to %s for %s", key, this.toString())); + String user = key; + String password = secret; + props.setProperty("user",String.valueOf(user)); + props.setProperty("password",String.valueOf(password)); + clients = null; + } + + @Override + public boolean post(String partition, String data) { + boolean success = true; + Properties properties=configuration.getProperties(); + if(properties!=null && properties.getProperty("metric.enabled")!=null ){ + isMetricEnabled=Boolean.valueOf(properties.getProperty("metric.enabled")); + } + if(isMetricEnabled){ + initMetric(); + } + + // Create clients once and reuse them on subsequent posts. This is + // to support failover to other servers in the Dmaap cluster. + if ((clients == null) || (clients.isEmpty())) { + LOG.info("Getting CambriaBatchingPublisher Clients ..."); + clients = getClients(); + } + + for (MRBatchingPublisher client : clients) { + try { + LOG.debug(String.format("Posting %s to %s", data, client)); + client.send(partition, data); + } catch (IOException e) { + e.printStackTrace(); + success = false; + } + } + if(isMetricEnabled){ + ( (DmaapRequestCounterMetric) metricRegistry.metric("DMAAP_KPI")).incrementPublishedMessage(); + } + return success; + } + + /** + * Close producer Dmaap client + */ + @Override + public void close() { + if ((clients == null) || (clients.isEmpty())) { + return; + } + + LOG.debug("Closing Dmaap producer clients...."); + for (MRBatchingPublisher client : clients) { + try { + client.close(1, TimeUnit.SECONDS); + } catch (IOException | InterruptedException e) { + LOG.warn(String.format("Failed to cleanly close Dmaap connection for [%s]", client)); + e.printStackTrace(); + } + } + } + + @Override + public void useHttps(boolean yes) { + useHttps = yes; + } + + private MetricService getMetricservice() { +/* + return AppcDmaapAdapterActivator.getMetricService(); +*/ + + BundleContext bctx = FrameworkUtil.getBundle(MetricService.class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(MetricService.class.getName()); + if (sref != null) { + LOG.info("Metric Service from bundlecontext"); + return (MetricService) bctx.getService(sref); + + } else { + LOG.info("Metric Service error from bundlecontext"); + LOG.warn("Cannot find service reference for org.openecomp.appc.metricservice.MetricService"); + return null; + + } + } + + public Metric getMetric(String name){ + return metricRegistry.metric(name); + } +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapUtil.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapUtil.java new file mode 100644 index 000000000..39857b856 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/DmaapUtil.java @@ -0,0 +1,83 @@ +/*- + * ============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.adapter.messaging.dmaap.impl; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class DmaapUtil { + private final static String delimiter = "_"; + private static String createPreferredRouteFileIfNotExist(String topic) throws IOException { + String topicPreferredRouteFileName = null; + topicPreferredRouteFileName = topic+"preferredRoute.properties"; + File fo= new File(topicPreferredRouteFileName); + if(!fo.exists()) { + ClassLoader classLoader = DmaapUtil.class.getClassLoader(); + InputStream inputStream = classLoader.getResourceAsStream("preferredRoute.txt"); + Properties props = new Properties(); + props.load(inputStream); + String fileName = topic != null ? topic+delimiter+"MR1" : delimiter+"MR1"; + props.setProperty("preferredRouteKey", fileName); + topicPreferredRouteFileName = topic + "preferredRoute.properties"; + props.store(new FileOutputStream(topicPreferredRouteFileName), "preferredRoute.properties file created on the fly for topic:" + topic + " on:" + System.currentTimeMillis()); + } + return topicPreferredRouteFileName; + } + + public static String createConsumerPropFile(String topic, Properties props)throws IOException { + String defaultProfFileName = "consumer.properties"; + String topicConsumerPropFileName = createConsumerProducerPropFile(topic, defaultProfFileName,props); + return topicConsumerPropFileName; + } + + public static String createProducerPropFile(String topic, Properties props)throws IOException { + String defaultProfFileName = "producer.properties"; + String topicConsumerPropFileName = createConsumerProducerPropFile(topic, defaultProfFileName,props); + return topicConsumerPropFileName; + } + + private static String createConsumerProducerPropFile(String topic, String defaultProfFileName, Properties props) throws IOException { + ClassLoader classLoader = DmaapUtil.class.getClassLoader(); + InputStream inputStream = classLoader.getResourceAsStream(defaultProfFileName); + Properties defaultProps = new Properties(); + defaultProps.load(inputStream); + defaultProps.setProperty("topic",topic); + + String preferredRouteFileName = DmaapUtil.createPreferredRouteFileIfNotExist(topic); + if(props != null && !props.isEmpty()){ + defaultProps.putAll(props); + } + defaultProps.setProperty("topic",topic); + defaultProps.setProperty("DME2preferredRouterFilePath",preferredRouteFileName); + String id = defaultProps.getProperty("id"); + String topicConsumerPropFileName = defaultProfFileName; + topicConsumerPropFileName = id != null ? id+delimiter+topicConsumerPropFileName : delimiter+topicConsumerPropFileName; + topicConsumerPropFileName = topic != null ? topic+delimiter+topicConsumerPropFileName : delimiter+topicConsumerPropFileName; + + defaultProps.store(new FileOutputStream(topicConsumerPropFileName), defaultProfFileName+" file created on the fly for topic:"+topic+" on:"+System.currentTimeMillis()); + return topicConsumerPropFileName; + } + +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/impl/EventSenderImpl.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/EventSenderDmaapImpl.java index 0f7d40f5b..c671c6fdb 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/impl/EventSenderImpl.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/messaging/dmaap/impl/EventSenderDmaapImpl.java @@ -19,33 +19,33 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap.impl; +package org.openecomp.appc.adapter.messaging.dmaap.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import org.openecomp.appc.adapter.dmaap.EventSender; -import org.openecomp.appc.adapter.dmaap.Producer; -import org.openecomp.appc.adapter.dmaap.DmaapDestination; -import org.openecomp.appc.adapter.dmaap.event.EventHeader; -import org.openecomp.appc.adapter.dmaap.event.EventMessage; -import org.openecomp.appc.adapter.dmaap.event.EventStatus; -import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.adapter.message.EventSender; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.message.event.EventHeader; +import org.openecomp.appc.adapter.message.event.EventMessage; +import org.openecomp.appc.adapter.message.event.EventStatus; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapProducerImpl; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; import org.openecomp.appc.exceptions.APPCException; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import org.openecomp.sdnc.sli.SvcLogicContext; - -public class EventSenderImpl implements EventSender +public class EventSenderDmaapImpl implements EventSender { - private static final EELFLogger LOG = EELFManager.getInstance().getLogger(EventSenderImpl.class); - public static final String EVENT_TOPIC_WRITE = "event.topic.write"; - public static final String EVENT_CLIENT_KEY = "event.client.key"; - public static final String EVENT_CLIENT_SECRET = "event.client.secret"; - public static final String EVENT_POOL_MEMBERS = "event.pool.members"; + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(EventSenderDmaapImpl.class); + public static final String EVENT_TOPIC_WRITE = "dmaap.event.topic.write"; + public static final String DMAAP_USERNAME = "dmaap.appc.username"; + public static final String DMAAP_PASSWORD = "dmaap.appc.password"; + public static final String EVENT_POOL_MEMBERS = "dmaap.event.pool.members"; private static Configuration configuration = ConfigurationFactory.getConfiguration(); @@ -59,21 +59,21 @@ public class EventSenderImpl implements EventSender this.producerMap = producerMap; } - public EventSenderImpl(){ + public EventSenderDmaapImpl(){ } public void initialize(){ Properties properties = configuration.getProperties(); String writeTopic; - String apiKey; - String apiSecret; + String username; + String password; final List<String> pool = new ArrayList<>(); - for(DmaapDestination destination:DmaapDestination.values()){ + for(MessageDestination destination: MessageDestination.values()){ writeTopic = properties.getProperty(destination + "." + EVENT_TOPIC_WRITE); - apiKey = properties.getProperty(destination + "." + EVENT_CLIENT_KEY); - apiSecret = properties.getProperty(destination + "." + EVENT_CLIENT_SECRET); + username = properties.getProperty(destination + "." + DMAAP_USERNAME); + password = properties.getProperty(destination + "." + DMAAP_PASSWORD); String hostNames = properties.getProperty(destination + "." + EVENT_POOL_MEMBERS); if (hostNames != null && !hostNames.isEmpty()) { @@ -83,12 +83,8 @@ public class EventSenderImpl implements EventSender LOG.debug(String.format("pool = %s, taken from property: %s", pool, destination + "." + EVENT_POOL_MEMBERS)); LOG.debug(String.format("writeTopic = %s, taken from property: %s", writeTopic, destination + "." + EVENT_TOPIC_WRITE)); - LOG.debug(String.format("apiKey = %s, taken from property: %s", apiKey, destination + "." + EVENT_CLIENT_KEY)); - Producer producer = new DmaapProducer(pool, writeTopic); - - if (apiKey != null && apiSecret != null) { - producer.updateCredentials(apiKey, apiSecret); - } + LOG.debug(String.format("username = %s, taken from property: %s", username, destination + "." + DMAAP_USERNAME)); + Producer producer = new DmaapProducerImpl(pool, writeTopic,username, password); for (String url : pool) { if (url.contains("3905") || url.contains("https")) { @@ -103,7 +99,7 @@ public class EventSenderImpl implements EventSender } @Override - public boolean sendEvent(DmaapDestination destination,EventMessage msg) { + public boolean sendEvent(MessageDestination destination, EventMessage msg) { String jsonStr = msg.toJson(); String id = msg.getEventHeader().getEventId(); LOG.info(String.format("Posting Message [%s - %s]", id, jsonStr)); @@ -112,7 +108,43 @@ public class EventSenderImpl implements EventSender } @Override - public boolean sendEvent(DmaapDestination destination,Map<String, String> params, SvcLogicContext ctx) throws APPCException { + public boolean sendEvent(MessageDestination destination, EventMessage msg, String eventTopicName) { + String jsonStr = msg.toJson(); + String id = msg.getEventHeader().getEventId(); + LOG.info(String.format("Posting Message [%s - %s]", id, jsonStr)); + Producer producer = createProducer(destination, eventTopicName); + return producer.post(id, jsonStr); + } + + private Producer createProducer(MessageDestination destination, String eventTopicName) { + Properties properties = configuration.getProperties(); + final List<String> pool = new ArrayList<>(); + String username = properties.getProperty(destination + "." + DMAAP_USERNAME); + String password = properties.getProperty(destination + "." + DMAAP_PASSWORD); + String hostNames = properties.getProperty(destination + "." + EVENT_POOL_MEMBERS); + + if (hostNames != null && !hostNames.isEmpty()) { + LOG.debug(String.format("hostNames = %s, taken from property: %s", hostNames, destination + "." + EVENT_POOL_MEMBERS)); + Collections.addAll(pool, hostNames.split(",")); + } + + LOG.debug(String.format("pool = %s, taken from property: %s", pool, destination + "." + EVENT_POOL_MEMBERS)); + LOG.debug(String.format("writeTopic = %s, taken from property: %s", eventTopicName, destination + "." + EVENT_TOPIC_WRITE)); + LOG.debug(String.format("username = %s, taken from property: %s", username, destination + "." + DMAAP_USERNAME)); + Producer producer = new DmaapProducerImpl(pool, eventTopicName,username, password); + + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + LOG.debug("Producer should use HTTPS"); + producer.useHttps(true); + break; + } + } + return producer; + } + + @Override + public boolean sendEvent(MessageDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException { if (params == null) { String message = "Parameters map is empty (null)"; @@ -134,10 +166,10 @@ public class EventSenderImpl implements EventSender LOG.error(message); throw new APPCException(message); } - EventMessage dmaapEventMessage = new EventMessage( + EventMessage eventMessage = new EventMessage( new EventHeader(eventTime, apiVer, eventId), new EventStatus(code, reason)); - return sendEvent(destination,dmaapEventMessage); + return sendEvent(destination,eventMessage); } } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml index a8caf666f..eefe8e504 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -24,10 +24,10 @@ <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="eventSenderBean" class="org.openecomp.appc.adapter.dmaap.impl.EventSenderImpl" + <bean id="eventSenderBean" class="org.openecomp.appc.adapter.messaging.dmaap.impl.EventSenderDmaapImpl" init-method="initialize" scope="singleton"> </bean> - <service id="eventSenderService" interface="org.openecomp.appc.adapter.dmaap.EventSender" ref="eventSenderBean" /> + <service id="eventSenderService" interface="org.openecomp.appc.adapter.message.EventSender" ref="eventSenderBean" /> </blueprint> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/consumer.properties b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/consumer.properties new file mode 100644 index 000000000..facd33e4d --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/consumer.properties @@ -0,0 +1,57 @@ +### +# ============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========================================================= +### + +#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH > +TransportType=HTTPAAF +Latitude =50.000000 +Longitude =-100.000000 +Version =1.0 +ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events +Environment =TEST +Partner=BOT_R +routeOffer=MR1 +SubContextPath =/ +Protocol =http +MethodType =GET +username =admin +password =admin +contenttype =application/json +authKey=01234567890abcde:01234567890abcdefghijklmn +authDate=2016-02-18T13:57:37-0800 +host=127.0.0.1 +topic=org.openecomp.appc.UNIT-TEST +group=jmsgrp +id=2 +timeout=15000 +limit=1000 +filter= +AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler +AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler +AFT_DME2_REQ_TRACE_ON=true +AFT_ENVIRONMENT=AFTUAT +AFT_DME2_EP_CONN_TIMEOUT=15000 +AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000 +AFT_DME2_EP_READ_TIMEOUT_MS=50000 +sessionstickinessrequired=NO +DME2preferredRouterFilePath=preferredRoute.txt + + + diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/preferredRoute.txt b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/preferredRoute.txt new file mode 100644 index 000000000..662b0aa7d --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/preferredRoute.txt @@ -0,0 +1 @@ +preferredRouteKey=MR1
\ No newline at end of file diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/producer.properties b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/producer.properties new file mode 100644 index 000000000..4901d517e --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/resources/producer.properties @@ -0,0 +1,52 @@ +### +# ============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========================================================= +### + +#TransportType-Specify which way user want to use. I.e. <HTTPAAF,DME2,HTTPAUTH > +TransportType=HTTPAAF +Latitude =50.000000 +Longitude =-100.000000 +Version =1.0 +ServiceName =dmaap-v1.dev.dmaap.dt.saat.acsi.openecomp.org/events +Environment =TEST +Partner=BOT_R +SubContextPath =/ +Protocol =http +MethodType =POST +username =admin +password =admin +contenttype = application/json +authKey=01234567890abcde:01234567890abcdefghijklmn +authDate=2016-07-20T11:30:56-0700 +host=127.0.0.1 +topic=org.openecomp.appc.UNIT-TEST +partition=2 +maxBatchSize=100 +maxAgeMs=250 +AFT_DME2_EXCHANGE_REQUEST_HANDLERS=com.att.nsa.test.PreferredRouteRequestHandler +AFT_DME2_EXCHANGE_REPLY_HANDLERS=com.att.nsa.test.PreferredRouteReplyHandler +AFT_DME2_REQ_TRACE_ON=true +AFT_ENVIRONMENT=AFTUAT +AFT_DME2_EP_CONN_TIMEOUT=15000 +AFT_DME2_ROUNDTRIP_TIMEOUT_MS=240000 +AFT_DME2_EP_READ_TIMEOUT_MS=50000 +sessionstickinessrequired=NO +DME2preferredRouterFilePath=preferredRoute.txt +MessageSentThreadOccurance=50 diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/SimpleExamplePublisher.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/SimpleExamplePublisher.java new file mode 100644 index 000000000..a0ae92ea8 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/SimpleExamplePublisher.java @@ -0,0 +1,134 @@ +/*- + * ============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.adapter.messaging.dmaap; + +import java.io.*; +import java.util.List; +import java.util.Properties; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import com.att.nsa.mr.client.MRConsumer; +import org.json.JSONObject; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapUtil; + +import com.att.nsa.mr.client.MRBatchingPublisher; +import com.att.nsa.mr.client.MRClientFactory; +import com.att.nsa.mr.client.MRPublisher.message; + + +/** + *An example of how to use the Java publisher. + */ +public class SimpleExamplePublisher +{ + + public static void main(String []args) throws InterruptedException, Exception{ + int msgCount = 1; + SimpleExamplePublisher publisher = new SimpleExamplePublisher(); + + int i=0; + + String topicProducerPropFileName = DmaapUtil.createProducerPropFile("org.openecomp.appc.UNIT-TEST", null); + while (i< msgCount) + { + publisher.publishMessage(topicProducerPropFileName,i); + i++; + } + + fetchMessage(); + } + + + public void publishMessage( String producerFilePath,int count ) throws IOException, InterruptedException, Exception + { + // create our publisher + final MRBatchingPublisher pub = MRClientFactory.createBatchingPublisher (producerFilePath); + // publish some messages + final JSONObject msg1 = new JSONObject (); + msg1.put ( "Partition:2", "Message:" +count); + //msg1.put ( "greeting", "Hello .." ); + + pub.send ( "2", msg1.toString()); + // close the publisher to make sure everything's sent before exiting. The batching + // publisher interface allows the app to get the set of unsent messages. It could + // write them to disk, for example, to try to send them later. + final List<message> stuck = pub.close ( 20, TimeUnit.SECONDS ); + if ( stuck.size () > 0 ) + { + System.err.println ( stuck.size() + " messages unsent" ); + } + else + { + System.out.println ( "Clean exit; all messages sent." ); + } + } + + + public static void fetchMessage() + { + int count = 0; + + try + { + String topic = "org.openecomp.appc.UNIT-TEST"; + Properties props = new Properties(); + props.put("id", "1"); + props.put("group", "group1"); + String topicConsumerPropFileName1 = DmaapUtil.createConsumerPropFile(topic,props); + final MRConsumer consumer1 = MRClientFactory.createConsumer ( topicConsumerPropFileName1); + + props = new Properties(); + props.put("id", "2"); + props.put("group", "group2"); + String topicConsumerPropFileName2 = DmaapUtil.createConsumerPropFile(topic,props); + final MRConsumer consumer2 = MRClientFactory.createConsumer ( topicConsumerPropFileName2); + + for ( String msg : consumer1.fetch () ) + { + count++; + System.out.println ( "consumer1 "+count + ": " + msg ); + } + for ( String msg : consumer2.fetch () ) + { + count++; + System.out.println ( "consumer1 "+count + ": " + msg ); + } + + + } + catch ( Exception x ) + { + System.out.println("inside cons exc"); + System.err.println ( x.getClass().getName () + ": " + x.getMessage () ); + } + } +} + + + + + + + + + diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/dmaap/TestAppcDmaapAdapterActivator.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestAppcDmaapAdapterActivator.java index e97014198..6626938a7 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/dmaap/TestAppcDmaapAdapterActivator.java +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestAppcDmaapAdapterActivator.java @@ -19,13 +19,13 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.messaging.dmaap; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.junit.Test; -import org.openecomp.appc.adapter.dmaap.AppcDmaapAdapterActivator; +import org.openecomp.appc.adapter.messaging.dmaap.AppcDmaapAdapterActivator; public class TestAppcDmaapAdapterActivator { diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapConsuming.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapConsuming.java new file mode 100644 index 000000000..23647d61a --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapConsuming.java @@ -0,0 +1,84 @@ +/*- + * ============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.adapter.messaging.dmaap; + + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapConsumerImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.junit.Ignore; + +import java.util.Arrays; +import java.util.List; + +/** + * Must have a DMaaP cluster or simulator up and running + * Update the hostname, topic, client properties in + * resources/org/openecomp/appc/default.properties + * + */ +public class TestDmaapConsuming { + + private static Consumer dmaapConsumer; + private static Consumer httpConsumer; + + @BeforeClass + public static void setUp() { + + Configuration configuration = ConfigurationFactory.getConfiguration(); + + List<String> hosts = Arrays.asList(configuration.getProperty("poolMembers").split(",")); + String topic = configuration.getProperty("topic.read"); + String consumerName = configuration.getProperty("client.name"); + String consumerId = configuration.getProperty("client.name.id"); + String msgFilter = configuration.getProperty("message.filter"); + String user = configuration.getProperty("dmaap.appc.username"); + String password = configuration.getProperty("dmaap.appc.password"); + + httpConsumer = new HttpDmaapConsumerImpl(hosts, topic, consumerName, consumerId, msgFilter); + dmaapConsumer = new DmaapConsumerImpl(hosts, topic, consumerName, consumerId,user,password,msgFilter); + } + + @Test + @Ignore + public void testHttpFetchMessages() { + testFetchMessages(httpConsumer); + } + + @Test + @Ignore + public void testFetchMessages() { + testFetchMessages(dmaapConsumer); + } + + private void testFetchMessages(Consumer consumer) { + List<String> messages = consumer.fetch(1000, 100); + Assert.assertNotNull(messages); + Assert.assertFalse(messages.isEmpty()); + } + +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapEventSender.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapEventSender.java new file mode 100644 index 000000000..b35f9871d --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapEventSender.java @@ -0,0 +1,169 @@ +/*- + * ============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.adapter.messaging.dmaap; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mockito; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.message.event.EventHeader; +import org.openecomp.appc.adapter.message.event.EventMessage; +import org.openecomp.appc.adapter.message.event.EventStatus; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapProducerImpl; +import org.openecomp.appc.adapter.messaging.dmaap.impl.EventSenderDmaapImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + + +public class TestDmaapEventSender { + + private static Properties props; + private static Map<String,Producer> producerMap = new HashMap<>(); + private static EventMessage eventMessage; + + @BeforeClass + public static void setUp() { + + Configuration configuration = ConfigurationFactory.getConfiguration(); // test.properties file placed in home dir. + + props = new Properties(); + props.setProperty(EventSenderDmaapImpl.EVENT_POOL_MEMBERS, + configuration.getProperty(EventSenderDmaapImpl.EVENT_POOL_MEMBERS) != null ? + configuration.getProperty(EventSenderDmaapImpl.EVENT_POOL_MEMBERS) : "member1,member2,member3"); + props.setProperty(EventSenderDmaapImpl.EVENT_TOPIC_WRITE, + configuration.getProperty(EventSenderDmaapImpl.EVENT_TOPIC_WRITE) != null ? + configuration.getProperty(EventSenderDmaapImpl.EVENT_TOPIC_WRITE) : "topic1"); + + String eventClientKey = configuration.getProperty(EventSenderDmaapImpl.DMAAP_USERNAME); + if (eventClientKey != null) { + props.setProperty(EventSenderDmaapImpl.DMAAP_USERNAME,eventClientKey); + } + String eventClientSecret = configuration.getProperty(EventSenderDmaapImpl.DMAAP_PASSWORD); + if (eventClientSecret != null) { + props.setProperty(EventSenderDmaapImpl.DMAAP_PASSWORD, eventClientSecret); + } + + Producer producer = Mockito.mock(DmaapProducerImpl.class); + producerMap.put(MessageDestination.DCAE.toString(),producer); + Mockito.when(producer.post(Matchers.anyString(), Matchers.anyString())).thenReturn(true); + + eventMessage = new EventMessage( + new EventHeader("2016-03-15T10:59:33.79Z", "1.01", "17"), + new EventStatus(404, "No krokodil found")); + } + + @Test + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderWithProperties() { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Assert.assertTrue(eventSender.sendEvent(MessageDestination.DCAE, eventMessage)); + } + + @Test + public void testDmaapEventSenderWithNullProperties() { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); +// eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Assert.assertTrue(eventSender.sendEvent(MessageDestination.DCAE, eventMessage)); + } + + /* + * This test runs agains a real Dmaap (or a simulator) that should be cofigured in test.properties file. + */ + @Test + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderWithDmaapSim() { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + Assert.assertTrue(eventSender.sendEvent(MessageDestination.DCAE, eventMessage)); + } + + + @Test + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderDG() throws APPCException { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Map<String,String> params = new HashMap<>(); + + params.put("eventTime", eventMessage.getEventHeader().getEventTime()); + params.put("apiVer", eventMessage.getEventHeader().getApiVer()); + params.put("eventId", eventMessage.getEventHeader().getEventId()); + params.put("reason", eventMessage.getEventStatus().getReason()); + params.put("code", "200"); + + Assert.assertTrue(eventSender.sendEvent(MessageDestination.DCAE,params, new SvcLogicContext())); + } + + @Test(expected = APPCException.class) + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderDGNoParams() throws APPCException { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Map<String,String> params = new HashMap<>(); + + Assert.assertFalse(eventSender.sendEvent(MessageDestination.DCAE,params, new SvcLogicContext())); + } + + + @Test(expected = APPCException.class) + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderDGNullParam() throws APPCException { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Map<String,String> params = null; + + Assert.assertFalse(eventSender.sendEvent(MessageDestination.DCAE,params, new SvcLogicContext())); + } + + @Test(expected = APPCException.class) + @Ignore // requires connection to a live DMaaP server + public void testDmaapEventSenderDGNoParam() throws APPCException { + EventSenderDmaapImpl eventSender = new EventSenderDmaapImpl(); + eventSender.initialize(); + eventSender.setProducerMap(producerMap); + Map<String,String> params = new HashMap<>(); + +// params.put("apiVer", eventMessage.getEventHeader().getApiVer()); + params.put("eventId", eventMessage.getEventHeader().getEventId()); + params.put("reason", eventMessage.getEventStatus().getReason()); + params.put("code", "200"); + + eventSender.sendEvent(MessageDestination.DCAE,params, new SvcLogicContext()); + } + +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapProducing.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapProducing.java new file mode 100644 index 000000000..b5b7c9538 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/TestDmaapProducing.java @@ -0,0 +1,80 @@ +/*- + * ============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.adapter.messaging.dmaap; + + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapProducerImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +import java.util.Arrays; +import java.util.List; + +/** + * Must have a DMaaP cluster or simulator up and running + * Update the hostname, topic, client properties in + * resources/org/openecomp/appc/default.properties + * + */ +public class TestDmaapProducing { + + private static Producer httpProducer; + private static Producer dmaapProducer; + + @BeforeClass + public static void setUp() { + + Configuration configuration = ConfigurationFactory.getConfiguration(); + + List<String> hosts = Arrays.asList(configuration.getProperty("poolMembers").split(",")); + String topic = configuration.getProperty("topic.write"); + String user = configuration.getProperty("dmaap.appc.username"); + String password = configuration.getProperty("dmaap.appc.password"); + + dmaapProducer = new DmaapProducerImpl(hosts, topic,user,password); + httpProducer = new HttpDmaapProducerImpl(hosts, topic); + httpProducer.updateCredentials(user,password); + } + + @Test + @Ignore + public void testHttpPostMessage() { + testPostMessage(httpProducer); + } + + @Test + @Ignore + public void testPostMessages() { + testPostMessage(dmaapProducer); + } + + private void testPostMessage(Producer producer) { + Assert.assertTrue(producer.post("partition", "{\"message\": \"Hello, world!\"}")); + } + +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/impl/TestConsumerProducerImpl.java b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/impl/TestConsumerProducerImpl.java new file mode 100644 index 000000000..4b936351a --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/test/java/org/openecomp/appc/adapter/messaging/dmaap/impl/TestConsumerProducerImpl.java @@ -0,0 +1,242 @@ +/*- + * ============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.adapter.messaging.dmaap.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.*; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapConsumerImpl; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapProducerImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class TestConsumerProducerImpl { + + private Collection<String> urls; + private String topicRead; + private String topicWrite; + private String group; + private String groupId; + private String user; + private String password; + + @Before + public void setup() { + System.out.println("setup entry..."); +// urls = new HashSet<String>(); +// urls.add("dmaaphost1"); +// urls.add("dmaaphost2"); +// //remove unavailable dmaap instance for build +// //urls.add("dmaaphost3"); +// +// topicRead = "APPC-UNIT-TEST"; +// topicWrite = "APPC-UNIT-TEST"; +// group = "APPC-CLIENT"; +// groupId = "0"; + Configuration configuration = ConfigurationFactory.getConfiguration(); + List<String> hosts = Arrays.asList(configuration.getProperty("poolMembers").split(",")); + urls = new HashSet<String>(hosts); + topicRead = configuration.getProperty("topic.read"); + topicWrite = configuration.getProperty("topic.write"); + user = configuration.getProperty("dmaap.appc.username"); + password = configuration.getProperty("dmaap.appc.password"); + group = "APPC-CLIENT"; + groupId = "0"; + + + runoff(); + } + + /** + * Test that we can read and write and that the messages come back in order + */ + @Ignore + @Test + public void testWriteRead() { + System.out.println("testWriteRead entry..."); + Producer p = new DmaapProducerImpl(urls, topicWrite,user,password); + + String s1 = UUID.randomUUID().toString(); + String s2 = UUID.randomUUID().toString(); + if (p.post("TEST", s1) == false) { + // try again - 2nd attempt may succeed if cambria client failed over + p.post("TEST", s1); + } + if (p.post("TEST", s2) == false) { + // try again - 2nd attempt may succeed if cambria client failed over + p.post("TEST", s2); + } + + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + List<String> out = c.fetch(); + // if fetch is empty, try again - a 2nd attempt may succeed if + // cambria client has failed over + if ((out == null) || out.isEmpty()) { + out = c.fetch(); + } + + assertNotNull(out); + assertEquals(2, out.size()); + assertEquals(s1, out.get(0)); + assertEquals(s2, out.get(1)); + + } + + /** + * Test that we can read and write and that the messages come back in order + */ + @Test + @Ignore // Https Not support on jenkins server + public void testWriteReadHttps() { + System.out.println("testWriteReadHttps entry..."); + Producer p = new DmaapProducerImpl(urls, topicWrite,user,password); + p.useHttps(true); + + String s1 = UUID.randomUUID().toString(); + String s2 = UUID.randomUUID().toString(); + if (p.post("TEST", s1) == false) { + // try again - 2nd attempt may succeed if cambria client failed over + p.post("TEST", s1); + } + if (p.post("TEST", s2) == false) { + // try again - 2nd attempt may succeed if cambria client failed over + p.post("TEST", s2); + } + + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + c.useHttps(true); + + List<String> out = c.fetch(); + // if fetch is empty, try again - a 2nd attempt may succeed if + // cambria client has failed over + if ((out == null) || out.isEmpty()) { + out = c.fetch(); + } + + assertNotNull(out); + assertEquals(2, out.size()); + assertEquals(s1, out.get(0)); + assertEquals(s2, out.get(1)); + + } + + @Test + @Ignore // requires connection to a live DMaaP server + public void testBadUrl() { + System.out.println("testBadUrl entry..."); + urls.clear(); + urls.add("something.local"); + + // Producer p = new DmaapProducerImpl(urls, topicWrite); + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + List<String> result = c.fetch(1000, 1000); + + assertNotNull(result); + assertTrue(result.isEmpty()); + } + + @Test + @Ignore // requires connection to a live DMaaP server + public void testAuth() { + System.out.println("testAuth entry..."); + Producer p = new DmaapProducerImpl(urls, topicWrite,user,password); + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + + p.updateCredentials("key", "secret"); + c.updateCredentials("key", "secret"); + + // TODO - Do some protected dmaap queries when the apis are updated + } + + /** + * Test DMaaP client failover to another server when a bad url is encountered + + */ + @Ignore + @Test + public void testFailover() { + System.out.println("testFailover entry..."); + urls.clear(); + urls.add("openecomp2.org"); // bad url + urls.add("dmaaphost2"); + Producer p = new DmaapProducerImpl(urls, topicWrite,user,password); + + String s1 = UUID.randomUUID().toString(); + if (p.post("TEST", s1) == false) { + // try again - cambria client should have failed over + p.post("TEST", s1); + } + + urls.clear(); + urls.add("openecomp3.org"); // bad url + urls.add("dmaaphost3"); + + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + List<String> out = c.fetch(1000, 1000); + // if fetch is empty, try again - cambria client should have failed over + if ((out == null) || out.isEmpty()) { + out = c.fetch(); + } + + assertNotNull(out); + assertEquals(1, out.size()); + assertEquals(s1, out.get(0)); + } + + /** + * Reads through the entire topic so it is clean for testing. WARNING - ONLY USE ON TOPICS WHERE YOU ARE THE ONLY + * WRITER. Could end in an infinite loop otherwise. + */ + private void runoff() { + Consumer c = new DmaapConsumerImpl(urls, topicRead, group, groupId,user,password); + List<String> data; + do { + data = c.fetch(1000, 10000); + } while (!data.isEmpty() && data.size()!=1); + } + + @Test + @Ignore + public void testFilter() { + System.out.println("testFilter entry..."); + List<String> res; + String filter = "{\"class\":\"Assigned\",\"field\":\"request\"}"; + Consumer c = new DmaapConsumerImpl(urls, "DCAE-CLOSED-LOOP-EVENTS-DEV1510SIM", group, groupId,user,password,filter); + res = c.fetch(2000, 10); + assertFalse(res.isEmpty()); + + res.clear(); + filter = "{\"class\":\"Assigned\",\"field\":\"response\"}"; + c = new DmaapConsumerImpl(urls, "DCAE-CLOSED-LOOP-EVENTS-DEV1510SIM", group, groupId,user,password, filter); + res = c.fetch(2000, 10); + assertTrue(res.isEmpty()); + } +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml index 2181888fc..8f5b55c73 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/pom.xml @@ -19,6 +19,12 @@ </dependency> <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <scope>compile</scope> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml index 90a31629e..baf04ddec 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-features/src/main/resources/features.xml @@ -34,6 +34,8 @@ <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> <!-- <feature version="${sdnctl.sli.version}">sdnc-sli</feature> --> <bundle>mvn:org.openecomp.appc/appc-dmaap-adapter-bundle/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-message-adapter-factory/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-message-adapter-api/${project.version}</bundle> </feature> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml index 851c3a19e..845c477f4 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml +++ b/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-installer/pom.xml @@ -37,6 +37,16 @@ <artifactId>appc-dmaap-adapter-bundle</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build> diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/pom.xml b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/pom.xml new file mode 100644 index 000000000..5e2e6c6b2 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/pom.xml @@ -0,0 +1,141 @@ +<?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> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-message-adapter-api</artifactId> + <packaging>bundle</packaging> + <name>appc-message-adapter-api</name> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-metric-bundle</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + </dependency> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.adapter.message.*</Export-Package> + <!--<Export-Serice>org.openecomp.appc.adapter.message.EventSender</Export-Serice>--> + <Import-Package>org.openecomp.appc.metricservice.*,com.att.nsa.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,!org.osgi.service.event.*,org.osgi.service.*,org.osgi.util.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.*,javax.naming.*,javax.crypto.*, com.sun.jersey.spi.container.servlet,org.eclipse.jetty.servlets</Import-Package> + <!--<Embed-Dependency>appc-common</Embed-Dependency>--> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|sli-provider|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Bundle-Blueprint>OSGI-INF/blueprint/blueprint.xml</Bundle-Blueprint> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CallableConsumer.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/CallableConsumer.java index 7c282911d..bbc541167 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/CallableConsumer.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/CallableConsumer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; import java.util.List; import java.util.concurrent.Callable; diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Consumer.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Consumer.java index 32034e5fb..e99f884a2 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Consumer.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Consumer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; import java.util.List; @@ -54,9 +54,6 @@ public interface Consumer { */ public void updateCredentials(String apiKey, String apiSecret); - // TODO - Implement once Cambria allows you to set outside of constructor - // public void setFilter(String filter); - /** * Creates a dmaap client using a https connection * @@ -65,4 +62,9 @@ public interface Consumer { */ public void useHttps(boolean yes); + /** + * Closes the dmaap client https connection + */ + void close(); + } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/EventSender.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/EventSender.java index 7d4a7c090..e4338f0e4 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/EventSender.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/EventSender.java @@ -19,17 +19,18 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; -import java.util.Map; - -import org.openecomp.appc.adapter.dmaap.event.EventMessage; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.SvcLogicContext; import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; +import java.util.Map; + +import org.openecomp.appc.adapter.message.event.EventMessage; public interface EventSender extends SvcLogicJavaPlugin{ - boolean sendEvent(DmaapDestination destination, EventMessage msg); - boolean sendEvent(DmaapDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException; + boolean sendEvent(MessageDestination destination, EventMessage msg); + boolean sendEvent(MessageDestination destination, EventMessage msg,String eventTopicName); + boolean sendEvent(MessageDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException; } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Manager.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Manager.java index 183e618ba..2990036f5 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Manager.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Manager.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; import java.util.Set; diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/MessageAdapterFactory.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/MessageAdapterFactory.java new file mode 100644 index 000000000..741563b58 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/MessageAdapterFactory.java @@ -0,0 +1,39 @@ +/*- + * ============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.adapter.message; + +import java.util.Collection; +import java.util.Set; + +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.adapter.message.Producer; + +public interface MessageAdapterFactory { + + // TODO: how do you configure the MessageService type? + + public Producer createProducer(Collection<String> pools, String writeTopic, String apiKey, String apiSecret); + + public Producer createProducer(Collection<String> pools, Set<String> writeTopics, String apiKey, String apiSecret); + + public Consumer createConsumer(Collection<String> pool, String readTopic, + String clientName, String clientId, String filter_json, String apiKey, String apiSecret); +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapDestination.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/MessageDestination.java index efbe194ba..b952441e1 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/DmaapDestination.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/MessageDestination.java @@ -19,8 +19,8 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; -public enum DmaapDestination { +public enum MessageDestination { DCAE } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Producer.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Producer.java index f19c516be..5981606cb 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/Producer.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/Producer.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap; +package org.openecomp.appc.adapter.message; public interface Producer { @@ -43,4 +43,9 @@ public interface Producer { */ public void useHttps(boolean yes); + /** + * Closes the dmaap client https connection + */ + void close(); + } diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventHeader.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventHeader.java index dd951fe37..3d897d42a 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventHeader.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventHeader.java @@ -19,11 +19,10 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap.event; +package org.openecomp.appc.adapter.message.event; import com.fasterxml.jackson.annotation.JsonProperty; - public class EventHeader { @JsonProperty("eventTime") diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventMessage.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventMessage.java index af5cff2f9..e5fad6089 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventMessage.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventMessage.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap.event; +package org.openecomp.appc.adapter.message.event; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @@ -45,8 +45,6 @@ import java.io.Serializable; */ - - @JsonSerialize(include = Inclusion.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class EventMessage implements Serializable { diff --git a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventStatus.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventStatus.java index f5d7a59d4..85b4db02f 100644 --- a/appc-adapters/appc-dmaap-adapter/appc-dmaap-adapter-bundle/src/main/java/org/openecomp/appc/adapter/dmaap/event/EventStatus.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/java/org/openecomp/appc/adapter/message/event/EventStatus.java @@ -19,11 +19,10 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.adapter.dmaap.event; +package org.openecomp.appc.adapter.message.event; import com.fasterxml.jackson.annotation.JsonProperty; - public class EventStatus { @JsonProperty("code") diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..a1e5c7172 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,28 @@ +<?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========================================================= + --> + + +<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"> + +</blueprint> diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/org/openecomp/appc/default.properties b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..00c95bca1 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-api/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,23 @@ +### +# ============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========================================================= +### + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/pom.xml b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/pom.xml new file mode 100644 index 000000000..21cba8179 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/pom.xml @@ -0,0 +1,150 @@ +<?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> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-message-adapter-factory</artifactId> + <packaging>bundle</packaging> + <name>appc-message-adapter-factory</name> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-core</artifactId> + </dependency> + <dependency> + <groupId>org.objenesis</groupId> + <artifactId>objenesis</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>org.openecomp.appc.adapter.factory</Export-Package> + <Bundle-Activator>org.openecomp.appc.adapter.factory.DmaapMessageAdapterFactoryActivator</Bundle-Activator> + <Export-Service>org.openecomp.appc.adapter.message.MessageAdapterFactory</Export-Service> + <Import-Package>org.openecomp.appc.adapter.messaging.*,org.openecomp.appc.adapter.message.*,org.openecomp.appc.metricservice.*,com.att.nsa.*org.openecomp.sdnc.core.sli.*,org.osgi.framework.*,!org.osgi.service.event.*,org.osgi.service.*,org.osgi.util.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.*,javax.naming.*,javax.crypto.*, com.sun.jersey.spi.container.servlet,org.eclipse.jetty.servlets</Import-Package> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + <Bundle-Blueprint>OSGI-INF/blueprint/blueprint.xml</Bundle-Blueprint> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryActivator.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryActivator.java new file mode 100644 index 000000000..26e0f3da9 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryActivator.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.adapter.factory; + +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class DmaapMessageAdapterFactoryActivator implements BundleActivator { + private ServiceRegistration registration; + + @Override + public void start(BundleContext context) throws Exception { + registration = context.registerService( + MessageAdapterFactory.class.getName(), + new DmaapMessageAdapterFactoryImpl(), + null); + } + + @Override + public void stop(BundleContext context) throws Exception { + registration.unregister(); + } + +} diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryImpl.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryImpl.java new file mode 100644 index 000000000..604cbf738 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/DmaapMessageAdapterFactoryImpl.java @@ -0,0 +1,47 @@ +/*- + * ============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.adapter.factory; + +import java.util.Collection; +import java.util.Set; + +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.adapter.messaging.dmaap.http.HttpDmaapConsumerImpl; +import org.openecomp.appc.adapter.messaging.dmaap.http.HttpDmaapProducerImpl; + +public class DmaapMessageAdapterFactoryImpl implements MessageAdapterFactory { + + public Producer createProducer(Collection<String> pools, String writeTopic, String apiKey, String apiSecret) { + return new HttpDmaapProducerImpl(pools, writeTopic); + } + + public Producer createProducer(Collection<String> pools, Set<String> writeTopics, String apiKey, String apiSecret) { + return new HttpDmaapProducerImpl(pools, writeTopics); + } + + public Consumer createConsumer(Collection<String> pool, String readTopic, + String clientName, String clientId, String filter_json, String apiKey, String apiSecret) { + return new HttpDmaapConsumerImpl(pool, readTopic, clientName, clientId, apiKey, apiSecret, filter_json); + } +} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Action.java b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/MessageService.java index a8fe8035b..5bbfd6ddb 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Action.java +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/java/org/openecomp/appc/adapter/factory/MessageService.java @@ -19,37 +19,38 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL.model; +package org.openecomp.appc.adapter.factory; +/** + * The message service types that are available. Only DMaaP available + **/ +public enum MessageService { + DMaaP("dmaap"); -public enum Action { - Restart("Restart"), Rebuild("Rebuild"), Migrate("Migrate"), Evacuate("Evacuate"); + private String val; + + private MessageService(String val) { + this.val = val; + } + + public String getValue() { + return val; + } /** - * Converts the string to an Action - * - * @param value - * The string to try and convert. Is case insensitive - * @return The action matching the string or null if no match was found. + * Tries to match a string to a MessageService. If no match is found, returns the default (DMaaP) + * + * @param input + * the string to try and match + * @return A MessasgeService */ - public static Action toAction(String value) { - if (value != null) { - for (Action e : values()) { - if (e.getValue().toUpperCase().equals(value.toUpperCase())) { - return e; + public static MessageService parse(String input) { + if (input != null) { + for (MessageService ms : MessageService.values()) { + if (ms.getValue().equals(input.toLowerCase())) { + return ms; } } } - - return null; - } - - private String value; - - private Action(String valueToUse) { - value = valueToUse; - } - - public final String getValue() { - return value; + return MessageService.DMaaP; // Default } } diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..a1e5c7172 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,28 @@ +<?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========================================================= + --> + + +<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"> + +</blueprint> diff --git a/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/org/openecomp/appc/default.properties b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..00c95bca1 --- /dev/null +++ b/appc-adapters/appc-dmaap-adapter/appc-message-adapter-factory/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,23 @@ +### +# ============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========================================================= +### + +org.openecomp.appc.bootstrap.file=appc.properties +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. diff --git a/appc-adapters/appc-dmaap-adapter/pom.xml b/appc-adapters/appc-dmaap-adapter/pom.xml index 5d90baacd..212488a2c 100644 --- a/appc-adapters/appc-dmaap-adapter/pom.xml +++ b/appc-adapters/appc-dmaap-adapter/pom.xml @@ -9,7 +9,7 @@ <artifactId>appc-dmaap-adapter</artifactId> <name>DMaaP Adapter</name> - <description>Adapter to read and write messages on the Universal Event Broker (Cambria).</description> + <description>Adapter to read and write messages on the DMaaP Service</description> <packaging>pom</packaging> <reporting> @@ -98,8 +98,10 @@ </reporting> <modules> + <module>appc-message-adapter-api</module> <module>appc-dmaap-adapter-bundle</module> <module>appc-dmaap-adapter-features</module> <module>appc-dmaap-adapter-installer</module> + <module>appc-message-adapter-factory</module> </modules> </project> diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml index db08ff17e..061ec5a09 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/pom.xml @@ -16,84 +16,137 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> - <classifier>jar-with-dependencies</classifier> <scope>compile</scope> - </dependency> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-common</artifactId> - <version>${project.version}</version> - <scope>test</scope> - </dependency> - <dependency> - <groupId>javax</groupId> - <artifactId>javaee-api</artifactId> - <version>7.0</version> - </dependency> - - <dependency> - <groupId>com.att.cdp</groupId> - <artifactId>cdp-pal-common</artifactId> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>com.att.cdp</groupId> - <artifactId>cdp-pal-openstack</artifactId> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>javax.ws.rs</groupId> - <artifactId>javax.ws.rs-api</artifactId> - </dependency> - - <!-- Jersey support needed for OpenStack connector and API version logic --> - <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-client</artifactId> - </dependency> - - <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-json</artifactId> - </dependency> - - <dependency> - <groupId>javax.xml.bind</groupId> - <artifactId>jaxb-api</artifactId> - <version>2.1</version> - </dependency> - - <dependency> - <groupId>javax.xml</groupId> - <artifactId>jaxp-api</artifactId> - <version>1.4.2</version> - </dependency> - - <!-- Needed to run test cases --> - <dependency> - <groupId>org.glassfish.jersey.core</groupId> - <artifactId>jersey-common</artifactId> - <version>2.9.1</version> - </dependency> - - <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-jaxrs</artifactId> - <version>1.9.12</version> - </dependency> - - <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - <version>4.5.1</version> - </dependency> + <exclusions> + <exclusion> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.25.1</version> + <scope>compile</scope> + </dependency> + + + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-client</artifactId> + <version>2.25.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-server</artifactId> + <version>2.25.1</version> + <scope>compile</scope> + </dependency> + +<!-- <dependency> --> +<!-- <groupId>javax</groupId> --> +<!-- <artifactId>javaee-api</artifactId> --> +<!-- <version>7.0</version> --> +<!-- </dependency> --> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + <version>2.0.1</version> + <scope>compile</scope> + </dependency> + +<!-- <dependency> --> +<!-- <groupId>org.glassfish.jersey.containers</groupId> --> +<!-- <artifactId>jersey-container-servlet</artifactId> --> +<!-- <version>2.25.1</version> --> +<!-- <scope>provided</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.glassfish.jersey.connectors</groupId> + <artifactId>jersey-grizzly-connector</artifactId> + <version>2.25.1</version> + <scope>compile</scope> + </dependency> +<!-- <dependency> --> +<!-- <groupId>org.glassfish.jersey.media</groupId> --> +<!-- <artifactId>jersey-media-json-jackson</artifactId> --> +<!-- <version>2.25.1</version> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>com.fasterxml.jackson.jaxrs</groupId> --> +<!-- <artifactId>jackson-jaxrs-base</artifactId> --> +<!-- </dependency> --> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.2</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>provided</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>provided</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + +<!-- <dependency> --> +<!-- <groupId>org.codehaus.jackson</groupId> --> +<!-- <artifactId>jackson-jaxrs</artifactId> --> +<!-- <version>1.9.12</version> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>commons-codec</groupId> --> +<!-- <artifactId>commons-codec</artifactId> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>org.apache.httpcomponents</groupId> --> +<!-- <artifactId>httpclient</artifactId> --> +<!-- <version>4.5.1</version> --> +<!-- </dependency> --> <dependency> <groupId>junit</groupId> @@ -101,80 +154,56 @@ <scope>test</scope> </dependency> - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-common</artifactId> - <scope>compile</scope> - <!-- Added exclusion to prevent missing dependency issue on dblib --> - <exclusions> - <exclusion> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>dblib-provider</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-provider</artifactId> - <scope>compile</scope> - <!-- Added exclusion to prevent missing dependency issue on dblib --> - <exclusions> - <exclusion> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>dblib-provider</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>equinoxSDK381</groupId> - <artifactId>org.eclipse.osgi</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </dependency> - - <dependency> - <groupId>mysql</groupId> - <artifactId>mysql-connector-java</artifactId> - <version>5.1.31</version> - <type>jar</type> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>com.vmware</groupId> - <artifactId>vijava</artifactId> - <version>5.1</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>xerces</groupId> - <artifactId>xerces</artifactId> - <version>2.4.0</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpcore</artifactId> - <version>${apache.httpcomponents.version}</version> - </dependency> - - <dependency> - <groupId>commons-logging</groupId> - <artifactId>commons-logging</artifactId> - <version>1.2</version> - </dependency> +<!-- <dependency> --> +<!-- <groupId>equinoxSDK381</groupId> --> +<!-- <artifactId>org.eclipse.osgi</artifactId> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>org.slf4j</groupId> --> +<!-- <artifactId>slf4j-api</artifactId> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>org.slf4j</groupId> --> +<!-- <artifactId>jcl-over-slf4j</artifactId> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>mysql</groupId> --> +<!-- <artifactId>mysql-connector-java</artifactId> --> +<!-- <version>5.1.31</version> --> +<!-- <type>jar</type> --> +<!-- <scope>compile</scope> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>com.vmware</groupId> --> +<!-- <artifactId>vijava</artifactId> --> +<!-- <version>5.1</version> --> +<!-- <scope>compile</scope> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>xerces</groupId> --> +<!-- <artifactId>xerces</artifactId> --> +<!-- <version>2.4.0</version> --> +<!-- <scope>provided</scope> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>org.apache.httpcomponents</groupId> --> +<!-- <artifactId>httpcore</artifactId> --> +<!-- <version>${apache.httpcomponents.version}</version> --> +<!-- </dependency> --> + +<!-- <dependency> --> +<!-- <groupId>commons-logging</groupId> --> +<!-- <artifactId>commons-logging</artifactId> --> +<!-- <version>1.2</version> --> +<!-- </dependency> --> </dependencies> @@ -188,13 +217,15 @@ <instructions> <Bundle-SymbolicName>appc-iaas-adapter</Bundle-SymbolicName> <Bundle-Activator>org.openecomp.appc.adapter.iaas.AppcProviderAdapterActivator</Bundle-Activator> - <Export-Package>org.openecomp.appc.adapter.iaas</Export-Package> - <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*,com.sun.jersey.*</Import-Package> - <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Export-Package>org.openecomp.appc.adapter.iaas,com.att.cdp.zones.model</Export-Package> + <DynamicImport-Package>javax.*</DynamicImport-Package> + <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,javax.net.ssl,org.xml.sax</Import-Package> +<!-- <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,javax.ws.rs.*,javax.net.*,javax.xml.*,org.xml.*</Import-Package> --> +<!-- <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*,javax.xml.*</Import-Package> --> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!org.eclipse.osgi|slf4j-api|jcl-over-slf4j|</Embed-Dependency> +<!-- <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> --> <Embed-Transitive>true</Embed-Transitive> </instructions> - - <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> </configuration> </plugin> </plugins> diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java index dec975cfb..0e68b7d69 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/AppcProviderAdapterActivator.java @@ -26,12 +26,13 @@ import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; import org.openecomp.appc.i18n.Msg; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + /** * This activator is used to initialize and terminate the connection pool to one or more providers. * <p> @@ -94,7 +95,13 @@ public class AppcProviderAdapterActivator implements BundleActivator { configuration = ConfigurationFactory.getConfiguration(); String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); logger.info(Msg.COMPONENT_INITIALIZING, appName, "IAAS adapter"); - adapter = new ProviderAdapterImpl(configuration.getProperties()); + try{ + adapter = new ProviderAdapterImpl(configuration.getProperties()); + }catch(Throwable t){ + logger.error("Error initializing APPC IAAS ProviderAdapterImpl",t); + throw t; + } + if (registration == null) { logger.info(Msg.REGISTERING_SERVICE, appName, adapter.getAdapterName(), ProviderAdapter.class.getSimpleName()); diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java index f7a8b30ed..4f14e14ff 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/ProviderAdapter.java @@ -65,6 +65,17 @@ public interface ProviderAdapter extends SvcLogicJavaPlugin { * The fully-qualified URL of the instance to be manipulated as it is known to the provider. */ static final String PROPERTY_IDENTITY_URL = "org.openecomp.appc.identity.url"; + + /** + * The Rebuild VM flag is an optional payload parameter for the Evacuate API. + */ + static final String PROPERTY_REBUILD_VM = "org.openecomp.appc.rebuildvm"; + + /** + * The target host id is an optional payload parameter for the Evacuate API. + */ + static final String PROPERTY_TARGETHOST_ID = "org.openecomp.appc.targethost.id"; + /** * heat stack id to perform operation on stack */ @@ -75,6 +86,8 @@ public interface ProviderAdapter extends SvcLogicJavaPlugin { static final String PROPERTY_INPUT_SNAPSHOT_ID = "org.openecomp.appc.snapshot.id"; static final String DG_OUTPUT_PARAM_NAMESPACE = "output."; + + static final String SKIP_HYPERVISOR_CHECK = "org.openecomp.appc.skiphypervisorcheck"; /** * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java index b1bba0918..683bc141c 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ProviderAdapterImpl.java @@ -19,52 +19,32 @@ * ============LICENSE_END========================================================= */ + package org.openecomp.appc.adapter.iaas.impl; -import com.woorea.openstack.base.client.OpenStackBaseException; -import com.woorea.openstack.heat.Heat; -import org.glassfish.grizzly.http.util.HttpStatus; import org.openecomp.appc.Constants; import org.openecomp.appc.adapter.iaas.ProviderAdapter; -import org.openecomp.appc.adapter.openstack.heat.SnapshotResource; -import org.openecomp.appc.adapter.openstack.heat.StackResource; -import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams; -import org.openecomp.appc.adapter.openstack.heat.model.Snapshot; +import org.openecomp.appc.adapter.iaas.provider.operation.api.IProviderOperation; +import org.openecomp.appc.adapter.iaas.provider.operation.api.ProviderOperationFactory; +import org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Property; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuateServer; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.appc.exceptions.UnknownProviderException; -import org.openecomp.appc.i18n.Msg; -import org.openecomp.appc.pool.Pool; -import org.openecomp.appc.pool.PoolExtensionException; import org.openecomp.appc.util.StructuredPropertyHelper; import org.openecomp.appc.util.StructuredPropertyHelper.Node; -import com.att.cdp.exceptions.*; -import com.att.cdp.openstack.OpenStackContext; -import com.att.cdp.openstack.connectors.HeatConnector; -import com.att.cdp.openstack.util.ExceptionMapper; -import com.att.cdp.pal.util.StringHelper; -import com.att.cdp.zones.*; import com.att.cdp.zones.model.Image; import com.att.cdp.zones.model.Server; -import com.att.cdp.zones.model.ServerBootSource; import com.att.cdp.zones.model.Stack; -import com.att.cdp.zones.model.Server.Status; -import com.att.cdp.zones.spi.AbstractService; -import com.att.cdp.zones.spi.RequestState; 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.slf4j.MDC; - -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; -import java.io.IOException; -import java.net.URI; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.regex.Pattern; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; /** * This class implements the {@link ProviderAdapter} interface. This interface defines the behaviors that our service @@ -74,192 +54,18 @@ import java.util.regex.Pattern; public class ProviderAdapterImpl implements ProviderAdapter { /** - * The name of the adapter - */ - @SuppressWarnings("nls") - private static final String ADAPTER_NAME = "Appc IaaS Adapter"; - - /** - * The username and password to use for dynamically created connections - */ - private static String DEFAULT_USER; - private static String DEFAULT_PASS; - - /** - * The constant used to define the adapter name in the mapped diagnostic context - */ - @SuppressWarnings("nls") - private static final String MDC_ADAPTER = "adapter"; - - /** - * The constant used to define the service name in the mapped diagnostic context - */ - @SuppressWarnings("nls") - static final String MDC_SERVICE = "service"; - - /** - * The constant for the status code for a failed outcome - */ - @SuppressWarnings("nls") - private static final String OUTCOME_FAILURE = "failure"; - - /** - * The constant for the status code for a successful outcome - */ - @SuppressWarnings("nls") - private static final String OUTCOME_SUCCESS = "success"; - - /** - * A constant for the property token "provider" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER = "provider"; - - /** - * A constant for the property token "identity" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_IDENTITY = "identity"; - - /** - * A constant for the property token "tenant" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_TENANT = "tenant"; - - /** - * A constant for the property token "tenant name" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_TENANT_NAME = "name"; - - /** - * A constant for the property token "password" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR - - /** - * A constant for the property token "userid" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_TENANT_USERID = "userid"; - - /** - * A constant for the property token "type" used in the structured property specifications - */ - @SuppressWarnings("nls") - private static final String PROPERTY_PROVIDER_TYPE = "type"; - - /** - * The name of the service to evacuate a server - */ - @SuppressWarnings("nls") - private static final String EVACUATE_SERVICE = "evacuateServer"; - - /** - * The name of the service to migrate a server - */ - @SuppressWarnings("nls") - private static final String MIGRATE_SERVICE = "migrateServer"; - - /** - * The name of the service to rebuild a server - */ - @SuppressWarnings("nls") - private static final String REBUILD_SERVICE = "rebuildServer"; - - /** - * The name of the service to restart a server - */ - @SuppressWarnings("nls") - private static final String RESTART_SERVICE = "restartServer"; - - /** - * The name of the service to check status of a server - */ - @SuppressWarnings("nls") - private static final String VMSTATUSCHECK_SERVICE = "vmStatuschecker"; - - - /** - * The name of the service to restart a server - */ - @SuppressWarnings("nls") - private static final String SNAPSHOT_SERVICE = "createSnapshot"; - - /** - * The name of the service to terminate a stack - */ - @SuppressWarnings("nls") - private static final String TERMINATE_STACK = "terminateStack"; - - /** - * The name of the service to snapshot a stack - */ - @SuppressWarnings("nls") - private static final String SNAPSHOT_STACK = "snapshotStack"; - - /** - * The name of a service to start a server - */ - @SuppressWarnings("nls") - private static final String START_SERVICE = "startServer"; - - /** - * The name of the service to stop a server - */ - @SuppressWarnings("nls") - private static final String STOP_SERVICE = "stopServer"; - - /** - * The name of the service to stop a server - */ - @SuppressWarnings("nls") - private static final String TERMINATE_SERVICE = "terminateServer"; - - /** - * The name of the service to lookup a server - */ - @SuppressWarnings("nls") - private static final String LOOKUP_SERVICE = "lookupServer"; - - /** * The logger to be used */ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderAdapterImpl.class); - - private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; - - /** - * The constant for a left parenthesis - */ - private static final char LPAREN = '('; - - /** - * The constant for a new line control code - */ - private static final char NL = '\n'; - - /** - * The constant for a single quote - */ - private static final char QUOTE = '\''; - /** - * The constant for a right parenthesis - */ - private static final char RPAREN = ')'; - - /** - * The constant for a space + * A reference to the adapter configuration object. */ - private static final char SPACE = ' '; + private Configuration configuration; /** - * A reference to the adapter configuration object. + * reference to operation factory */ - private Configuration configuration; + ProviderOperationFactory factory = ProviderOperationFactory.getInstance(); /** * A cache of providers that are predefined. @@ -267,9 +73,11 @@ public class ProviderAdapterImpl implements ProviderAdapter { private Map<String /* provider name */, ProviderCache> providerCache; /** - * A list of valid initial VM statuses for a migrate operations + * The username and password to use for dynamically created connections */ - private static final Collection<Status> migratableStatuses = Arrays.asList(Status.READY, Status.RUNNING, Status.SUSPENDED); + private static String DEFAULT_USER; + private static String DEFAULT_PASS; + /** * This default constructor is used as a work around because the activator wasnt getting called @@ -304,999 +112,149 @@ public class ProviderAdapterImpl implements ProviderAdapter { } - /** - * Returns the symbolic name of the adapter - * - * @return The adapter name - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#getAdapterName() - */ - @Override - public String getAdapterName() { - return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); - } - - @SuppressWarnings("nls") @Override - public Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Image snapshot = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, SNAPSHOT_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Snapshot"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.SNAPSHOTING_SERVER, appName); - String msg; - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - debugParameters(params); - debugContext(ctx); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - Server server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - - if (hasImageAccess(rc, context)) { - snapshot = createSnapshot(rc, server); - doSuccess(rc); - } else { - msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), - "Accessing Image Service Failed"); - logger.error(msg); - doFailure(rc, HttpStatus.FORBIDDEN_403, msg); - } - context.close(); - } - } catch (ResourceNotFoundException e) { - msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - SNAPSHOT_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - return snapshot; - } - - private boolean validateVM(RequestContext rc, String appName, String vm_url, VMURL vm) - throws RequestFailedException { - String msg; - if (vm == null) { - msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - return true; - } - validateVMURL(vm); - return false; - } - - private Image createSnapshot(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - Context context = server.getContext(); - Provider provider = context.getProvider(); - ImageService service = context.getImageService(); // Already checked access by this point - - String snapshotName = generateSnapshotName(server.getName()); - - logger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(), - snapshotName)); - - // Request Snapshot - String msg; - while (rc.attempt()) { - try { - server.createSnapshot(snapshotName); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - - // Locate snapshot image - Image snapshot = null; - while (rc.attempt()) { - try { - snapshot = service.getImageByName(snapshotName); - if (snapshot != null) { - break; - } - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - - // Wait for it to be ready - waitForStateChange(rc, snapshot, Image.Status.ACTIVE); - - return snapshot; - } + public Server restartServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - private String generateSnapshotName(String server) { - SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); - return String.format("Snapshot of %s at %s", server, df.format(new Date())); + IProviderOperation op = factory.getOperationObject(Operation.RESTART_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /** - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#evacuateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, EVACUATE_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Evacuate"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.EVACUATING_SERVER, appName); - String msg; - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - String providerName = params.get(ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; + public Server stopServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - Context context = null; - try { - context = getContext(rc, vm_url, providerName); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - evacuateServer(rc, server); - server.refreshStatus(); - context.close(); - doSuccess(rc); - } - } catch (ResourceNotFoundException e) { - msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - EVACUATE_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - - return server; + IProviderOperation op = factory.getOperationObject(Operation.STOP_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /** - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#migrateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, MIGRATE_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Migrate"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.MIGRATING_SERVER, appName); - String msg; - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - debugParameters(params); - debugContext(ctx); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - migrateServer(rc, server); - server.refreshStatus(); - context.close(); - doSuccess(rc); - } - } catch (ResourceNotFoundException e) { - msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - MIGRATE_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - - return server; - } + public Server startServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - private void evacuateServer(RequestContext rc, @SuppressWarnings("unused") Server server) throws ZoneException, RequestFailedException { - doFailure(rc, HttpStatus.NOT_IMPLEMENTED_501, "The operation 'EVACUATE' is not yet implemented"); + IProviderOperation op = factory.getOperationObject(Operation.START_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - private void migrateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - String msg; - Context ctx = server.getContext(); - ComputeService service = ctx.getComputeService(); - - // Init status will equal final status - Status initialStatus = server.getStatus(); - - if (initialStatus == null) { - throw new ZoneException("Failed to determine server's starting status"); - } - - // We can only migrate certain statuses - if (!migratableStatuses.contains(initialStatus)) { - throw new ZoneException(String.format("Cannot migrate server that is in %s state. Must be in one of [%s]", - initialStatus, migratableStatuses)); - } - - boolean inConfirmPhase = false; - try { - while (rc.attempt()) { - try { - if (!inConfirmPhase) { - // Initial migrate request - service.migrateServer(server.getId()); - // Wait for change to verify resize - waitForStateChange(rc, server, Status.READY); - inConfirmPhase = true; - } - - // Verify resize - service.processResize(server); - // Wait for complete. will go back to init status - waitForStateChange(rc, server, initialStatus); - logger.info("Completed migrate request successfully"); - return; - } catch (ContextConnectionException e) { - msg = getConnectionExceptionMessage(rc, ctx, e); - logger.error(msg, e); - rc.delay(); - } - } - } catch (ZoneException e) { - String phase = inConfirmPhase ? "VERIFY MIGRATE" : "REQUEST MIGRATE"; - msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, server.getName(), server.getId(), phase, - e.getMessage()); - generateEvent(rc, false, msg); - logger.error(msg, e); - throw new RequestFailedException("Migrate Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - } - - } - - /** - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#rebuildServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server rebuildServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, REBUILD_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Rebuild"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.REBUILDING_SERVER, appName); - String msg; - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - debugParameters(params); - debugContext(ctx); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + public Server rebuildServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - // Manually checking image service until new PAL release - if (hasImageAccess(rc, context)) { - rebuildServer(rc, server); - doSuccess(rc); - } else { - msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), - "Accessing Image Service Failed"); - logger.error(msg); - doFailure(rc, HttpStatus.FORBIDDEN_403, msg); - } - context.close(); - } - } catch (ResourceNotFoundException e) { - msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - STOP_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - - return server; + IProviderOperation op = factory.getOperationObject(Operation.REBUILD_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /** - * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. - * <p> - * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form - * <pre> - * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] - * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service - * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the - * server by its UUID, and then perform the restart. - * </p> - * - * @throws UnknownProviderException - * If the provider cannot be found - * @throws IllegalArgumentException - * if the expected argument(s) are not defined or are invalid - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#restartServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server restartServer(Map<String, String> params, SvcLogicContext ctx) - throws UnknownProviderException, IllegalArgumentException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, RESTART_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Restart"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.RESTARTING_SERVER, appName); - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; + public Server terminateServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - restartServer(rc, server); - context.close(); - doSuccess(rc); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - - return server; + IProviderOperation op = factory.getOperationObject(Operation.TERMINATE_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /* *********************************************************************************/ - /* DEVEN PANCHAL: This method is used to check the status of the VM */ - /**********************************************************************************/ - public Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws UnknownProviderException, IllegalArgumentException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, VMSTATUSCHECK_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter: vmstatuscheck"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - - String statusvm; - switch (server.getStatus()) { - case DELETED: - statusvm = "deleted"; - break; - - case RUNNING: - statusvm = "running"; - break; - - case ERROR: - statusvm = "error"; - break; - - case READY: - statusvm = "ready"; - break; - - case PAUSED: - statusvm = "paused"; - break; - - case SUSPENDED: - statusvm = "suspended"; - break; - - case PENDING: - statusvm = "pending"; - break; - - default: - statusvm = "default-unknown state-should never occur"; - break; - } - - - String statusofVM = statusvm; - context.close(); - SvcLogicContext svcLogic = rc.getSvcLogicContext(); - svcLogic.setStatus(OUTCOME_SUCCESS); - svcLogic.setAttribute("org.openecomp.statusofvm", statusofVM); - svcLogic.setAttribute(Constants.STATUS_OF_VM, statusofVM); - svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } - - return server; - } - - /* *********************************************************************************/ - - - /** - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#startServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server startServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, START_SERVICE); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.RESTARTING_SERVER, appName); - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - String providerName = params.get(ProviderAdapter.PROPERTY_PROVIDER_NAME); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - Context context = null; - try { - context = getContext(rc, vm_url, providerName); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - stopServer(rc, server); - server.refreshStatus(); - context.close(); - doSuccess(rc); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - START_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - doFailure(rc, e.getStatus(), e.getMessage()); - } + public Server evacuateServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - return server; + IProviderOperation op = factory.getOperationObject(Operation.EVACUATE_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + // pass this object's reference to EvacuateServer to allow rebuild after evacuate + ((EvacuateServer) op).setProvideAdapterRef(this); + return (Server) op.doOperation(params, context); } - /** - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#stopServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") @Override - public Server stopServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, STOP_SERVICE); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.STOPPING_SERVER, appName); - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - ctx.setAttribute("STOP_STATUS", "SUCCESS"); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - if (server.getStatus().equals(Status.PENDING)) { - throw new RequestFailedException("Server is in pending Status"); - } - stopServer(rc, server); - server.refreshStatus(); - if (server.getStatus().equals(Status.ERROR)) { - throw new RequestFailedException("Server is in ERROR state after operation"); - } - context.close(); - doSuccess(rc); - }else{ - ctx.setAttribute("STOP_STATUS", "SERVER_NOT_FOUND"); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - ctx.setAttribute("STOP_STATUS", "SERVER_NOT_FOUND"); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - STOP_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - ctx.setAttribute("STOP_STATUS", "ERROR"); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - logger.error(EELFResourceManager.format(Msg.STOP_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); - ctx.setAttribute("STOP_STATUS", "ERROR"); - doFailure(rc, e.getStatus(), e.getMessage()); - } + public Server migrateServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - return server; + IProviderOperation op = factory.getOperationObject(Operation.MIGRATE_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /** - * This method is used to validate that the parameters contain all required property names, and that the values are - * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists. - * - * @param ctx - * The request context object that manages the request - * @param parameters - * The parameters to be checked - * @param propertyNames - * The list of property names that are required to be present. - * @throws RequestFailedException - * If the parameters are not valid - */ - @SuppressWarnings({ - "nls", "static-method" - }) - private void validateParametersExist(@SuppressWarnings("unused") RequestContext ctx, Map<String, String> parameters, String... propertyNames) - throws RequestFailedException { - boolean success = true; - StringBuilder msg = new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(MDC_SERVICE))); - msg.append(NL); - for (String propertyName : propertyNames) { - String value = parameters.get(propertyName); - if (value == null || value.trim().length() == 0) { - success = false; - msg.append(QUOTE); - msg.append(propertyName); - msg.append(QUOTE); - msg.append(SPACE); - } - } + @Override + public Server vmStatuschecker(Map<String, String> params, SvcLogicContext context) throws APPCException { - if (!success) { - logger.error(msg.toString()); - throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400, (Server)null); - } + IProviderOperation op = factory.getOperationObject(Operation.VMSTATUSCHECK_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } - /** - * This method is used to create a diagnostic dump of the context for the log - * - * @param context - * The context to be dumped - */ - @SuppressWarnings({ - "nls", "static-method" - }) - private void debugContext(SvcLogicContext context) { - Set<String> keys = context.getAttributeKeySet(); - StringBuilder builder = new StringBuilder(); - - builder.append("Service Logic Context: Status "); - builder.append(LPAREN); - builder.append(context.getStatus()); - builder.append(RPAREN); - builder.append(", Attribute count "); - builder.append(LPAREN); - builder.append(keys == null ? "none" : Integer.toString(keys.size())); - builder.append(RPAREN); - if (keys != null && !keys.isEmpty()) { - builder.append(NL); - for (String key : keys) { - String value = context.getAttribute(key); - builder.append("Attribute "); - builder.append(LPAREN); - builder.append(key); - builder.append(RPAREN); - builder.append(", value "); - builder.append(LPAREN); - builder.append(value == null ? "" : value); - builder.append(RPAREN); - builder.append(NL); - } - } + @Override + public Stack terminateStack(Map<String, String> params, SvcLogicContext context) throws APPCException { - logger.debug(builder.toString()); + IProviderOperation op = factory.getOperationObject(Operation.TERMINATE_STACK); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Stack) op.doOperation(params, context); } - void validateVMURL(VMURL vm) throws RequestFailedException { - String name = "vm-id"; - if (vm == null) { - throw new RequestFailedException(String.format("The value %s cannot be null.", name)); - } - - // Check that its a good uri - // This will probably never get hit bc of an earlier check while parsing - // the string to a VMURL - try { - //noinspection ResultOfMethodCallIgnored - URI.create(vm.toString()); - } catch (Exception e) { - throw new RequestFailedException( - String.format("The value %s is not well formed [%s].", name, vm.toString())); - } - - // Check the tenant and vmid segments - String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})"; - Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE); + @Override + public Stack snapshotStack(Map<String, String> params, SvcLogicContext context) throws APPCException { - if (!pattern.matcher(vm.getTenantId()).matches()) { - throw new RequestFailedException( - String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId())); - } - if (!pattern.matcher(vm.getServerId()).matches()) { - throw new RequestFailedException( - String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId())); - } + IProviderOperation op = factory.getOperationObject(Operation.SNAPSHOT_STACK); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Stack) op.doOperation(params, context); } - @SuppressWarnings("unused") - private void validateIdentityURL(IdentityURL id) throws RequestFailedException { - String name = "identity-url"; - if (id == null) { - throw new RequestFailedException(String.format("The value %s cannot be null.", name)); - } + @Override + public Stack restoreStack(Map<String, String> params, SvcLogicContext context) throws APPCException { - // Check that its a good uri - // This will probably never get hit bc of an earlier check while parsing - // the string to a VMURL - try { - //noinspection ResultOfMethodCallIgnored - URI.create(id.toString()); - } catch (Exception e) { - throw new RequestFailedException( - String.format("The value %s is not well formed [%s].", name, id.toString())); - } + IProviderOperation op = factory.getOperationObject(Operation.RESTORE_STACK); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Stack) op.doOperation(params, context); } - /** - * This method is used to dump the value of the parameters to the log for debugging purposes. - * - * @param parameters - * The parameters to be printed to the log - */ - @SuppressWarnings("static-method") - private void debugParameters(Map<String, String> parameters) { - for (String key : parameters.keySet()) { - logger.debug(Msg.PROPERTY_VALUE, key, parameters.get(key)); - } - } + @Override + public Server lookupServer(Map<String, String> params, SvcLogicContext context) throws APPCException { - /** - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param code - * @param message - */ - @SuppressWarnings("static-method") - private void doFailure(RequestContext rc, HttpStatus code, String message) { - try { - doFailure(rc, code, message, null); - } catch (APPCException ignored) {/* never happens */} + IProviderOperation op = factory.getOperationObject(Operation.LOOKUP_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Server) op.doOperation(params, context); } + @Override + public Image createSnapshot(Map<String, String> params, SvcLogicContext context) throws APPCException { - private void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws APPCException { - SvcLogicContext svcLogic = rc.getSvcLogicContext(); - String msg = (message == null) ? code.getReasonPhrase() : message; - if (msg.contains("\n")) { - msg = msg.substring(0, msg.indexOf("\n")); - } - String status; - try { - status = Integer.toString(code.getStatusCode()); - } catch (Exception e) { - status = "500"; - } - svcLogic.setStatus(OUTCOME_FAILURE); - svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, status); - svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); - svcLogic.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, msg); - - if (null != cause) throw new APPCException(cause); - } - - /** - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - */ - @SuppressWarnings("static-method") - private void doSuccess(RequestContext rc) { - SvcLogicContext svcLogic = rc.getSvcLogicContext(); - svcLogic.setStatus(OUTCOME_SUCCESS); - svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + IProviderOperation op = factory.getOperationObject(Operation.SNAPSHOT_SERVICE); + op.setProviderCache(this.providerCache); + op.setDefaultPass(DEFAULT_PASS); + op.setDefaultUser(DEFAULT_USER); + return (Image) op.doOperation(params, context); } /** - * Generates the event indicating what happened + * Returns the symbolic name of the adapter * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param success - * True if the event represents a successful outcome - * @param msg - * The detailed message + * @return The adapter name + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#getAdapterName() */ - private void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) { - // indication to the DG to generate the event? + @Override + public String getAdapterName() { + return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); } - /** - * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a - * supported provider, regardless of region(s), and to return an opened context that can be used to access that - * server. - * - * @param rc - * The request context that wraps and manages the state of the request - * @param selfLinkURL - * The fully-qualified self-link URL of the server - * @param providerName - * The name of the provider to be searched - * @return The context that can be used to access the server, or null if not found. - */ - @SuppressWarnings("nls") - private Context getContext(RequestContext rc, String selfLinkURL, String providerName) { - VMURL vm = VMURL.parseURL(selfLinkURL); - IdentityURL ident = IdentityURL.parseURL(providerName); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - if (vm == null) { - String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL); - logger.error(msg); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - return null; - } - - /* - * Get the cache of tenants and contexts for the named provider, if one exists - */ - ProviderCache cache = providerCache.get(providerName); - - /* - * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to - * the cache and continue, otherwise fail the request. - */ - if (cache == null) { - if (ident != null) { - cache = createProviderCache(vm, ident); - } - if (cache != null) { - providerCache.put(cache.getProviderName(), cache); - } else { - String msg = - EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName, providerCache.keySet().toString()); - logger.error(msg); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - return null; - } - } - - if (providerName == null) { - logger - .debug(String.format("Using the default provider cache [%s] since no valid identity url was passed in.", - cache.getIdentityURL())); - } - - // get the tenant cache for the vm - String identityURL = cache.getIdentityURL(); - TenantCache tenantCache = cache.getTenant(vm.getTenantId()); - - if(tenantCache == null){ - //no tenantCache matching tenant, add tenant to the provider cache - tenantCache = cache.addTenant(vm.getTenantId(),null,DEFAULT_USER, DEFAULT_PASS); - - if(tenantCache == null){ - //tenant not found - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - return null; - } - } - - //reserve the context - String tenantName = tenantCache.getTenantName(); - String tenantId = tenantCache.getTenantId(); - String region = tenantCache.determineRegion(vm); - - if (region != null) { - Pool<Context> pool = tenantCache.getPools().get(region); - - while (rc.attempt()) { - try { - Context context = pool.reserve(); - - /* - * Insert logic here to test the context for connectivity because we may have gotten one from - * the pool that was previously created. - */ - if (context.isStale()) { - context.relogin(); - } - return context; - } catch (PoolExtensionException e) { - String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL, - tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()), - Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } catch (Exception e) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e, - e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName()); - - logger.error(msg, e); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - return null; - } - } - - String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL); - logger.error(msg); - doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); - return null; - } - - - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - return null; - } /** * initialize the provider adapter by building the context cache @@ -1313,57 +271,57 @@ public class ProviderAdapterImpl implements ProviderAdapter { * <p> * For example, the following definitions show how the namespace hierarchy is defined for two providers, with * two tenants on the first provider and a single tenant for the second provider. <pre> - * provider1.type=OpenStackProvider1 - * provider1.name=OpenStackProviderName1 - * provider1.identity=http://192.168.1.2:5000/v2.0 - * provider1.tenant1.name=MY-TENANT-NAME - * provider1.tenant1.userid=userid - * provider1.tenant1.password=userid@123 - * provider1.tenant2.name=MY-TENANT-NAME - * provider1.tenant2.userid=userid - * provider1.tenant2.password=userid@123 - * provider2.type=OpenStackProvider2 - * provider2.name=OpenStackProviderName2 - * provider2.identity=http://192.168.1.2:5000/v2.0 - * provider2.tenant1.name=MY-TENANT-NAME - * provider2.tenant1.userid=userid - * provider2.tenant1.password=userid@123 + * provider1.type=OpenStackProvider + * provider1.name=ILAB + * provider1.identity=http://provider1:5000/v2.0 + * provider1.tenant1.name=CDP-ONAP-APPC + * provider1.tenant1.userid=cdpdev + * provider1.tenant1.password=cdpdev@123 + * provider1.tenant2.name=TEST-TENANT + * provider1.tenant2.userid=testUser + * provider1.tenant2.password=testPassword + * provider2.type=OpenStackProvider + * provider2.name=PDK1 + * provider2.identity=http://provider2:5000/v2.0 + * provider2.tenant1.name=someName + * provider2.tenant1.userid=someUser + * provider2.tenant1.password=somePassword * </pre> * </p> */ providerCache = new HashMap<>(); Properties properties = configuration.getProperties(); - List<Node> providers = StructuredPropertyHelper.getStructuredProperties(properties, PROPERTY_PROVIDER); + List<Node> providers = StructuredPropertyHelper.getStructuredProperties(properties, Property.PROVIDER); for (Node provider : providers) { ProviderCache cache = new ProviderCache(); List<Node> providerNodes = provider.getChildren(); for (Node node : providerNodes) { - if (node.getName().equals(PROPERTY_PROVIDER_TYPE)) { + if (node.getName().equals(Property.PROVIDER_TYPE)) { cache.setProviderType(node.getValue()); - } else if (node.getName().equals(PROPERTY_PROVIDER_IDENTITY)) { + } else if (node.getName().equals(Property.PROVIDER_IDENTITY)) { cache.setIdentityURL(node.getValue()); cache.setProviderName(node.getValue()); - } else if (node.getName().startsWith(PROPERTY_PROVIDER_TENANT)) { + } else if (node.getName().startsWith(Property.PROVIDER_TENANT)) { String tenantName = null; String userId = null; String password = null; for (Node node2 : node.getChildren()) { switch (node2.getName()) { - case PROPERTY_PROVIDER_TENANT_NAME: + case Property.PROVIDER_TENANT_NAME: tenantName = node2.getValue(); break; - case PROPERTY_PROVIDER_TENANT_USERID: + case Property.PROVIDER_TENANT_USERID: userId = node2.getValue(); DEFAULT_USER = node2.getValue(); break; - case PROPERTY_PROVIDER_TENANT_PASSWORD: + case Property.PROVIDER_TENANT_PASSWORD: password = node2.getValue(); DEFAULT_PASS = node2.getValue(); break; } } - + cache.addTenant(null, tenantName, userId, password); } } @@ -1383,1341 +341,4 @@ public class ProviderAdapterImpl implements ProviderAdapter { } } - /** - * This method is called to rebuild the provided server. - * <p> - * If the server was booted from a volume, then the request is failed immediately and no action is taken. Rebuilding - * a VM from a bootable volume, where the bootable volume itself is not rebuilt, serves no purpose. - * </p> - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void rebuildServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - - ServerBootSource builtFrom = server.getBootSource(); - String msg; - - // Throw exception for non image/snap boot source - if (ServerBootSource.VOLUME.equals(builtFrom)) { - msg = String.format("Rebuilding is currently not supported for servers built from bootable volumes [%s]", - server.getId()); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server); - } - /* - * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the - * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down - * to one we can deal with. If not, then we have to fail the request. - */ - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - if (server.getStatus().equals(Status.PENDING)) { - waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); - } - - /* - * Get the image to use. This is determined by the presence or absence of snapshot images. If any snapshots - * exist, then the latest snapshot is used, otherwise the image used to construct the VM is used. - */ - List<Image> snapshots = server.getSnapshots(); - String imageToUse; - if (snapshots != null && !snapshots.isEmpty()) { - imageToUse = snapshots.get(0).getId(); - } else { - imageToUse = server.getImage(); - ImageService imageService = server.getContext().getImageService(); - try { - while (rc.attempt()) { - try { - /* - * We are just trying to make sure that the image exists. We arent interested in the details at - * this point. - */ - imageService.getImage(imageToUse); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), - imageService.getURL(), context.getTenant().getName(), context.getTenant().getId(), - e.getMessage(), Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - } catch (ZoneException e) { - msg = EELFResourceManager.format(Msg.IMAGE_NOT_FOUND, imageToUse, "rebuild"); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - - /* - * We determine what to do based on the current state of the server - */ - switch (server.getStatus()) { - case DELETED: - // Nothing to do, the server is gone - msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), - server.getTenantId(), "rebuilt"); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - - case RUNNING: - // Attempt to stop the server, then rebuild it - stopServer(rc, server); - rebuildServer(rc, server, imageToUse); - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case ERROR: - msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), - server.getTenantId(), "rebuild"); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - - case READY: - // Attempt to rebuild the server - rebuildServer(rc, server, imageToUse); - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case PAUSED: - // if paused, un-pause it, stop it, and rebuild it - unpauseServer(rc, server); - stopServer(rc, server); - rebuildServer(rc, server, imageToUse); - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case SUSPENDED: - // Attempt to resume the suspended server, stop it, and rebuild it - resumeServer(rc, server); - stopServer(rc, server); - rebuildServer(rc, server, imageToUse); - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - default: - // Hmmm, unknown status, should never occur - msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), - server.getTenantId(), server.getStatus().name()); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - } - } - - /** - * This method handles the case of restarting a server once we have found the server and have obtained the abstract - * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server object representing the server we want to operate on - * @throws ZoneException - */ - @SuppressWarnings("nls") - private void restartServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - /* - * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the - * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down - * to one we can deal with. If not, then we have to fail the request. - */ - String msg; - if (server.getStatus().equals(Status.PENDING)) { - waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); - } - - /* - * We determine what to do based on the current state of the server - */ - switch (server.getStatus()) { - case DELETED: - // Nothing to do, the server is gone - msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), - server.getTenantId(), "restarted"); - generateEvent(rc, false, msg); - logger.error(msg); - break; - - case RUNNING: - // Attempt to stop and start the server - stopServer(rc, server); - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case ERROR: - msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), - server.getTenantId(), "rebuild"); - generateEvent(rc, false, msg); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); - - case READY: - // Attempt to start the server - startServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case PAUSED: - // if paused, un-pause it - unpauseServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case SUSPENDED: - // Attempt to resume the suspended server - resumeServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - default: - // Hmmm, unknown status, should never occur - msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), - server.getTenantId(), server.getStatus().name()); - generateEvent(rc, false, msg); - logger.error(msg); - break; - } - - } - - /** - * Resume a suspended server and wait for it to enter a running state - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to be resumed - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - logger.debug(Msg.RESUME_SERVER, server.getId()); - - Context context = server.getContext(); - String msg; - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - while (rc.attempt()) { - try { - server.resume(); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - waitForStateChange(rc, server, Status.RUNNING); - } - - /** - * Start the server and wait for it to enter a running state - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to be started - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - logger.debug(Msg.START_SERVER, server.getId()); - String msg; - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - while (rc.attempt()) { - try { - server.start(); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - waitForStateChange(rc, server, Status.RUNNING); - } - - /** - * Stop the specified server and wait for it to stop - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to be stopped - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - logger.debug(Msg.STOP_SERVER, server.getId()); - - String msg; - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - while (rc.attempt()) { - try { - server.stop(); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - waitForStateChange(rc, server, Status.READY, Status.ERROR); - } - - /** - * Un-Pause a paused server and wait for it to enter a running state - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to be un-paused - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - logger.debug(Msg.UNPAUSE_SERVER, server.getId()); - - String msg; - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - while (rc.attempt()) { - try { - server.unpause(); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - waitForStateChange(rc, server, Status.RUNNING, Status.READY); - } - - /** - * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. - * <p> - * This method checks the state of the server periodically for one of the desired states. When the server enters one - * of the desired states, the method returns a successful indication (true). If the server never enters one of the - * desired states within the allocated timeout period, then the method returns a failed response (false). No - * exceptions are thrown from this method. - * </p> - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to wait on - * @param desiredStates - * A variable list of desired states, any one of which is allowed. - * @throws RequestFailedException - * If the request times out or fails for some reason - */ - @SuppressWarnings("nls") - private void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates) - throws RequestFailedException { - int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); - int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - String msg; - - long endTime = System.currentTimeMillis() + (timeout * 1000); // - - while (rc.attempt()) { - try { - try { - server.waitForStateChange(pollInterval, timeout, desiredStates); - break; - } catch (TimeoutException e) { - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - List<String> list = new ArrayList<>(); - for (Server.Status desiredState : desiredStates) { - list.add(desiredState.name()); - } - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } catch (ZoneException e) { - List<String> list = new ArrayList<>(); - for (Server.Status desiredState : desiredStates) { - list.add(desiredState.name()); - } - String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), - "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(), - e.getMessage()); - logger.error(reason); - logger.error(EELFResourceManager.format(e)); - - // Instead of failing we are going to wait and try again. - // Timeout is reduced by delay time - logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); - rc.delay(); - timeout = (int) (endTime - System.currentTimeMillis()) / 1000; - // throw new RequestFailedException(e, operation, reason, - // HttpStatus.BAD_GATEWAY_502, server); - } - } - - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - } - - /** - * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. - * <p> - * This method checks the state of the server periodically for one of the desired states. When the server enters one - * of the desired states, the method returns a successful indication (true). If the server never enters one of the - * desired states within the allocated timeout period, then the method returns a failed response (false). No - * exceptions are thrown from this method. - * </p> - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param image - * The server to wait on - * @param desiredStates - * A variable list of desired states, any one of which is allowed. - * @throws RequestFailedException - * If the request times out or fails for some reason - * @throws NotLoggedInException - */ - @SuppressWarnings("nls") - private void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates) - throws RequestFailedException, NotLoggedInException { - int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); - int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); - Context context = image.getContext(); - Provider provider = context.getProvider(); - ImageService service = context.getImageService(); - String msg; - - long endTime = System.currentTimeMillis() + (timeout * 1000); // - - while (rc.attempt()) { - try { - try { - image.waitForStateChange(pollInterval, timeout, desiredStates); - break; - } catch (TimeoutException e) { - @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") - List<String> list = new ArrayList<>(); - for (Image.Status desiredState : desiredStates) { - list.add(desiredState.name()); - } - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } catch (ZoneException e) { - List<String> list = new ArrayList<>(); - for (Image.Status desiredState : desiredStates) { - list.add(desiredState.name()); - } - String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), - "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(), - e.getMessage()); - logger.error(reason); - logger.error(EELFResourceManager.format(e)); - - // Instead of failing we are going to wait and try again. - // Timeout is reduced by delay time - logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); - rc.delay(); - timeout = (int) (endTime - System.currentTimeMillis()) / 1000; - // throw new RequestFailedException(e, operation, reason, - // HttpStatus.BAD_GATEWAY_502, server); - } - } - - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server()); - } - rc.reset(); - } - - /** - * Rebuild the indicated server with the indicated image. This method assumes the server has been determined to be - * in the correct state to do the rebuild. - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * the server to be rebuilt - * @param image - * The image to be used (or snapshot) - * @throws RequestFailedException - * if the server does not change state in the allotted time - */ - @SuppressWarnings("nls") - private void rebuildServer(RequestContext rc, Server server, String image) throws RequestFailedException { - String msg; - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - - try { - while (rc.attempt()) { - try { - server.rebuild(image); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - - /* - * We need to provide some time for OpenStack to start processing the request. - */ - try { - Thread.sleep(10L * 1000L); - } catch (InterruptedException e) { - logger.trace("Sleep threw interrupted exception, should never occur"); - } - } catch (ZoneException e) { - msg = - EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), e.getMessage()); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - - /* - * Once we have started the process, now we wait for the final state of stopped. This should be the final state - * (since we started the rebuild with the server stopped). - */ - waitForStateChange(rc, server, Status.READY); - - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - } - - /** - * Looks up the indicated server using the provided context and returns the server to the caller - * - * @param rc - * The request context - * @param context - * The provider context - * @param id - * The id of the server - * @return The server, or null if there is a problem - * @throws ZoneException - * If the server cannot be found - * @throws RequestFailedException - * If the server cannot be found because we cant connect to the provider - */ - @SuppressWarnings("nls") - private Server lookupServer(RequestContext rc, Context context, String id) - throws ZoneException, RequestFailedException { - ComputeService service = context.getComputeService(); - Server server = null; - String msg; - Provider provider = context.getProvider(); - - while (rc.attempt()) { - try { - server = service.getServer(id); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); - throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - return server; - } - - private String getConnectionExceptionMessage(RequestContext rc, Context ctx, ContextConnectionException e) - throws ZoneException { - return EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, ctx.getProvider().getName(), - ctx.getComputeService().getURL(), ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - } - - private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) { - if (vm != null && ident != null) { - ProviderCache cache = new ProviderCache(); - - cache.setIdentityURL(ident.toString()); - cache.setProviderName(ident.toString()); - // cache.setProviderType("OpenStack"); - - TenantCache tenant = cache.addTenant(vm.getTenantId(),null, DEFAULT_USER, DEFAULT_PASS); - - // Make sure we could initialize the the cache otherwise return null - if (tenant != null && tenant.isInitialized()) { - return cache; - } - } - return null; - } - - /** - * This method is used to delete an existing virtual machine given the fully qualified URL of the machine. - * <p> - * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form - * <pre> - * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] - * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service - * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the - * server by its UUID, and then perform the restart. - * </p> - * - * @throws UnknownProviderException - * If the provider cannot be found - * @throws IllegalArgumentException - * if the expected argument(s) are not defined or are invalid - * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#terminateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) - */ - @SuppressWarnings("nls") - @Override - public Server terminateServer(Map<String, String> params, SvcLogicContext ctx) - throws UnknownProviderException, IllegalArgumentException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, TERMINATE_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:Terminate"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - if (logger.isDebugEnabled()) { - logger.debug("Inside org.openecomp.appc.adapter.iaas.impl.ProviderAdapter.terminateServer"); - } - - try { - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - debugParameters(params); - debugContext(ctx); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); - - VMURL vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - Context context = null; - try { - context = getContext(rc, vm_url, identStr); - if (context != null) { - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - logger.info(EELFResourceManager.format(Msg.TERMINATING_SERVER, server.getName())); - terminateServer(rc, server); - logger.info(EELFResourceManager.format(Msg.TERMINATE_SERVER, server.getName())); - context.close(); - doSuccess(rc); - }else{ - ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - RESTART_SERVICE, vm_url, context == null ? "Unknown" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - logger.error(EELFResourceManager.format(Msg.TERMINATE_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); - doFailure(rc, e.getStatus(), e.getMessage()); - ctx.setAttribute("TERMINATE_STATUS", "ERROR"); - } - - return server; - } - - /** - * This method handles the case of restarting a server once we have found the server and have obtained the abstract - * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server object representing the server we want to operate on - * @throws ZoneException - */ - @SuppressWarnings("nls") - private void terminateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - /* - * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the - * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down - * to one we can deal with. If not, then we have to fail the request. - */ - String msg; - if (server.getStatus().equals(Status.PENDING)) { - waitForStateChange(rc, server, Status.READY, Status.RUNNING, Status.ERROR, Status.SUSPENDED, Status.PAUSED); - } - - /* - * We determine what to do based on the current state of the server - */ - switch (server.getStatus()) { - case DELETED: - // Nothing to do, the server is gone - msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), - server.getTenantId(), "restarted"); - generateEvent(rc, false, msg); - logger.error(msg); - break; - - case RUNNING: - // Attempt to stop and start the server - logger.info("stopping SERVER"); - stopServer(rc, server); - deleteServer(rc, server); - logger.info("after delete SERVER"); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - case ERROR: - - case READY: - - case PAUSED: - - case SUSPENDED: - // Attempt to delete the suspended server - deleteServer(rc, server); - generateEvent(rc, true, OUTCOME_SUCCESS); - break; - - default: - // Hmmm, unknown status, should never occur - msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), - server.getTenantId(), server.getStatus().name()); - generateEvent(rc, false, msg); - logger.error(msg); - break; - } - - } - - /** - * Start the server and wait for it to enter a running state - * - * @param rc - * The request context that manages the state and recovery of the request for the life of its processing. - * @param server - * The server to be started - * @throws ZoneException - * @throws RequestFailedException - */ - @SuppressWarnings("nls") - private void deleteServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { - String msg; - Context context = server.getContext(); - Provider provider = context.getProvider(); - ComputeService service = context.getComputeService(); - while (rc.attempt()) { - try { - logger.info("deleting SERVER"); - server.delete(); - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); - logger.error(msg); - throw new RequestFailedException("Delete Server", msg, HttpStatus.BAD_GATEWAY_502, server); - } - rc.reset(); - } - - private boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) { - logger.info("Checking permissions for image service."); - try { - ImageService service = context.getImageService(); - service.getImageByName("CHECK_IMAGE_ACCESS"); - logger.info("Image service is accessible."); - return true; - } catch (ZoneException e) { - logger.warn("Image service could not be accessed. Some operations may fail.", e); - return false; - } - } - - @SuppressWarnings("nls") - @Override - public Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { - Stack stack = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - - ctx.setAttribute("TERMINATE_STATUS", "STACK_NOT_FOUND"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - try { - - logAndValidate(params, ctx, rc, TERMINATE_STACK, "Terminate Stack", - ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME, - ProviderAdapter.PROPERTY_STACK_ID); - - String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); - String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - - Context context = resolveContext(rc, params, appName, vm_url); - - try { - if (context != null) { - stack = lookupStack(rc, context, stackId); - logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); - logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName())); - deleteStack(rc, stack); - logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName())); - context.close(); - doSuccess(rc); - }else{ - ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); - } - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - TERMINATE_STACK, vm_url, context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - } catch (RequestFailedException e) { - logger.error(EELFResourceManager.format(Msg.TERMINATE_STACK_FAILED, appName, "n/a", "n/a")); - doFailure(rc, e.getStatus(), e.getMessage()); - } - return stack; - } - - @Override - public Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { - Stack stack = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - - ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - String vm_url = null; - Context context = null; - try { - - logAndValidate(params, ctx, rc, SNAPSHOT_STACK, "Snapshot Stack", - ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME, - ProviderAdapter.PROPERTY_STACK_ID); - - String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); - vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - - context = resolveContext(rc, params, appName, vm_url); - - if (context != null) { - stack = lookupStack(rc, context, stackId); - logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); - logger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName())); - - Snapshot snapshot = snapshotStack(rc, stack); - - ctx.setAttribute(ProviderAdapter.DG_OUTPUT_PARAM_NAMESPACE + - ProviderAdapter.PROPERTY_SNAPSHOT_ID, snapshot.getId()); - - logger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId())); - context.close(); - doSuccess(rc); - } else { - ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); - } - - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); - } catch (RequestFailedException e) { - logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack")); - doFailure(rc, e.getStatus(), e.getMessage(), e); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - "snapshotStack", vm_url, null == context ? "n/a" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); - } - return stack; - } - - @Override - public Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { - Stack stack = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); - - ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - String vm_url = null; - Context context = null; - - try { - - logAndValidate(params, ctx, rc, SNAPSHOT_STACK, "Snapshot Stack", - ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME, - ProviderAdapter.PROPERTY_STACK_ID, - ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); - - String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); - vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - - String snapshotId = params.get(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); - - context = resolveContext(rc, params, appName, vm_url); - - if (context != null) { - stack = lookupStack(rc, context, stackId); - logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); - logger.info(EELFResourceManager.format(Msg.RESTORING_STACK, stack.getName(), snapshotId)); - restoreStack(stack, snapshotId); - logger.info(EELFResourceManager.format(Msg.STACK_RESTORED, stack.getName(), snapshotId)); - context.close(); - doSuccess(rc); - } else { - ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); - } - - } catch (ResourceNotFoundException e) { - String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); - } catch (RequestFailedException e) { - logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "restoreStack")); - doFailure(rc, e.getStatus(), e.getMessage(), e); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - "restoreStack", vm_url, null == context ? "n/a" : context.getTenantName()); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); - } - return stack; - } - - private void logAndValidate(Map<String, String> params, SvcLogicContext ctx, RequestContext rc, String methodName, String serviceName, String ... attributes) - throws RequestFailedException { - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, SNAPSHOT_STACK); - MDC.put(MDC_SERVICE_NAME, String.format("App-C IaaS Adapter:%s", serviceName)); - if (logger.isDebugEnabled()) { - logger.debug(String.format("Inside org.openecomp.appc.adapter.iaas.impl.ProviderAdapter.%s", methodName)); - } - - validateParametersExist(rc, params, attributes); - - debugParameters(params); - debugContext(ctx); - } - - private Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vm_url) - throws RequestFailedException { - - VMURL vm = VMURL.parseURL(vm_url); - if (vm == null) { - String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - logger.error(msg); - return null; - } - validateVMURL(vm); - IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); - String identStr = (ident == null) ? null : ident.toString(); - - return getContext(rc, vm_url, identStr); - - } - - private void deleteStack(RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { - SvcLogicContext ctx = rc.getSvcLogicContext(); - Context context = stack.getContext(); - StackService stackService = context.getStackService(); - logger.debug("Deleting Stack: " + "id:{ " + stack.getId() + "}"); - stackService.deleteStack(stack); - - // wait for the stack deletion - boolean success = waitForStackStatus(rc, stack, Stack.Status.DELETED); - if (success) { - ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); - } else { - ctx.setAttribute("TERMINATE_STATUS", "ERROR"); - throw new RequestFailedException("Delete Stack failure : " + Msg.STACK_OPERATION_EXCEPTION.toString()); - } - } - - private boolean waitForStackStatus(RequestContext rc, Stack stack, Stack.Status expectedStatus) throws ZoneException, RequestFailedException { - SvcLogicContext ctx = rc.getSvcLogicContext(); - Context context = stack.getContext(); - StackService stackService = context.getStackService(); - - int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); - int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); - long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; - Stack.Status stackStatus; - while (System.currentTimeMillis() < maxTimeToWait) { - stackStatus = stackService.getStack(stack.getName(), stack.getId()).getStatus(); - logger.debug("Stack status : " + stackStatus.toString()); - if (stackStatus == expectedStatus) { - return true; - } else if (stackStatus == Stack.Status.FAILED) { - return false; - } else { - try { - Thread.sleep(pollInterval * 1000); - } catch (InterruptedException e) { - logger.trace("Sleep threw interrupted exception, should never occur"); - } - } - } - - ctx.setAttribute("TERMINATE_STATUS", "ERROR"); - throw new TimeoutException("Timeout waiting for stack status change"); - - } - - private Snapshot snapshotStack(@SuppressWarnings("unused") RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { - Snapshot snapshot = new Snapshot(); - Context context = stack.getContext(); - - OpenStackContext osContext = (OpenStackContext)context; - - final HeatConnector heatConnector = osContext.getHeatConnector(); - ((OpenStackContext)context).refreshIfStale(heatConnector); - - trackRequest(context); - RequestState.put("SERVICE", "Orchestration"); - RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); - - Heat heat = heatConnector.getClient(); - - SnapshotResource snapshotResource = new SnapshotResource(heat); - - try { - - snapshot = snapshotResource.create(stack.getName(), stack.getId(), new CreateSnapshotParams()).execute(); - - // wait for the stack deletion - StackResource stackResource = new StackResource(heat); - if (!waitForStack(stack, stackResource, "SNAPSHOT_COMPLETE")) { - throw new RequestFailedException("Stack Snapshot failed."); - } - - } catch (OpenStackBaseException e) { - ExceptionMapper.mapException(e); - } - - return snapshot; - } - - private void restoreStack(Stack stack, String snapshotId) throws ZoneException, RequestFailedException { - Context context = stack.getContext(); - - OpenStackContext osContext = (OpenStackContext)context; - - final HeatConnector heatConnector = osContext.getHeatConnector(); - ((OpenStackContext)context).refreshIfStale(heatConnector); - - trackRequest(context); - RequestState.put("SERVICE", "Orchestration"); - RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); - - Heat heat = heatConnector.getClient(); - - SnapshotResource snapshotResource = new SnapshotResource(heat); - - try { - - snapshotResource.restore(stack.getName(), stack.getId(), snapshotId).execute(); - - // wait for the snapshot restore - StackResource stackResource = new StackResource(heat); - if (!waitForStack(stack, stackResource, "RESTORE_COMPLETE")) { - throw new RequestFailedException("Snapshot restore failed."); - } - - } catch (OpenStackBaseException e) { - ExceptionMapper.mapException(e); - } - - } - - private boolean waitForStack(Stack stack, StackResource stackResource, String expectedStatus) - throws OpenStackBaseException, TimeoutException { - int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); - int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); - long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; - - while (System.currentTimeMillis() < maxTimeToWait) { - String stackStatus = stackResource.show(stack.getName(), stack.getId()).execute().getStackStatus(); - logger.debug("Stack status : " + stackStatus); - if (stackStatus.toUpperCase().contains("FAILED")) return false; - if(checkStatus(expectedStatus, pollInterval, stackStatus)) return true; - } - throw new TimeoutException("Timeout waiting for stack status change"); - } - - private boolean checkStatus(String expectedStatus, int pollInterval, String actualStatus) { - if (actualStatus.toUpperCase().equals(expectedStatus)) { - return true; - } else { - try { - Thread.sleep(pollInterval * 1000); - } catch (InterruptedException ignored) { - } - } - return false; - } - - private void trackRequest(Context context, AbstractService.State... states) { - RequestState.clear(); - - if (null == states) return; - for (AbstractService.State state : states) { - RequestState.put(state.getName(), state.getValue()); - } - - Thread currentThread = Thread.currentThread(); - StackTraceElement[] stack = currentThread.getStackTrace(); - if (stack != null && stack.length > 0) { - int index = 0; - StackTraceElement element; - for (; index < stack.length; index++) { - element = stack[index]; - if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$ - break; - } - } - index++; - - if (index < stack.length) { - element = stack[index]; - RequestState.put(RequestState.METHOD, element.getMethodName()); - RequestState.put(RequestState.CLASS, element.getClassName()); - RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber())); - RequestState.put(RequestState.THREAD, currentThread.getName()); - RequestState.put(RequestState.PROVIDER, context.getProvider().getName()); - RequestState.put(RequestState.TENANT, context.getTenantName()); - RequestState.put(RequestState.PRINCIPAL, context.getPrincipal()); - } - } - } - - private Stack lookupStack(RequestContext rc, Context context, String id) - throws ZoneException, RequestFailedException { - StackService stackService = context.getStackService(); - Stack stack = null; - String msg; - Provider provider = context.getProvider(); - while (rc.attempt()) { - try { - List<Stack> stackList = stackService.getStacks(); - for (Stack stackObj : stackList) { - if (stackObj.getId().equals(id)) { - stack = stackObj; - break; - } - } - break; - } catch (ContextConnectionException e) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), stackService.getURL(), - context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), - Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), - Integer.toString(rc.getRetryLimit())); - logger.error(msg, e); - rc.delay(); - } - - } - if (rc.isFailed()) { - msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), stackService.getURL()); - logger.error(msg); - doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); - throw new RequestFailedException("Lookup Stack", msg, HttpStatus.BAD_GATEWAY_502, stack); - } - - if (stack == null) { - throw new ResourceNotFoundException("Stack not found with Id : {" + id + "}"); - } - return stack; - } - - @SuppressWarnings("nls") - @Override - public Server lookupServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Server server = null; - RequestContext rc = new RequestContext(ctx); - rc.isAlive(); //should we test the return and fail if false? - MDC.put(MDC_ADAPTER, ADAPTER_NAME); - MDC.put(MDC_SERVICE, LOOKUP_SERVICE); - MDC.put(MDC_SERVICE_NAME, "App-C IaaS Adapter:LookupServer"); - String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - - //for debugging merge into single method? - debugParameters(params); - debugContext(ctx); - - String vm_url = null; - VMURL vm = null; - try { - - //process vm_url - validateParametersExist(rc, params, ProviderAdapter.PROPERTY_INSTANCE_URL, - ProviderAdapter.PROPERTY_PROVIDER_NAME); - vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); - vm = VMURL.parseURL(vm_url); - if (validateVM(rc, appName, vm_url, vm)) return null; - - - //use try with resource to ensure context is closed (returned to pool) - try(Context context = resolveContext(rc, params, appName, vm_url)){ - //resloveContext & getContext call doFailure and log errors before returning null - if (context != null){ - server = lookupServer(rc, context, vm.getServerId()); - logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); - ctx.setAttribute("serverFound", "success"); - doSuccess(rc); - } - } catch (ZoneException e) { - //server not found - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - ctx.setAttribute("serverFound", "failure"); - } catch (IOException e) { - //exception closing context - String msg = EELFResourceManager.format(Msg.CLOSE_CONTEXT_FAILED, e, vm_url); - logger.error(msg); - } catch (Throwable t) { - String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), - LOOKUP_SERVICE, vm_url, "Unknown" ); - logger.error(msg, t); - doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); - } - - } catch (RequestFailedException e) { - // parameters not valid, unable to connect to provider - String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); - logger.error(msg); - doFailure(rc, HttpStatus.NOT_FOUND_404, msg); - ctx.setAttribute("serverFound", "failure"); - } - return server; - } } diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java index 8ac81b2b9..adf6a4039 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/ServiceCatalog.java @@ -45,7 +45,6 @@ import com.att.cdp.zones.spi.AbstractService; import com.att.cdp.zones.spi.RequestState; import com.att.cdp.zones.spi.AbstractService.State; -import com.sun.jersey.api.client.ClientHandlerException; import com.woorea.openstack.base.client.OpenStackBaseException; import com.woorea.openstack.base.client.OpenStackClientConnector; import com.woorea.openstack.base.client.OpenStackResponseException; @@ -168,7 +167,7 @@ public class ServiceCatalog { */ private OpenStackSimpleTokenProvider tokenProvider; - public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JerseyConnector"; + public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JaxRs20Connector"; /** * Create the ServiceCatalog cache and load it from the specified provider diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java index c0c114dc8..07c934004 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/impl/TenantCache.java @@ -43,8 +43,8 @@ import com.att.cdp.zones.ContextFactory; import com.att.cdp.zones.Provider; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; - -import com.sun.jersey.api.client.ClientHandlerException; +import com.woorea.openstack.connector.JaxRs20Connector; +//import com.sun.jersey.api.client.ClientHandlerException; import com.woorea.openstack.keystone.model.Access.Service.Endpoint; /** @@ -60,8 +60,8 @@ public class TenantCache implements Allocator<Context>, Destructor<Context> { public static final String POOL_PROVIDER_NAME = "pool.provider.name"; public static final String POOL_TENANT_NAME = "pool.tenant.name"; - public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JerseyConnector"; - + //public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JerseyConnector"; + public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JaxRs20Connector"; /** * The provider we are part of */ @@ -198,15 +198,17 @@ public class TenantCache implements Allocator<Context>, Destructor<Context> { break; } catch (ContextConnectionException e) { attempt++; - logger.error(Msg.CONNECTION_FAILED_RETRY, provider.getProviderName(), url, tenantName, tenantId, e.getMessage(), Integer.toString(delay), Integer.toString(attempt), - Integer.toString(limit)); + if (attempt <= limit) { + logger.error(Msg.CONNECTION_FAILED_RETRY, provider.getProviderName(), url, tenantName, tenantId, e.getMessage(), Integer.toString(delay), Integer.toString(attempt), + Integer.toString(limit)); - try { - Thread.sleep(delay * 1000L); - } catch (InterruptedException ie) { - // ignore + try { + Thread.sleep(delay * 1000L); + } catch (InterruptedException ie) { + // ignore + } } - } catch (ClientHandlerException | ZoneException e) { + } catch ( ZoneException e) { logger.error(e.getMessage()); break; } diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java new file mode 100644 index 000000000..0bdc7669f --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java @@ -0,0 +1,61 @@ +/*- + * ============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.adapter.iaas.provider.operation.api; + +import org.openecomp.appc.adapter.iaas.impl.ProviderCache; +import org.openecomp.appc.exceptions.APPCException; +import com.att.cdp.zones.model.ModelObject; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.Map; + +/** + * @since September 26, 2016 + */ +public interface IProviderOperation { + + /** + * perform specific provider operation + * @param params + * @param context + * @return Object represents Stack, Server Or Image + */ + ModelObject doOperation(Map<String,String> params, SvcLogicContext context) throws APPCException; + + /** + * sets a cache of providers that are predefined. + * @param providerCache + */ + void setProviderCache(Map<String /* provider name */, ProviderCache> providerCache); + + /** + * should be initialized by user + * @param defaultUser + */ + void setDefaultUser(String defaultUser); + + /** + * should be initialized by user + * @param defaultPass + */ + void setDefaultPass(String defaultPass); +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java new file mode 100644 index 000000000..dd604a555 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java @@ -0,0 +1,119 @@ +/*- + * ============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.adapter.iaas.provider.operation.api; + +import org.openecomp.appc.adapter.iaas.provider.operation.impl.*; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.exceptions.APPCException; + +import java.util.HashMap; +import java.util.Map; + +/** + * Singleton factory of provider operations objects with cache + * @since September 26, 2016 + */ +public class ProviderOperationFactory { + + /** + * holds instance of the class + */ + private static ProviderOperationFactory instance; + + /** + * holds concrete operations objects + */ + private Map<Operation, IProviderOperation> operations; + + /** + * private constructor + */ + private ProviderOperationFactory() { + this.operations = new HashMap<>(); + } + + /** + * @return instance of the factory + */ + public static ProviderOperationFactory getInstance() { + if (instance == null) { + instance = new ProviderOperationFactory(); + } + return instance; + } + + /** + * @param op + * @return concrete operation impl + */ + public IProviderOperation getOperationObject(Operation op) throws APPCException { + + IProviderOperation opObject = operations.get(op); + if (opObject == null) { + switch (op) { + case EVACUATE_SERVICE: + opObject = new EvacuateServer(); + break; + case MIGRATE_SERVICE: + opObject = new MigrateServer(); + break; + case REBUILD_SERVICE: + opObject = new RebuildServer(); + break; + case RESTART_SERVICE: + opObject = new RestartServer(); + break; + case VMSTATUSCHECK_SERVICE: + opObject = new VmStatuschecker(); + break; + case SNAPSHOT_SERVICE: + opObject = new CreateSnapshot(); + break; + case TERMINATE_STACK: + opObject = new TerminateStack(); + break; + case SNAPSHOT_STACK: + opObject = new SnapshotStack(); + break; + case RESTORE_STACK: + opObject = new RestoreStack(); + break; + case START_SERVICE: + opObject = new StartServer(); + break; + case STOP_SERVICE: + opObject = new StopServer(); + break; + case TERMINATE_SERVICE: + opObject = new TerminateServer(); + break; + case LOOKUP_SERVICE: + opObject = new LookupServer(); + break; + default: + throw new APPCException("Unsupported provider operation."); + } + operations.put(op,opObject); + } + return opObject; + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java new file mode 100644 index 000000000..e3c592c89 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.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.adapter.iaas.provider.operation.common.constants; + +/** + * @since September 26, 2016 + */ +public class Constants { + + public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + public static final String MDC_SERVICE = "service"; + public static final String MDC_ADAPTER = "adapter"; + + /** + * The constant for a left parenthesis + */ + public static final char LPAREN = '('; + + /** + * The constant for a new line control code + */ + public static final char NL = '\n'; + + /** + * The constant for a single quote + */ + public static final char QUOTE = '\''; + + /** + * The constant for a right parenthesis + */ + public static final char RPAREN = ')'; + + /** + * The constant for a space + */ + public static final char SPACE = ' '; +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java new file mode 100644 index 000000000..702c469cb --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java @@ -0,0 +1,36 @@ +/*- + * ============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.adapter.iaas.provider.operation.common.constants; + +/** + * @since September 26, 2016 + */ +public class Property { + + public static final String PROVIDER = "provider"; + public static final String PROVIDER_IDENTITY = "identity"; + public static final String PROVIDER_TENANT = "tenant"; + public static final String PROVIDER_TENANT_NAME = "name"; + public static final String PROVIDER_TENANT_PASSWORD = "password"; + public static final String PROVIDER_TENANT_USERID = "userid"; + public static final String PROVIDER_TYPE = "type"; +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java new file mode 100644 index 000000000..768ccc0c0 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java @@ -0,0 +1,93 @@ +/*- + * ============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.adapter.iaas.provider.operation.common.enums; + +/** + * @since September 26, 2016 + */ +public enum Operation { + EVACUATE_SERVICE { + public String toString(){ + return "evacuateServer"; + } + }, + MIGRATE_SERVICE { + public String toString(){ + return "migrateServer"; + } + }, + REBUILD_SERVICE { + public String toString(){ + return "rebuildServer"; + } + }, + RESTART_SERVICE { + public String toString(){ + return "restartServer"; + } + }, + VMSTATUSCHECK_SERVICE { + public String toString(){ + return "vmStatuschecker"; + } + }, + SNAPSHOT_SERVICE { + public String toString(){ + return "createSnapshot"; + } + }, + TERMINATE_STACK { + public String toString(){ + return "terminateStack"; + } + }, + SNAPSHOT_STACK { + public String toString(){ + return "snapshotStack"; + } + }, + START_SERVICE { + public String toString(){ + return "startServer"; + } + }, + STOP_SERVICE { + public String toString(){ + return "stopServer"; + } + }, + TERMINATE_SERVICE { + public String toString(){ + return "terminateServer"; + } + }, + LOOKUP_SERVICE { + public String toString(){ + return "lookupServer"; + } + }, + RESTORE_STACK{ + public String toString(){ + return "restoreStack"; + } + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java new file mode 100644 index 000000000..017c69879 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java @@ -0,0 +1,38 @@ +/*- + * ============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.adapter.iaas.provider.operation.common.enums; + +/** + * @since September 26, 2016 + */ +public enum Outcome { + FAILURE { + public String toString(){ + return "failure"; + } + }, + SUCCESS { + public String toString(){ + return "success"; + } + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java new file mode 100644 index 000000000..c96dc6e84 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java @@ -0,0 +1,291 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.DATE_FORMAT; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +import org.slf4j.MDC; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + + +public class CreateSnapshot extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(CreateSnapshot.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + + private String generateSnapshotName(String server) { + SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df2.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "create snapshot"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot"); + + metricsLogger.info("Snapshot Name Generated: Snapshot of %s at %s", server, df.format(new Date())); + + return String.format("Snapshot of %s at %s", server, df.format(new Date())); + } + + private Image createSnapshot(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + Context context = server.getContext(); + Provider provider = context.getProvider(); + ImageService service = context.getImageService(); // Already checked access by this point + + String snapshotName = generateSnapshotName(server.getName()); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "create snapshot"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot"); + + logger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(), + snapshotName)); + metricsLogger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(), + snapshotName)); + + // Request Snapshot + String msg; + while (rc.attempt()) { + try { + server.createSnapshot(snapshotName); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + metricsLogger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + // Locate snapshot image + Image snapshot = null; + while (rc.attempt()) { + try { + snapshot = service.getImageByName(snapshotName); + if (snapshot != null) { + break; + } + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + metricsLogger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + // Wait for it to be ready + waitForStateChange(rc, snapshot, Image.Status.ACTIVE); + + return snapshot; + } + + private Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + Image snapshot = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + String msg; + + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "create snapshot"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot"); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + Server server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + if (hasImageAccess(rc, context)) { + snapshot = createSnapshot(rc, server); + doSuccess(rc); + } else { + msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), + "Accessing Image Service Failed"); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.FORBIDDEN_403, msg); + } + context.close(); + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + metricsLogger.error(msg, e); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + Operation.SNAPSHOT_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + return snapshot; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.SNAPSHOT_SERVICE.toString(), "App-C IaaS Adapter:Snapshot", ADAPTER_NAME); + logOperation(Msg.SNAPSHOTING_SERVER, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "create snapshot"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot"); + + metricsLogger.info("Executing Provider Operation: Create Snapshot"); + + return createSnapshot(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java new file mode 100644 index 000000000..d749fc225 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java @@ -0,0 +1,378 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Hypervisor; +import com.att.cdp.zones.model.Hypervisor.Status; +import com.att.cdp.zones.model.Hypervisor.State; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +public class EvacuateServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + private ProviderAdapterImpl paImpl = null; + + + private void evacuateServer(RequestContext rc, @SuppressWarnings("unused") Server server, String target_host) throws ZoneException, RequestFailedException { + + String msg; + Context ctx = server.getContext(); + Provider provider = ctx.getProvider(); + ComputeService service = ctx.getComputeService(); + + /* + * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the + * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down + * to one we can deal with. If not, then we have to fail the request. + */ + try { + if (server.getStatus().equals(Server.Status.PENDING)) { + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED); + } + } catch (RequestFailedException e) { + // evacuate is a special case. If the server is still in a Pending state, we want to continue with evacuate + logger.info("Evacuate server - ignore RequestFailedException from waitForStateChange() ..."); + } + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "evacuate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuteServer"); + + + try { + while (rc.attempt()) { + try { + logger.debug("Calling CDP moveServer - server id = " + server.getId()); + service.moveServer(server.getId(), target_host); + // Wait for completion, expecting the server to go to a non pending state + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + metricsLogger.error(msg,e); + rc.delay(); + } + } + + } catch (ZoneException e) { + msg = + EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(), e.getMessage()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Evacute Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Evacuate Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#evacuateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + private Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + String msg; + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "evacuate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuateServer"); + + ctx.setAttribute("EVACUATE_STATUS", "ERROR"); + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + // retrieve the optional parameters + String rebuild_vm = params.get(ProviderAdapter.PROPERTY_REBUILD_VM); + String targethost_id = params.get(ProviderAdapter.PROPERTY_TARGETHOST_ID); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + // check target host status + if (isComputeNodeDown(context, targethost_id)) { + msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(), + "Target host " + targethost_id +" status is not UP/ENABLED"); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Evacuate Server", msg, HttpStatus.BAD_REQUEST_400, server); + } + + // save hypervisor name before evacuate + String hypervisor = server.getHypervisor().getHostName(); + + evacuateServer(rc, server, targethost_id); + + server.refreshAll(); + String hypervisor_after_evacuate = server.getHypervisor().getHostName(); + logger.debug("Hostname before evacuate: " + hypervisor + ", After evacuate: " + hypervisor_after_evacuate); + + // check hypervisor host name after evacuate. If it is unchanged, the evacuate failed. + if ((hypervisor != null) && (hypervisor.equals(hypervisor_after_evacuate))) { + msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(), + "Hypervisor host " + hypervisor + " after evacuate is the same as before evacuate. Provider (ex. Openstack) recovery actions may be needed."); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Evacuate Server", msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server); + + } + + // check VM status after evacuate + if (server.getStatus() == Server.Status.ERROR) { + msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(), + "VM is in ERROR state after evacuate. Provider (ex. Openstack) recovery actions may be needed."); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Evacuate Server", msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server); + } + + context.close(); + doSuccess(rc); + ctx.setAttribute("EVACUATE_STATUS", "SUCCESS"); + + // If a snapshot exists, do a rebuild to apply the latest snapshot to the evacuated server. + // This is the default behavior unless the optional parameter is set to FALSE. + if ((rebuild_vm == null) || !(rebuild_vm.equalsIgnoreCase("false"))) { + List<Image> snapshots = server.getSnapshots(); + if (snapshots == null || snapshots.isEmpty()) { + logger.debug("No snapshots available - skipping rebuild after evacuate"); + } else if (paImpl != null) { + logger.debug("Executing a rebuild after evacuate"); + paImpl.rebuildServer(params, ctx); + // Check error code for rebuild errors. Evacuate had set it to 200 after + // a successful evacuate. Rebuild updates the error code. + String rebuildErrorCode = ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE); + if (rebuildErrorCode != null) { + try { + int error_code = Integer.parseInt(rebuildErrorCode); + if (error_code != HttpStatus.OK_200.getStatusCode()) { + logger.debug("Rebuild after evacuate failed - error code=" + error_code + + ", message=" + ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE)); + msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_REBUILD_FAILED, server.getName(), hypervisor, + hypervisor_after_evacuate, ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE)); + logger.error(msg); + metricsLogger.error(msg); + ctx.setAttribute("EVACUATE_STATUS", "ERROR"); + // update error message while keeping the error code the same as before + doFailure(rc, HttpStatus.getHttpStatus(error_code), msg); + } + } catch (NumberFormatException e) { + // ignore + } + } + } + } + + } + } catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + Operation.EVACUATE_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + metricsLogger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, "n/a", "n/a", e.getMessage()); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /* + * Check if a Compute node is down. + * + * This method attempts to find a given host in the list of hypervisors for a given + * context. The only case where a node is considered down is if a matching hypervisor + * is found and it's state and status are not UP/ENABLED. + * + * @param context + * The current context + * @param host + * The host name (short or fully qualified) of a compute node + * @return true if the node is determined as down, false for all other cases + */ + private boolean isComputeNodeDown(Context context, String host) throws ZoneException { + ComputeService service = context.getComputeService(); + boolean node_down = false; + + // Check host status. A node is considered down only if a matching target host is + // found and it's state/status is not UP/ENABLED. + if ((host != null) && !(host.isEmpty())) { + List<Hypervisor> hypervisors = service.getHypervisors(); + logger.debug("List of Hypervisors retrieved: " + Arrays.toString(hypervisors.toArray())); + for (Hypervisor h : hypervisors) { + if (h.getHostName().startsWith(host)) { + // host matches one of the hypervisors + State hstate = h.getState(); + Status hstatus = h.getStatus(); + logger.debug("Host matching hypervisor: " + h.getHostName() + ", State/Status: " + + hstate.toString() + "/" + hstatus.toString()); + if ((hstate != null) && (hstatus != null)) { + if (!(hstate.equals(State.UP)) || !(hstatus.equals(Status.ENABLED))) { + node_down = true; + } + } + } + } + } + return node_down; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.EVACUATE_SERVICE.toString(), "App-C IaaS Adapter:Evacuate", ADAPTER_NAME); + logOperation(Msg.EVACUATING_SERVER, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "evacuate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuateServer"); + + + metricsLogger.info("Executing Provider Operation: Evacuate"); + return evacuateServer(params, context); + } + + public void setProvideAdapterRef(ProviderAdapterImpl pai) { + paImpl = pai; + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java new file mode 100644 index 000000000..03a76cb8b --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java @@ -0,0 +1,124 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.io.IOException; +import java.util.Map; + +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +/** + * @since September 26, 2016 + */ +public class LookupServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + + public Server lookupServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); //should we test the return and fail if false? + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + String vm_url = null; + VMURL vm = null; + try { + + //process vm_url + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + + //use try with resource to ensure context is closed (returned to pool) + try(Context context = resolveContext(rc, params, appName, vm_url)){ + //resloveContext & getContext call doFailure and log errors before returning null + if (context != null){ + rc.reset(); + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + ctx.setAttribute("serverFound", "success"); + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "LookupServer", vm_url); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + doSuccess(rc); + } + } catch (ZoneException e) { + //server not found + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("serverFound", "failure"); + } catch (IOException e) { + //exception closing context + String msg = EELFResourceManager.format(Msg.CLOSE_CONTEXT_FAILED, e, vm_url); + logger.error(msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + Operation.LOOKUP_SERVICE.toString(), vm_url, "Unknown" ); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + + } catch (RequestFailedException e) { + // parameters not valid, unable to connect to provider + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("serverFound", "failure"); + } + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.LOOKUP_SERVICE.toString(), "App-C IaaS Adapter:LookupServer", ADAPTER_NAME); + logOperation(Msg.LOOKING_SERVER_UP, params, context); + return lookupServer(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java new file mode 100644 index 000000000..1b17d1c5c --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java @@ -0,0 +1,284 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.MIGRATE_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +import org.slf4j.MDC; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + + +/** + * @since September 26, 2016 + */ +public class MigrateServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * A list of valid initial VM statuses for a migrate operations + */ + private final Collection<Server.Status> migratableStatuses = Arrays.asList(Server.Status.READY, Server.Status.RUNNING, Server.Status.SUSPENDED); + + + private String getConnectionExceptionMessage(RequestContext rc, Context ctx, ContextConnectionException e) + throws ZoneException { + return EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, ctx.getProvider().getName(), + ctx.getComputeService().getURL(), ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + } + + private void migrateServer(RequestContext rc, Server server, SvcLogicContext svcCtx) + throws ZoneException, RequestFailedException { + String msg; + Context ctx = server.getContext(); + ComputeService service = ctx.getComputeService(); + + // Init status will equal final status + Server.Status initialStatus = server.getStatus(); + + if (initialStatus == null) { + throw new ZoneException("Failed to determine server's starting status"); + } + + // We can only migrate certain statuses + if (!migratableStatuses.contains(initialStatus)) { + throw new ZoneException(String.format("Cannot migrate server that is in %s state. Must be in one of [%s]", + initialStatus, migratableStatuses)); + } + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "migrate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer"); + // Is the skip Hypervisor check attribute populated? + String skipHypervisorCheck = null; + if (svcCtx != null) { + skipHypervisorCheck = svcCtx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK); + + } + + // // Always perform Hypervisor check + // unless the skip is set to true + + if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) { + + // Check of the Hypervisor for the VM Server is UP and reachable + + checkHypervisor(server); + + } + + boolean inConfirmPhase = false; + try { + while (rc.attempt()) { + try { + if (!inConfirmPhase) { + // Initial migrate request + service.migrateServer(server.getId()); + // Wait for change to verify resize + waitForStateChange(rc, server, Server.Status.READY); + inConfirmPhase = true; + } + + // Verify resize + service.processResize(server); + // Wait for complete. will go back to init status + waitForStateChange(rc, server, initialStatus); + logger.info("Completed migrate request successfully"); + metricsLogger.info("Completed migrate request successfully"); + return; + } catch (ContextConnectionException e) { + msg = getConnectionExceptionMessage(rc, ctx, e); + logger.error(msg, e); + metricsLogger.error(msg, e); + rc.delay(); + } + } + } catch (ZoneException e) { + String phase = inConfirmPhase ? "VERIFY MIGRATE" : "REQUEST MIGRATE"; + msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, server.getName(), server.getId(), phase, + e.getMessage()); + generateEvent(rc, false, msg); + logger.error(msg, e); + metricsLogger.error(msg, e); + throw new RequestFailedException("Migrate Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#migrateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + private Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + String msg; + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "migrate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer"); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + migrateServer(rc, server, ctx); + server.refreshStatus(); + context.close(); + doSuccess(rc); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + MIGRATE_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.MIGRATE_SERVICE.toString(), "App-C IaaS Adapter:Migrate", ADAPTER_NAME); + logOperation(Msg.MIGRATING_SERVER, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "migrate server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer"); + + + metricsLogger.info("Executing Provider Operation: Migrate"); + + return migrateServer(params,context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java new file mode 100644 index 000000000..959c1ad41 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java @@ -0,0 +1,503 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.ServerBootSource; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.util.List; +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +import org.slf4j.MDC; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +/** + * @since September 26, 2016 + */ +public class RebuildServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RebuildServer.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + /** + * Rebuild the indicated server with the indicated image. This method assumes the server has been determined to be + * in the correct state to do the rebuild. + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * the server to be rebuilt + * @param image + * The image to be used (or snapshot) + * @throws RequestFailedException + * if the server does not change state in the allotted time + */ + @SuppressWarnings("nls") + private void rebuildServer(RequestContext rc, Server server, String image) throws RequestFailedException { + logger.debug(Msg.REBUILD_SERVER, server.getId()); + + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "rebuild server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer"); + + try { + while (rc.attempt()) { + try { + server.rebuild(image); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + metricsLogger.error(msg,e); + rc.delay(); + } + } + + /* + * We need to provide some time for OpenStack to start processing the request. + */ + try { + Thread.sleep(10L * 1000L); + } catch (InterruptedException e) { + logger.trace("Sleep threw interrupted exception, should never occur"); + metricsLogger.trace("Sleep threw interrupted exception, should never occur"); + } + } catch (ZoneException e) { + msg = + EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), e.getMessage()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + + rc.reset(); + /* + * Once we have started the process, now we wait for the final state of stopped. This should be the final state + * (since we started the rebuild with the server stopped). + */ + waitForStateChange(rc, server, Server.Status.READY); + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + /** + * This method is called to rebuild the provided server. + * <p> + * If the server was booted from a volume, then the request is failed immediately and no action is taken. Rebuilding + * a VM from a bootable volume, where the bootable volume itself is not rebuilt, serves no purpose. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void rebuildServer(RequestContext rc, Server server, SvcLogicContext ctx) + throws ZoneException, RequestFailedException { + + ServerBootSource builtFrom = server.getBootSource(); + String msg; + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "rebuild server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer"); + + // Throw exception for non image/snap boot source + if (ServerBootSource.VOLUME.equals(builtFrom)) { + msg = String.format("Rebuilding is currently not supported for servers built from bootable volumes [%s]", + server.getId()); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server); + } + + /* + * Pending is a bit of a special case. If we find the server is in a + * pending state, then the provider is in the process of changing state + * of the server. So, lets try to wait a little bit and see if the state + * settles down to one we can deal with. If not, then we have to fail + * the request. + */ + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + if (server.getStatus().equals(Server.Status.PENDING)) { + rc.reset(); + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, + Server.Status.SUSPENDED, Server.Status.PAUSED); + } + + // Is the skip Hypervisor check attribute populated? + String skipHypervisorCheck = null; + if (ctx != null) { + skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK); + + } + + // Always perform Hypervisor Status checks + // unless the skip is set to true + if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) { + + // Check of the Hypervisor for the VM Server is UP and reachable + checkHypervisor(server); + } + + /* + * Get the image to use. This is determined by the presence or + * absence of snapshot images. If any snapshots exist, then the + * latest snapshot is used, otherwise the image used to construct + * the VM is used. + */ + List<Image> snapshots = server.getSnapshots(); + String imageToUse; + if (snapshots != null && !snapshots.isEmpty()) { + imageToUse = snapshots.get(0).getId(); + } else { + imageToUse = server.getImage(); + ImageService imageService = server.getContext().getImageService(); + rc.reset(); + try { + while (rc.attempt()) { + try { + /* + * We are just trying to make sure that the image + * exists. We arent interested in the details at + * this point. + */ + imageService.getImage(imageToUse); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), + imageService.getURL(), context.getTenant().getName(), context.getTenant().getId(), + e.getMessage(), Long.toString(rc.getRetryDelay()), + Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + metricsLogger.error(msg); + rc.delay(); + } + } + } catch (ZoneException e) { + msg = EELFResourceManager.format(Msg.IMAGE_NOT_FOUND, imageToUse, "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + + /* + * We determine what to do based on the current state of the server + */ + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "rebuilt"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case RUNNING: + // Attempt to stop the server, then rebuild it + stopServer(rc, server); + rc.reset(); + rebuildServer(rc, server, imageToUse); + rc.reset(); + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: RUNNING"); + break; + + case ERROR: + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Attempt to rebuild the server + rebuildServer(rc, server, imageToUse); + rc.reset(); + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: READY"); + break; + + case PAUSED: + // if paused, un-pause it, stop it, and rebuild it + unpauseServer(rc, server); + rc.reset(); + stopServer(rc, server); + rc.reset(); + rebuildServer(rc, server, imageToUse); + rc.reset(); + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: PAUSED"); + break; + + case SUSPENDED: + // Attempt to resume the suspended server, stop it, and rebuild it + resumeServer(rc, server); + rc.reset(); + stopServer(rc, server); + rc.reset(); + rebuildServer(rc, server, imageToUse); + rc.reset(); + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: SUSPENDED"); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + + + } + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#rebuildServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + public Server rebuildServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + String msg; + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "rebuild server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer"); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + ctx.setAttribute("REBUILD_STATUS", "ERROR"); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + rc.reset(); + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + // Manually checking image service until new PAL release + if (hasImageAccess(rc, context)) { + rebuildServer(rc, server, ctx); + doSuccess(rc); + ctx.setAttribute("REBUILD_STATUS", "SUCCESS"); + } else { + msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), + "Accessing Image Service Failed"); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.FORBIDDEN_403, msg); + } + context.close(); + } + else + { + ctx.setAttribute("REBUILD_STATUS", "CONTEXT_NOT_FOUND"); + } + } + catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + ctx.setAttribute("REBUILD_STATUS", "ERROR"); + } + catch (ResourceNotFoundException e) { + msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + ctx.setAttribute("REBUILD_STATUS", "ERROR"); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + STOP_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + ctx.setAttribute("REBUILD_STATUS", "ERROR"); + logger.error(msg, t); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + ctx.setAttribute("REBUILD_STATUS", "ERROR"); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.REBUILD_SERVICE.toString(), "App-C IaaS Adapter:Rebuild", ADAPTER_NAME); + logOperation(Msg.REBUILDING_SERVER, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "rebuild server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer"); + + + metricsLogger.info("Executing Provider Operation: Rebuild"); + + + return rebuildServer(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java new file mode 100644 index 000000000..45e8f469f --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java @@ -0,0 +1,320 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.NetworkService; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Network; +import com.att.cdp.zones.model.Port; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Subnet; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + + +public class RestartServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestartServer.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + + /** + * This method handles the case of restarting a server once we have found the server and have obtained the abstract + * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server object representing the server we want to operate on + * @throws ZoneException + */ + @SuppressWarnings("nls") + private void restartServer(RequestContext rc, Server server, SvcLogicContext ctx) + throws ZoneException, RequestFailedException { + + /* + * Pending is a bit of a special case. If we find the server is in a + * pending state, then the provider is in the process of changing state + * of the server. So, lets try to wait a little bit and see if the state + * settles down to one we can deal with. If not, then we have to fail + * the request. + */ + String msg; + if (server.getStatus().equals(Server.Status.PENDING)) { + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, + Server.Status.SUSPENDED, Server.Status.PAUSED); + } + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "restart server"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer"); + + String skipHypervisorCheck = null; + if (ctx != null) { + skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK); + + } + + // Always perform Virtual Machine/Hypervisor Status/Network checks + // unless the skip is set to true + if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) { + + // Check of the Hypervisor for the VM Server is UP and reachable + + checkHypervisor(server); + + } + + /* + * We determine what to do based on the current state of the server + */ + + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "restarted"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + break; + + case RUNNING: + // Attempt to stop and start the server + stopServer(rc, server); + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: RUNNING"); + break; + + case ERROR: + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "rebuild"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Attempt to start the server + startServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: READY"); + break; + + case PAUSED: + // if paused, un-pause it + unpauseServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: PAUSED"); + break; + + case SUSPENDED: + // Attempt to resume the suspended server + resumeServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + metricsLogger.info("Server status: SUSPENDED"); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + break; + } + + + } + + /** + * This method is used to restart an existing virtual machine given the fully qualified URL of the machine. + * <p> + * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form + * <pre> + * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] + * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service + * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the + * server by its UUID, and then perform the restart. + * </p> + * + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IllegalArgumentException + * if the expected argument(s) are not defined or are invalid + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#restartServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + private Server restartServer(Map<String, String> params, SvcLogicContext ctx) + throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "GET server status"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer"); + + ctx.setAttribute("RESTART_STATUS", "ERROR"); + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + rc.reset(); + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + rc.reset(); + restartServer(rc, server, ctx); + context.close(); + doSuccess(rc); + ctx.setAttribute("RESTART_STATUS", "SUCCESS"); + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "RestartServer", vm_url); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + metricsLogger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException { + + setMDC(RESTART_SERVICE.toString(), "App-C IaaS Adapter:Restart", ADAPTER_NAME); + logOperation(Msg.RESTARTING_SERVER, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "execute restart"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer"); + + metricsLogger.info("Executing Provider Operation: Restart"); + + + return restartServer(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java new file mode 100644 index 000000000..018c8e2e6 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java @@ -0,0 +1,152 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation; +import org.openecomp.appc.adapter.openstack.heat.SnapshotResource; +import org.openecomp.appc.adapter.openstack.heat.StackResource; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.openstack.OpenStackContext; +import com.att.cdp.openstack.connectors.HeatConnector; +import com.att.cdp.openstack.util.ExceptionMapper; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Stack; +import com.att.cdp.zones.spi.RequestState; +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 com.woorea.openstack.base.client.OpenStackBaseException; +import com.woorea.openstack.heat.Heat; +import org.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + + +public class RestoreStack extends ProviderStackOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestoreStack.class); + + private void restoreStack(Stack stack, String snapshotId) throws ZoneException, RequestFailedException { + Context context = stack.getContext(); + + OpenStackContext osContext = (OpenStackContext)context; + + final HeatConnector heatConnector = osContext.getHeatConnector(); + ((OpenStackContext)context).refreshIfStale(heatConnector); + + trackRequest(context); + RequestState.put("SERVICE", "Orchestration"); + RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); + + Heat heat = heatConnector.getClient(); + + SnapshotResource snapshotResource = new SnapshotResource(heat); + + try { + + snapshotResource.restore(stack.getName(), stack.getId(), snapshotId).execute(); + + // wait for the snapshot restore + StackResource stackResource = new StackResource(heat); + if (!waitForStack(stack, stackResource, "RESTORE_COMPLETE")) { + throw new RequestFailedException("Snapshot restore failed."); + } + + } catch (OpenStackBaseException e) { + ExceptionMapper.mapException(e); + } + + } + + public Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + String vm_url = null; + Context context = null; + + try { + + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, ProviderAdapter.PROPERTY_PROVIDER_NAME, + ProviderAdapter.PROPERTY_STACK_ID, ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + String snapshotId = params.get(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID); + + context = resolveContext(rc, params, appName, vm_url); + + + if (context != null) { + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName())); + restoreStack(stack, snapshotId); + logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName())); + context.close(); + doSuccess(rc); + }else { + ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); + } + + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "restoreStack")); + doFailure(rc, e.getStatus(), e.getMessage(), e); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + "restoreStack", vm_url, null == context ? "n/a" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); + } + return stack; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.RESTORE_STACK.toString(), "App-C IaaS Adapter:Restore-Stack", ADAPTER_NAME); + logOperation(Msg.RESTORING_STACK, params, context); + return restoreStack(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java new file mode 100644 index 000000000..5014e759f --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java @@ -0,0 +1,237 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation; +import org.openecomp.appc.adapter.openstack.heat.SnapshotResource; +import org.openecomp.appc.adapter.openstack.heat.StackResource; +import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams; +import org.openecomp.appc.adapter.openstack.heat.model.Snapshot; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.openstack.OpenStackContext; +import com.att.cdp.openstack.connectors.HeatConnector; +import com.att.cdp.openstack.util.ExceptionMapper; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Stack; +import com.att.cdp.zones.spi.RequestState; +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 com.woorea.openstack.base.client.OpenStackBaseException; +import com.woorea.openstack.heat.Heat; +import org.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Map; + +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +import org.slf4j.MDC; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + + +/** + * @since September 26, 2016 + */ +public class SnapshotStack extends ProviderStackOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(SnapshotStack.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + + private Snapshot snapshotStack(@SuppressWarnings("unused") RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { + Snapshot snapshot = new Snapshot(); + Context context = stack.getContext(); + + OpenStackContext osContext = (OpenStackContext)context; + + final HeatConnector heatConnector = osContext.getHeatConnector(); + ((OpenStackContext)context).refreshIfStale(heatConnector); + + trackRequest(context); + RequestState.put("SERVICE", "Orchestration"); + RequestState.put("SERVICE_URL", heatConnector.getEndpoint()); + + Heat heat = heatConnector.getClient(); + + SnapshotResource snapshotResource = new SnapshotResource(heat); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "snapshot stack"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack"); + + try { + + snapshot = snapshotResource.create(stack.getName(), stack.getId(), new CreateSnapshotParams()).execute(); + + // wait for the stack deletion + StackResource stackResource = new StackResource(heat); + if (!waitForStack(stack, stackResource, "SNAPSHOT_COMPLETE")) { + throw new RequestFailedException("Stack Snapshot failed."); + } + + } catch (OpenStackBaseException e) { + ExceptionMapper.mapException(e); + } + + return snapshot; + } + + + public Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + String vm_url = null; + Context context = null; + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "snapshot stack"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack"); + + + try { + + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + context = resolveContext(rc, params, appName, vm_url); + + if (context != null) { + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName())); + metricsLogger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName())); + + Snapshot snapshot = snapshotStack(rc, stack); + + ctx.setAttribute(ProviderAdapter.DG_OUTPUT_PARAM_NAMESPACE + + ProviderAdapter.PROPERTY_SNAPSHOT_ID, snapshot.getId()); + + logger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId())); + metricsLogger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId())); + context.close(); + doSuccess(rc); + } else { + ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure"); + } + + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e); + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack")); + metricsLogger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack")); + doFailure(rc, e.getStatus(), e.getMessage(), e); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + "snapshotStack", vm_url, null == context ? "n/a" : context.getTenantName()); + logger.error(msg, t); + metricsLogger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t); + } + return stack; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + setMDC(Operation.SNAPSHOT_STACK.toString(), "App-C IaaS Adapter:Snapshot-Stack", ADAPTER_NAME); + logOperation(Msg.SNAPSHOTING_STACK, params, context); + + /* + * Set Time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "cdp"); + MDC.put("TargetServiceName", "snapshot stack"); + MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack"); + + metricsLogger.info("Executing Provider Operation: Snapshot Stack"); + + return snapshotStack(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java new file mode 100644 index 000000000..41b0afd69 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java @@ -0,0 +1,186 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.START_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +public class StartServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartServer.class); + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#startServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + public Server startServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + ctx.setAttribute("START_STATUS", "ERROR"); + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + rc.reset(); + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + String msg; + + /* + * We determine what to do based on the current state of the server + */ + + /* + * Pending is a bit of a special case. If we find the server is in a + * pending state, then the provider is in the process of changing state + * of the server. So, lets try to wait a little bit and see if the state + * settles down to one we can deal with. If not, then we have to fail + * the request. + */ + + if (server.getStatus().equals(Server.Status.PENDING)) { + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, + Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED); + } + + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "started"); + logger.error(msg); + // metricsLogger.error(msg); + throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case RUNNING: + // Nothing to do, the server is already running + logger.info("Server was already running"); + break; + + case ERROR: + // Server is in error state + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "start"); + logger.error(msg); + // metricsLogger.error(msg); + throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Server is stopped attempt to start the server + rc.reset(); + startServer(rc, server); + break; + + case PAUSED: + // if paused, un-pause it + rc.reset(); + unpauseServer(rc, server); + // metricsLogger.info("Server status: PAUSED"); + break; + + case SUSPENDED: + // Attempt to resume the suspended server + rc.reset(); + resumeServer(rc, server); + // metricsLogger.info("Server status: SUSPENDED"); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + // metricsLogger.error(msg); + throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + context.close(); + doSuccess(rc); + ctx.setAttribute("START_STATUS", "SUCCESS"); + } + else + { + ctx.setAttribute("START_STATUS", "CONTEXT_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + START_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.START_SERVICE.toString(), "App-C IaaS Adapter:Start", ADAPTER_NAME); + logOperation(Msg.STARTING_SERVER, params, context); + return startServer(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java new file mode 100644 index 000000000..9429d5654 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java @@ -0,0 +1,198 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + + +public class StopServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(StopServer.class); + private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger(); + + /** + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#stopServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + public Server stopServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + ctx.setAttribute("STOP_STATUS", "SUCCESS"); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + ctx.setAttribute("STOP_STATUS", "ERROR"); + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + rc.reset(); + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + String msg; + /* + * We determine what to do based on the current state of the server + */ + + /* + * Pending is a bit of a special case. If we find the server is in a + * pending state, then the provider is in the process of changing state + * of the server. So, lets try to wait a little bit and see if the state + * settles down to one we can deal with. If not, then we have to fail + * the request. + */ + + if (server.getStatus().equals(Server.Status.PENDING)) { + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, + Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED); + } + + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "stopped"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case RUNNING: + // Attempt to stop the server + rc.reset(); + stopServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + break; + + case ERROR: + // Server is in error state + msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(), + server.getTenantId(), "stop"); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + + case READY: + // Nothing to do, the server was already stopped + logger.info("Server was already stopped"); + break; + + case PAUSED: + // if paused, un-pause it and then stop it + rc.reset(); + unpauseServer(rc, server); + rc.reset(); + stopServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + break; + + case SUSPENDED: + // Attempt to resume the suspended server and after that stop it + rc.reset(); + resumeServer(rc, server); + rc.reset(); + stopServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + metricsLogger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server); + } + context.close(); + doSuccess(rc); + ctx.setAttribute("STOP_STATUS", "SUCCESS"); + msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "StopServer", vm_url); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + + }else{ + ctx.setAttribute("STOP_STATUS", "CONTEXT_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + STOP_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.STOP_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(STOP_SERVICE.toString(), "App-C IaaS Adapter:Stop", ADAPTER_NAME); + logOperation(Msg.STOPPING_SERVER, params, context); + return stopServer(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java new file mode 100644 index 000000000..d0deda741 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java @@ -0,0 +1,248 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.TERMINATE_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +public class TerminateServer extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class); + + /** + * Start the server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be started + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + private void deleteServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + logger.info("deleting SERVER"); + server.delete(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Delete Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + /** + * This method handles the case of restarting a server once we have found the server and have obtained the abstract + * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction). + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server object representing the server we want to operate on + * @throws ZoneException + */ + @SuppressWarnings("nls") + private void terminateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + /* + * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the + * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down + * to one we can deal with. If not, then we have to fail the request. + */ + String msg; + if (server.getStatus().equals(Server.Status.PENDING)) { + waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED); + } + + /* + * We determine what to do based on the current state of the server + */ + switch (server.getStatus()) { + case DELETED: + // Nothing to do, the server is gone + msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), + server.getTenantId(), "restarted"); + generateEvent(rc, false, msg); + logger.error(msg); + break; + + case RUNNING: + // Attempt to stop and start the server + logger.info("stopping SERVER"); + stopServer(rc, server); + deleteServer(rc, server); + logger.info("after delete SERVER"); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + break; + + case ERROR: + + case READY: + + case PAUSED: + + case SUSPENDED: + // Attempt to delete the suspended server + deleteServer(rc, server); + generateEvent(rc, true, Outcome.SUCCESS.toString()); + break; + + default: + // Hmmm, unknown status, should never occur + msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(), + server.getTenantId(), server.getStatus().name()); + generateEvent(rc, false, msg); + logger.error(msg); + break; + } + + } + + /** + * This method is used to delete an existing virtual machine given the fully qualified URL of the machine. + * <p> + * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form + * <pre> + * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id] + * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service + * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the + * server by its UUID, and then perform the restart. + * </p> + * + * @throws UnknownProviderException + * If the provider cannot be found + * @throws IllegalArgumentException + * if the expected argument(s) are not defined or are invalid + * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#terminateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext) + */ + @SuppressWarnings("nls") + public Server terminateServer(Map<String, String> params, SvcLogicContext ctx) + throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.TERMINATING_SERVER, server.getName())); + terminateServer(rc, server); + logger.info(EELFResourceManager.format(Msg.TERMINATE_SERVER, server.getName())); + context.close(); + doSuccess(rc); + }else{ + ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND"); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.TERMINATE_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage())); + doFailure(rc, e.getStatus(), e.getMessage()); + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + } + + return server; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException { + + setMDC(TERMINATE_SERVICE.toString(), "App-C IaaS Adapter:Terminate", ADAPTER_NAME); + logOperation(Msg.TERMINATING_SERVER, params, context); + return terminateServer(params,context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java new file mode 100644 index 000000000..220c00d8c --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java @@ -0,0 +1,128 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.StackService; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Stack; +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.glassfish.grizzly.http.util.HttpStatus; + +import java.util.Map; + +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; + +/** + * @since September 26, 2016 + */ +public class TerminateStack extends ProviderStackOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class); + + private void deleteStack(RequestContext rc, Stack stack) throws ZoneException, RequestFailedException { + SvcLogicContext ctx = rc.getSvcLogicContext(); + Context context = stack.getContext(); + StackService stackService = context.getStackService(); + logger.debug("Deleting Stack: " + "id:{ " + stack.getId() + "}"); + stackService.deleteStack(stack); + + // wait for the stack deletion + boolean success = waitForStackStatus(rc, stack, Stack.Status.DELETED); + if (success) { + ctx.setAttribute("TERMINATE_STATUS", "SUCCESS"); + } else { + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + throw new RequestFailedException("Delete Stack failure : " + Msg.STACK_OPERATION_EXCEPTION.toString()); + } + } + + @SuppressWarnings("nls") + public Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException { + Stack stack = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + ctx.setAttribute("TERMINATE_STATUS", "STACK_NOT_FOUND"); + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID); + + String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID); + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + Context context = resolveContext(rc, params, appName, vm_url); + + try { + if (context != null) { + rc.reset(); + stack = lookupStack(rc, context, stackId); + logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString()); + logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName())); + deleteStack(rc, stack); + logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName())); + context.close(); + doSuccess(rc); + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "TerminateStack", vm_url); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + Operation.TERMINATE_STACK.toString(), vm_url, context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + logger.error(EELFResourceManager.format(Msg.TERMINATE_STACK_FAILED, appName, "n/a", "n/a")); + doFailure(rc, e.getStatus(), e.getMessage()); + } + return stack; + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + setMDC(Operation.TERMINATE_STACK.toString(), "App-C IaaS Adapter:Terminate-Stack", ADAPTER_NAME); + logOperation(Msg.TERMINATING_STACK, params, context); + return terminateStack(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java new file mode 100644 index 000000000..0df17caa4 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java @@ -0,0 +1,160 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.IdentityURL; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.util.Map; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE; +import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + + +public class VmStatuschecker extends ProviderServerOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(VmStatuschecker.class); + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + /* *********************************************************************************/ + /* DEVEN PANCHAL: This method is used to check the status of the VM */ + /**********************************************************************************/ + public Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws UnknownProviderException, IllegalArgumentException { + Server server = null; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + + try { + validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, + ProviderAdapter.PROPERTY_PROVIDER_NAME); + + String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL); + + VMURL vm = VMURL.parseURL(vm_url); + if (validateVM(rc, appName, vm_url, vm)) return null; + + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + Context context = null; + try { + context = getContext(rc, vm_url, identStr); + if (context != null) { + server = lookupServer(rc, context, vm.getServerId()); + logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString()); + + String statusvm; + switch (server.getStatus()) { + case DELETED: + statusvm = "deleted"; + break; + + case RUNNING: + statusvm = "running"; + break; + + case ERROR: + statusvm = "error"; + break; + + case READY: + statusvm = "ready"; + break; + + case PAUSED: + statusvm = "paused"; + break; + + case SUSPENDED: + statusvm = "suspended"; + break; + + case PENDING: + statusvm = "pending"; + break; + + default: + statusvm = "default-unknown state-should never occur"; + break; + } + + + String statusofVM = statusvm; + context.close(); + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(Outcome.SUCCESS.toString()); + svcLogic.setAttribute("org.openecomp.statusofvm", statusofVM); + svcLogic.setAttribute(Constants.STATUS_OF_VM, statusofVM); + svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + } + } catch (ResourceNotFoundException e) { + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + } catch (Throwable t) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(), + RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName()); + logger.error(msg, t); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + } + } catch (RequestFailedException e) { + doFailure(rc, e.getStatus(), e.getMessage()); + } + + return server; + } + + /* *********************************************************************************/ + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException { + + setMDC(Operation.VMSTATUSCHECK_SERVICE.toString(), "App-C IaaS Adapter:VmStatusCheck", ADAPTER_NAME); + logOperation(Msg.CHECKING_SERVER, params, context); + return vmStatuschecker(params, context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java new file mode 100644 index 000000000..58753f527 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java @@ -0,0 +1,457 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl.base; + +import org.openecomp.appc.adapter.iaas.ProviderAdapter; +import org.openecomp.appc.adapter.iaas.impl.*; +import org.openecomp.appc.adapter.iaas.provider.operation.api.IProviderOperation; +import org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants; +import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolExtensionException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.model.ModelObject; +import com.att.cdp.zones.model.Server; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.net.URI; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_ADAPTER; +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + +/** + * @since September 26, 2016 + */ +public abstract class ProviderOperation implements IProviderOperation { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class); + protected static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public void setProviderCache(Map<String, ProviderCache> providerCache) { + this.providerCache = providerCache; + } + + /** + * A cache of providers that are predefined. + */ + private Map<String /* provider name */, ProviderCache> providerCache; + + + public void setDefaultUser(String defaultUser) { + DEFAULT_USER = defaultUser; + } + + public void setDefaultPass(String defaultPass) { + DEFAULT_PASS = defaultPass; + } + + /** + * The username and password to use for dynamically created connections + */ + private static String DEFAULT_USER; + private static String DEFAULT_PASS; + + + /** + * set MDC props + * @param service + * @param serviceName + * @param adapterName + */ + protected void setMDC(String service, String serviceName, String adapterName){ + MDC.put(MDC_ADAPTER, adapterName); + MDC.put(MDC_SERVICE, service); + MDC.put(MDC_SERVICE_NAME, serviceName); + } + + /** + * initial log of the operation + * @param msg + * @param params + * @param context + */ + protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context){ + + String appName = configuration.getProperty(org.openecomp.appc.Constants.PROPERTY_APPLICATION_NAME); + logger.info(msg, appName); + + debugParameters(params); + debugContext(context); + } + + /** + * This method is used to dump the value of the parameters to the log for debugging purposes. + * + * @param parameters + * The parameters to be printed to the log + */ + private void debugParameters(Map<String, String> parameters) { + for (String key : parameters.keySet()) { + logger.debug(Msg.PROPERTY_VALUE, key, parameters.get(key)); + } + } + + /** + * This method is used to create a diagnostic dump of the context for the log + * + * @param context + * The context to be dumped + */ + @SuppressWarnings({ + "nls", "static-method" + }) + private void debugContext(SvcLogicContext context) { + Set<String> keys = context.getAttributeKeySet(); + StringBuilder builder = new StringBuilder(); + + builder.append("Service Logic Context: Status "); + builder.append(Constants.LPAREN); + builder.append(context.getStatus()); + builder.append(Constants.RPAREN); + builder.append(", Attribute count "); + builder.append(Constants.LPAREN); + builder.append(keys == null ? "none" : Integer.toString(keys.size())); + builder.append(Constants.RPAREN); + if (keys != null && !keys.isEmpty()) { + builder.append(Constants.NL); + for (String key : keys) { + String value = context.getAttribute(key); + builder.append("Attribute "); + builder.append(Constants.LPAREN); + builder.append(key); + builder.append(Constants.RPAREN); + builder.append(", value "); + builder.append(Constants.LPAREN); + builder.append(value == null ? "" : value); + builder.append(Constants.RPAREN); + builder.append(Constants.NL); + } + } + + logger.debug(builder.toString()); + } + + + /** + * This method is used to validate that the parameters contain all required property names, and that the values are + * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists. + * + * @param parameters + * The parameters to be checked + * @param propertyNames + * The list of property names that are required to be present. + * @throws RequestFailedException + * If the parameters are not valid + */ + protected void validateParametersExist(Map<String, String> parameters, String... propertyNames) + throws RequestFailedException { + boolean success = true; + StringBuilder msg = new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(MDC_SERVICE))); + msg.append(Constants.NL); + for (String propertyName : propertyNames) { + String value = parameters.get(propertyName); + if (value == null || value.trim().length() == 0) { + success = false; + msg.append(Constants.QUOTE); + msg.append(propertyName); + msg.append(Constants.QUOTE); + msg.append(Constants.SPACE); + } + } + + if (!success) { + logger.error(msg.toString()); + throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400, (Server)null); + } + } + + /** + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param code + * @param message + */ + protected void doFailure(RequestContext rc, HttpStatus code, String message) { + try { + doFailure(rc, code, message, null); + } catch (APPCException ignored) {/* never happens */} + } + + protected void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws APPCException { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = (message == null) ? code.getReasonPhrase() : message; + if (msg.contains("\n")) { + msg = msg.substring(0, msg.indexOf("\n")); + } + String status; + try { + status = Integer.toString(code.getStatusCode()); + } catch (Exception e) { + status = "500"; + } + svcLogic.setStatus(Outcome.FAILURE.toString()); + svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE, status); + svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + + if (null != cause) throw new APPCException(cause); + } + + /** + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + */ + @SuppressWarnings("static-method") + protected void doSuccess(RequestContext rc) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + svcLogic.setStatus(Outcome.SUCCESS.toString()); + svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode())); + } + + protected boolean validateVM(RequestContext rc, String appName, String vm_url, VMURL vm) + throws RequestFailedException { + String msg; + if (vm == null) { + msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return true; + } + validateVMURL(vm); + return false; + } + + protected void validateVMURL(VMURL vm) throws RequestFailedException { + String name = "vm-id"; + if (vm == null) { + throw new RequestFailedException(String.format("The value %s cannot be null.", name)); + } + + // Check that its a good uri + // This will probably never get hit bc of an earlier check while parsing + // the string to a VMURL + try { + //noinspection ResultOfMethodCallIgnored + URI.create(vm.toString()); + } catch (Exception e) { + throw new RequestFailedException( + String.format("The value %s is not well formed [%s].", name, vm.toString())); + } + + // Check the tenant and vmid segments + String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})"; + Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE); + + if (!pattern.matcher(vm.getTenantId()).matches()) { + throw new RequestFailedException( + String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId())); + } + if (!pattern.matcher(vm.getServerId()).matches()) { + throw new RequestFailedException( + String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId())); + } + } + + private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) { + if (vm != null && ident != null) { + ProviderCache cache = new ProviderCache(); + + cache.setIdentityURL(ident.toString()); + cache.setProviderName(ident.toString()); + // cache.setProviderType("OpenStack"); + + TenantCache tenant = cache.addTenant(vm.getTenantId(),null, DEFAULT_USER, DEFAULT_PASS); + + // Make sure we could initialize the the cache otherwise return null + if (tenant != null && tenant.isInitialized()) { + return cache; + } + } + return null; + } + + /** + * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a + * supported provider, regardless of region(s), and to return an opened context that can be used to access that + * server. + * + * @param rc + * The request context that wraps and manages the state of the request + * @param selfLinkURL + * The fully-qualified self-link URL of the server + * @param providerName + * The name of the provider to be searched + * @return The context that can be used to access the server, or null if not found. + */ + @SuppressWarnings("nls") + protected Context getContext(RequestContext rc, String selfLinkURL, String providerName) { + VMURL vm = VMURL.parseURL(selfLinkURL); + IdentityURL ident = IdentityURL.parseURL(providerName); + String appName = configuration.getProperty(org.openecomp.appc.Constants.PROPERTY_APPLICATION_NAME); + + if (vm == null) { + String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + + /* + * Get the cache of tenants and contexts for the named provider, if one exists + */ + ProviderCache cache = providerCache.get(providerName); + + /* + * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to + * the cache and continue, otherwise fail the request. + */ + if (cache == null) { + if (ident != null) { + cache = createProviderCache(vm, ident); + } + if (cache != null) { + providerCache.put(cache.getProviderName(), cache); + } else { + String msg = + EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName, providerCache.keySet().toString()); + logger.error(msg); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + } + + if (providerName == null) { + logger + .debug(String.format("Using the default provider cache [%s] since no valid identity url was passed in.", + cache.getIdentityURL())); + } + + // get the tenant cache for the vm + String identityURL = cache.getIdentityURL(); + TenantCache tenantCache = cache.getTenant(vm.getTenantId()); + + if(tenantCache == null){ + //no tenantCache matching tenant, add tenant to the provider cache + tenantCache = cache.addTenant(vm.getTenantId(),null,DEFAULT_USER, DEFAULT_PASS); + + if(tenantCache == null){ + //tenant not found + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + return null; + } + } + + //reserve the context + String tenantName = tenantCache.getTenantName(); + String tenantId = tenantCache.getTenantId(); + String region = tenantCache.determineRegion(vm); + + if (region != null) { + Pool<Context> pool = tenantCache.getPools().get(region); + + while (rc.attempt()) { + try { + Context context = pool.reserve(); + + /* + * Insert logic here to test the context for connectivity because we may have gotten one from + * the pool that was previously created. + */ + if (context.isStale()) { + context.relogin(); + } + return context; + } catch (PoolExtensionException e) { + String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL, + tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()), + Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } catch (Exception e) { + String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e, + e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName()); + + logger.error(msg, e); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + return null; + } + } + + String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + return null; + } + + + String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL); + logger.error(msg); + doFailure(rc, HttpStatus.NOT_FOUND_404, msg); + return null; + } + + protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vm_url) + throws RequestFailedException { + + VMURL vm = VMURL.parseURL(vm_url); + if (vm == null) { + String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url); + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg); + logger.error(msg); + return null; + } + validateVMURL(vm); + IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL)); + String identStr = (ident == null) ? null : ident.toString(); + + return getContext(rc, vm_url, identStr); + + } + + + + + + + + protected abstract ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException; + + @Override + public ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + + return executeProviderOperation(params,context); + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java new file mode 100644 index 000000000..0a27a7ac9 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java @@ -0,0 +1,573 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl.base; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.impl.*; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.NotLoggedInException; +import com.att.cdp.exceptions.TimeoutException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.pal.util.StringHelper; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.NetworkService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Hypervisor; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Network; +import com.att.cdp.zones.model.Port; +import com.att.cdp.zones.model.Server; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import org.glassfish.grizzly.http.util.HttpStatus; +import java.util.ArrayList; +import java.util.List; + +/** + * @since September 29, 2016 + */ +public abstract class ProviderServerOperation extends ProviderOperation{ + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderServerOperation.class); + + /** + * Looks up the indicated server using the provided context and returns the server to the caller + * + * @param rc + * The request context + * @param context + * The provider context + * @param id + * The id of the server + * @return The server, or null if there is a problem + * @throws ZoneException + * If the server cannot be found + * @throws RequestFailedException + * If the server cannot be found because we cant connect to the provider + */ + @SuppressWarnings("nls") + protected Server lookupServer(RequestContext rc, Context context, String id) + throws ZoneException, RequestFailedException { + ComputeService service = context.getComputeService(); + Server server = null; + String msg; + Provider provider = context.getProvider(); + + while (rc.attempt()) { + try { + server = service.getServer(id); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + return server; + } + + + + /** + * Resume a suspended server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be resumed + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + protected void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.RESUME_SERVER, server.getId()); + + Context context = server.getContext(); + String msg; + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.resume(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Server.Status.RUNNING); + } + + + protected boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) { + logger.info("Checking permissions for image service."); + try { + ImageService service = context.getImageService(); + service.getImageByName("CHECK_IMAGE_ACCESS"); + logger.info("Image service is accessible."); + return true; + } catch (ZoneException e) { + logger.warn("Image service could not be accessed. Some operations may fail.", e); + return false; + } + } + + + /** + * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. + * <p> + * This method checks the state of the server periodically for one of the desired states. When the server enters one + * of the desired states, the method returns a successful indication (true). If the server never enters one of the + * desired states within the allocated timeout period, then the method returns a failed response (false). No + * exceptions are thrown from this method. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param image + * The server to wait on + * @param desiredStates + * A variable list of desired states, any one of which is allowed. + * @throws RequestFailedException + * If the request times out or fails for some reason + * @throws NotLoggedInException + */ + @SuppressWarnings("nls") + protected void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates) + throws RequestFailedException, NotLoggedInException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); + Context context = image.getContext(); + Provider provider = context.getProvider(); + ImageService service = context.getImageService(); + String msg; + + long endTime = System.currentTimeMillis() + (timeout * 1000); // + + while (rc.attempt()) { + try { + try { + image.waitForStateChange(pollInterval, timeout, desiredStates); + break; + } catch (TimeoutException e) { + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + List<String> list = new ArrayList<>(); + for (Image.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } catch (ZoneException e) { + List<String> list = new ArrayList<>(); + for (Image.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), + "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(), + e.getMessage()); + logger.error(reason); + logger.error(EELFResourceManager.format(e)); + + // Instead of failing we are going to wait and try again. + // Timeout is reduced by delay time + logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); + rc.delay(); + timeout = (int) (endTime - System.currentTimeMillis()) / 1000; + // throw new RequestFailedException(e, operation, reason, + // HttpStatus.BAD_GATEWAY_502, server); + } + } + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server()); + } + rc.reset(); + } + + + /** + * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. + * <p> + * This method checks the state of the server periodically for one of the desired states. When the server enters one + * of the desired states, the method returns a successful indication (true). If the server never enters one of the + * desired states within the allocated timeout period, then the method returns a failed response (false). No + * exceptions are thrown from this method. + * </p> + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to wait on + * @param desiredStates + * A variable list of desired states, any one of which is allowed. + * @throws RequestFailedException + * If the request times out or fails for some reason + */ + @SuppressWarnings("nls") + protected void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates) + throws RequestFailedException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT); + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + String msg; + + long endTime = System.currentTimeMillis() + (timeout * 1000); // + + while (rc.attempt()) { + try { + try { + server.waitForStateChange(pollInterval, timeout, desiredStates); + break; + } catch (TimeoutException e) { + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + List<String> list = new ArrayList<>(); + for (Server.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } catch (ZoneException e) { + List<String> list = new ArrayList<>(); + for (Server.Status desiredState : desiredStates) { + list.add(desiredState.name()); + } + String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(), + "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(), + e.getMessage()); + logger.error(reason); + logger.error(EELFResourceManager.format(e)); + + // Instead of failing we are going to wait and try again. + // Timeout is reduced by delay time + logger.info(String.format("Retrying in %ds", rc.getRetryDelay())); + rc.delay(); + timeout = (int) (endTime - System.currentTimeMillis()) / 1000; + // throw new RequestFailedException(e, operation, reason, + // HttpStatus.BAD_GATEWAY_502, server); + } + } + + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + } + + /** + * Stop the specified server and wait for it to stop + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be stopped + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + protected void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.STOP_SERVER, server.getId()); + + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.stop(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Server.Status.READY, Server.Status.ERROR); + } + + /** + * Start the server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be started + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + protected void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.START_SERVER, server.getId()); + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.start(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Server.Status.RUNNING); + } + + + /** + * Un-Pause a paused server and wait for it to enter a running state + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server to be un-paused + * @throws ZoneException + * @throws RequestFailedException + */ + @SuppressWarnings("nls") + protected void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException { + logger.debug(Msg.UNPAUSE_SERVER, server.getId()); + + String msg; + Context context = server.getContext(); + Provider provider = context.getProvider(); + ComputeService service = context.getComputeService(); + while (rc.attempt()) { + try { + server.unpause(); + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL()); + logger.error(msg); + throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server); + } + rc.reset(); + waitForStateChange(rc, server, Server.Status.RUNNING, Server.Status.READY); + } + + + /** + * Generates the event indicating what happened + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param success + * True if the event represents a successful outcome + * @param msg + * The detailed message + */ + protected void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) { + // indication to the DG to generate the event? + } + + /** + * Checks if the VM is connected to the Virtual Network and reachable + * + * @param rc + * The request context that manages the state and recovery of the request for the life of its processing. + * @param server + * The server object representing the server we want to operate on + * @param context + * The interface cloud service provider to access services or the object model, or both + + */ + protected void checkVirtualMachineNetworkStatus(RequestContext rc, Server server, Context context) + throws ZoneException, RequestFailedException { + + logger.info("Performing the VM Server networking status checks..."); + List<Port> ports = server.getPorts(); + + NetworkService netSvc = context.getNetworkService(); + + String msg; + for (Port port : ports) { + + switch (port.getPortState().toString().toUpperCase()) { + /** + * The port is connected, configured, and usable for communication + */ + case "ONLINE": + Network network = netSvc.getNetworkById(port.getNetwork()); + // Subnet subnet = netSvc.getSubnetById(port.getSubnetId()); + if (!network.getStatus().equals(Network.Status.ACTIVE.toString())) { + msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId()); + logger.error(msg); + doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg); + throw new RequestFailedException("VM Server Network is DOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412, + server); + } + break; + + /** + * The port is disconnected or powered-off and cannot be used for + * communication + */ + case "OFFLINE": + msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId()); + logger.error(msg); + doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg); + throw new RequestFailedException("VM Server Port status is OFFLINE", msg.toString(), HttpStatus.PRECONDITION_FAILED_412, + server); + + /** + * The port's status is changing because of some event or operation. + * The final state is yet to be determined. + */ + case "PENDING": + msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId()); + logger.error(msg); + doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg); + throw new RequestFailedException("VM Server Port status is PENDING", msg.toString(), HttpStatus.PRECONDITION_FAILED_412, + server); + + /** + * The port is in an unknown state and cannot be used. + */ + case "UNKNOWN": + msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId()); + logger.error(msg); + doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg); + throw new RequestFailedException("VM Server Port status is UNKNOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412, + server); + } + + } + logger.info("Passed the VM Server the Hypervisor status checks.."); + + } + + /** + * Checks if the VM is connected to the Virtual Network and reachable + * + * @param server + * The server object representing the server we want to operate on + */ + protected void checkHypervisor(Server server) + throws ZoneException, RequestFailedException { + + logger.info("Performing the Hypervisor status checks.."); + String status = null, state = null, msg = null; + + status = server.getHypervisor().getStatus().toString(); + state = server.getHypervisor().getState().toString(); + + if (!status.equals(Hypervisor.Status.ENABLED.toString()) || !state.equals(Hypervisor.State.UP.toString())) { + msg = EELFResourceManager.format(Msg.HYPERVISOR_DOWN_ERROR, server.getHypervisor().getHostName(), server.getName()); + logger.error(msg.toString()); + + //doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg); + throw new RequestFailedException("Hypervisor status DOWN or NOT ENABLED", msg.toString(), HttpStatus.PRECONDITION_FAILED_412, + server); + + } + + logger.info("Passed the Hypervisor status checks.."); + + } + + /** + * Checks if a Host machine is reachable + * + * @param ipAddress + * IP Address of the Host Machine. + * @param server + * The server object representing the Virtual Machine server + * @return boolean + * + */ + /*private boolean isHostReachable(String ipAddress) throws IOException { + + InetAddress address = InetAddress.getByName(ipAddress); + + return address.isReachable(15000); + + + }*/ + +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java new file mode 100644 index 000000000..2eb2b69cf --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java @@ -0,0 +1,186 @@ +/*- + * ============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.adapter.iaas.provider.operation.impl.base; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.iaas.impl.RequestContext; +import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; +import org.openecomp.appc.adapter.openstack.heat.StackResource; +import org.openecomp.appc.i18n.Msg; +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.TimeoutException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.StackService; +import com.att.cdp.zones.model.Stack; +import com.att.cdp.zones.spi.AbstractService; +import com.att.cdp.zones.spi.RequestState; +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 com.woorea.openstack.base.client.OpenStackBaseException; +import org.glassfish.grizzly.http.util.HttpStatus; + +import java.util.List; + +/** + * @since September 29, 2016 + */ +public abstract class ProviderStackOperation extends ProviderOperation{ + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderStackOperation.class); + + + protected void trackRequest(Context context, AbstractService.State... states) { + RequestState.clear(); + + if (null == states) return; + for (AbstractService.State state : states) { + RequestState.put(state.getName(), state.getValue()); + } + + Thread currentThread = Thread.currentThread(); + StackTraceElement[] stack = currentThread.getStackTrace(); + if (stack != null && stack.length > 0) { + int index = 0; + StackTraceElement element; + for (; index < stack.length; index++) { + element = stack[index]; + if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$ + break; + } + } + index++; + + if (index < stack.length) { + element = stack[index]; + RequestState.put(RequestState.METHOD, element.getMethodName()); + RequestState.put(RequestState.CLASS, element.getClassName()); + RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber())); + RequestState.put(RequestState.THREAD, currentThread.getName()); + RequestState.put(RequestState.PROVIDER, context.getProvider().getName()); + RequestState.put(RequestState.TENANT, context.getTenantName()); + RequestState.put(RequestState.PRINCIPAL, context.getPrincipal()); + } + } + } + + private boolean checkStatus(String expectedStatus, int pollInterval, String actualStatus) { + if (actualStatus.toUpperCase().equals(expectedStatus)) { + return true; + } else { + try { + Thread.sleep(pollInterval * 1000); + } catch (InterruptedException ignored) { + } + } + return false; + } + + protected boolean waitForStack(Stack stack, StackResource stackResource, String expectedStatus) + throws OpenStackBaseException, TimeoutException { + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); + long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; + + while (System.currentTimeMillis() < maxTimeToWait) { + String stackStatus = stackResource.show(stack.getName(), stack.getId()).execute().getStackStatus(); + logger.debug("Stack status : " + stackStatus); + if (stackStatus.toUpperCase().contains("FAILED")) return false; + if(checkStatus(expectedStatus, pollInterval, stackStatus)) return true; + } + throw new TimeoutException("Timeout waiting for stack status change"); + } + + protected Stack lookupStack(RequestContext rc, Context context, String id) + throws ZoneException, RequestFailedException { + StackService stackService = context.getStackService(); + Stack stack = null; + String msg; + Provider provider = context.getProvider(); + while (rc.attempt()) { + try { + List<Stack> stackList = stackService.getStacks(); + for (Stack stackObj : stackList) { + if (stackObj.getId().equals(id)) { + stack = stackObj; + break; + } + } + break; + } catch (ContextConnectionException e) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), stackService.getURL(), + context.getTenant().getName(), context.getTenant().getId(), e.getMessage(), + Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()), + Integer.toString(rc.getRetryLimit())); + logger.error(msg, e); + rc.delay(); + } + + } + if (rc.isFailed()) { + msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), stackService.getURL()); + logger.error(msg); + doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg); + throw new RequestFailedException("Lookup Stack", msg, HttpStatus.BAD_GATEWAY_502, stack); + } + + if (stack == null) { + throw new ResourceNotFoundException("Stack not found with Id : {" + id + "}"); + } + return stack; + } + + + protected boolean waitForStackStatus(RequestContext rc, Stack stack, Stack.Status expectedStatus) throws ZoneException, RequestFailedException { + SvcLogicContext ctx = rc.getSvcLogicContext(); + Context context = stack.getContext(); + StackService stackService = context.getStackService(); + + int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL); + int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT); + long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000; + Stack.Status stackStatus; + while (System.currentTimeMillis() < maxTimeToWait) { + stackStatus = stackService.getStack(stack.getName(), stack.getId()).getStatus(); + logger.debug("Stack status : " + stackStatus.toString()); + if (stackStatus == expectedStatus) { + return true; + } else if (stackStatus == Stack.Status.FAILED) { + return false; + } else { + try { + Thread.sleep(pollInterval * 1000); + } catch (InterruptedException e) { + logger.trace("Sleep threw interrupted exception, should never occur"); + } + } + } + + ctx.setAttribute("TERMINATE_STATUS", "ERROR"); + throw new TimeoutException("Timeout waiting for stack status change"); + + } +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/utils/Constants.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/utils/Constants.java new file mode 100644 index 000000000..7d896c451 --- /dev/null +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/utils/Constants.java @@ -0,0 +1,31 @@ +/*- + * ============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.adapter.utils; + + +public class Constants { + + /** + * The name of the adapter + */ + public static final String ADAPTER_NAME = "Appc IaaS Adapter"; +} diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java index d83c18b04..abf35db39 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImpl.java @@ -259,13 +259,12 @@ public class TestProviderAdapterImpl { * If the identity service is not available or cannot be created * @throws IOException * if an I/O error occurs - * @throws UnknownProviderException - * If the provider cannot be found + * @throws APPCException */ // @Ignore @Test public void testRestartRunningServer() - throws IllegalStateException, IllegalArgumentException, ZoneException, UnknownProviderException, IOException { + throws IllegalStateException, IllegalArgumentException, ZoneException, IOException, APPCException { Properties properties = new Properties(); properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); @@ -350,15 +349,14 @@ public class TestProviderAdapterImpl { * or are invalid. * @throws IllegalStateException * If the identity service is not available or cannot be created - * @throws UnknownProviderException - * If the provider cannot be found * @throws IOException * if an I/O error occurs + * @throws APPCException */ // @Ignore @Test public void testRestartStoppedServer() - throws IllegalStateException, IllegalArgumentException, ZoneException, UnknownProviderException, IOException { + throws IllegalStateException, IllegalArgumentException, ZoneException, IOException, APPCException { Properties properties = new Properties(); properties.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, IDENTITY_URL); properties.setProperty(ContextFactory.PROPERTY_REGION, REGION_NAME); diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImplNoConnection.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderOperation.java index d4683aa80..f9b571320 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderAdapterImplNoConnection.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestProviderOperation.java @@ -19,41 +19,43 @@ * ============LICENSE_END========================================================= */ - - package org.openecomp.appc.adapter.iaas.impl; import java.lang.reflect.Field; +import java.util.Map; +import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation; +import org.openecomp.appc.exceptions.APPCException; +import com.att.cdp.zones.model.ModelObject; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl; -import org.openecomp.appc.adapter.iaas.impl.RequestContext; -import org.openecomp.appc.adapter.iaas.impl.RequestFailedException; -import org.openecomp.appc.adapter.iaas.impl.VMURL; +import org.slf4j.MDC; + import org.openecomp.appc.configuration.ConfigurationFactory; import org.openecomp.sdnc.sli.SvcLogicContext; -import org.slf4j.MDC; + +import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE; /** * This class is used to test methods and functions of the adapter implementation that do not require and do not set up * connections to any providers. + * + * @since Jan 20, 2016 + * @version $Id$ */ -public class TestProviderAdapterImplNoConnection { +public class TestProviderOperation extends ProviderOperation{ private static Class<?> providerAdapterImplClass; private static Class<?> configurationFactoryClass; private static Field providerCacheField; private static Field configField; - private ProviderAdapterImpl adapter; - /** * Use reflection to locate fields and methods so that they can be manipulated during the test to change the * internal state accordingly. - * + * * @throws NoSuchFieldException * if the field(s) dont exist * @throws SecurityException @@ -75,96 +77,93 @@ public class TestProviderAdapterImplNoConnection { } /** - * initialize the test cases - */ - @Before - public void setup() { - adapter = new ProviderAdapterImpl(false); - } - - /** * This test expects a failure because the value to be validated is a null URL - * + * * @throws RequestFailedException * Expected */ @SuppressWarnings("nls") @Test(expected = RequestFailedException.class) public void testValidateParameterPatternExpectFailNullValue() throws RequestFailedException { - MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + MDC.put(MDC_SERVICE, "junit"); SvcLogicContext svcContext = new SvcLogicContext(); RequestContext rc = new RequestContext(svcContext); String link = null; - adapter.validateVMURL(VMURL.parseURL(link)); + validateVMURL(VMURL.parseURL(link)); } /** * This test expects a failure because the value to be validated is an empty URL - * + * * @throws RequestFailedException * Expected */ @SuppressWarnings("nls") @Test(expected = RequestFailedException.class) public void testValidateParameterPatternExpectFailEmptyValue() throws RequestFailedException { - MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + MDC.put(MDC_SERVICE, "junit"); SvcLogicContext svcContext = new SvcLogicContext(); RequestContext rc = new RequestContext(svcContext); String link = ""; - adapter.validateVMURL(VMURL.parseURL(link)); + validateVMURL(VMURL.parseURL(link)); } /** * This test expects a failure because the value to be validated is a blank URL - * + * * @throws RequestFailedException * Expected */ @SuppressWarnings("nls") @Test(expected = RequestFailedException.class) public void testValidateParameterPatternExpectFailBlankValue() throws RequestFailedException { - MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + MDC.put(MDC_SERVICE, "junit"); SvcLogicContext svcContext = new SvcLogicContext(); RequestContext rc = new RequestContext(svcContext); String link = " "; - adapter.validateVMURL(VMURL.parseURL(link)); + validateVMURL(VMURL.parseURL(link)); } /** * This test expects a failure because the value to be validated is a bad URL - * + * * @throws RequestFailedException * Expected */ @SuppressWarnings("nls") @Test(expected = RequestFailedException.class) public void testValidateParameterPatternExpectFailBadURL() throws RequestFailedException { - MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + MDC.put(MDC_SERVICE, "junit"); SvcLogicContext svcContext = new SvcLogicContext(); RequestContext rc = new RequestContext(svcContext); String link = "http://some.host:1234/01d82c08594a4b23a0f9260c94be0c4d/"; - adapter.validateVMURL(VMURL.parseURL(link)); + validateVMURL(VMURL.parseURL(link)); } /** * This test expects to pass - * + * * @throws RequestFailedException * Un-Expected */ @SuppressWarnings("nls") @Test public void testValidateParameterPatternValidURL() throws RequestFailedException { - MDC.put(ProviderAdapterImpl.MDC_SERVICE, "junit"); + MDC.put(MDC_SERVICE, "junit"); SvcLogicContext svcContext = new SvcLogicContext(); RequestContext rc = new RequestContext(svcContext); String link = "http://some.host:1234/v2/01d82c08594a4b23a0f9260c94be0c4d/servers/f888f89f-096b-421e-ba36-34f714071551"; - adapter.validateVMURL(VMURL.parseURL(link)); + validateVMURL(VMURL.parseURL(link)); + } + + @Override + protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException { + return null; } } diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java index 852bb4137..d99f89b29 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/test/java/org/openecomp/appc/adapter/iaas/impl/TestVMURL.java @@ -43,11 +43,10 @@ public class TestVMURL { @BeforeClass public static void before() { - Properties props = ConfigurationFactory.getConfiguration().getProperties(); - IP = props.getProperty("test.ip"); - PORT = props.getProperty("test.port"); - TENANTID = props.getProperty("test.tenantid"); - VMID = props.getProperty("test.vmid"); + IP = "192.168.1.2"; + PORT = "5000"; + TENANTID = "abcde12345fghijk6789lmnopq123rst"; + VMID = "abc12345-1234-5678-890a-abcdefg12345"; URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID); } diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml index aef1e03f6..4a58e9072 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/pom.xml @@ -19,12 +19,6 @@ </dependency> <dependency> - <groupId>commons-lang</groupId> - <artifactId>commons-lang</artifactId> - <scope>compile</scope> - </dependency> - - <dependency> <groupId>org.opendaylight.mdsal</groupId> <artifactId>features-mdsal</artifactId> <classifier>features</classifier> @@ -39,13 +33,6 @@ <type>zip</type> </dependency> -<!-- <dependency> --> -<!-- Required for launching the feature tests --> -<!-- <groupId>org.opendaylight.yangtools</groupId> --> -<!-- <artifactId>features-test</artifactId> --> -<!-- <scope>test</scope> --> -<!-- </dependency> --> - <dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>features-yangtools</artifactId> diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml index 5ca8f8ebd..40fcce680 100644 --- a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml +++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-features/src/main/resources/features.xml @@ -27,14 +27,16 @@ <!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository> +<!-- <repository>mvn:org.ops4j.pax.web/pax-web-features/6.0.3/xml/features</repository> --> <feature name='appc-iaas-adapter' description="appc-iaas-adapter" version='${project.version}'> <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> -<!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> +<!-- <feature>pax-jetty</feature> --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> <feature>sdnc-sli</feature> <bundle>mvn:org.openecomp.appc/appc-iaas-adapter-bundle/${project.version}</bundle> + </feature> </features> diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml index 766a19314..19f9ebb72 100644 --- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml +++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/pom.xml @@ -22,11 +22,11 @@ <artifactId>appc-common</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-dmaap-adapter-bundle</artifactId> --> +<!-- <version>${project.version}</version> --> +<!-- </dependency> --> <dependency> <groupId>javax</groupId> @@ -159,6 +159,11 @@ <groupId>org.json</groupId> <artifactId>json</artifactId> </dependency> + <dependency> + <groupId>com.jcraft</groupId> + <artifactId>jsch</artifactId> + <version>0.1.54</version> + </dependency> </dependencies> @@ -174,13 +179,13 @@ <Bundle-Activator>org.openecomp.appc.adapter.netconf.AppcNetconfAdapterActivator</Bundle-Activator> <Export-Package>org.openecomp.appc.adapter.netconf,org.openecomp.appc.adapter.netconf.dao,org.openecomp.appc.adapter.netconf.util,org.openecomp.appc.adapter.netconf.exception</Export-Package> <Import-Package> - org.w3c.dom.*,com.sun.org.apache.xerces.*,javax.sql.*,javax.sql.rowset.*,javax.xml.*,org.openecomp.appc.adapter.dmaap.*,javax.crypto.*,org.openecomp.appc.common.exception.*,com.mysql.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.* + !org.slf4j.event,org.w3c.dom.*,com.sun.org.apache.xerces.*,javax.sql.*,javax.sql.rowset.*,javax.xml.*,org.openecomp.appc.adapter.messaging.*,javax.crypto.*,org.openecomp.appc.common.exception.*,com.mysql.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.* </Import-Package> <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|dblib-provider|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|appc-dmaap-adapter-bundle</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> - <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> +<!-- <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> --> </configuration> </plugin> </plugins> diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java index 92141e1b7..93d27babf 100644 --- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java +++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-bundle/src/main/java/org/openecomp/appc/adapter/netconf/util/Constants.java @@ -59,6 +59,7 @@ public class Constants { public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; public static final String RESOURCEKEY = "resourceKey"; + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; } diff --git a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml index 3ce57da86..aefcc50d6 100644 --- a/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml +++ b/appc-adapters/appc-netconf-adapter/appc-netconf-adapter-features/src/main/resources/features.xml @@ -30,7 +30,9 @@ <feature name='appc-netconf-adapter' description="appc-netconf-adapter" version='${project.version}'> <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> - <bundle>mvn:org.openecomp.appc/appc-dmaap-adapter-bundle/${project.version}</bundle> +<!-- <bundle>mvn:org.openecomp.appc/appc-dmaap-adapter-bundle/${project.version}</bundle> --> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> + <bundle start-level="75">mvn:org.openecomp.sdnc.core/dblib-provider/${sdnctl.dblib.version}</bundle> <bundle start-level="83" start="true">mvn:org.openecomp.appc/appc-netconf-adapter-bundle/${project.version}</bundle> </feature> diff --git a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml index b3d24f1fe..d93e34bd4 100644 --- a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml +++ b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/pom.xml @@ -13,27 +13,15 @@ <dependencies> <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - </dependency> - <!-- http://mvnrepository.com/artifact/commons-logging/commons-logging --> - <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> - <!-- http://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>4.4.4</version> </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - <version>4.5.1</version> - </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> @@ -41,18 +29,17 @@ <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> - </dependency> + </dependency> <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> - <classifier>jar-with-dependencies</classifier> - <scope>compile</scope> </dependency> - <dependency> + <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> <scope>test</scope> </dependency> <dependency> @@ -116,6 +103,7 @@ <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-common</artifactId> <version>2.9.1</version> + <scope>test</scope> </dependency> <dependency> @@ -161,10 +149,10 @@ </exclusions> </dependency> - <dependency> - <groupId>equinoxSDK381</groupId> - <artifactId>org.eclipse.osgi</artifactId> - </dependency> +<!-- <dependency> --> +<!-- <groupId>equinoxSDK381</groupId> --> +<!-- <artifactId>org.eclipse.osgi</artifactId> --> +<!-- </dependency> --> <dependency> <groupId>org.slf4j</groupId> @@ -212,11 +200,9 @@ <Bundle-Activator>org.openecomp.appc.adapter.rest.RestActivator</Bundle-Activator> <Export-Package>org.openecomp.appc.adapter.rest</Export-Package> <Import-Package>org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*</Import-Package> - <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis</Embed-Dependency> + <Embed-Dependency>*;scope=compile|runtime;artifactId=!sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|jaxp-api</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> - - <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> </configuration> </plugin> </plugins> diff --git a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java index 4c1baeb01..8a382d778 100644 --- a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java +++ b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestActivator.java @@ -26,12 +26,14 @@ import org.openecomp.appc.adapter.rest.impl.RestAdapterImpl; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; import org.openecomp.appc.i18n.Msg; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + /** * This activator is used to initialize and terminate the connection pool to one or more providers. * <p> diff --git a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java index 0d4a19709..c84c81253 100644 --- a/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java +++ b/appc-adapters/appc-rest-adapter/appc-rest-adapter-bundle/src/main/java/org/openecomp/appc/adapter/rest/RestAdapter.java @@ -39,7 +39,7 @@ import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; */ public interface RestAdapter extends SvcLogicJavaPlugin { - /** + /** * The type of provider to be accessed to locate and operate on a virtual machine instance. This is used to load the * correct provider support through the CDP IaaS abstraction layer and can be OpenStackProvider, BareMetalProvider, * or any other supported provider type. diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/.gitignore b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/.gitignore new file mode 100644 index 000000000..755cdc373 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/target/ +/.settings/ diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/pom.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/pom.xml new file mode 100644 index 000000000..094ca9ab6 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/pom.xml @@ -0,0 +1,223 @@ +<?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> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-rest-healthcheck-adapter-bundle</artifactId> + <packaging>bundle</packaging> + <name>rest healthcheck Adapter - bundle</name> + + <dependencies> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + <!-- http://mvnrepository.com/artifact/commons-logging/commons-logging --> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + <!-- http://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore --> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>4.4.4</version> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcpkix-jdk15on</artifactId> + <version>1.47</version> + </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15on</artifactId> + <version>1.47</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <classifier>jar-with-dependencies</classifier> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-common</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.att.cdp</groupId> + <artifactId>cdp-pal-openstack</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-rest-healthcheck-adapter</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.adapter.restHealthcheck.RestHealthcheckActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.adapter.restHealthcheck</Export-Package> + <Import-Package> + org.openecomp.sdnctl.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*,javax.security.auth.* + </Import-Package> + <Embed-Dependency> + *;scope=compile|runtime;artifactId=!sli-common|!appc-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|xml-apis + </Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + + <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckActivator.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckActivator.java new file mode 100644 index 000000000..a6c9c3f4e --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckActivator.java @@ -0,0 +1,113 @@ + +/*- + * ============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.adapter.restHealthcheck; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.restHealthcheck.impl.RestHealthcheckAdapterImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; + +public class RestHealthcheckActivator implements BundleActivator { + + /** + * The bundle registration + */ + private ServiceRegistration registration = null; + + /** + * The reference to the actual implementation object that implements the services + */ + private RestHealthcheckAdapter adapter; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestHealthcheckActivator.class); + + /** + * The configuration object used to configure this bundle + */ + private Configuration configuration; + + /** + * Called when this bundle is started so the Framework can perform the bundle-specific activities necessary to start + * this bundle. This method can be used to register services or to allocate any resources that this bundle needs. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being started. + * @throws java.lang.Exception + * If this method throws an exception, this bundle is marked as stopped and the Framework will remove + * this bundle's listeners, unregister all services registered by this bundle, and release all services + * used by this bundle. + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + logger.info("Starting bundle " + getName()); + + adapter = new RestHealthcheckAdapterImpl(); + if (registration == null) { + registration = context.registerService(RestHealthcheckAdapter.class, adapter, null); + } + + } + + /** + * Called when this bundle is stopped so the Framework can perform the bundle-specific activities necessary to stop + * the bundle. In general, this method should undo the work that the BundleActivator.start method started. There + * should be no active threads that were started by this bundle when this bundle returns. A stopped bundle must not + * call any Framework objects. + * <p> + * This method must complete and return to its caller in a timely manner. + * </p> + * + * @param context + * The execution context of the bundle being stopped. + * @throws java.lang.Exception + * If this method throws an exception, the bundle is still marked as stopped, and the Framework will + * remove the bundle's listeners, unregister all services registered by the bundle, and release all + * services used by the bundle. * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + logger.info("Stopping bundle " + getName()); + + if (registration != null) { + + registration.unregister(); + registration = null; + + } + } + + public String getName() { + return "APPC Rest Healthcheck adapter"; + } + +} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckAdapter.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckAdapter.java new file mode 100644 index 000000000..87cd02e23 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/RestHealthcheckAdapter.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.adapter.restHealthcheck; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; +import com.att.cdp.zones.model.Server; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + + +public interface RestHealthcheckAdapter extends SvcLogicJavaPlugin { + + + static final String PROPERTY_PROVIDER_TYPE = "org.openecomp.appc.provider.type"; + + + static final String PROPERTY_PROVIDER_NAME = "org.openecomp.appc.provider.name"; + + static final String PROPERTY_INSTANCE_URL = "org.openecomp.appc.instance.url"; + + + static final String PROPERTY_IDENTITY_URL = "org.openecomp.appc.identity.url"; + + String getAdapterName(); + + void checkHealth(Map<String, String> params, SvcLogicContext ctx) ; + +} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RequestContext.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RequestContext.java new file mode 100644 index 000000000..975a9c334 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RequestContext.java @@ -0,0 +1,246 @@ +/*- + * ============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.adapter.restHealthcheck.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.sdnc.sli.SvcLogicContext; + +public class RequestContext { + /** + * The number of seconds of wait time between successive attempts to connect to the provider. This is used to + * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid + * request, server not found, etc. + */ + private Integer retryDelay; + + /** + * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or + * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc. + */ + private Integer retryLimit; + + /** + * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time + * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the + * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to + * milliseconds for the request context. + */ + private Long timeToLive; + + /** + * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the + * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is + * failed with a timeout exception, regardless of the state of the provider. + */ + private long accumulatedTime; + + /** + * The total number of retries attempted so far + */ + private int attempt; + + /** + * The time when the stopwatch was started + */ + private long startTime = -1; + + /** + * The service logic (DG) context from the SLI + */ + private SvcLogicContext svcLogicContext; + + /** + * The configuration + */ + + + /** + * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called. + */ + private boolean retryFailed; + + /** + * Creates the request context + * + * @param context + * The service logic (SLI) context associated with the current DG + */ + public RequestContext(SvcLogicContext context) { + setSvcLogicContext(context); + } + + /** + * @return The retry delay, in seconds. If zero, then no retry is to be performed + */ + public int getRetryDelay() { + if (retryDelay == null) { + int value = 10; + retryDelay = Integer.valueOf(value); + } + + return retryDelay.intValue(); + } + + /** + * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the + * thread interruption, timer handling, etc. + */ + public void delay() { + long time = getRetryDelay() * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + /** + * @return The number of retries that are allowed per connection + */ + public int getRetryLimit() { + if (retryLimit == null) { + int value = 10; + retryLimit = Integer.valueOf(value); + } + + return retryLimit.intValue(); + } + + /** + * Check and count the connection attempt. + * + * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted + * and it should NOT be attempted. + */ + public boolean attempt() { + if (retryFailed || attempt >= getRetryLimit()) { + retryFailed = true; + return false; + } + attempt++; + + return true; + } + + /** + * @return The number of retry attempts so far + */ + public int getAttempts() { + return attempt; + } + + /** + * @return True if the retry limit has been exceeded, false otherwise + */ + public boolean isFailed() { + return retryFailed; + } + + /** + * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so + * far. + * <p> + * Each time this method is called it accumulates the total duration since the last time it was called to the total + * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as + * the total time used is less than or equal to the time to live limit, the method returns true. It is important to + * call this method at the very beginning of the process so that all parts of the process are tracked. + * </p> + * + * @return True if the total time to live has not been exceeded. False indicates that the total time to live has + * been exceeded and no further processing should be performed. + */ + public boolean isAlive() { + long now = System.currentTimeMillis(); + if (startTime == -1) { + startTime = now; + return true; + } + accumulatedTime += (now - startTime); + startTime = now; + if (accumulatedTime > timeToLive) { + return false; + } + return true; + } + + /** + * @return The total amount of time used, in milliseconds. + */ + public long getTotalDuration() { + return accumulatedTime; + } + + /** + * This method is called to reset the retry counters. It has no effect on the time to live accumulator. + */ + public void reset() { + attempt = 0; + } + + /** + * Sets the time to live to the value, expressed in seconds + * + * @param time + * The time to live, in seconds + */ + public void setTimeToLiveSeconds(int time) { + setTimeToLiveMS(time * 1000L); + } + + /** + * Sets the time to live to the value, expressed in milliseconds + * + * @param time + * The time to live, in milliseconds + */ + public void setTimeToLiveMS(long time) { + this.timeToLive = time; + } + + /** + * @return The service logic context associated with this request + */ + public SvcLogicContext getSvcLogicContext() { + return svcLogicContext; + } + + /** + * @param svcLogicContext + * The service logic context to be associated with this request + */ + public void setSvcLogicContext(SvcLogicContext svcLogicContext) { + this.svcLogicContext = svcLogicContext; + } +} diff --git a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestFailedException.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RequestFailedException.java index 047eb8b1f..b4a6d2922 100644 --- a/appc-adapters/appc-chef-adapter/appc-chef-adapter-bundle/src/main/java/org/openecomp/appc/adapter/chef/impl/RequestFailedException.java +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RequestFailedException.java @@ -20,16 +20,14 @@ */ -package org.openecomp.appc.adapter.chef.impl; + +package org.openecomp.appc.adapter.restHealthcheck.impl; import org.glassfish.grizzly.http.util.HttpStatus; + import com.att.cdp.zones.model.Server; -/** - * This class is used to capture the exact cause and point of failure for the processing of a request. It is then used - * to encode the reason for the failure, status code, and anything else that needs to be captured and reported for - * diagnostic purposes. - */ + public class RequestFailedException extends Exception { /** diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RestHealthcheckAdapterImpl.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RestHealthcheckAdapterImpl.java new file mode 100644 index 000000000..13bc81ac4 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/java/org/openecomp/appc/adapter/restHealthcheck/impl/RestHealthcheckAdapterImpl.java @@ -0,0 +1,336 @@ +/*- + * ============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.adapter.restHealthcheck.impl; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Pattern; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.adapter.restHealthcheck.RestHealthcheckAdapter; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.exceptions.UnknownProviderException; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.pool.Pool; +import org.openecomp.appc.pool.PoolExtensionException; +import org.openecomp.appc.util.StructuredPropertyHelper; +import org.openecomp.appc.util.StructuredPropertyHelper.Node; + + +import com.att.cdp.exceptions.ContextConnectionException; +import com.att.cdp.exceptions.ResourceNotFoundException; +import com.att.cdp.exceptions.TimeoutException; +import com.att.cdp.exceptions.ZoneException; +import com.att.cdp.pal.util.StringHelper; +import com.att.cdp.zones.ComputeService; +import com.att.cdp.zones.Context; +import com.att.cdp.zones.ImageService; +import com.att.cdp.zones.Provider; +import com.att.cdp.zones.model.Image; +import com.att.cdp.zones.model.Server; +import com.att.cdp.zones.model.Server.Status; +import com.att.cdp.zones.model.ServerBootSource; +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.glassfish.grizzly.http.util.HttpStatus; +import org.slf4j.MDC; + +import java.net.InetAddress; +import java.util.Locale; +import java.util.UUID; +import static com.att.eelf.configuration.Configuration.*; + +import org.apache.http.*; +import org.apache.http.client.*; +import org.apache.http.client.methods.*; +import org.apache.http.impl.client.*; +import org.apache.http.util.EntityUtils; +import java.io.IOException; +import org.apache.http.entity.StringEntity; +import java.net.InetAddress; + +public class RestHealthcheckAdapterImpl implements RestHealthcheckAdapter { + + /** + * The constant used to define the adapter name in the mapped diagnostic + * context + */ + + + @SuppressWarnings("nls") + public static final String MDC_ADAPTER = "adapter"; + + /** + * The constant used to define the service name in the mapped diagnostic + * context + */ + @SuppressWarnings("nls") + public static final String MDC_SERVICE = "service"; + + /** + * The constant for the status code for a failed outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_FAILURE = "failure"; + + /** + * The constant for the status code for a successful outcome + */ + @SuppressWarnings("nls") + public static final String OUTCOME_SUCCESS = "success"; + + /** + * A constant for the property token "provider" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER = "provider"; + + /** + * A constant for the property token "identity" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_IDENTITY = "identity"; + + /** + * A constant for the property token "name" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_NAME = "name"; + + /** + * A constant for the property token "tenant" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT = "tenant"; + + /** + * A constant for the property token "tenant name" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_NAME = "name"; + + /** + * A constant for the property token "password" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_PASSWORD = "password"; // NOSONAR + + /** + * A constant for the property token "userid" used in the structured + * property specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TENANT_USERID = "userid"; + + /** + * A constant for the property token "type" used in the structured property + * specifications + */ + @SuppressWarnings("nls") + public static final String PROPERTY_PROVIDER_TYPE = "type"; + + + @SuppressWarnings("nls") + public static final String PING_SERVICE = "pingServer"; + + /** + * The logger to be used + */ + private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestHealthcheckAdapterImpl.class); + + /** + * The constant for a left parenthesis + */ + private static final char LPAREN = '('; + + /** + * The constant for a new line control code + */ + private static final char NL = '\n'; + + /** + * The constant for a single quote + */ + private static final char QUOTE = '\''; + + /** + * The constant for a right parenthesis + */ + private static final char RPAREN = ')'; + + /** + * The constant for a space + */ + private static final char SPACE = ' '; + + /** + * A reference to the adapter configuration object. + */ + private Configuration configuration; + + /** + * A cache of providers that are predefined. + */ + // private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * This default constructor is used as a work around because the activator + * wasnt getting called + */ + /** + * A cache of providers that are predefined. + */ + // private Map<String /* provider name */, ProviderCache> providerCache; + + /** + * This default constructor is used as a work around because the activator + * wasnt getting called + */ + public RestHealthcheckAdapterImpl() { + initialize(); + + } + + + public RestHealthcheckAdapterImpl(boolean initialize) { + + if (initialize) { + initialize(); + + } + } + + + public RestHealthcheckAdapterImpl(Properties props) { + initialize(); + + } + + + @Override + public String getAdapterName() { + return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME); + } + + public void checkHealth(Map<String, String> params, SvcLogicContext ctx) { + logger.info("VNF rest health check"); + String uri=params.get("VNF.URI"); + String endPoint=params.get("VNF.endpoint"); + String tUrl=uri+"/"+endPoint; + RequestContext rc = new RequestContext(ctx); + rc.isAlive(); + + try { + HttpGet httpGet = new HttpGet(tUrl); + HttpClient httpClient = HttpClients.createDefault(); + HttpResponse response = null; + response = httpClient.execute(httpGet); + int responseCode=response.getStatusLine().getStatusCode(); + HttpEntity entity = response.getEntity(); + String responseOutput=EntityUtils.toString(entity); + if(responseCode==200) + { + doSuccess(rc,responseCode,responseOutput); + } + else + { + doHealthCheckFailure(rc,responseCode,responseOutput); + } + } catch (Exception ex) { + doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString()); + } + } + + + + + @SuppressWarnings("static-method") + private void doFailure(RequestContext rc, HttpStatus code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = (message == null) ? code.getReasonPhrase() : message; + if (msg.contains("\n")) { + msg = msg.substring(msg.indexOf("\n")); + } + + String status; + try { + status = Integer.toString(code.getStatusCode()); + } catch (Exception e) { + status = "500"; + } + svcLogic.setStatus(OUTCOME_FAILURE); + svcLogic.setAttribute("healthcheck.result.code", "200"); + svcLogic.setAttribute("healthcheck.result.message", status+" "+msg); + } + + + /** + * @param rc + * The request context that manages the state and recovery of the + * request for the life of its processing. + */ + @SuppressWarnings("static-method") + private void doHealthCheckFailure(RequestContext rc, int code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = Integer.toString(code)+" "+message; + svcLogic.setAttribute("healthcheck.result.code", "200"); + svcLogic.setAttribute("healthcheck.result.message", msg); + + } + + + @SuppressWarnings("static-method") + private void doSuccess(RequestContext rc, int code, String message) { + SvcLogicContext svcLogic = rc.getSvcLogicContext(); + String msg = Integer.toString(code)+" "+message; + svcLogic.setAttribute("healthcheck.result.code", "400"); + svcLogic.setAttribute("healthcheck.result.message", msg); + + } + + + /** + * initialize the provider adapter by building the context cache + */ + private void initialize() { + + + logger.info("init rest health check adapter!!!!!"); + } + +} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..d7d9e5cb1 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,76 @@ +### +# ============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========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# 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},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=org/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=org/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java new file mode 100644 index 000000000..c21435d2e --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/ExecutorHarness.java @@ -0,0 +1,180 @@ +/*- + * ============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.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.appc.test.InterceptLogger; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +/** + * This class is used as a test harness to wrap the call to an executor node. + */ + +public class ExecutorHarness { + + /** + * The executor to be tested + */ + private SvcLogicJavaPlugin executor; + + /** + * The collection of all exec methods found on the class + */ + private Map<String, Method> methods; + + /** + * The field of the class being tested that contains the reference to the logger to be used. This is modified to + * point to our interception logger for the test. + */ + private Field contextLogger; + + /** + * The interception logger that buffers all messages logged and allows us to look at them as part of the test case. + */ + private InterceptLogger logger; + + /** + * Create the harness and initialize it + * + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + @SuppressWarnings("nls") + public ExecutorHarness() throws NoSuchFieldException, SecurityException, IllegalArgumentException, + IllegalAccessException { + methods = new HashMap<>(); + new SvcLogicContext(); + + Class<?> contextClass = SvcLogicContext.class; + contextLogger = contextClass.getDeclaredField("LOG"); + contextLogger.setAccessible(true); + logger = new InterceptLogger(); + contextLogger.set(null, logger); + } + + /** + * Convenience constructor + * + * @param executor + * The executor to be tested by the harness + * @throws SecurityException + * If a security manager, s, is present and any of the following conditions is met: + * <ul> + * <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared field</li> + * <li>the caller's class loader is not the same as or an ancestor of the class loader for the current + * class and invocation of s.checkPackageAccess() denies access to the package of this class</li> + * </ul> + * @throws NoSuchFieldException + * if a field with the specified name is not found. + * @throws IllegalAccessException + * if this Field object is enforcing Java language access control and the underlying field is either + * inaccessible or final. + * @throws IllegalArgumentException + * if the specified object is not an instance of the class or interface declaring the underlying field + * (or a subclass or implementor thereof), or if an unwrapping conversion fails. + */ + public ExecutorHarness(SvcLogicJavaPlugin executor) throws NoSuchFieldException, SecurityException, + IllegalArgumentException, IllegalAccessException { + this(); + setExecutor(executor); + } + + /** + * @param executor + * The java plugin class to be executed + */ + public void setExecutor(SvcLogicJavaPlugin executor) { + this.executor = executor; + scanExecutor(); + } + + /** + * @return The java plugin class to be executed + */ + public SvcLogicJavaPlugin getExecutor() { + return executor; + } + + /** + * @return The set of all methods that meet the signature requirements + */ + public List<String> getExecMethodNames() { + List<String> names = new ArrayList<>(); + names.addAll(methods.keySet()); + return names; + } + + /** + * Returns an indication if the named method is a valid executor method that could be called from a DG execute node + * + * @param methodName + * The method name to be validated + * @return True if the method name meets the signature requirements, false if the method either does not exist or + * does not meet the requirements. + */ + public boolean isExecMethod(String methodName) { + return methods.containsKey(methodName); + } + + /** + * This method scans the executor class hierarchy to locate all methods that match the required signature of the + * executor and records these methods in a map. + */ + private void scanExecutor() { + methods.clear(); + Class<?> executorClass = executor.getClass(); + Method[] publicMethods = executorClass.getMethods(); + for (Method method : publicMethods) { + if (method.getReturnType().equals(Void.class)) { + Class<?>[] paramTypes = method.getParameterTypes(); + if (paramTypes.length == 2) { + if (Map.class.isAssignableFrom(paramTypes[0]) + && SvcLogicContext.class.isAssignableFrom(paramTypes[1])) { + methods.put(method.getName(), method); + } + } + } + } + } +} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java new file mode 100644 index 000000000..acb122914 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/java/org/openecomp/appc/test/InterceptLogger.java @@ -0,0 +1,452 @@ +/*- + * ============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.test; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Marker; + +import ch.qos.logback.classic.Level; + +/** + * This class is used as an intercept logger that can be used in testing to intercept and record all messages that are + * logged, thus allowing a junit test case to examine the log output and make assertions. + */ +public class InterceptLogger implements org.slf4j.Logger { + + /** + * This inner class represents an intercepted log event. + */ + public class LogRecord { + private Level level; + private String message; + private long timestamp; + private Throwable t; + + public LogRecord(Level level, String message) { + setLevel(level); + setTimestamp(System.currentTimeMillis()); + setMessage(message); + } + + public LogRecord(Level level, String message, Throwable t) { + this(level, message); + setThrowable(t); + } + + /** + * @return the value of level + */ + public Level getLevel() { + return level; + } + + /** + * @return the value of message + */ + public String getMessage() { + return message; + } + + /** + * @return the value of timestamp + */ + public long getTimestamp() { + return timestamp; + } + + /** + * @param level + * the value for level + */ + public void setLevel(Level level) { + this.level = level; + } + + /** + * @param message + * the value for message + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @param timestamp + * the value for timestamp + */ + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * @return the value of t + */ + public Throwable getThrowable() { + return t; + } + + /** + * @param t + * the value for t + */ + public void setThrowable(Throwable t) { + this.t = t; + } + + } + + /** + * The list of all intercepted log events + */ + private List<LogRecord> events; + + /** + * Create the intercept logger + */ + public InterceptLogger() { + events = new ArrayList<LogRecord>(1000); + } + + /** + * @return Returns all intercepted log events + */ + public List<LogRecord> getLogRecords() { + return events; + } + + /** + * Clears all log events + */ + public void clear() { + events.clear(); + } + + @Override + public void debug(Marker marker, String msg) { + debug(msg); + } + + @Override + public void debug(Marker marker, String format, Object arg) { + debug(MessageFormat.format(format, arg)); + } + + @Override + public void debug(Marker marker, String format, Object... arguments) { + debug(MessageFormat.format(format, arguments)); + } + + @Override + public void debug(Marker marker, String format, Object arg1, Object arg2) { + debug(MessageFormat.format(format, arg1, arg2)); + } + + @Override + public void debug(Marker marker, String msg, Throwable t) { + debug(msg, t); + } + + @Override + public void debug(String msg) { + events.add(new LogRecord(Level.DEBUG, msg)); + } + + @Override + public void debug(String format, Object arg) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg))); + } + + @Override + public void debug(String format, Object... arguments) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arguments))); + } + + @Override + public void debug(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.DEBUG, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void debug(String msg, Throwable t) { + events.add(new LogRecord(Level.DEBUG, msg, t)); + } + + @Override + public void error(Marker marker, String msg) { + error(msg); + } + + @Override + public void error(Marker marker, String format, Object arg) { + error(format, arg); + } + + @Override + public void error(Marker marker, String format, Object... arguments) { + error(format, arguments); + } + + @Override + public void error(Marker marker, String format, Object arg1, Object arg2) { + error(format, arg1, arg2); + } + + @Override + public void error(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public void error(String msg) { + events.add(new LogRecord(Level.ERROR, msg)); + } + + @Override + public void error(String format, Object arg) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg))); + } + + @Override + public void error(String format, Object... arguments) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arguments))); + } + + @Override + public void error(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.ERROR, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void error(String msg, Throwable t) { + events.add(new LogRecord(Level.ERROR, msg, t)); + } + + @Override + public String getName() { + return null; + } + + @Override + public void info(Marker marker, String msg) { + info(msg); + } + + @Override + public void info(Marker marker, String format, Object arg) { + info(format, arg); + } + + @Override + public void info(Marker marker, String format, Object... arguments) { + info(format, arguments); + } + + @Override + public void info(Marker marker, String format, Object arg1, Object arg2) { + info(format, arg1, arg2); + } + + @Override + public void info(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public void info(String msg) { + events.add(new LogRecord(Level.INFO, msg)); + } + + @Override + public void info(String format, Object arg) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg))); + } + + @Override + public void info(String format, Object... arguments) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arguments))); + } + + @Override + public void info(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.INFO, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void info(String msg, Throwable t) { + events.add(new LogRecord(Level.INFO, msg, t)); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public boolean isDebugEnabled(Marker marker) { + return true; + } + + @Override + public boolean isErrorEnabled() { + return true; + } + + @Override + public boolean isErrorEnabled(Marker marker) { + return true; + } + + @Override + public boolean isInfoEnabled() { + return true; + } + + @Override + public boolean isInfoEnabled(Marker marker) { + return true; + } + + @Override + public boolean isTraceEnabled() { + return true; + } + + @Override + public boolean isTraceEnabled(Marker marker) { + return true; + } + + @Override + public boolean isWarnEnabled() { + return true; + } + + @Override + public boolean isWarnEnabled(Marker marker) { + return true; + } + + @Override + public void trace(Marker marker, String msg) { + trace(msg); + } + + @Override + public void trace(Marker marker, String format, Object arg) { + trace(format, arg); + } + + @Override + public void trace(Marker marker, String format, Object... argArray) { + trace(format, argArray); + } + + @Override + public void trace(Marker marker, String format, Object arg1, Object arg2) { + trace(format, arg1, arg2); + } + + @Override + public void trace(Marker marker, String msg, Throwable t) { + trace(msg, t); + } + + @Override + public void trace(String msg) { + events.add(new LogRecord(Level.TRACE, msg)); + } + + @Override + public void trace(String format, Object arg) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg))); + } + + @Override + public void trace(String format, Object... arguments) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arguments))); + } + + @Override + public void trace(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.TRACE, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void trace(String msg, Throwable t) { + events.add(new LogRecord(Level.TRACE, msg, t)); + } + + @Override + public void warn(Marker marker, String msg) { + warn(msg); + } + + @Override + public void warn(Marker marker, String format, Object arg) { + warn(format, arg); + } + + @Override + public void warn(Marker marker, String format, Object... arguments) { + warn(format, arguments); + } + + @Override + public void warn(Marker marker, String format, Object arg1, Object arg2) { + warn(format, arg1, arg2); + } + + @Override + public void warn(Marker marker, String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } + + @Override + public void warn(String msg) { + events.add(new LogRecord(Level.WARN, msg)); + } + + @Override + public void warn(String format, Object arg) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg))); + } + + @Override + public void warn(String format, Object... arguments) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arguments))); + } + + @Override + public void warn(String format, Object arg1, Object arg2) { + events.add(new LogRecord(Level.WARN, MessageFormat.format(format, arg1, arg2))); + } + + @Override + public void warn(String msg, Throwable t) { + events.add(new LogRecord(Level.WARN, msg, t)); + } +} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..0c56e3342 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -0,0 +1,95 @@ +### +# ============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========================================================= +### + +# +# Default properties for the APP-C Provider Adapter +# +# ------------------------------------------------------------------------------------------------- +# +# 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},. + +appc.application.name=APPC + +# +# Define the message resource bundle name to be loaded +org.openecomp.appc.resources=/opt/openecomp/appc/i18n/MessageResources +# +# The name of the adapter. +org.openecomp.appc.provider.adaptor.name=org.openecomp.appc.appc_provider_adapter +# +# Set up the logging environment +# +org.openecomp.appc.logging.file=/opt/openecomp/appc/logback.xml +org.openecomp.appc.logging.path=${user.home};etc;../etc +org.openecomp.appc.logger=org.openecomp.appc +org.openecomp.appc.security.logger=org.openecomp.appc.security +# +# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon +# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0 +# means that the upper bound on the pool is unbounded. +org.openecomp.appc.provider.min.pool=1 +org.openecomp.appc.provider.max.pool=0 + +# +# The following properties are used to configure the retry logic for connection to the +# IaaS provider(s). The retry delay property is the amount of time, in seconds, the +# application waits between retry attempts. The retry limit is the number of retries +# that are allowed before the request is failed. +org.openecomp.appc.provider.retry.delay = 30 +org.openecomp.appc.provider.retry.limit = 10 + +# +# The trusted hosts list for SSL access when a certificate is not provided. +# +provider.trusted.hosts=* +# +# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc). +# If the server does not change state to a valid state within the alloted time, the operation +# fails. +org.openecomp.appc.server.state.change.timeout=300 +# +# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider +# to refresh the status of a resource we are waiting on. +# +org.openecomp.appc.openstack.poll.interval=20 +# +# The connection information to connect to the provider we are using. These properties +# are "structured" properties, in that the name is a compound name, where the nodes +# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal +# position are defining the same entity. For example, provider1.type and provider1.name +# are defining the same provider, whereas provider2.name and provider2.type are defining +# the values for a different provider. Any number of providers can be defined in this +# way. +# + + + +provider1.identity=http://localhost:4000/v2.0 +provider1.tenant1.name=Provider1 +provider1.tenant1.userid=test +provider1.tenant1.password=test + +# After a change to the provider make sure to recheck these values with an api call to proivider1.identity/tokens +test.expected-regions=1 +test.expected-endpoints=1 diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/.gitignore b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/.gitignore new file mode 100644 index 000000000..615a76bbc --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/.gitignore @@ -0,0 +1,4 @@ +/target/ +/bin/ +/classes/ +/.settings/ diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/pom.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/pom.xml new file mode 100644 index 000000000..20a990482 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/pom.xml @@ -0,0 +1,122 @@ +<?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-rest-healthcheck-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-rest-healthcheck-adapter-features</artifactId> + <name>rest healthcheck Adaptor - Features</name> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </dependency> + + <!-- dependency for opendaylight-karaf-empty for use by testing --> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>opendaylight-karaf-empty</artifactId> + <type>zip</type> + </dependency> + +<!-- <dependency> --> +<!-- Required for launching the feature tests --> +<!-- <groupId>org.opendaylight.yangtools</groupId> --> +<!-- <artifactId>features-test</artifactId> --> +<!-- <scope>test</scope> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </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> + <!-- 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. --> + <!-- <plugin> --> + <!-- <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> --> + <!-- </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> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/src/main/resources/features.xml new file mode 100644 index 000000000..d9cb37c49 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?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-rest-adapter-${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"> + + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${features-mdsal.version}/xml/features</repository> + + <feature name='appc-rest-healthcheck-adapter' description="appc-rest-healthcheck-adapter" version='${project.version}'> + <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <feature>sdnc-sli</feature> + <bundle>mvn:org.openecomp.appc/appc-rest-healthcheck-adapter-bundle/${project.version}</bundle> + </feature> + +</features> diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/.gitignore b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/pom.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/pom.xml new file mode 100644 index 000000000..4dc4a4d13 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/pom.xml @@ -0,0 +1,126 @@ +<?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-rest-healthcheck-adapter</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-rest-healthcheck-adapter-installer</artifactId> + <name>Chef Adapter - Karaf Installer</name> + <packaging>pom</packaging> + <properties> + <application.name>appc-rest-healthcheck-adapter</application.name> + <features.boot>appc-rest-healthcheck-adapter</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-rest-healthcheck-adapter-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter-bundle</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_installer_zip.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..9fbaad8c5 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..1ac5a82bc --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,47 @@ +<!-- + ============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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>adapter</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + +</assembly> diff --git a/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/main/resources/scripts/install-feature.sh b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/appc-rest-healthcheck-adapter-installer/src/main/resources/scripts/install-feature.sh @@ -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========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/appc-adapters/appc-rest-healthcheck-adapter/pom.xml b/appc-adapters/appc-rest-healthcheck-adapter/pom.xml new file mode 100644 index 000000000..fd95c0bf6 --- /dev/null +++ b/appc-adapters/appc-rest-healthcheck-adapter/pom.xml @@ -0,0 +1,125 @@ +<?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/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-adapters</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-rest-healthcheck-adapter</artifactId> + <name>rest healthcheck adaptor</name> + <description>Abstraction to connect to and utilize the services of cloud providers such as OpenStack or VMWare.</description> + <packaging>pom</packaging> + + <reporting> + <plugins> + <plugin> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalDependencies> + <additionalDependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4</artifactId> + <version>${antlr.version}</version> + </additionalDependency> + <additionalDependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + <version>4.3</version> + </additionalDependency> + </additionalDependencies> + </configuration> + <reportSets> + <reportSet> + <reports> + <report>javadoc-no-fork</report> + <report>test-javadoc-no-fork</report> + </reports> + </reportSet> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jxr-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>aggregate</id> + <reports> + <report>aggregate</report> + <report>test-aggregate</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-changelog-plugin</artifactId> + <version>2.3</version> + <reportSets> + <reportSet> + <id>dual-report</id> + <configuration> + <type>range</type> + <range>30</range> + </configuration> + <reports> + <report>changelog</report> + <report>file-activity</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>taglist-maven-plugin</artifactId> + <version>2.4</version> + </plugin> + </plugins> + </reporting> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter-features</artifactId> + <classifier>features</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-rest-healthcheck-adapter-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + + </dependencyManagement> + + <modules> + <module>appc-rest-healthcheck-adapter-bundle</module> + <module>appc-rest-healthcheck-adapter-features</module> + <module>appc-rest-healthcheck-adapter-installer</module> + </modules> +</project> diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java index 7eb069f55..5443d5de9 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/Constants.java @@ -46,14 +46,37 @@ public class Constants { // input fields names public static final String PAYLOAD = "payload"; + public static final String CONNECTION_RETRY_DELAY = "org.openecomp.appc.ssh.connection.retry.delay"; + public static final String CONNECTION_RETRY_COUNT = "org.openecomp.appc.ssh.connection.retry.count"; + public static final int DEFAULT_CONNECTION_RETRY_DELAY = 60; + public static final int DEFAULT_CONNECTION_RETRY_COUNT = 5; - public static final String PARAM_IN_connection_details = "connection-details"; + public static final int DEFAULT_SSH_COMMAND_RETRY_COUNT = 3; + + public static final int DEFAULT_CHECKACTIVE_RETRY_COUNT = 3; + public static final int DEFAULT_CHECKACTIVE_RETRY_DELAY = 30; + + public static final int DEFAULT_STOP_RETRY_COUNT = 3; + public static final int DEFAULT_STOP_RETRY_DELAY = 30; //seconds + + public static final String PARAM_IN_CONNECTION_DETAILS = "connection-details"; + public static final String PARAM_IN_NODE_NAME = "node-name"; + public static final String PARAM_IN_NODE_STATUS = "node-status"; + public static final String PARAM_IN_VM_URL = "vm-url"; public static final String SKIP_EXECUTION_INSTALLER_BIN_FILE = "Skip-execution-installer-bin-file"; public static final String SKIP_DEPLOY = "Skip-deploy"; public static final String UPGRADE_VERSION = "upgrade-version"; //command to get number of UP hosts public static final String STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh | grep -o UP | wc -l"; + //command to get each VNFC status + public static final String VNFC_STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh"; + //command to restart node + public static final String RESTART_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh --restart -f --nodes"; + //command to start node + public static final String START_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-start.sh -f --nodes"; + //command to stop node + public static final String STOP_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh -f --nodes"; public static final int STATE_COMMAND_RESULT = 18; //commands to check FE hosts public static final String FE_STATE_TRUE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o TRUE | wc -l"; @@ -62,6 +85,12 @@ public class Constants { public static final int FE_STATE_FALSE_TEST_RESULT = 2; public static final String FE_OPERATIONAL_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o 'NOT FULLY OPERATIONAL' | wc -l"; public static final int FE_OPERATIONAL_TEST_RESULT = 2; + + //smp commands + public static final String SMP_CHECK_ACTIVE_STATE_COMMAND = "cat skyfall-scp/runtime/SCP_SMP_*/smp/log/system.log| grep SSS | tail -1"; + public static final String SMP_STATE_ACTIVE="SMP is active"; + public static final String SMP_STATE_INACTIVE="SMP is not active"; + //rsync command public static final String RSYNC_COMMAND = "yes n | /opt/jnetx/skyfall-scp/asp-rsync.sh --check | grep -o 'is active' | wc -l"; public static final int RSYNC_COMMAND_RESULT = 9; @@ -70,17 +99,19 @@ public class Constants { public static final String PARAM_IN_FILE_URL = "source-file-url"; public static final String DOWNLOAD_COMMAND = "wget -N %s"; - // pre-define jnetx VM names + // pre-define VM names public static final String[] VM_NAMES = {"fe1", "fe2", "be1", "be2", "be3", "be4", "be5", "smp1", "smp2"}; public static final String DEFAULT_DISK_SPACE = "10240000"; public static final String DF_COMMAND_TEMPLATE = "ssh %s df | grep vda1 | grep -v grep | tr -s ' '|cut -d ' ' -f4"; public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; - // constants fo DG - public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details"; + // constants for DG + public static final String CONNECTION_DETAILS_FIELD_NAME = PARAM_IN_CONNECTION_DETAILS; public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; - public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; + public static final String VNF_HOST_IP2_ADDRESS_FIELD_NAME = "vnf-host-ip2-address"; + public static final String DG_ERROR_FIELD_NAME = "org.openecom.appc.dg.error"; } diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java index 0b3275f5d..39faa321f 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-api/src/main/java/org/openecomp/appc/adapter/ssh/SshConnection.java @@ -34,6 +34,11 @@ public interface SshConnection { void connect(); /** + * Connect to SSH Server using a retry mechanism + */ + void connectWithRetry(); + + /** * Disconnect from SSH server. */ void disconnect(); diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml index 6f565dc09..2984a16cd 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-features/src/main/resources/features.xml @@ -25,6 +25,8 @@ 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-ssh-adapter' description="appc-ssh-adapter" version='${project.version}'> +<!-- <feature version='${sdnctl.dblib.version}'>sdnc-dblib</feature> --> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-ssh-adapter-api/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-ssh-adapter-sshd/${project.version}</bundle> </feature> diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml index 35bb0cf92..76601450e 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/pom.xml @@ -1,62 +1,64 @@ <?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> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-ssh-adapter</artifactId> - <version>1.1.0-SNAPSHOT</version> - </parent> +<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-ssh-adapter</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> - <artifactId>appc-ssh-adapter-sshd</artifactId> - <packaging>bundle</packaging> + <artifactId>appc-ssh-adapter-sshd</artifactId> + <packaging>bundle</packaging> - <dependencies> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-ssh-adapter-api</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.apache.sshd</groupId> - <artifactId>sshd-core</artifactId> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.att.eelf</groupId> - <artifactId>eelf-core</artifactId> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - </dependency> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-common</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>dblib-provider</artifactId> - </dependency> - </dependencies> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ssh-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Export-Service>org.openecomp.appc.adapter.ssh.SshAdapter</Export-Service> - <Private-Package>org.openecomp.appc.adapter.ssh.impl.*</Private-Package> - <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional</Import-Package> - <Embed-Dependency>!dblib-provider,appc-common,jasypt,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> - </instructions> - </configuration> - </plugin> - </plugins> - </build> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Service>org.openecomp.appc.adapter.ssh.SshAdapter</Export-Service> + <Private-Package>org.openecomp.appc.adapter.ssh.impl.*</Private-Package> + <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> + <Embed-Dependency>!dblib-provider,jasypt,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> </project> diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java index 4d8b83b6f..e87bfa264 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshConnectionSshd.java @@ -21,6 +21,12 @@ package org.openecomp.appc.adapter.ssh.sshd; +import org.openecomp.appc.adapter.ssh.Constants; +import org.openecomp.appc.adapter.ssh.SshConnection; +import org.openecomp.appc.adapter.ssh.SshException; +import org.openecomp.appc.encryption.EncryptionTool; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; import org.apache.sshd.ClientChannel; import org.apache.sshd.ClientSession; import org.apache.sshd.SshClient; @@ -29,9 +35,7 @@ import org.apache.sshd.client.future.AuthFuture; import org.apache.sshd.client.future.OpenFuture; import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.keyprovider.FileKeyPairProvider; -import org.openecomp.appc.adapter.ssh.SshConnection; -import org.openecomp.appc.adapter.ssh.SshException; -import org.openecomp.appc.encryption.EncryptionTool; + import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; @@ -43,130 +47,187 @@ import java.security.KeyPair; */ class SshConnectionSshd implements SshConnection { - private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); - - private static final long AUTH_TIMEOUT = 60000; - private static final long EXEC_TIMEOUT = 120000; - - private String host; - private int port; - private String username; - private String password; - private long timeout = EXEC_TIMEOUT; - private String keyFile; - private SshClient sshClient; - private ClientSession clientSession; - - public SshConnectionSshd(String host, int port, String username, String password, String keyFile) { - this.host = host; - this.port = port; - this.username = username; - this.password = password; - this.keyFile = keyFile; - } - - public SshConnectionSshd(String host, int port, String username, String password) { - this(host, port, username, password, null); - } - - public SshConnectionSshd(String host, int port, String keyFile) { - this(host, port, null, null, keyFile); - } - - @Override - public void connect() { - sshClient = SshClient.setUpDefaultClient(); - sshClient.start(); - try { - clientSession = sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession(); - if(password != null) { - clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password)); - } - if(keyFile != null) { - KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[]{keyFile}); - KeyPair keyPair = keyPairProvider.loadKeys().iterator().next(); - clientSession.addPublicKeyIdentity(keyPair); - } - AuthFuture authFuture = clientSession.auth(); - authFuture.await(AUTH_TIMEOUT); - if(!authFuture.isSuccess()) { - throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "]. Authentication failed."); - } - } catch(RuntimeException e) { - throw e; - } catch(Exception e) { - throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", e); - } - if(logger.isDebugEnabled()) { - logger.debug("SSH: connected to [" + toString() + "]"); - } - } - - @Override - public void disconnect() { - try { - if(logger.isDebugEnabled()) { - logger.debug("SSH: disconnecting from [" + toString() + "]"); - } - clientSession.close(false); - } finally { - if(sshClient != null) { - sshClient.stop(); - } - } - } - - @Override - public void setExecTimeout(long timeout) { - this.timeout = timeout; - } - - @Override - public int execCommand(String cmd, OutputStream out, OutputStream err) { - return execCommand(cmd, out, err, false); - } - - @Override - public int execCommandWithPty(String cmd, OutputStream out) { - return execCommand(cmd, out, out, true); - } - - private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) { - try { - if(logger.isDebugEnabled()) { - logger.debug("SSH: executing command"); - } - ChannelExec client = clientSession.createExecChannel(cmd); + private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger(); + + private static final long AUTH_TIMEOUT = 60000; + private static final long EXEC_TIMEOUT = 120000; + + private String host; + private int port; + private String username; + private String password; + private long timeout = EXEC_TIMEOUT; + private String keyFile; + private SshClient sshClient; + private ClientSession clientSession; + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + + public SshConnectionSshd(String host, int port, String username, String password, String keyFile) { + this.host = host; + this.port = port; + this.username = username; + this.password = password; + this.keyFile = keyFile; + } + + public SshConnectionSshd(String host, int port, String username, String password) { + this(host, port, username, password, null); + } + + public SshConnectionSshd(String host, int port, String keyFile) { + this(host, port, null, null, keyFile); + } + + @Override + public void connect() { + sshClient = SshClient.setUpDefaultClient(); + sshClient.start(); + try { + clientSession = + sshClient.connect(EncryptionTool.getInstance().decrypt(username), host, port).await().getSession(); + if (password != null) { + clientSession.addPasswordIdentity(EncryptionTool.getInstance().decrypt(password)); + } + if (keyFile != null) { + KeyPairProvider keyPairProvider = new FileKeyPairProvider(new String[] { + keyFile + }); + KeyPair keyPair = keyPairProvider.loadKeys().iterator().next(); + clientSession.addPublicKeyIdentity(keyPair); + } + AuthFuture authFuture = clientSession.auth(); + authFuture.await(AUTH_TIMEOUT); + if (!authFuture.isSuccess()) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + + "]. Authentication failed."); + } + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].", + e); + } + if (logger.isDebugEnabled()) { + logger.debug("SSH: connected to [" + toString() + "]"); + } + } + + @Override + public void connectWithRetry() { + int retryCount = 0; + int retryDelay = 0; + int retriesLeft = 0; + retryCount = configuration.getIntegerProperty(Constants.CONNECTION_RETRY_COUNT, + Constants.DEFAULT_CONNECTION_RETRY_COUNT); + retryDelay = configuration.getIntegerProperty(Constants.CONNECTION_RETRY_DELAY, + Constants.DEFAULT_CONNECTION_RETRY_DELAY); + retriesLeft = retryCount + 1; + do { + try { + this.connect(); + break; + } catch (RuntimeException e) { + if (retriesLeft > 1) { + logger.debug("SSH Connection failed. Waiting for change in server's state."); + waitForConnection(retryDelay); + retriesLeft--; + logger.debug("Retrying SSH connection. Attempt [" + Integer.toString(retryCount - retriesLeft + 1) + + "] out of [" + retryCount + "]"); + } else { + throw e; + } + } catch (Exception e) { + throw e; + } + } while (retriesLeft > 0); + } + + @Override + public void disconnect() { + try { + if (logger.isDebugEnabled()) { + logger.debug("SSH: disconnecting from [" + toString() + "]"); + } + clientSession.close(false); + } finally { + if (sshClient != null) { + sshClient.stop(); + } + } + } + + @Override + public void setExecTimeout(long timeout) { + this.timeout = timeout; + } + + @Override + public int execCommand(String cmd, OutputStream out, OutputStream err) { + return execCommand(cmd, out, err, false); + } + + @Override + public int execCommandWithPty(String cmd, OutputStream out) { + return execCommand(cmd, out, out, true); + } + + private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) { + try { + if (logger.isDebugEnabled()) { + logger.debug("SSH: executing command"); + } + ChannelExec client = clientSession.createExecChannel(cmd); client.setUsePty(usePty); // use pseudo-tty? - client.setOut(out); - client.setErr(err); - OpenFuture openFuture = client.open(); - int exitStatus = 0; - try { - client.waitFor(ClientChannel.CLOSED, timeout); - openFuture.verify(); - Integer exitStatusI = client.getExitStatus(); - if(exitStatusI == null) { - throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]. Operation timed out."); - } - exitStatus = exitStatusI; - } finally { - client.close(false); - } - return exitStatus; - } catch(RuntimeException e) { - throw e; - } catch(Exception t) { - throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", t); - } - } - - @Override - public String toString() { - String address = host; - if(username != null) { - address = username + '@' +address; - } - return address; - } + client.setOut(out); + client.setErr(err); + OpenFuture openFuture = client.open(); + int exitStatus = 0; + try { + client.waitFor(ClientChannel.CLOSED, timeout); + openFuture.verify(); + Integer exitStatusI = client.getExitStatus(); + if (exitStatusI == null) { + throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host + + ":" + port + "]. Operation timed out."); + } + exitStatus = exitStatusI; + } finally { + client.close(false); + } + return exitStatus; + } catch (RuntimeException e) { + throw e; + } catch (Exception t) { + throw new SshException( + "Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", t); + } + } + + private void waitForConnection(int retryDelay) { + long time = retryDelay * 1000L; + long future = System.currentTimeMillis() + time; + if (time != 0) { + while (System.currentTimeMillis() < future && time > 0) { + try { + Thread.sleep(time); + } catch (InterruptedException e) { + /* + * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that + * case, the thread is resumed before the delay time has actually expired, so re-calculate the + * amount of delay time needed and reenter the sleep until we get to the future time. + */ + time = future - System.currentTimeMillis(); + } + } + } + } + + @Override + public String toString() { + String address = host; + if (username != null) { + address = username + '@' + address; + } + return address; + } } diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java index a12e2be93..4e7f8d2f5 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/java/org/openecomp/appc/adapter/ssh/sshd/SshdDataAccessService.java @@ -27,14 +27,11 @@ import org.openecomp.appc.adapter.ssh.Constants; import org.openecomp.appc.adapter.ssh.SshConnectionDetails; import org.openecomp.appc.adapter.ssh.SshDataAccessException; import org.openecomp.appc.adapter.ssh.SshDataAccessService; -import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.resource.dblib.DbLibService; import java.sql.SQLException; import java.util.ArrayList; - - public class SshdDataAccessService implements SshDataAccessService { private String schema = Constants.NETCONF_SCHEMA; diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml index f9d10868a..d6c0f686f 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -22,17 +22,17 @@ <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"> + 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="sshdBean" class="org.openecomp.appc.adapter.ssh.sshd.SshAdapterSshd" scope="singleton"/> - <service id="sshAdapter" interface="org.openecomp.appc.adapter.ssh.SshAdapter" ref="sshdBean"/> + <bean id="sshdBean" class="org.openecomp.appc.adapter.ssh.sshd.SshAdapterSshd" scope="singleton"/> + <service id="sshAdapter" interface="org.openecomp.appc.adapter.ssh.SshAdapter" ref="sshdBean"/> - <reference id="dbLibServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.resource.dblib.DbLibService" /> - <bean id="sshdDAServiceBean" class="org.openecomp.appc.adapter.ssh.sshd.SshdDataAccessService" scope="singleton"> - <property name="dbLibService" ref="dbLibServiceRef" /> - </bean> + <reference id="dbLibServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.resource.dblib.DbLibService" /> + <bean id="sshdDAServiceBean" class="org.openecomp.appc.adapter.ssh.sshd.SshdDataAccessService" scope="singleton"> + <property name="dbLibService" ref="dbLibServiceRef" /> + </bean> - <service id="sshDAService" interface="org.openecomp.appc.adapter.ssh.SshDataAccessService" ref="sshdDAServiceBean"/> + <service id="sshDAService" interface="org.openecomp.appc.adapter.ssh.SshDataAccessService" ref="sshdDAServiceBean"/> </blueprint> diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java index 980395476..1d7d06df2 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-sshd/src/test/java/org/openecomp/appc/adapter/ssh/sshd/SshAdapterTest.java @@ -49,7 +49,6 @@ import java.security.PublicKey; import java.util.Collections; import java.util.EnumSet; -@Ignore public class SshAdapterTest { private static final boolean START_SERVER = true; diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java index c0ccdfaee..df50396ed 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshAdapterMock.java @@ -24,9 +24,6 @@ package org.openecomp.appc.adapter.ssh; import java.util.ArrayList; import java.util.List; -import org.openecomp.appc.adapter.ssh.SshAdapter; -import org.openecomp.appc.adapter.ssh.SshConnection; - public class SshAdapterMock implements SshAdapter { private List<SshConnectionMock> connectionMocks = new ArrayList<>(); diff --git a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java index 3194edcfb..ed03a6107 100644 --- a/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java +++ b/appc-adapters/appc-ssh-adapter/appc-ssh-adapter-tests/src/main/java/org/openecomp/appc/adapter/ssh/SshConnectionMock.java @@ -59,6 +59,11 @@ public class SshConnectionMock implements SshConnection { } @Override + public void connectWithRetry() { + connectCallCount++; + } + + @Override public void disconnect() { disconnectCallCount++; } diff --git a/appc-adapters/pom.xml b/appc-adapters/pom.xml index 216b294d2..0e4e12c33 100644 --- a/appc-adapters/pom.xml +++ b/appc-adapters/pom.xml @@ -17,5 +17,6 @@ <module>appc-dmaap-adapter</module> <module>appc-netconf-adapter</module> <module>appc-ssh-adapter</module> + <module>appc-rest-healthcheck-adapter</module> </modules> </project> diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml b/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml index 1c5e7dd75..607ab7745 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml +++ b/appc-asdc-listener/appc-asdc-listener-bundle/pom.xml @@ -1,7 +1,7 @@ -<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"> +<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-asdc-listener</artifactId> <groupId>org.openecomp.appc</groupId> @@ -31,12 +31,12 @@ <dependency> <groupId>org.openecomp.sdc</groupId> <artifactId>sdc-distribution-client</artifactId> - <version>1.0.0-SNAPSHOT</version> + <version>1.0.0</version> </dependency> <dependency> <groupId>org.openecomp.appc</groupId> - <artifactId>appc-dmaap-adapter-bundle</artifactId> + <artifactId>appc-message-adapter-api</artifactId> <version>${project.version}</version> </dependency> @@ -98,6 +98,35 @@ <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> + + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-tosca-lib</artifactId> + <version>${toscalib.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <version>1.7</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-parser-impl</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + <version>${odl.ietf-inet-types.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + <version>${odl.ietf-yang-types.version}</version> + </dependency> </dependencies> @@ -128,35 +157,15 @@ <Export-Package>org.openecomp.appc.sdc.listener</Export-Package> <Import-Package> org.openecomp.appc.licmgr, - org.openecomp.appc.adapter.dmaap, - !ch.qos.*, - !com.att.*, - !fj.*, - !groovy.lang, - !javax.jms, - !javax.mail.*, - !org.apache.log4j.*, - !org.codehaus.commons.compiler, - !org.codehaus.groovy.*, - !org.codehaus.janino, - !org.jasypt.*, - !org.yaml.snakeyaml.*, - !com.ibm.icu.text, - !org.apache.log, - !com.sun.faces.spi, + org.openecomp.appc.adapter.messaging.*, + com.att.eelf.*, *;resolution:=optional </Import-Package> <Embed-Dependency> - sdc-distribution-client, appc-common, - appc-dmaap-adapter-bundle, appc-license-manager-api, - snakeyaml, - logback-core, - logback-classic, eelf-core, - saClientLibrary, - cambriaClient, - functionaljava, - httpcore,httpclient, - gson;scope=compile|runtime;inline=false + sdc-distribution-client,snakeyaml, + saClientLibrary,cambriaClient,saToolkit, + functionaljava,httpcore,httpclient,gson; + scope=compile|runtime;inline=false </Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java index 651ea282c..5084771f1 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java +++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcCallback.java @@ -21,26 +21,25 @@ package org.openecomp.appc.sdc.listener; -import java.net.URI; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.lang3.concurrent.BasicThreadFactory; -import org.openecomp.appc.adapter.dmaap.EventSender; - +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.appc.adapter.message.EventSender; import org.openecomp.sdc.api.IDistributionClient; import org.openecomp.sdc.api.consumer.INotificationCallback; import org.openecomp.sdc.api.notification.IArtifactInfo; import org.openecomp.sdc.api.notification.INotificationData; import org.openecomp.sdc.api.notification.IResourceInstance; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; +import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; +import java.net.URI; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + public class AsdcCallback implements INotificationCallback { private final EELFLogger logger = EELFManager.getInstance().getLogger(AsdcCallback.class); diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java index e73b90695..f415e2ef1 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java +++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcConfig.java @@ -21,17 +21,12 @@ package org.openecomp.appc.sdc.listener; -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import org.openecomp.sdc.api.consumer.IConfiguration; -import org.openecomp.sdc.utils.ArtifactTypeEnum; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdc.api.consumer.IConfiguration; + +import java.net.URI; +import java.util.*; public class AsdcConfig implements IConfiguration { @@ -106,6 +101,11 @@ public class AsdcConfig implements IConfiguration { return false; } + //@Override + public boolean isFilterInEmptyResources() { + return false; + } + @Override public String getAsdcAddress() { return host; diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java index 2d6192749..762ec18eb 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java +++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/AsdcListener.java @@ -20,6 +20,8 @@ */ package org.openecomp.appc.sdc.listener; +import org.openecomp.sdc.impl.DistributionClientFactory; +import org.openecomp.sdc.utils.DistributionActionResultEnum; import java.net.URL; import java.util.HashMap; @@ -37,7 +39,6 @@ import org.openecomp.sdc.utils.DistributionActionResultEnum; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; - public class AsdcListener { /** @@ -111,7 +112,7 @@ public class AsdcListener { Map<String, String> headers = new HashMap<>(); // TODO - Replace the header below to sdc's requirements. What should the new value be - headers.put("HTTP_CSP_ID", "test"); + headers.put("USER_ID", "test"); // TODO - How to format the url. Always same endpoint or ports? String host = config.getAsdcAddress(); diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java index fcc5e7dda..a5a786f62 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java +++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/DownloadAndStoreOp.java @@ -21,11 +21,11 @@ package org.openecomp.appc.sdc.listener; -import org.openecomp.appc.adapter.dmaap.EventSender; -import org.openecomp.appc.adapter.dmaap.DmaapDestination; -import org.openecomp.appc.adapter.dmaap.event.EventHeader; -import org.openecomp.appc.adapter.dmaap.event.EventMessage; -import org.openecomp.appc.adapter.dmaap.event.EventStatus; +import org.openecomp.appc.adapter.message.EventSender; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.event.EventHeader; +import org.openecomp.appc.adapter.message.event.EventMessage; +import org.openecomp.appc.adapter.message.event.EventStatus; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.appc.licmgr.Constants; import org.openecomp.appc.licmgr.LicenseManager; @@ -136,11 +136,10 @@ public class DownloadAndStoreOp implements Runnable { String vnfType = artifactPayload.get(RESOURCE_NAME.name()); String version = artifactPayload.get(RESOURCE_VERSION.name()); String packageArtifactID = artifactPayload.get(ARTIFACT_UUID.name()); - String packageArtifactVersion = artifactPayload.get(INTERNAL_VERSION.name()); try { - if (null == vnfType || null == version || null == packageArtifactID || null == packageArtifactVersion || vnfType.isEmpty() || version.isEmpty() || packageArtifactID.isEmpty() || packageArtifactVersion.isEmpty()) { - throw new APPCException(String.format("Missing information in ASDC request. Details: resource_type='%s', resource_version='%s', artifactID='%s', artifactVersion='%s'", vnfType, version, packageArtifactID, packageArtifactVersion)); + if (null == vnfType || null == version || null == packageArtifactID || vnfType.isEmpty() || version.isEmpty() || packageArtifactID.isEmpty()) { + throw new APPCException(String.format("Missing information in ASDC request. Details: resource_type='%s', resource_version='%s', artifactID='%s'", vnfType, version, packageArtifactID)); } Map<String, String> existingArtifactPayload = licenseService.retrieveLicenseModelData(vnfType, version); @@ -221,7 +220,7 @@ public class DownloadAndStoreOp implements Runnable { new EventHeader((new java.util.Date()).toString(), serviceVersion, distributionID), new EventStatus(401, errorDescription)); - eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); + eventSender.sendEvent(MessageDestination.DCAE, eventMessage); } } diff --git a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java index 46efba438..87045b3e5 100644 --- a/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java +++ b/appc-asdc-listener/appc-asdc-listener-bundle/src/main/java/org/openecomp/appc/sdc/listener/Util.java @@ -20,6 +20,7 @@ */ package org.openecomp.appc.sdc.listener; +import org.openecomp.sdc.utils.DistributionStatusEnum; import org.json.JSONException; import org.json.JSONObject; diff --git a/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml b/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml index 0af2a9d70..6780def7c 100644 --- a/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml +++ b/appc-asdc-listener/appc-asdc-listener-features/src/main/resources/features.xml @@ -31,6 +31,7 @@ <feature name='appc-asdc-listener' description="asdc listener" version='${project.version}'> <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-asdc-listener-bundle/${project.version}</bundle> </feature> diff --git a/appc-asdc-listener/appc-yang-generator/pom.xml b/appc-asdc-listener/appc-yang-generator/pom.xml new file mode 100644 index 000000000..6834bd85d --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/pom.xml @@ -0,0 +1,47 @@ +<?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-asdc-listener</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-yang-generator</artifactId> + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>com.att.eelf</groupId> + <artifactId>eelf-core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.velocity</groupId> + <artifactId>velocity</artifactId> + <version>1.7</version> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-parser-impl</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-tosca-lib</artifactId> + <version>${toscalib.version}</version> + </dependency> + </dependencies> + + +</project>
\ No newline at end of file diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/YANGGenerator.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/YANGGenerator.java new file mode 100644 index 000000000..112790d86 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/YANGGenerator.java @@ -0,0 +1,46 @@ +/*- + * ============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.yang; + +import org.openecomp.appc.yang.exception.YANGGenerationException; + +import java.io.OutputStream; + +/** + * The Interface YANGGenerator - provides method to generate YANG file from TOSCA. + */ +public interface YANGGenerator { + + /** + * Generate YANG from TOSCA. + * if any exceptional Type is coming in the input tosca as a part of configuration parameter property, YANGGenerationException will be thrown. + * This API is not supporting below mentioned built-in Types: + * bits, decimal64, enumeration, identityref, leafref, union + * + * @param uniqueID - Set as module name in the yang, mandatory, cannot be null or empty + * @param tosca - TOSCA String from which the YANG is to be generated, mandatory, cannot be null or empty + * @param stream - The outputStream to which the generated yang is written, mandatory, cannot be null + * @throws YANGGenerationException - Thrown when any error occurred during method execution, the origin can be found from ex.getCause() or ex.getMessage() + */ + + void generateYANG(String uniqueID, String tosca, OutputStream stream) throws YANGGenerationException; +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/exception/YANGGenerationException.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/exception/YANGGenerationException.java new file mode 100644 index 000000000..b049e6f21 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/exception/YANGGenerationException.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.yang.exception; + +/** + * The Class YANGGenerationException. + */ +public class YANGGenerationException extends Exception { + + + /** + * Instantiates a new YANG generation exception. + * + * @param message - the appropriate message + * @param cause -the appropriate cause + */ + public YANGGenerationException(String message,Throwable cause){ + super(message,cause); + } + + + /** + * Instantiates new YANG generation exception + * @param message + */ + public YANGGenerationException(String message){ + super(message); + } +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorFactory.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorFactory.java new file mode 100644 index 000000000..ca5c0ae7d --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorFactory.java @@ -0,0 +1,49 @@ +/*- + * ============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.yang.impl; + +import org.openecomp.appc.yang.YANGGenerator; + +/** + * A factory for creating YANGGenerator objects. + */ +public class YANGGeneratorFactory { + + private YANGGeneratorFactory(){} + + private static class InstanceHolder + { + private static YANGGeneratorImpl instance = new YANGGeneratorImpl(); + private InstanceHolder(){} + } + + /** + * Gets the YANG generator. + * + * @return the YANG generator + */ + public static YANGGenerator getYANGGenerator() + { + return InstanceHolder.instance; + } + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorImpl.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorImpl.java new file mode 100644 index 000000000..0ca7878a9 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/impl/YANGGeneratorImpl.java @@ -0,0 +1,173 @@ +/*- + * ============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.yang.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.apache.commons.lang.StringUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.exception.ParseErrorException; +import org.apache.velocity.exception.ResourceNotFoundException; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl; +import org.openecomp.appc.yang.YANGGenerator; +import org.openecomp.appc.yang.exception.YANGGenerationException; +import org.openecomp.appc.yang.objects.Leaf; +import org.openecomp.appc.yang.type.YangTypes; +import org.openecomp.sdc.tosca.datatypes.model.NodeType; +import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition; +import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate; +import org.openecomp.sdc.tosca.services.yamlutil.ToscaExtensionYamlUtil; + +import java.io.*; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("CheckStyle") +public class YANGGeneratorImpl implements YANGGenerator { + + private static final EELFLogger Log = EELFManager.getInstance().getLogger(YANGGeneratorImpl.class); + private static final String MODULE_TYPE = "moduleType"; + private static final String LEAVES = "leaves"; + + + /* (non-Javadoc) + * @see org.openecomp.appc.yang.YANGGenerator#generateYANG(java.lang.String, java.lang.String, java.io.OutputStream) + */ + @Override + public void generateYANG(String uniqueID, String tosca, OutputStream stream) + throws YANGGenerationException { + Log.info("Entered into generateYANG."); + Log.debug("Received Tosca:\n" + tosca +"\n Received uniqueID: "+uniqueID); + + validateInput(uniqueID, tosca, stream); + Map<String,Object> parsedToscaMap = parseTosca(tosca); + String moduleType =parsedToscaMap.get(MODULE_TYPE).toString(); + List<Leaf> leaves = (List<Leaf>) parsedToscaMap.get(LEAVES); + VelocityEngine ve = new VelocityEngine(); + ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + ve.init(); + Template template; + + try { + template = ve.getTemplate("templates/YangTemplate.vm"); + } catch ( ResourceNotFoundException | ParseErrorException ex) { + Log.error("Error while retrieving YANG Template", ex); + throw new YANGGenerationException("Error while retrieving YANG Template",ex); + } + + VelocityContext vc = new VelocityContext(); + + vc.put("moduleName", uniqueID); + vc.put(MODULE_TYPE, moduleType); + vc.put(LEAVES, leaves); + + StringWriter sw = new StringWriter(); + template.merge(vc,sw); + Log.debug("generated YANG \n "+sw.toString()); + try { + String yang = sw.toString(); + validateYang(yang); + stream.write(yang.getBytes()); + stream.flush(); + } catch (IOException e) { + Log.error("Error while writing to outputstream", e); + throw new YANGGenerationException("Error writing to outputstream",e); + } finally { + try { + stream.close(); + } catch (IOException e) { + Log.error("Error while closing outputstream", e); + } + } + Log.info("exiting generateYANG method."); + } + + private void validateYang(String yang) throws YANGGenerationException { + + try(InputStream inputYangStream = new ByteArrayInputStream(yang.getBytes())){ + YangStatementSourceImpl statementSource = new YangStatementSourceImpl(inputYangStream); + if(statementSource.getYangAST()==null){ + throw new YANGGenerationException("Syntax Error in Generated YANG = " + yang); + } + } + catch(IOException e){ + Log.error("Error validating yang file "+ yang,e); + throw new YANGGenerationException("Invalid YANG generated",e); + } + } + + private Map<String,Object> parseTosca(String tosca) throws YANGGenerationException { + Log.info("Entered into parseTosca."); + ServiceTemplate serviceTemplate = new ToscaExtensionYamlUtil().yamlToObject(tosca, ServiceTemplate.class); + Map<String, NodeType> nodeTypeMap = serviceTemplate.getNode_types(); + String kind = nodeTypeMap.keySet().toArray(new String[0])[0]; + NodeType nodeType = nodeTypeMap.get(kind); + Map<String,Object> returnMap= new HashMap<>(); + Map<String, PropertyDefinition> propertyDefinitionFromTOSCA = nodeType.getProperties(); + returnMap.put(MODULE_TYPE, kind); + List<Leaf> leaves = new LinkedList<>(); + + for(Map.Entry<String, PropertyDefinition> entry: propertyDefinitionFromTOSCA.entrySet()){ + Leaf leaf = new Leaf(); + leaf.setName(entry.getKey()); + PropertyDefinition pd = entry.getValue(); + Map<String,String> typeMap=YangTypes.getYangTypeMap(); + if (typeMap.containsKey(pd.getType())) { + String paramType = typeMap.get(pd.getType()); + leaf.setType(paramType); + leaf.setDescription(!StringUtils.isEmpty(pd.getDescription()) ? pd.getDescription() : ""); + leaf.setMandatory((pd.getRequired() != null) ? Boolean.toString(pd.getRequired()) : Boolean.toString(false)); + leaf.setDefaultValue((pd.get_default() != null) ? pd.get_default().toString(): ""); + leaves.add(leaf); + } else { + YANGGenerationException yangGenerationException = new YANGGenerationException(pd.getType() + " Type is not supported ", null); + Log.error(pd.getType() + " Type is not supported ", yangGenerationException); + throw yangGenerationException; + } + } + returnMap.put(LEAVES, leaves); + Log.info("exiting parseTosca method with return MAP "+returnMap); + return returnMap; + } + + private void validateInput(String uniqueID, String tosca, OutputStream stream) throws YANGGenerationException { + Log.info("Entered into validateInput."); + if(StringUtils.isEmpty(uniqueID)) { + throw new YANGGenerationException("uniqueID is mandatory, cannot be null or empty.",null); + } + if(StringUtils.isEmpty(tosca)) { + throw new YANGGenerationException("tosca is mandatory, cannot be null or empty.",null); + } + if(stream == null){ + throw new YANGGenerationException("stream is mandatory, cannot be null.",null); + } + Log.info("exiting validateInput method."); + } + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/objects/Leaf.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/objects/Leaf.java new file mode 100644 index 000000000..d7f328db1 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/objects/Leaf.java @@ -0,0 +1,69 @@ +/*- + * ============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.yang.objects; + +public class Leaf { + private String name; + private String type; + private String description; + private String mandatory; + private String defaultValue; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getMandatory() { + return mandatory; + } + public void setMandatory(String mandatory) { + this.mandatory = mandatory; + } + public String getDefaultValue() { + return defaultValue; + } + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + @Override + public String toString() { + return "Leaf [name=" + name + ", type=" + type + ", description=" + description + ", mandatory=" + mandatory + + ", defaultValue=" + defaultValue + "]"; + } + + + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/type/YangTypes.java b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/type/YangTypes.java new file mode 100644 index 000000000..3e818623d --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/java/org/openecomp/appc/yang/type/YangTypes.java @@ -0,0 +1,105 @@ +/*- + * ============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.yang.type; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class YangTypes { + + private static final Map<String, String> yangTypeMap; + private YangTypes(){} + static { + Map<String, String> typeMap = new HashMap<>(); + + /* standard Types */ + /* typeMap.put("bits","bits"); + typeMap.put("leafref","leafref"); + typeMap.put("decimal64","decimal64"); + typeMap.put("enumeration","enumeration"); + typeMap.put("identityref","identityref"); + typeMap.put("union","union");*/ + typeMap.put("binary","binary"); + typeMap.put("boolean","boolean"); + typeMap.put("empty","empty"); + typeMap.put("instance-identifier","instance-identifier"); + typeMap.put("int8","int8"); + typeMap.put("int16","int16"); + typeMap.put("int32","int32"); + typeMap.put("int64","int64"); + typeMap.put("string","string"); + typeMap.put("uint8","uint8"); + typeMap.put("uint16","uint16"); + typeMap.put("uint32","uint32"); + typeMap.put("uint64","uint64"); + + + /* ietf-yang-types */ + + typeMap.put("counter32","yang:counter32"); + typeMap.put("zero-based-counter32","yang:zero-based-counter32"); + typeMap.put("counter64","yang:counter64"); + typeMap.put("zero-based-counter64","yang:zero-based-counter64"); + typeMap.put("gauge32","yang:gauge32"); + typeMap.put("gauge64","yang:gauge64"); + typeMap.put("object-identifier","yang:object-identifier"); + typeMap.put("object-identifier-128","yang:object-identifier-128"); + typeMap.put("yang-identifier","yang:yang-identifier"); + typeMap.put("date-and-time","yang:date-and-time"); + typeMap.put("timeticks","yang:timeticks"); + typeMap.put("timestamp","yang:timestamp"); + typeMap.put("phys-address","yang:phys-address"); + typeMap.put("mac-address","yang:mac-address"); + typeMap.put("xpath1.0","yang:xpath1.0"); + typeMap.put("hex-string","yang:hex-string"); + typeMap.put("uuid","yang:uuid"); + typeMap.put("dotted-quad","yang:dotted-quad"); + + /* ietf-inet-types */ + + typeMap.put("ip-version","inet:ip-version"); + typeMap.put("dscp","inet:dscp"); + typeMap.put("ipv6-flow-label","inet:ipv6-flow-label"); + typeMap.put("port-number","inet:port-number"); + typeMap.put("as-number","inet:as-number"); + typeMap.put("ip-address","inet:ip-address"); + typeMap.put("ipv4-address","inet:ipv4-address"); + typeMap.put("ipv6-address","inet:ipv6-address"); + typeMap.put("ip-address-no-zone","inet:ip-address-no-zone"); + typeMap.put("ipv4-address-no-zone","inet:ipv4-address-no-zone"); + typeMap.put("ipv6-address-no-zone","inet:ipv6-address-no-zone"); + typeMap.put("ip-prefix","inet:ip-prefix"); + typeMap.put("ipv4-prefix","inet:ipv4-prefix"); + typeMap.put("ipv6-prefix","inet:ipv6-prefix"); + typeMap.put("domain-name","inet:domain-name"); + typeMap.put("host","inet:host"); + typeMap.put("uri","inet:uri"); + + yangTypeMap = Collections.unmodifiableMap(typeMap); + } + + public static Map<String, String> getYangTypeMap(){ + return yangTypeMap; + } + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/main/resources/templates/YangTemplate.vm b/appc-asdc-listener/appc-yang-generator/src/main/resources/templates/YangTemplate.vm new file mode 100644 index 000000000..ab608c5e1 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/main/resources/templates/YangTemplate.vm @@ -0,0 +1,47 @@ +module $moduleName { + yang-version 1; + namespace "org:openecomp:appc:vnf:$moduleName"; + prefix appc-vnf; + organization "Copyright 2017 AT&T Intellectual Property."; + + description + "$moduleType description"; + + revision "2017-01-01" { + description + "$moduleName Configuration"; + } + + import ietf-inet-types { + prefix inet; + } + + import ietf-yang-types { + prefix yang; + } + + grouping vnf-config-grp { + container vnf-config { + #foreach( $data in $leaves ) + leaf $data.getName() { + type $data.getType(); + description "$data.getDescription()"; + mandatory $data.getMandatory(); + default "$data.getDefaultValue()"; + } + #end +} + } + + container vnf-config-repo { + list vnf-config-list { + key "vnf-identifier"; + leaf vnf-identifier { + type string; + } + uses vnf-config-grp; + } + + } + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/test/java/org/openecomp/appc/TestYANGGenerator.java b/appc-asdc-listener/appc-yang-generator/src/test/java/org/openecomp/appc/TestYANGGenerator.java new file mode 100644 index 000000000..398a8587b --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/test/java/org/openecomp/appc/TestYANGGenerator.java @@ -0,0 +1,194 @@ +/*- + * ============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; + +import org.junit.*; +import org.junit.rules.TemporaryFolder; +import org.openecomp.appc.yang.YANGGenerator; +import org.openecomp.appc.yang.exception.YANGGenerationException; +import org.openecomp.appc.yang.impl.YANGGeneratorFactory; + +import java.io.*; + +/** + * The Class TestYANGGenerator - Junit Test Class for all related test cases. + */ +@Ignore +public class TestYANGGenerator { + + private YANGGenerator yangGenerator = YANGGeneratorFactory.getYANGGenerator(); + private static String tosca; + private static String toscaWithSyntaxError; + private static String expectedYang; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + /** + * Run before test method. + * + * @throws IOException Signals that an I/O exception has occurred. + */ + @Before + public void runBeforeTestMethod() throws IOException { + tosca= getFileContent("tosca/toscaFile.yml"); + toscaWithSyntaxError = getFileContent("tosca/toscaFileWithSyntaxError.yml"); + expectedYang = getFileContent("yang/expectedYang.yang"); + } + + /** + * Test YANG generator for success. + * + * @throws IOException Signals that an I/O exception has occurred. + * @throws YANGGenerationException the YANG generation exception + */ + @Test + public void TestYANGGeneratorForSuccess() throws IOException, YANGGenerationException { + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + Assert.assertNotNull(tosca); + Assert.assertFalse("tosca file is emply or blank", tosca.equals("")); + yangGenerator.generateYANG("ATD456", tosca, out); + out.flush(); + out.close(); + String generatedYang = getFileContent(tempFile); + Assert.assertEquals(expectedYang,generatedYang); + } + + @Test(expected = YANGGenerationException.class) + public void testYangGenerationForSyntaxError() throws IOException, YANGGenerationException { + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + yangGenerator.generateYANG("ATD456",toscaWithSyntaxError,out); + } + + + /** + * Test for Yang Generator which generates YANG that is not matching with expected YANG. + * + * @throws IOException Signals that an I/O exception has occurred. + * @throws YANGGenerationException - the YANG generation exception + */ + @Test + public void unmatchedYangGenerationTest() throws IOException, YANGGenerationException { + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + yangGenerator.generateYANG("112476", tosca, out); + out.flush(); + out.close(); + String generatedYang = getFileContent(tempFile); + Assert.assertNotSame(expectedYang, generatedYang); + + } + + /** + * Yang generation test for empty tosca input. + * + * @throws YANGGenerationException the YANG generation exception + */ + @Test(expected = YANGGenerationException.class) + public void YangGenerationTestForEmptyUniqueIDInput() throws IOException, YANGGenerationException { +// OutputStream out = new FileOutputStream(classLoader.getResource("yang/generatedYang.yang").getFile()); + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + yangGenerator.generateYANG("", tosca, out); + } + + /** + * Yang generation test for empty tosca input. + * + * @throws YANGGenerationException the YANG generation exception + */ + @Test(expected = YANGGenerationException.class) + public void YangGenerationTestForUnSupportedType() throws IOException, YANGGenerationException { + tosca= getFileContent("tosca/toscaFileWithUnsupportedTypes.yml"); + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + yangGenerator.generateYANG("", tosca, out); + } + + /** + * Yang generation test for empty tosca input. + * + * @throws YANGGenerationException the YANG generation exception + */ + @Test(expected = YANGGenerationException.class) + public void YangGenerationTestForEmptyToscaInput() throws IOException, YANGGenerationException { + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + yangGenerator.generateYANG("1111", "", out); + } + + /** + * YANG generation test with invalid method arguments. + * + * @throws YANGGenerationException the YANG generation exception + */ + @Test(expected = YANGGenerationException.class) + public void YANGGenerationTestWithInvalidMethodArguments() throws YANGGenerationException { + yangGenerator.generateYANG("112476", "ToscaSAMPLE", null); + } + + @Test(expected = YANGGenerationException.class) + public void YANGGenerationTestWithIOException() throws IOException, YANGGenerationException { + File tempFile = temporaryFolder.newFile("generatedYang.yang"); + OutputStream out = new FileOutputStream(tempFile); + out.flush(); + out.close(); + yangGenerator.generateYANG("1111", tosca, out); + } + + + private String getFileContent(String fileName) throws IOException + { + ClassLoader classLoader = new TestYANGGenerator().getClass().getClassLoader(); + InputStream is = new FileInputStream(classLoader.getResource(fileName).getFile()); + BufferedReader buf = new BufferedReader(new InputStreamReader(is)); + String line = buf.readLine(); + StringBuilder sb = new StringBuilder(); + + while (line != null) { + sb.append(line).append("\n"); + line = buf.readLine(); + } + String fileString = sb.toString(); + is.close(); + return fileString; + } + + private String getFileContent(File file) throws IOException + { + InputStream is = new FileInputStream(file); + BufferedReader buf = new BufferedReader(new InputStreamReader(is)); + String line = buf.readLine(); + StringBuilder sb = new StringBuilder(); + + while (line != null) { + sb.append(line).append("\n"); + line = buf.readLine(); + } + String fileString = sb.toString(); + is.close(); + return fileString; + } + +} diff --git a/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFile.yml b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFile.yml new file mode 100644 index 000000000..22a29b69b --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFile.yml @@ -0,0 +1,295 @@ +node_types: + Property Definition: + derived_from: org.openecomp.genericvnf + version: V1 + description: '' + properties: + param1: + type: domain-name + description: param1 desc + required: true + default: param1 def val + status: SUPPORTED + param2: + type: ipv4-address-no-zone + description: param2 desc + required: true + default: param2 def val + status: SUPPORTED + param3: + type: instance-identifier + description: param3 desc + required: true + default: param3 def val + status: SUPPORTED + param4: + type: uuid + description: param4 desc + required: true + default: param4 def val + status: SUPPORTED + param5: + type: empty + description: param5 desc + required: true + default: param5 def val + status: SUPPORTED + param6: + type: object-identifier-128 + description: param6 desc + required: true + default: param6 def val + status: SUPPORTED + param7: + type: dscp + description: param7 desc + required: true + default: param7 def val + status: SUPPORTED + param8: + type: int64 + description: param8 desc + required: true + default: param8 def val + status: SUPPORTED + param9: + type: zero-based-counter64 + description: param9 desc + required: true + default: param9 def val + status: SUPPORTED + param10: + type: int8 + description: param10 desc + required: true + default: param10 def val + status: SUPPORTED + param11: + type: host + description: param11 desc + required: true + default: param11 def val + status: SUPPORTED + param12: + type: uint32 + description: param12 desc + required: true + default: param12 def val + status: SUPPORTED + param13: + type: timeticks + description: param13 desc + required: true + default: param13 def val + status: SUPPORTED + param15: + type: mac-address + description: param15 desc + required: true + default: param15 def val + status: SUPPORTED + param16: + type: as-number + description: param16 desc + required: true + default: param16 def val + status: SUPPORTED + param17: + type: counter64 + description: param17 desc + required: true + default: param17 def val + status: SUPPORTED + param19: + type: xpath1.0 + description: param19 desc + required: true + default: param19 def val + status: SUPPORTED + param20: + type: ip-version + description: param20 desc + required: true + default: param20 def val + status: SUPPORTED + param21: + type: port-number + description: param21 desc + required: true + default: param21 def val + status: SUPPORTED + param22: + type: int16 + description: param22 desc + required: true + default: param22 def val + status: SUPPORTED + param23: + type: ipv6-address-no-zone + description: param23 desc + required: true + default: param23 def val + status: SUPPORTED + param24: + type: hex-string + description: param24 desc + required: true + default: param24 def val + status: SUPPORTED + param26: + type: uint64 + description: param26 desc + required: true + default: param26 def val + status: SUPPORTED + param27: + type: uint8 + description: param27 desc + required: true + default: param27 def val + status: SUPPORTED + param28: + type: ipv4-prefix + description: param28 desc + required: true + default: param28 def val + status: SUPPORTED + param29: + type: ipv6-prefix + description: param29 desc + required: true + default: param29 def val + status: SUPPORTED + param30: + type: gauge64 + description: param30 desc + required: true + default: param30 def val + status: SUPPORTED + param31: + type: counter32 + description: param31 desc + required: true + default: param31 def val + status: SUPPORTED + param32: + type: string + description: param32 desc + required: true + default: param32 def val + status: SUPPORTED + param33: + type: object-identifier + description: param33 desc + required: true + default: param33 def val + status: SUPPORTED + param34: + type: ip-address-no-zone + description: param34 desc + required: true + default: param34 def val + status: SUPPORTED + param36: + type: gauge32 + description: param36 desc + required: true + default: param36 def val + status: SUPPORTED + param37: + type: ipv4-address + description: param37 desc + required: true + default: param37 def val + status: SUPPORTED + param38: + type: ip-prefix + description: param38 desc + required: true + default: param38 def val + status: SUPPORTED + param39: + type: uint16 + description: param39 desc + required: true + default: param39 def val + status: SUPPORTED + param40: + type: timestamp + description: param40 desc + required: true + default: param40 def val + status: SUPPORTED + param42: + type: dotted-quad + description: param42 desc + required: true + default: param42 def val + status: SUPPORTED + param43: + type: uri + description: param43 desc + required: true + default: param43 def val + status: SUPPORTED + param44: + type: ipv6-address + description: param44 desc + required: true + default: param44 def val + status: SUPPORTED + param45: + type: ipv6-flow-label + description: param45 desc + required: true + default: param45 def val + status: SUPPORTED + param46: + type: zero-based-counter32 + description: param46 desc + required: true + default: param46 def val + status: SUPPORTED + param47: + type: ip-address + description: param47 desc + required: true + default: param47 def val + status: SUPPORTED + param48: + type: boolean + description: param48 desc + required: true + default: param48 def val + status: SUPPORTED + param50: + type: yang-identifier + description: param50 desc + required: true + default: param50 def val + status: SUPPORTED + param51: + type: int32 + description: param51 desc + required: true + default: param51 def val + status: SUPPORTED + param52: + type: date-and-time + description: param52 desc + required: true + default: param52 def val + status: SUPPORTED + param53: + type: phys-address + description: param53 desc + required: true + default: param53 def val + status: SUPPORTED +topology_template: + node_templates: + Property Definition_Template: + type: Property Definition + properties: + param 1: <rule-type:rule1> <resk1:resk2 , resk2:resv2 , resk3:resv3> param1 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> + param 2: <rule-type:rule2> <resk1:resk2 , resk2:resv2> param2 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> diff --git a/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithSyntaxError.yml b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithSyntaxError.yml new file mode 100644 index 000000000..61c0af5c8 --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithSyntaxError.yml @@ -0,0 +1,295 @@ +node_types: + Property Definition: + derived_from: org.openecomp.genericvnf + version: V1 + description: '' + properties: + param 1: + type: domain-name + description: param1 desc + required: true + default: param1 def val + status: SUPPORTED + param2: + type: ipv4-address-no-zone + description: param2 desc + required: true + default: param2 def val + status: SUPPORTED + param3: + type: instance-identifier + description: param3 desc + required: true + default: param3 def val + status: SUPPORTED + param4: + type: uuid + description: param4 desc + required: true + default: param4 def val + status: SUPPORTED + param5: + type: empty + description: param5 desc + required: true + default: param5 def val + status: SUPPORTED + param6: + type: object-identifier-128 + description: param6 desc + required: true + default: param6 def val + status: SUPPORTED + param7: + type: dscp + description: param7 desc + required: true + default: param7 def val + status: SUPPORTED + param8: + type: int64 + description: param8 desc + required: true + default: param8 def val + status: SUPPORTED + param9: + type: zero-based-counter64 + description: param9 desc + required: true + default: param9 def val + status: SUPPORTED + param10: + type: int8 + description: param10 desc + required: true + default: param10 def val + status: SUPPORTED + param11: + type: host + description: param11 desc + required: true + default: param11 def val + status: SUPPORTED + param12: + type: uint32 + description: param12 desc + required: true + default: param12 def val + status: SUPPORTED + param13: + type: timeticks + description: param13 desc + required: true + default: param13 def val + status: SUPPORTED + param15: + type: mac-address + description: param15 desc + required: true + default: param15 def val + status: SUPPORTED + param16: + type: as-number + description: param16 desc + required: true + default: param16 def val + status: SUPPORTED + param17: + type: counter64 + description: param17 desc + required: true + default: param17 def val + status: SUPPORTED + param19: + type: xpath1.0 + description: param19 desc + required: true + default: param19 def val + status: SUPPORTED + param20: + type: ip-version + description: param20 desc + required: true + default: param20 def val + status: SUPPORTED + param21: + type: port-number + description: param21 desc + required: true + default: param21 def val + status: SUPPORTED + param22: + type: int16 + description: param22 desc + required: true + default: param22 def val + status: SUPPORTED + param23: + type: ipv6-address-no-zone + description: param23 desc + required: true + default: param23 def val + status: SUPPORTED + param24: + type: hex-string + description: param24 desc + required: true + default: param24 def val + status: SUPPORTED + param26: + type: uint64 + description: param26 desc + required: true + default: param26 def val + status: SUPPORTED + param27: + type: uint8 + description: param27 desc + required: true + default: param27 def val + status: SUPPORTED + param28: + type: ipv4-prefix + description: param28 desc + required: true + default: param28 def val + status: SUPPORTED + param29: + type: ipv6-prefix + description: param29 desc + required: true + default: param29 def val + status: SUPPORTED + param30: + type: gauge64 + description: param30 desc + required: true + default: param30 def val + status: SUPPORTED + param31: + type: counter32 + description: param31 desc + required: true + default: param31 def val + status: SUPPORTED + param32: + type: string + description: param32 desc + required: true + default: param32 def val + status: SUPPORTED + param33: + type: object-identifier + description: param33 desc + required: true + default: param33 def val + status: SUPPORTED + param34: + type: ip-address-no-zone + description: param34 desc + required: true + default: param34 def val + status: SUPPORTED + param36: + type: gauge32 + description: param36 desc + required: true + default: param36 def val + status: SUPPORTED + param37: + type: ipv4-address + description: param37 desc + required: true + default: param37 def val + status: SUPPORTED + param38: + type: ip-prefix + description: param38 desc + required: true + default: param38 def val + status: SUPPORTED + param39: + type: uint16 + description: param39 desc + required: true + default: param39 def val + status: SUPPORTED + param40: + type: timestamp + description: param40 desc + required: true + default: param40 def val + status: SUPPORTED + param42: + type: dotted-quad + description: param42 desc + required: true + default: param42 def val + status: SUPPORTED + param43: + type: uri + description: param43 desc + required: true + default: param43 def val + status: SUPPORTED + param44: + type: ipv6-address + description: param44 desc + required: true + default: param44 def val + status: SUPPORTED + param45: + type: ipv6-flow-label + description: param45 desc + required: true + default: param45 def val + status: SUPPORTED + param46: + type: zero-based-counter32 + description: param46 desc + required: true + default: param46 def val + status: SUPPORTED + param47: + type: ip-address + description: param47 desc + required: true + default: param47 def val + status: SUPPORTED + param48: + type: boolean + description: param48 desc + required: true + default: param48 def val + status: SUPPORTED + param50: + type: yang-identifier + description: param50 desc + required: true + default: param50 def val + status: SUPPORTED + param51: + type: int32 + description: param51 desc + required: true + default: param51 def val + status: SUPPORTED + param52: + type: date-and-time + description: param52 desc + required: true + default: param52 def val + status: SUPPORTED + param53: + type: phys-address + description: param53 desc + required: true + default: param53 def val + status: SUPPORTED +topology_template: + node_templates: + Property Definition_Template: + type: Property Definition + properties: + param 1: <rule-type:rule1> <resk1:resk2 , resk2:resv2 , resk3:resv3> param1 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> + param 2: <rule-type:rule2> <resk1:resk2 , resk2:resv2> param2 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> diff --git a/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithUnsupportedTypes.yml b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithUnsupportedTypes.yml new file mode 100644 index 000000000..7f27a018f --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/test/resources/tosca/toscaFileWithUnsupportedTypes.yml @@ -0,0 +1,349 @@ +node_types: + Property Definition: + derived_from: org.openecomp.genericvnf + version: V1 + description: '' + properties: + param1: + type: domain-name + description: param1 desc + required: true + default: param1 def val + status: SUPPORTED + param2: + type: ipv4-address-no-zone + description: param2 desc + required: true + default: param2 def val + status: SUPPORTED + param3: + type: instance-identifier + description: param3 desc + required: true + default: param3 def val + status: SUPPORTED + param4: + type: uuid + description: param4 desc + required: true + default: param4 def val + status: SUPPORTED + param5: + type: empty + description: param5 desc + required: true + default: param5 def val + status: SUPPORTED + param6: + type: object-identifier-128 + description: param6 desc + required: true + default: param6 def val + status: SUPPORTED + param7: + type: dscp + description: param7 desc + required: true + default: param7 def val + status: SUPPORTED + param8: + type: int64 + description: param8 desc + required: true + default: param8 def val + status: SUPPORTED + param9: + type: zero-based-counter64 + description: param9 desc + required: true + default: param9 def val + status: SUPPORTED + param10: + type: int8 + description: param10 desc + required: true + default: param10 def val + status: SUPPORTED + param11: + type: host + description: param11 desc + required: true + default: param11 def val + status: SUPPORTED + param12: + type: uint32 + description: param12 desc + required: true + default: param12 def val + status: SUPPORTED + param13: + type: timeticks + description: param13 desc + required: true + default: param13 def val + status: SUPPORTED + param14: + type: enumeration + description: param14 desc + required: true + default: param14 def val + status: SUPPORTED + param15: + type: mac-address + description: param15 desc + required: true + default: param15 def val + status: SUPPORTED + param16: + type: as-number + description: param16 desc + required: true + default: param16 def val + status: SUPPORTED + param17: + type: counter64 + description: param17 desc + required: true + default: param17 def val + status: SUPPORTED + param18: + type: bits + description: param18 desc + required: true + default: param18 def val + status: SUPPORTED + param19: + type: xpath1.0 + description: param19 desc + required: true + default: param19 def val + status: SUPPORTED + param20: + type: ip-version + description: param20 desc + required: true + default: param20 def val + status: SUPPORTED + param21: + type: port-number + description: param21 desc + required: true + default: param21 def val + status: SUPPORTED + param22: + type: int16 + description: param22 desc + required: true + default: param22 def val + status: SUPPORTED + param23: + type: ipv6-address-no-zone + description: param23 desc + required: true + default: param23 def val + status: SUPPORTED + param24: + type: hex-string + description: param24 desc + required: true + default: param24 def val + status: SUPPORTED + param25: + type: decimal64 + description: param25 desc + required: true + default: param25 def val + status: SUPPORTED + param26: + type: uint64 + description: param26 desc + required: true + default: param26 def val + status: SUPPORTED + param27: + type: uint8 + description: param27 desc + required: true + default: param27 def val + status: SUPPORTED + param28: + type: ipv4-prefix + description: param28 desc + required: true + default: param28 def val + status: SUPPORTED + param29: + type: ipv6-prefix + description: param29 desc + required: true + default: param29 def val + status: SUPPORTED + param30: + type: gauge64 + description: param30 desc + required: true + default: param30 def val + status: SUPPORTED + param31: + type: counter32 + description: param31 desc + required: true + default: param31 def val + status: SUPPORTED + param32: + type: string + description: param32 desc + required: true + default: param32 def val + status: SUPPORTED + param33: + type: object-identifier + description: param33 desc + required: true + default: param33 def val + status: SUPPORTED + param34: + type: ip-address-no-zone + description: param34 desc + required: true + default: param34 def val + status: SUPPORTED + param35: + type: identityref + description: param35 desc + required: true + default: param35 def val + status: SUPPORTED + param36: + type: gauge32 + description: param36 desc + required: true + default: param36 def val + status: SUPPORTED + param37: + type: ipv4-address + description: param37 desc + required: true + default: param37 def val + status: SUPPORTED + param38: + type: ip-prefix + description: param38 desc + required: true + default: param38 def val + status: SUPPORTED + param39: + type: uint16 + description: param39 desc + required: true + default: param39 def val + status: SUPPORTED + param40: + type: timestamp + description: param40 desc + required: true + default: param40 def val + status: SUPPORTED + param41: + type: union + description: param41 desc + required: true + default: param41 def val + status: SUPPORTED + param42: + type: dotted-quad + description: param42 desc + required: true + default: param42 def val + status: SUPPORTED + param43: + type: uri + description: param43 desc + required: true + default: param43 def val + status: SUPPORTED + param44: + type: ipv6-address + description: param44 desc + required: true + default: param44 def val + status: SUPPORTED + param45: + type: ipv6-flow-label + description: param45 desc + required: true + default: param45 def val + status: SUPPORTED + param46: + type: zero-based-counter32 + description: param46 desc + required: true + default: param46 def val + status: SUPPORTED + param47: + type: ip-address + description: param47 desc + required: true + default: param47 def val + status: SUPPORTED + param48: + type: boolean + description: param48 desc + required: true + default: param48 def val + status: SUPPORTED + param49: + type: leafref + description: param49 desc + required: true + default: param49 def val + status: SUPPORTED + param50: + type: yang-identifier + description: param50 desc + required: true + default: param50 def val + status: SUPPORTED + param51: + type: int32 + description: param51 desc + required: true + default: param51 def val + status: SUPPORTED + param52: + type: date-and-time + description: param52 desc + required: true + default: param52 def val + status: SUPPORTED + param53: + type: phys-address + description: param53 desc + required: true + default: param53 def val + status: SUPPORTED + param54: + type: phys-add + description: param54 desc + required: true + default: param54 def val + status: SUPPORTED + param55: + type: null + description: param55 desc + required: true + default: param55 def val + status: SUPPORTED + param56: + type: + description: param56 desc + required: true + default: param56 def val + status: SUPPORTED +topology_template: + node_templates: + Property Definition_Template: + type: Property Definition + properties: + param 1: <rule-type:rule1> <resk1:resk2 , resk2:resv2 , resk3:resv3> param1 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> + param 2: <rule-type:rule2> <resk1:resk2 , resk2:resv2> param2 source <reqk1:reqv1 , reqk2:reqv2 , reqk3:reqv3> diff --git a/appc-asdc-listener/appc-yang-generator/src/test/resources/yang/expectedYang.yang b/appc-asdc-listener/appc-yang-generator/src/test/resources/yang/expectedYang.yang new file mode 100644 index 000000000..3515ce69b --- /dev/null +++ b/appc-asdc-listener/appc-yang-generator/src/test/resources/yang/expectedYang.yang @@ -0,0 +1,321 @@ +module ATD456 { + yang-version 1; + namespace "org:openecomp:appc:vnf:ATD456"; + prefix appc-vnf; + organization "Copyright 2017 AT&T Intellectual Property."; + + description + "Property Definition description"; + + revision "2017-01-01" { + description + "ATD456 Configuration"; + } + + import ietf-inet-types { + prefix inet; + } + + import ietf-yang-types { + prefix yang; + } + + grouping vnf-config-grp { + container vnf-config { + leaf param1 { + type inet:domain-name; + description "param1 desc"; + mandatory true; + default "param1 def val"; + } + leaf param2 { + type inet:ipv4-address-no-zone; + description "param2 desc"; + mandatory true; + default "param2 def val"; + } + leaf param3 { + type instance-identifier; + description "param3 desc"; + mandatory true; + default "param3 def val"; + } + leaf param4 { + type yang:uuid; + description "param4 desc"; + mandatory true; + default "param4 def val"; + } + leaf param5 { + type empty; + description "param5 desc"; + mandatory true; + default "param5 def val"; + } + leaf param6 { + type yang:object-identifier-128; + description "param6 desc"; + mandatory true; + default "param6 def val"; + } + leaf param7 { + type inet:dscp; + description "param7 desc"; + mandatory true; + default "param7 def val"; + } + leaf param8 { + type int64; + description "param8 desc"; + mandatory true; + default "param8 def val"; + } + leaf param9 { + type yang:zero-based-counter64; + description "param9 desc"; + mandatory true; + default "param9 def val"; + } + leaf param10 { + type int8; + description "param10 desc"; + mandatory true; + default "param10 def val"; + } + leaf param11 { + type inet:host; + description "param11 desc"; + mandatory true; + default "param11 def val"; + } + leaf param12 { + type uint32; + description "param12 desc"; + mandatory true; + default "param12 def val"; + } + leaf param13 { + type yang:timeticks; + description "param13 desc"; + mandatory true; + default "param13 def val"; + } + leaf param15 { + type yang:mac-address; + description "param15 desc"; + mandatory true; + default "param15 def val"; + } + leaf param16 { + type inet:as-number; + description "param16 desc"; + mandatory true; + default "param16 def val"; + } + leaf param17 { + type yang:counter64; + description "param17 desc"; + mandatory true; + default "param17 def val"; + } + leaf param19 { + type yang:xpath1.0; + description "param19 desc"; + mandatory true; + default "param19 def val"; + } + leaf param20 { + type inet:ip-version; + description "param20 desc"; + mandatory true; + default "param20 def val"; + } + leaf param21 { + type inet:port-number; + description "param21 desc"; + mandatory true; + default "param21 def val"; + } + leaf param22 { + type int16; + description "param22 desc"; + mandatory true; + default "param22 def val"; + } + leaf param23 { + type inet:ipv6-address-no-zone; + description "param23 desc"; + mandatory true; + default "param23 def val"; + } + leaf param24 { + type yang:hex-string; + description "param24 desc"; + mandatory true; + default "param24 def val"; + } + leaf param26 { + type uint64; + description "param26 desc"; + mandatory true; + default "param26 def val"; + } + leaf param27 { + type uint8; + description "param27 desc"; + mandatory true; + default "param27 def val"; + } + leaf param28 { + type inet:ipv4-prefix; + description "param28 desc"; + mandatory true; + default "param28 def val"; + } + leaf param29 { + type inet:ipv6-prefix; + description "param29 desc"; + mandatory true; + default "param29 def val"; + } + leaf param30 { + type yang:gauge64; + description "param30 desc"; + mandatory true; + default "param30 def val"; + } + leaf param31 { + type yang:counter32; + description "param31 desc"; + mandatory true; + default "param31 def val"; + } + leaf param32 { + type string; + description "param32 desc"; + mandatory true; + default "param32 def val"; + } + leaf param33 { + type yang:object-identifier; + description "param33 desc"; + mandatory true; + default "param33 def val"; + } + leaf param34 { + type inet:ip-address-no-zone; + description "param34 desc"; + mandatory true; + default "param34 def val"; + } + leaf param36 { + type yang:gauge32; + description "param36 desc"; + mandatory true; + default "param36 def val"; + } + leaf param37 { + type inet:ipv4-address; + description "param37 desc"; + mandatory true; + default "param37 def val"; + } + leaf param38 { + type inet:ip-prefix; + description "param38 desc"; + mandatory true; + default "param38 def val"; + } + leaf param39 { + type uint16; + description "param39 desc"; + mandatory true; + default "param39 def val"; + } + leaf param40 { + type yang:timestamp; + description "param40 desc"; + mandatory true; + default "param40 def val"; + } + leaf param42 { + type yang:dotted-quad; + description "param42 desc"; + mandatory true; + default "param42 def val"; + } + leaf param43 { + type inet:uri; + description "param43 desc"; + mandatory true; + default "param43 def val"; + } + leaf param44 { + type inet:ipv6-address; + description "param44 desc"; + mandatory true; + default "param44 def val"; + } + leaf param45 { + type inet:ipv6-flow-label; + description "param45 desc"; + mandatory true; + default "param45 def val"; + } + leaf param46 { + type yang:zero-based-counter32; + description "param46 desc"; + mandatory true; + default "param46 def val"; + } + leaf param47 { + type inet:ip-address; + description "param47 desc"; + mandatory true; + default "param47 def val"; + } + leaf param48 { + type boolean; + description "param48 desc"; + mandatory true; + default "param48 def val"; + } + leaf param50 { + type yang:yang-identifier; + description "param50 desc"; + mandatory true; + default "param50 def val"; + } + leaf param51 { + type int32; + description "param51 desc"; + mandatory true; + default "param51 def val"; + } + leaf param52 { + type yang:date-and-time; + description "param52 desc"; + mandatory true; + default "param52 def val"; + } + leaf param53 { + type yang:phys-address; + description "param53 desc"; + mandatory true; + default "param53 def val"; + } + } + } + + container vnf-config-repo { + list vnf-config-list { + key "vnf-identifier"; + leaf vnf-identifier { + type string; + } + uses vnf-config-grp; + } + + } + +} diff --git a/appc-asdc-listener/pom.xml b/appc-asdc-listener/pom.xml index 18179f552..23b6e86f7 100644 --- a/appc-asdc-listener/pom.xml +++ b/appc-asdc-listener/pom.xml @@ -98,6 +98,7 @@ </reporting> <modules> + <module>appc-yang-generator</module> <module>appc-asdc-listener-bundle</module> <module>appc-asdc-listener-features</module> <module>appc-asdc-listener-installer</module> diff --git a/appc-common/pom.xml b/appc-common/pom.xml index c39efe653..90cec79a7 100644 --- a/appc-common/pom.xml +++ b/appc-common/pom.xml @@ -4,10 +4,11 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc</artifactId> <version>1.1.0-SNAPSHOT</version> - </parent> - <artifactId>appc-common</artifactId> - <name>APP-C Common</name> - <description>Common library shared across all modules</description> + </parent> + <artifactId>appc-common</artifactId> + <name>APP-C Common</name> + <packaging>bundle</packaging> + <description>Common library shared across all modules</description> <!-- <packaging>bundle</packaging> --> @@ -82,6 +83,20 @@ <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> </dependencies> @@ -107,9 +122,11 @@ <configuration> <instructions> <Bundle-SymbolicName>appc-common</Bundle-SymbolicName> - <!-- <Export-Package>org.openecomp.appc.provider</Export-Package> --> - <Import-Package>!com.att,!javax.crypto.*, *</Import-Package> - <Embed-Dependency>eelf-core, jasypt</Embed-Dependency> + <Export-Package> + org.openecomp.appc.*, com.att.eelf.*, ch.qos.logback.*, org.jasypt.* + </Export-Package> + <Import-Package>*;resolution:=optional</Import-Package> + <Embed-Dependency>eelf-core, logback-core, logback-classic, jasypt</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> diff --git a/appc-common/src/main/java/org/openecomp/appc/Constants.java b/appc-common/src/main/java/org/openecomp/appc/Constants.java index bd72acfcf..7ddf38d03 100644 --- a/appc-common/src/main/java/org/openecomp/appc/Constants.java +++ b/appc-common/src/main/java/org/openecomp/appc/Constants.java @@ -50,9 +50,15 @@ public final class Constants { @SuppressWarnings("nls") public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; - public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + /** + * The name for the success message attribute to be set in the context + */ + @SuppressWarnings("nls") + public static final String ATTRIBUTE_SUCCESS_MESSAGE = "success-message"; public static final String DG_ATTRIBUTE_STATUS = "SvcLogic.status"; + public static final String DG_OUTPUT_STATUS_CODE = "output.status.code"; + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; /** * The property that defines the name of the DG service logic to be loaded @@ -156,20 +162,12 @@ public final class Constants { */ public static final String PROPERTY_STACK_STATE_CHANGE_TIMEOUT ="org.openecomp.appc.stack.state.change.timeout" ; - /** - * Private default constructor prevents instantiation - */ - @SuppressWarnings("nls") public static final String STATUS_GETTER = "status-getter"; - - - @SuppressWarnings("nls") public static final String VM_FUSION_STATUS_GETTER = "fusion-vm-status-getter"; - /** * The name for the status vm attribute to be set in the context when executing a vmstatuscheck. */ @@ -177,6 +175,34 @@ public final class Constants { @SuppressWarnings("nls") public static final String STATUS_OF_VM = "status-vm"; + /** + * Yang revision value to be used while generating YANG module + */ + public static final String YANG_REVISION = "2017-03-03"; + /** + * Yang revision format to be used while formatting YANG revision date + */ + public static final String YANG_REVISION_FORMAT = "YYYY-MM-DD"; + + /** + * Base container for yang that is generated to store in MD-SAL datastore + */ + public static final String YANG_BASE_CONTAINER = "vnf-config-repo"; + + /** + *VNF config list for yang that is generated to store in MD-SAL datastore + */ + public static final String YANG_VNF_CONFIG_LIST = "vnf-config-list"; + + /** + *Base container of VNF configuration data for yang that is generated to store in MD-SAL datastore + */ + public static final String YANG_VNF_CONFIG = "vnf-config"; + + /** + * Private default constructor prevents instantiation + */ + private Constants() { } diff --git a/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategies.java b/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategies.java new file mode 100644 index 000000000..780dbc59b --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategies.java @@ -0,0 +1,27 @@ +/*- + * ============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.cache; + + +public enum CacheStrategies { + LRU; +} diff --git a/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategy.java b/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategy.java new file mode 100644 index 000000000..c269ad231 --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/cache/CacheStrategy.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.cache; + + +public interface CacheStrategy <K,V>{ + V getObject(K key); + void putObject(K key,V value); +} diff --git a/appc-common/src/main/java/org/openecomp/appc/cache/MetadataCache.java b/appc-common/src/main/java/org/openecomp/appc/cache/MetadataCache.java new file mode 100644 index 000000000..db5915bcf --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/cache/MetadataCache.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.cache; + + +public interface MetadataCache <K,V>{ + V getObject(K key); + void putObject(K key,V value); +} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestListenerImpl.java b/appc-common/src/main/java/org/openecomp/appc/cache/impl/LRUCache.java index 63c98458a..0e8ba7308 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestListenerImpl.java +++ b/appc-common/src/main/java/org/openecomp/appc/cache/impl/LRUCache.java @@ -19,25 +19,33 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL.impl; +package org.openecomp.appc.cache.impl; -import java.util.Properties; +import java.util.LinkedHashMap; +import java.util.Map; -import org.junit.Before; -import org.openecomp.appc.configuration.ConfigurationFactory; -import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.CL.impl.ListenerImpl; +import org.openecomp.appc.cache.CacheStrategy; -public class TestListenerImpl { +public class LRUCache<K,V> implements CacheStrategy<K,V> { - ListenerImpl listener; + private Map<K,V> map; - @Before - public void setup() { - Properties props = ConfigurationFactory.getConfiguration().getProperties(); - ListenerProperties lProps = new ListenerProperties((String) props.get("test.prefix"), props); - lProps.getProperties().setProperty("topic.read.timeout", "5"); // Just for this test - listener = new ListenerImpl(lProps); + LRUCache(final Integer capacity){ + map = new LinkedHashMap<K,V>(capacity, 0.75F, true){ + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest){ + return size() > capacity; + } + }; } + @Override + public V getObject(K key) { + return map.get(key); + } + + @Override + public void putObject(K key, V value) { + map.put(key,value); + } } diff --git a/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheFactory.java b/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheFactory.java new file mode 100644 index 000000000..358b3bfd5 --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheFactory.java @@ -0,0 +1,50 @@ +/*- + * ============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.cache.impl; + +import org.openecomp.appc.cache.CacheStrategies; +import org.openecomp.appc.cache.CacheStrategy; +import org.openecomp.appc.cache.MetadataCache; + +public class MetadataCacheFactory { + + private static class ReferenceHolder{ + private static final MetadataCacheFactory FACTORY = new MetadataCacheFactory(); + } + private MetadataCacheFactory(){ + + } + + public static MetadataCacheFactory getInstance(){ + return ReferenceHolder.FACTORY; + } + + public MetadataCache getMetadataCache(){ + return new MetadataCacheImpl(); + } + public MetadataCache getMetadataCache(CacheStrategies cacheStrategy){ + return new MetadataCacheImpl(cacheStrategy); + } + + + +} diff --git a/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheImpl.java b/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheImpl.java new file mode 100644 index 000000000..e54de8781 --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/cache/impl/MetadataCacheImpl.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.cache.impl; + +import org.openecomp.appc.cache.CacheStrategies; +import org.openecomp.appc.cache.CacheStrategy; +import org.openecomp.appc.cache.MetadataCache; + + +public class MetadataCacheImpl<K,V> implements MetadataCache<K,V> { + + private CacheStrategy strategy; + + MetadataCacheImpl(){ + this(CacheStrategies.LRU); + } + + MetadataCacheImpl(CacheStrategies strategy){ + this.strategy = initializeStrategy(strategy); + } + + private CacheStrategy initializeStrategy(CacheStrategies strategy) { + switch (strategy){ + case LRU: + return new LRUCache<>(50); + } + return null; + } + + @Override + public V getObject(K key) { + return (V)strategy.getObject(key); + } + + @Override + public void putObject(K key, V value) { + strategy.putObject(key,value); + } +} diff --git a/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java b/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java index f64129011..d93b7588e 100644 --- a/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java +++ b/appc-common/src/main/java/org/openecomp/appc/configuration/Configuration.java @@ -37,10 +37,10 @@ import org.slf4j.Logger; */ public interface Configuration { - String PROPERTY_BOOTSTRAP_FILE_NAME = "org.openecomp.appc.bootstrap.file"; + String PROPERTY_BOOTSTRAP_FILE_NAME = "org_openecomp_appc_bootstrap_file"; // String DEFAULT_BOOTSTRAP_FILE_NAME = "appc.properties"; - String PROPERTY_BOOTSTRAP_FILE_PATH = "org.openecomp.appc.bootstrap.path"; - String DEFAULT_BOOTSTRAP_FILE_PATH = "${user.home},etc,../etc"; + String PROPERTY_BOOTSTRAP_FILE_PATH = "org_openecomp_appc_bootstrap_path"; // + String DEFAULT_BOOTSTRAP_FILE_PATH = "/opt/openecomp/appc/data/properties,${user.home},etc,../etc"; String PROPERTY_RESOURCE_BUNDLES = "org.openecomp.appc.resources"; String DEFAULT_RESOURCE_BUNDLES = "org/openecomp/appc/i18n/MessageResources"; diff --git a/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java b/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java index bbfd90de1..17a356745 100644 --- a/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java +++ b/appc-common/src/main/java/org/openecomp/appc/configuration/ConfigurationFactory.java @@ -113,7 +113,7 @@ public final class ConfigurationFactory { /** * The default properties resource to be loaded */ - private static final String DEFAULT_PROPERTIES = "org/openecomp/appc/default.properties"; + private static final String DEFAULT_PROPERTIES = "/opt/openecomp/appc/data/properties/appc.properties"; /** * This collection allows for special configurations to be created and maintained, organized by some identification diff --git a/appc-common/src/main/java/org/openecomp/appc/configuration/package.html b/appc-common/src/main/java/org/openecomp/appc/configuration/package.html index 4460a9e5c..5991f91b5 100644 --- a/appc-common/src/main/java/org/openecomp/appc/configuration/package.html +++ b/appc-common/src/main/java/org/openecomp/appc/configuration/package.html @@ -168,3 +168,4 @@ </p> </body> </html> +>>>>>>> app-controller/master:appc-common/src/main/java/org/openecomp/appc/configuration/package.html diff --git a/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java b/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java index 3e4237258..21f088323 100644 --- a/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java +++ b/appc-common/src/main/java/org/openecomp/appc/i18n/Msg.java @@ -254,6 +254,11 @@ public enum Msg implements EELFResolvableErrorEnum { SNAPSHOTING_SERVER, /** + * {0} IAAS Adapter look for server requested + */ + LOOKING_SERVER_UP, + + /** * {0} IAAS Adapter cannot perform requested service, VM url '{1}' is invalid */ INVALID_SELF_LINK_URL, @@ -320,6 +325,11 @@ public enum Msg implements EELFResolvableErrorEnum { UNPAUSE_SERVER, /** + * Server {0} is being rebuilt... + */ + REBUILD_SERVER, + + /** * Connection to provider {0} at identity {1} using tenant name {2} (id {3}) failed, reason={4}, retrying in {5} * seconds, attempt {6} of {7}. */ @@ -336,6 +346,11 @@ public enum Msg implements EELFResolvableErrorEnum { STOPPING_SERVER, /** + * {0} IAAS Adapter start server requested + */ + STARTING_SERVER, + + /** * Server {0} (id {1}) failed to rebuild, reason {2} */ REBUILD_SERVER_FAILED, @@ -391,6 +406,11 @@ public enum Msg implements EELFResolvableErrorEnum { * Server {0} (id {1}) failed to evacuate, reason {2} */ EVACUATE_SERVER_FAILED, + + /** + * Server {0} evacuate from host {1} to host {2} failed during the rebuild on host {2}, reason {3} + */ + EVACUATE_SERVER_REBUILD_FAILED, /** * APP-C instance is too busy @@ -465,6 +485,11 @@ public enum Msg implements EELFResolvableErrorEnum { AAI_DELETE_FAILED, /** + * APP-C is unable to query AAI for VNF_ID {0} + */ + AAI_QUERY_FAILED, + + /** * VNF {0} is configured */ VNF_CONFIGURED, @@ -495,6 +520,21 @@ public enum Msg implements EELFResolvableErrorEnum { VNF_TEST_FAILED, /** + * VNF {0} test failed for reason {1} + */ + VNF_NOT_FOUND, + + /** + * VNF {0} Healthcheck operation failed for reason {1} + */ + VNF_HEALTHCECK_FAILED, + + /** + * VM {0} Healthcheck operation failed for reason {1} + */ + VM_HEALTHCECK_FAILED, + + /** * Server {0} (id {1}) failed to stop during {2} phase, reason {3} */ STOP_SERVER_FAILED, @@ -568,7 +608,7 @@ public enum Msg implements EELFResolvableErrorEnum { CLOSE_CONTEXT_FAILED, /** - * Stack {0} is being snapshoted... + * {0} IAAS Adapter snapshoting stack */ SNAPSHOTING_STACK, @@ -578,7 +618,7 @@ public enum Msg implements EELFResolvableErrorEnum { STACK_SNAPSHOTED, /** - * Stack {0} is being restored to snapshot {1}... + * {0} IAAS Adapter restoring stack */ RESTORING_STACK, @@ -588,6 +628,11 @@ public enum Msg implements EELFResolvableErrorEnum { STACK_RESTORED, /** + * {0} IAAS Adapter checking server + */ + CHECKING_SERVER, + + /** * Parameter {0} is missing in svc request of {1}. */ MISSING_PARAMETER_IN_REQUEST, @@ -601,8 +646,128 @@ public enum Msg implements EELFResolvableErrorEnum { * Operation '{0}' for VNF type '{1}' from Source '{2}' with RequestID '{3}' on '{4}' with action '{5}' * ended in {6}ms with result '{7}' */ - APPC_METRIC_MSG; + APPC_METRIC_MSG, + + /** + * Parsing failied for{0} + */ + INPUT_PAYLOAD_PARSING_FAILED, + + /** + * Error occurred for due to {0} + */ + APPC_EXCEPTION, + + /** + * SSH Data Exception occurred due to {0} + */ + SSH_DATA_EXCEPTION, + + /** + * Json processing exception occurred due to {0} + */ + JSON_PROCESSING_EXCEPTION, + + /** + * Operation {0} succeed for {1} + */ + SUCCESS_EVENT_MESSAGE, + + /** + * Dependency model not found for VNF type {0} due to {1} + */ + DEPENDENCY_MODEL_NOT_FOUND, + + /** + * Invalid Dependency model for VNF Type {0} due to {1} + */ + INVALID_DEPENDENCY_MODEL, + + /** + * Failed to retrieve VNFC DG + */ + FAILURE_RETRIEVE_VNFC_DG, + + /** + * Network check for Server {0} failed for Port {1} + * + */ + SERVER_NETWORK_ERROR, + + /** + * Hypervisor check for Server {0} failed. Status is DOWN or UNKNOWN + * + */ + HYPERVISOR_DOWN_ERROR, + + /** + * Hypervisor Network check for Server {0} failed. Not reachable by APPC + * + */ + HYPERVISOR_NETWORK_ERROR, + + /** + * Restart application operation failed on server : {0}, reason {1} + */ + APPLICATION_RESTART_FAILED, + + /** + * Start application operation failed on server : {0}, reason {1} + */ + APPLICATION_START_FAILED, + + /** + * Start application operation failed on server : {0}, reason {1} + */ + APPLICATION_STOP_FAILED, + + /** + * Application on server {0} is being restarted... + */ + RESTART_APPLICATION, + + /** + * Application on server {0} is being started... + */ + START_APPLICATION, + + /** + * Application on server {0} is being started... + */ + STOP_APPLICATION, + + /** + * APPC LCM operations are disabled + */ + LCM_OPERATIONS_DISABLED, + + /** + * Application {0} received exception {1} while attempting to execute oam operation {2}, exception message = {3}|\ + */ + OAM_OPERATION_EXCEPTION, + + /** + * Application {0} is stopping... Waiting for {1} LCM request to complete + */ + OAM_OPERATION_STOPPING, + + /** + * Application {0} is stopped + */ + OAM_OPERATION_STOPPED, + + + /** + * Application {0} is started + */ + OAM_OPERATION_STARTING, + + /** + * Application {0} is started + */ + OAM_OPERATION_STARTED, + ; /** * Static initializer to ensure the resource bundles for this class are loaded... */ diff --git a/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java b/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java index dcc797138..2a600978f 100644 --- a/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java +++ b/appc-common/src/main/java/org/openecomp/appc/logging/LoggingConstants.java @@ -51,6 +51,7 @@ public class LoggingConstants { public static final String AAI = "A&AI"; public static final String DB = "DataBase"; public static final String APPC_PROVIDER = "APPC Provider"; + public static final String APPC_OAM_PROVIDER = "APPC OAM Provider"; public static final String STATE_MACHINE = "StateMachine"; public static final String WORKFLOW_MANAGER = "WorkflowManager"; public static final String REQUEST_VALIDATOR = "RequestValidator"; diff --git a/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java b/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java index c186a4afa..6ff192b20 100644 --- a/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java +++ b/appc-common/src/main/java/org/openecomp/appc/logging/LoggingUtils.java @@ -21,6 +21,13 @@ package org.openecomp.appc.logging; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResolvableErrorEnum; +import com.att.eelf.i18n.EELFResourceManager; +import org.slf4j.MDC; + import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; @@ -31,13 +38,6 @@ import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.TimeZone; -import org.openecomp.appc.i18n.Msg; -import org.slf4j.MDC; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.att.eelf.i18n.EELFResourceManager; - public class LoggingUtils { @@ -77,6 +77,20 @@ public class LoggingUtils { cleanAuditErrorContext(); } + public static void auditInfo(Instant beginTimeStamp, Instant endTimeStamp, String code, String responseDescription, String className,EELFResolvableErrorEnum resourceId, String... arguments) { + populateAuditLogContext(beginTimeStamp, endTimeStamp, code, responseDescription, className); + auditLogger.info(resourceId,arguments); + cleanAuditErrorContext(); + } + + public static void auditWarn(Instant beginTimeStamp, Instant endTimeStamp, String code, String responseDescription, String className,EELFResolvableErrorEnum resourceId, String... arguments) { + populateAuditLogContext(beginTimeStamp, endTimeStamp, code, responseDescription, className); + auditLogger.warn(resourceId,arguments); + cleanAuditErrorContext(); + } + + + public static void logMetricsMessage(Instant beginTimeStamp, Instant endTimeStamp, String targetEntity, String targetServiceName, String statusCode, String responseCode, String responseDescription, String className) { populateMetricLogContext(beginTimeStamp, endTimeStamp, targetEntity, targetServiceName, statusCode, responseCode, responseDescription, className); metricLogger.info(EELFResourceManager.format(Msg.APPC_METRIC_MSG, diff --git a/appc-common/src/main/java/org/openecomp/appc/metadata/MetadataService.java b/appc-common/src/main/java/org/openecomp/appc/metadata/MetadataService.java new file mode 100644 index 000000000..f8b54c717 --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/metadata/MetadataService.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.metadata; + +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; + + +public interface MetadataService { + String getVnfModel(DependencyModelIdentifier modelIdentifier); +} diff --git a/appc-common/src/main/java/org/openecomp/appc/metadata/impl/MetadataServiceImpl.java b/appc-common/src/main/java/org/openecomp/appc/metadata/impl/MetadataServiceImpl.java new file mode 100644 index 000000000..fb393aa74 --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/metadata/impl/MetadataServiceImpl.java @@ -0,0 +1,113 @@ +/*- + * ============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.metadata.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; + +import javax.sql.rowset.CachedRowSet; + +import org.openecomp.appc.cache.MetadataCache; +import org.openecomp.appc.cache.impl.MetadataCacheFactory; +import org.openecomp.appc.metadata.MetadataService; +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; + +import java.sql.SQLException; +import java.util.ArrayList; + + +public class MetadataServiceImpl implements MetadataService { + + private DbLibService dbLibService; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MetadataServiceImpl.class); + + private MetadataCache<DependencyModelIdentifier,String> cache; + + public MetadataServiceImpl(){ + initialize(); + } + + private void initialize(){ + cache = MetadataCacheFactory.getInstance().getMetadataCache(); + // TODO initialze dbLibService + } + + public void setDbLibService(DbLibService dbLibService) { + this.dbLibService = dbLibService; + } + + @Override + public String getVnfModel(DependencyModelIdentifier modelIdentifier) { + logger.debug("Reading Vnf Model data from cache for vnfType : "+ modelIdentifier.getVnfType() +" and catalog version : " +modelIdentifier.getCatalogVersion()); + String vnfModel = cache.getObject(modelIdentifier); + if(vnfModel ==null || vnfModel.length() ==0){ + logger.debug("Vnf Model not available in cache. Reading from database."); + vnfModel = readVnfModel(modelIdentifier); + if(vnfModel !=null && vnfModel.length()>0){ + logger.debug("Adding retrieved Vnf Model to cache."); + addVnfModel(modelIdentifier,vnfModel); + } + } + return vnfModel; + } + + private void addVnfModel(DependencyModelIdentifier modelIdentifier, String vnfModel) { + cache.putObject(modelIdentifier,vnfModel); + } + + private String readVnfModel(DependencyModelIdentifier modelIdentifier) { + + logger.debug("Reading Vnf Model data from database for RESOURCE_NAME : "+ modelIdentifier.getVnfType() +" and RESOURCE_VERSION : " +modelIdentifier.getCatalogVersion()); + StringBuilder query = new StringBuilder(); + String vnfModel =null; + query.append("SELECT ARTIFACT_CONTENT FROM sdnctl.ASDC_ARTIFACTS WHERE RESOURCE_NAME = ? ") ; + ArrayList<String> argList = new ArrayList<>(); + argList.add(modelIdentifier.getVnfType()); + + if (modelIdentifier.getCatalogVersion()==null){ + query.append(" ORDER BY SUBSTRING_INDEX(RESOURCE_VERSION, '.', 1)*1 DESC , " + + "SUBSTRING_INDEX(SUBSTRING_INDEX(RESOURCE_VERSION, '.', 2),'.', -1) *1 DESC , " + + "SUBSTRING_INDEX(RESOURCE_VERSION, '.', -1)*1 DESC ;"); + }else{ + query.append("AND RESOURCE_VERSION = ? ;"); + argList.add(modelIdentifier.getCatalogVersion()); + } + try { + final CachedRowSet data = dbLibService.getData(query.toString(), argList, "sdnctl"); + if (data.first()) { + vnfModel = data.getString("ARTIFACT_CONTENT"); + if (vnfModel == null || vnfModel.isEmpty()) { + logger.error("Invalid dependency model for vnf type : "+ modelIdentifier.getVnfType() +" and catalog version : " +modelIdentifier.getCatalogVersion()); + throw new RuntimeException("Invalid or Empty VNF Model"); + } + logger.debug("Retrieved Vnf Model : " + vnfModel); + }else { + logger.warn("VNF Model not found in datastore for RESOURCE_NAME : "+ modelIdentifier.getVnfType() +" AND RESOURCE_VERSION : " +modelIdentifier.getCatalogVersion()); + } + } catch (SQLException e) { + throw new RuntimeException("Database error occurred"); + } + return vnfModel; + } +} diff --git a/appc-common/src/main/java/org/openecomp/appc/metadata/objects/DependencyModelIdentifier.java b/appc-common/src/main/java/org/openecomp/appc/metadata/objects/DependencyModelIdentifier.java new file mode 100644 index 000000000..e3c82487e --- /dev/null +++ b/appc-common/src/main/java/org/openecomp/appc/metadata/objects/DependencyModelIdentifier.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.metadata.objects; + + +public class DependencyModelIdentifier { + private String vnfType; + private String catalogVersion; + + public DependencyModelIdentifier(String vnfType, String catalogVersion){ + this.vnfType = vnfType; + this.catalogVersion = catalogVersion; + } + + public int hashCode(){ + final int prime = 31; + int result = 1; + result = result * prime + (this.vnfType == null ? 0 :this.vnfType.hashCode()); + result = result * prime + (this.catalogVersion == null ? 0 :this.catalogVersion.hashCode()); + return result; + } + + public boolean equals(Object obj){ + if(obj ==null) + return false; + if(!(obj instanceof DependencyModelIdentifier)) + return false; + + DependencyModelIdentifier modelIdentifier = (DependencyModelIdentifier)obj; + if(this.vnfType == null){ + if(modelIdentifier.vnfType !=null) + return false; + } + else if(!this.vnfType.equals(modelIdentifier.vnfType)) + return false; + + if(this.catalogVersion == null){ + if(modelIdentifier.catalogVersion !=null) + return false; + } + else if(!this.catalogVersion.equals(modelIdentifier.catalogVersion)) + return false; + + return true; + } + + @Override + public String toString() { + return "DependencyModelIdentifier : vnfType = "+vnfType + " , catalogVersion = " +catalogVersion; + } + + public String getVnfType() { + return vnfType; + } + + public String getCatalogVersion() { + return catalogVersion; + } + +} diff --git a/appc-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..4d66c908c --- /dev/null +++ b/appc-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,38 @@ +<?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-common +--> +<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"> + + <reference id="dbLibServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.resource.dblib.DbLibService" /> + + <bean id="MetadataServiceImplBean" class="org.openecomp.appc.metadata.impl.MetadataServiceImpl" scope="singleton"> + <property name="dbLibService" ref="dbLibServiceRef" /> + </bean> + + <service id="MetadataService" interface="org.openecomp.appc.metadata.MetadataService" ref="MetadataServiceImplBean"/> + +</blueprint> diff --git a/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties b/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties index 0c571cbae..13e760f48 100644 --- a/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties +++ b/appc-common/src/main/resources/org/openecomp/appc/i18n/MessageResources.properties @@ -624,7 +624,7 @@ AAI_CONNECTION_FAILED=APPC0106E|\ APP-C is unable to communicate with A&AI|\ Connection to A&AI at service {0} failed after all retry attempts.|\ The connection to the A&AI at the indicated service URL cannot be opened. \ - All retries have been exhausted. APP-C is giving up on the connection and will?\ + All retries have been exhausted. APP-C is giving up on the connection and will \ reject the operation request.|\ . @@ -635,7 +635,7 @@ AAI_UPDATE_FAILED=APPC0107E|\ . AAI_GET_DATA_FAILED=APPC0108E|\ - APP-C is unable to retrieve VF/VFC {0} data for Transaction ID?{1}?as a \ + APP-C is unable to retrieve VF/VFC {0} data for Transaction ID {1} as a \ result of A&AI communication failure or its internal error.|\ Operation request will be rejected by APP-C|\ . @@ -643,8 +643,8 @@ AAI_GET_DATA_FAILED=APPC0108E|\ AAI_CONNECTION_FAILED_RETRY=APPC0105W|\ A&AI at identity {0} using VNF_ID {1} failed, reason={2}, retrying in {3} seconds, attempt {4} of {5}.|\ The connection to the A&AI could not be obtained for the indicated reason. APP-C will retry to connect \ - to the A&AI. The?message contains the retry delay, the current attempt and the maximum number of attempts.|\ - Correct the cause of the connection failure as indicated by the reason.? + to the A&AI. The message contains the retry delay, the current attempt and the maximum number of attempts.|\ + Correct the cause of the connection failure as indicated by the reason. AAI_DELETE_FAILED=APPC0114E|\ APP-C is unable to delete COMPONENT_ID {0} for reason {1}|\ @@ -652,6 +652,11 @@ AAI_DELETE_FAILED=APPC0114E|\ A&AI communication failure or its internal error.|\ . +AAI_QUERY_FAILED=APPC0115E|\ + Error Querying AAI with vnfID = {0}|\ + Querying AAI for the given vnf id returns failure to APPC|\ + . + VNF_CONFIGURED=APPC0118I|\ VNF {0} is configured|\ No resolution is required, this is an informational message|\ @@ -682,6 +687,21 @@ VNF_TEST_FAILED=APPC0122E|\ The test operation wasn't performed as a result of VNF communication failure or its internal error.|\ . +VNF_NOT_FOUND=APPC0123E|\ + VNF not found with vnf_id {0}|\ + The VNF wasn't found for the given vnf-id.|\ + . + +VNF_HEALTHCECK_FAILED=APPC0124E|\ + VNF {0} Healthcheck operation failed, reason {1}|\ + The health check operation wasn't performed as a result of VNF communication failure or its internal error.|\ + . + +VM_HEALTHCECK_FAILED=APPC0125E|\ + VM {0} Healthcheck operation failed, reason {1}|\ + The health check operation wasn't performed as a result of VNF communication failure or its internal error.|\ + . + STOP_SERVER_FAILED=APPC0112E|\ Server {0} (id {1}) failed to stop during {2} phase, reason {3}|\ The server stop failed for the indicated reason. Correct the cause of the failure and \ @@ -707,25 +727,25 @@ TERMINATE_STACK_FAILED=APPC0113E|\ included in the message. TERMINATING_SERVER=APPC0114I|\ - {0} IAAS Adapter?terminate server requested|\ + {0} IAAS Adapter terminate server requested|\ No resolution required|\ A graph has invoked the IAAS adapter and has requested the server to be terminated. The \ properties that govern the request are echoed immediately following this message. TERMINATING_STACK=APPC0115I|\ - {0} IAAS Adapter?terminate stack requested|\ + {0} IAAS Adapter terminate stack requested|\ No resolution required|\ A graph has invoked the IAAS adapter and has requested the server to be terminated. The \ properties that govern the request are echoed immediately following this message. TERMINATE_SERVER=APPC0116I|\ - Server {0} is being?terminated...|\ + Server {0} is being terminated...|\ No recovery required|\ The processing being performed by APPC requires that the indicated server be terminated. TERMINATE_STACK=APPC0117I|\ - Stack {0} is being?terminated...|\ + Stack {0} is being terminated...|\ No recovery required|\ The processing being performed by APPC requires that the indicated server be terminated. @@ -753,7 +773,7 @@ CLOSE_CONTEXT_FAILED=APPC0121E|\ message should be referred to support for assistance. SNAPSHOTING_STACK=APPC0122I|\ - Stack {0} is being?snapshoted...|\ + Stack {0} is being snapshoted...|\ No resolution is required|\ Stack snapshot. @@ -764,7 +784,7 @@ STACK_SNAPSHOTED==APPC0123I|\ RESTORING_STACK=APPC0124I|\ - Stack {0} is being?restored to snapshot {1}...|\ + Stack {0} is being restored to snapshot {1}...|\ No resolution is required|\ Stack restore. @@ -790,3 +810,162 @@ APPC_METRIC_MSG=APPC0128I|\ ended in {6} ms with result "{7}"|\ No resolution is required, this is an informational message|\ This message indicates that the APPC logged some operation to metric + + SNAPSHOTING_SERVER=APPC0129I|\ +{0} IAAS Adapter create snapshot of server requested|\ +No resolution is required, this is an informational message|\ +This message indicates that a IAAS Adapter create snapshot of server was requested. + +INPUT_PAYLOAD_PARSING_FAILED = APPC0130E|\ + Failed to parsing the input payload: {0}|\ + Please provide correct input string for parsing.|\ + . + +APPC_EXCEPTION = APPC0132E|\ + Error occurred for VNF type : {0}, reason {1}|\ + Runtime exception thrown by APPC.|\ + . + +SSH_DATA_EXCEPTION = APPC0133E|\ + SSH Data Exception occurred, reason {0}|\ + SSH Data exception occurred.|\ + . + +JSON_PROCESSING_EXCEPTION = APPC0134E|\ + Json processing exception occurred, reason {0}|\ + Json processing Exception|\ + . + +SUCCESS_EVENT_MESSAGE = APPC0136I|\ + Operation {0} succeed for {1}|\ + Success message.|\ + . +DEPENDENCY_MODEL_NOT_FOUND = APPC0137E|\ + Dependency model not found for VNF type {0}, reason {1}|\ + Please provide dependency model|\ + . + +INVALID_DEPENDENCY_MODEL = APPC0138E|\ + Invalid Dependency model for VNF Type {0}, reason {1}|\ + Invalid dependency model found |\ + . + + +FAILURE_RETRIEVE_VNFC_DG = APPC0139E|\ + Failed to retrieve DG for VNFC Type: {0}|\ + Failed to retrieve VNFC DG |\ + . + + +SERVER_NETWORK_ERROR=APPC0140E|\ + Server {0} either has a port {1} that is NOT online, or the status of the network to which the port is connected to is not ACTIVE|\ + Please ensure they are UP and running before requested operation|\ + It is critical that the VM Server is reachable by the Provider(ex: OpenStack) in order to be able to perform \ + the requested operation on it. + . + +REBUILD_SERVER=APPC0140I|\ + Server {0} is being rebuilt...|\ + No recovery required|\ + The processing being performed by APPC requires that the indicated server be rebuilt. + +HYPERVISOR_DOWN_ERROR=APPC0141E|\ + Hypervisor {0} for the Server {1} is either NOT ENABLED, or its status is DOWN or UNKNOWN|\ + Please ensure the Hypervisor is UP and running before proceeding with the requested operation|\ + It is critical that the Hypervisor that manages the Virtual Machine for the Server is reachable by the Provider(ex: OpenStack) in order to be able to perform \ + the requested operation on it. + . + + +HYPERVISOR_NETWORK_ERROR=APPC0142E|\ + Hypervisor {0} for the Server {1} is NOT Reachable by APPC for initiating the requested operation|\ + Please ensure the Hypervisor is connected to the network before proceeding with the requested operation|\ + It is critical that the Hypervisor that manages the Virtual Machine for the Server is reachable by the Provider(ex: OpenStack) in order to be able to perform \ + the requested operation on it. + +EVACUATE_SERVER_REBUILD_FAILED=APPC0143E|\ + Server {0} evacuate from host {1} to host {2} failed during the rebuild on host {2}, reason {3}|\ + The server rebuild after evacuation failed for the indicated reason. Correct the cause of the failure and \ + run a rebuild, if applicable.|\ + The adapter has attempted to rebuild after evacuating the indicated server but the rebuild request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +RESTART_APPLICATION=APPC0144I|\ + Application on server {0} is being restarted...|\ + No recovery required|\ + The processing being performed by APPC requires that the application on the indicated server be restarted. + +START_APPLICATION=APPC0145I|\ + Application on server {0} is being started...|\ + No recovery required|\ + The processing being performed by APPC requires that the application on the indicated server be started. + +APPLICATION_RESTART_FAILED=APPC0146E|\ + Restart application operation failed on server : {0}, reason {1}|\ + Restart application operation failure.|\ + Correct the cause of the failure as indicated by the reason. + +APPLICATION_START_FAILED=APPC0147E|\ + Start application operation failed on server : {0}, reason {1}|\ + Start application operation failure.|\ + Correct the cause of the failure as indicated by the reason. + +LOOKING_SERVER_UP=APPC0148I|\ +{0} IAAS Adapter looking up for the server requested|\ +No resolution is required, this is an informational message|\ +This message indicates that a IAAS Adapter lookup of server was requested. + +EVACUATE_SERVER_REBUILD_FAILED=APPC0149E|\ + Server {0} evacuate from host {1} to host {2} failed during the rebuild on host {2}, reason {3}|\ + The server rebuild after evacuation failed for the indicated reason. Correct the cause of the failure and \ + run a rebuild, if applicable.|\ + The adapter has attempted to rebuild after evacuating the indicated server but the rebuild request has \ + been failed by the provider for some reason. The reason returned by the provider is \ + included in the message. + +APPLICATION_STOP_FAILED=APPC0150E|\ + Stop application operation failed on server : {0}, reason {1}|\ + Stop application operation failure.|\ + Correct the cause of the failure as indicated by the reason. + +STOP_APPLICATION=APPC0151I|\ + Application on server {0} is being stopped...|\ + No recovery required|\ + The processing being performed by APPC requires that the application on the indicated server be stopped. + +LCM_OPERATIONS_DISABLED=APPC0152E|\ + APPC LCM operations have been administratively disabled|\ + No recovery required|\ + This is a indication that the APPC LCM operations are disabled. + +OAM_OPERATION_EXCEPTION=APPC0153E|\ + Application {0} received exception {1} while attempting to execute oam operation {2}, exception message = {3}|\ + The application controller attempted to perform an OAM operation \ + but an exception was caught. The class of the \ + exception is shown, as is the message associated with the exception. An \ + abbreviated stack trace is also displayed to provide information as to the \ + state of the thread at the time of the exception.|\ + Correct the cause of the exception and rerun. + +OAM_OPERATION_STOPPING=APPC0154W|\ + Application {0} is stopping... |\ + No recovery required|\ + The APPC will no longer accept new LCM requests. Previously accepted LCM requests will be allowed to complete. + +OAM_OPERATION_STOPPED=APPC0155W|\ + Application {0} is stopped|\ + No recovery required|\ + The APPC is not accepting new LCM requests and all previously accepted LCM requests have completed. + +OAM_OPERATION_STARTING=APPC0156I|\ + Application {0} is starting...|\ + No recovery required|\ + The APPC has initiated its startup procedure. Its internal components are coming online. Once completed it will start accepting LCM requests. \ + +OAM_OPERATION_STARTED=APPC0157I|\ + Application {0} is started|\ + No recovery required|\ + The APPC will now accept new LCM requests for processing. + + diff --git a/appc-common/src/test/java/org/openecomp/appc/metadata/TestMetadataService.java b/appc-common/src/test/java/org/openecomp/appc/metadata/TestMetadataService.java new file mode 100644 index 000000000..a6db669ca --- /dev/null +++ b/appc-common/src/test/java/org/openecomp/appc/metadata/TestMetadataService.java @@ -0,0 +1,51 @@ +/*- + * ============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.metadata; + +import org.openecomp.sdnc.sli.resource.dblib.DbLibService; +import com.sun.rowset.CachedRowSetImpl; +import org.mockito.Mockito; +import org.openecomp.appc.metadata.impl.MetadataServiceImpl; + +import javax.sql.rowset.CachedRowSet; +import java.sql.SQLException; +import java.util.ArrayList; + +import static org.mockito.Matchers.anyCollection; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; + + + +public class TestMetadataService { + + MetadataServiceImpl metadataService = new MetadataServiceImpl(); + + TestMetadataService() throws SQLException { + DbLibService dbLibService = mock(DbLibService.class); + metadataService.setDbLibService(dbLibService); + CachedRowSet mockRS = new CachedRowSetImpl(); + Mockito.when(dbLibService.getData(anyString(), (ArrayList<String>)anyCollection(), anyString())).thenReturn(mockRS); + } + + +} diff --git a/appc-dg-util/appc-dg-util-bundle/pom.xml b/appc-dg-util/appc-dg-util-bundle/pom.xml index 082204749..425bc9944 100644 --- a/appc-dg-util/appc-dg-util-bundle/pom.xml +++ b/appc-dg-util/appc-dg-util-bundle/pom.xml @@ -1,206 +1,212 @@ <?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> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-dg-util</artifactId> - <version>1.1.0-SNAPSHOT</version> - </parent> - - <artifactId>appc-dg-util-bundle</artifactId> - <packaging>bundle</packaging> - <name>appc-dg-util - bundle</name> - <properties> - <exam.version>4.9.1</exam.version> - <url.version>1.6.0</url.version> - <sal-netconf-connector.version>1.3.1-Beryllium-SR1</sal-netconf-connector.version> - </properties> - - <dependencies> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-common</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>javax</groupId> - <artifactId>javaee-api</artifactId> - <version>7.0</version> - </dependency> - - <dependency> - <groupId>org.openecomp.sdnc.adaptors</groupId> - <artifactId>aai-service-provider</artifactId> - </dependency> - - <dependency> - <groupId>javax.ws.rs</groupId> - <artifactId>javax.ws.rs-api</artifactId> - </dependency> - - <!-- Jersey support needed for OpenStack connector and API version logic --> - <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-client</artifactId> - </dependency> - - <dependency> - <groupId>com.sun.jersey</groupId> - <artifactId>jersey-json</artifactId> - </dependency> - - <dependency> - <groupId>javax.xml.bind</groupId> - <artifactId>jaxb-api</artifactId> - <version>2.1</version> - </dependency> - - <dependency> - <groupId>javax.xml</groupId> - <artifactId>jaxp-api</artifactId> - <version>1.4.2</version> - </dependency> - - <!-- Needed to run test cases --> - <dependency> - <groupId>org.glassfish.jersey.core</groupId> - <artifactId>jersey-common</artifactId> - <version>2.9.1</version> - </dependency> - - <dependency> - <groupId>org.codehaus.jackson</groupId> - <artifactId>jackson-jaxrs</artifactId> - <version>1.9.12</version> - </dependency> - - <dependency> - <groupId>commons-codec</groupId> - <artifactId>commons-codec</artifactId> - </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpclient</artifactId> - <version>4.5.1</version> - </dependency> - - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-common</artifactId> - <scope>compile</scope> - <!-- Added exclusion to prevent missing dependency issue on dblib --> - <exclusions> - <exclusion> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>dblib-provider</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-provider</artifactId> - <scope>compile</scope> - <!-- Added exclusion to prevent missing dependency issue on dblib --> - <exclusions> - <exclusion> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>dblib-provider</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>equinoxSDK381</groupId> - <artifactId>org.eclipse.osgi</artifactId> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </dependency> - - <dependency> - <groupId>mysql</groupId> - <artifactId>mysql-connector-java</artifactId> - <version>5.1.31</version> - <type>jar</type> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>com.vmware</groupId> - <artifactId>vijava</artifactId> - <version>5.1</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>xerces</groupId> - <artifactId>xerces</artifactId> - <version>2.4.0</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpcore</artifactId> - <version>${apache.httpcomponents.version}</version> - </dependency> - - <dependency> - <groupId>commons-logging</groupId> - <artifactId>commons-logging</artifactId> - <version>1.2</version> - </dependency> - - <dependency> - <groupId>org.json</groupId> - <artifactId>json</artifactId> - </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-netconf-adapter-bundle</artifactId> - <version>${project.version}</version> - </dependency> - - </dependencies> - - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Bundle-SymbolicName>appc-dg-util</Bundle-SymbolicName> - <Bundle-Activator>org.openecomp.appc.dg.util.AppcDgUtilActivator</Bundle-Activator> - <Export-Package>org.openecomp.appc.dg.util.*</Export-Package> - <Import-Package>org.openecomp.appc.adapter.netconf,org.openecomp.appc.adapter.netconf.dao,org.openecomp.appc.adapter.netconf.util,org.openecomp.appc.adapter.netconf.exception,org.openecomp.appc.adapter.dmaap.*,org.openecomp.sdnc.sli.*,org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*,javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*,javax.naming.*,com.fasterxml.*,javax.xml.parsers</Import-Package>n - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> - </instructions> - </configuration> - </plugin> - </plugins> - </build> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-util</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-dg-util-bundle</artifactId> + <packaging>bundle</packaging> + <name>appc-dg-util - bundle</name> + <properties> + <exam.version>4.9.1</exam.version> + <url.version>1.6.0</url.version> + <sal-netconf-connector.version>1.3.1-Beryllium-SR1</sal-netconf-connector.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>javax</groupId> + <artifactId>javaee-api</artifactId> + <version>7.0</version> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.adaptors</groupId> + <artifactId>aai-service-provider</artifactId> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + + <!-- Jersey support needed for OpenStack connector and API version logic --> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + </dependency> + + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-json</artifactId> + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.1</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>jaxp-api</artifactId> + <version>1.4.2</version> + </dependency> + + <!-- Needed to run test cases --> + <dependency> + <groupId>org.glassfish.jersey.core</groupId> + <artifactId>jersey-common</artifactId> + <version>2.9.1</version> + </dependency> + + <dependency> + <groupId>org.codehaus.jackson</groupId> + <artifactId>jackson-jaxrs</artifactId> + <version>1.9.12</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + <version>4.5.1</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + <scope>compile</scope> + <!-- Added exclusion to prevent missing dependency issue on dblib --> + <exclusions> + <exclusion> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>dblib-provider</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + + <dependency> + <groupId>mysql</groupId> + <artifactId>mysql-connector-java</artifactId> + <version>5.1.31</version> + <type>jar</type> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>com.vmware</groupId> + <artifactId>vijava</artifactId> + <version>5.1</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>xerces</groupId> + <artifactId>xerces</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + <version>${apache.httpcomponents.version}</version> + </dependency> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + </dependency> + + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </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-netconf-adapter-bundle</artifactId> + <!--<version>${project.version}</version> --> + <version>1.1.0-SNAPSHOT</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>appc-dg-util</Bundle-SymbolicName> + <Bundle-Activator>org.openecomp.appc.dg.util.AppcDgUtilActivator</Bundle-Activator> + <Export-Package>org.openecomp.appc.dg.util.*</Export-Package> + <Import-Package> + org.openecomp.appc.adapter.netconf,org.openecomp.appc.adapter.netconf.dao,org.openecomp.appc.adapter.netconf.util,com.att.eelf.*, + org.openecomp.appc.adapter.netconf.exception, org.openecomp.appc.adapter.messaging.*,org.openecomp.sdnc.sli.*, + org.openecomp.appc.exceptions, org.openecomp.appc.i18n, + org.osgi.framework.*,org.slf4j.*,com.vmware.*,org.apache.xerces.*,javax.net.*, + javax.net.ssl.*,org.xml.sax.*,javax.xml.bind.*, + javax.naming.*,com.fasterxml.*,javax.xml.parsers, *;resolution:=optional + </Import-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> </project> diff --git a/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java b/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java index 6f5bb0c92..1c898d4d3 100644 --- a/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java +++ b/appc-dg-util/appc-dg-util-bundle/src/main/java/org/openecomp/appc/dg/util/impl/ExecuteNodeActionImpl.java @@ -21,7 +21,6 @@ package org.openecomp.appc.dg.util.impl; -import org.openecomp.appc.adapter.netconf.util.Constants; import org.openecomp.appc.dg.util.ExecuteNodeAction; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.appc.i18n.Msg; @@ -33,13 +32,11 @@ import org.openecomp.sdnc.sli.SvcLogicException; import org.openecomp.sdnc.sli.SvcLogicResource; import org.openecomp.sdnc.sli.aai.AAIClient; import org.openecomp.sdnc.sli.aai.AAIService; -import org.openecomp.sdnc.sli.provider.ExecuteNodeExecutor; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -49,6 +46,7 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { protected static AAIClient client; private static final EELFLogger logger = EELFManager.getInstance().getLogger(ExecuteNodeActionImpl.class); + public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; public ExecuteNodeActionImpl() { } @@ -69,7 +67,7 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { } else { logger.info("AAIService error from bundlecontext"); - logger.error(EELFResourceManager.format(Msg.AAI_CONNECTION_FAILED, sref.toString())); + logger.error(EELFResourceManager.format(Msg.AAI_CONNECTION_FAILED, "AAIService")); } } @@ -95,7 +93,7 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { @Override public void getResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { initialize(); String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = - params.get("resourceKey"); + params.get("resourceKey"); if (logger.isDebugEnabled()) { logger.debug("inside getResorce"); logger.debug("Retrieving " + resourceType + " details from A&AI for Key : " + resourceKey); @@ -103,7 +101,7 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { client = aaiService; try { SvcLogicResource.QueryStatus response = - client.query(resourceType, false, null, resourceKey, ctx_prefix, null, ctx); + client.query(resourceType, false, null, resourceKey, ctx_prefix, null, ctx); logger.info("AAIResponse: " + response.toString()); ctx.setAttribute("getResource_result", response.toString()); } catch (SvcLogicException e) { @@ -117,8 +115,8 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { @Override public void postResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { initialize(); String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = - params.get("resourceKey"), att_name = params.get("attributeName"), att_value = - params.get("attributeValue"); + params.get("resourceKey"), att_name = params.get("attributeName"), att_value = + params.get("attributeValue"); if (logger.isDebugEnabled()) { logger.debug("inside postResource"); logger.debug("Updating " + resourceType + " details in A&AI for Key : " + resourceKey); @@ -167,36 +165,46 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { } //String ctx_prefix = params.get("prefix"); String resourceKey = params.get("resourceKey"); - String retrivalVnfKey = "vnf-id = '" + resourceKey + "' AND relationship-key = 'vserver.vserver-id'"; + // String retrivalVnfKey = "vnf-id = '" + resourceKey + "' AND relationship-key = 'vserver.vserver-id'"; + String retrivalVnfKey = "generic-vnf.vnf-id = '" + resourceKey + "'"; Map<String, String> paramsVnf = new HashMap<String, String>(); - paramsVnf.put("resourceType", "generic-vnf:relationship-list"); + paramsVnf.put("resourceType", "generic-vnf"); paramsVnf.put("prefix", "vnfRetrived"); paramsVnf.put("resourceKey", retrivalVnfKey); logger.debug("Retrieving VNF details from A&AI"); //Retrive all the relations of VNF - getResource(paramsVnf, ctx); - if (ctx.getAttribute("getResource_result").equals("SUCCESS")) { - if (ctx.getAttribute("vnfRetrived.heat-stack-id") != null) { - ctx.setAttribute("VNF.heat-stack-id", ctx.getAttribute("vnfRetrived.heat-stack-id")); + SvcLogicContext vnfCtx = new SvcLogicContext(); + getResource(paramsVnf, vnfCtx); + if (vnfCtx.getAttribute("getResource_result").equals("SUCCESS")) { + if (vnfCtx.getAttribute("vnfRetrived.heat-stack-id") != null) { + ctx.setAttribute("VNF.heat-stack-id", vnfCtx.getAttribute("vnfRetrived.heat-stack-id")); } + ctx.setAttribute("vnf.type",vnfCtx.getAttribute("vnfRetrived.vnf-type")); Map<String, String> vnfHierarchyMap = new ConcurrentHashMap<String, String>(); + + Map<String, Set<String>> vnfcHierarchyMap = new HashMap<String, Set<String>>(); int vmCount = 0; + int vnfcCount = 0; + Set<String> vmSet = null; + String vmURL = ""; logger.debug("Parsing Vserver details from VNF relations"); - for (String ctxKeySet : ctx - .getAttributeKeySet()) { //loop through relationship-list data, to get vserver relations - if (ctxKeySet.startsWith("vnfRetrived.") && ctx.getAttribute(ctxKeySet).equalsIgnoreCase("vserver")) { + for (String ctxKeySet : vnfCtx + .getAttributeKeySet()) { //loop through relationship-list data, to get vserver relations + if (ctxKeySet.startsWith("vnfRetrived.") && vnfCtx.getAttribute(ctxKeySet).equalsIgnoreCase("vserver")) { String vmKey = ctxKeySet.substring(0, ctxKeySet.length() - "related-to".length()); String vserverID = null; String tenantID = null; + String cloudOwner = null; + String cloudRegionId = null; int relationshipLength = 0; - if (ctx.getAttributeKeySet().contains(vmKey + "relationship-data_length")) { - relationshipLength = Integer.parseInt(ctx.getAttribute(vmKey + "relationship-data_length")); + if (vnfCtx.getAttributeKeySet().contains(vmKey + "relationship-data_length")) { + relationshipLength = Integer.parseInt(vnfCtx.getAttribute(vmKey + "relationship-data_length")); } for (int j = 0; j - < relationshipLength; j++) { //loop inside relationship data, to get vserver-id and tenant-id - String key = ctx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-key"); - String value = ctx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-value"); + < relationshipLength; j++) { //loop inside relationship data, to get vserver-id and tenant-id + String key = vnfCtx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-key"); + String value = vnfCtx.getAttribute(vmKey + "relationship-data[" + j + "].relationship-value"); vnfHierarchyMap.put("VNF.VM[" + vmCount + "]." + key, value); if ("vserver.vserver-id".equals(key)) { vserverID = value; @@ -204,23 +212,29 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { if ("tenant.tenant-id".equals(key)) { tenantID = value; } + if ("cloud-region.cloud-owner".equals(key)) { + cloudOwner = value; + } + if ("cloud-region.cloud-region-id".equals(key)) { + cloudRegionId = value; + } } int relatedPropertyLength = 0; - if (ctx.getAttributeKeySet().contains(vmKey + "related-to-property_length")) { + if (vnfCtx.getAttributeKeySet().contains(vmKey + "related-to-property_length")) { relatedPropertyLength = - Integer.parseInt(ctx.getAttribute(vmKey + "related-to-property_length")); + Integer.parseInt(vnfCtx.getAttribute(vmKey + "related-to-property_length")); } for (int j = 0; j < relatedPropertyLength; j++) { //loop inside related-to-property data, to get vserver-name - String key = ctx.getAttribute(vmKey + "related-to-property[" + j + "].property-key"); - String value = ctx.getAttribute(vmKey + "related-to-property[" + j + "].property-value"); + String key = vnfCtx.getAttribute(vmKey + "related-to-property[" + j + "].property-key"); + String value = vnfCtx.getAttribute(vmKey + "related-to-property[" + j + "].property-value"); vnfHierarchyMap.put("VNF.VM[" + vmCount + "]." + key, value); } //Retrive VM relations to find vnfc's //VM to VNFC is 1 to 1 relation - String vmRetrivalKey = "vserver-id = '" + vserverID + "' AND tenant_id = '" + tenantID + "'"; + String vmRetrivalKey = "vserver.vserver-id = '" + vserverID + "' AND tenant.tenant_id = '" + tenantID + "'" + "' AND cloud-region.cloud-owner = '" + cloudOwner + "' AND cloud-region.cloud-region-id = '" + cloudRegionId + "'"; Map<String, String> paramsVm = new HashMap<String, String>(); - paramsVm.put("resourceType", "vserver:relationship-list"); + paramsVm.put("resourceType", "vserver"); paramsVm.put("prefix", "vmRetrived"); paramsVm.put("resourceKey", vmRetrivalKey); SvcLogicContext vmCtx = new SvcLogicContext(); @@ -231,37 +245,43 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { if (logger.isDebugEnabled()) { logger.debug("Parsing VNFC details from VM relations"); } - vnfHierarchyMap.put("VNF.VM[" + vmCount + "].URL", - vmCtx.getAttribute("vmRetrived.vserver-selflink")); + vmURL = vmCtx.getAttribute("vmRetrived.vserver-selflink"); + vnfHierarchyMap.put("VNF.VM[" + vmCount + "].URL",vmURL); for (String ctxVnfcKeySet : vmCtx - .getAttributeKeySet()) { //loop through relationship-list data, to get vnfc relations + .getAttributeKeySet()) { //loop through relationship-list data, to get vnfc relations if (ctxVnfcKeySet.startsWith("vmRetrived.") && vmCtx.getAttribute(ctxVnfcKeySet) - .equalsIgnoreCase("vnfc")) { + .equalsIgnoreCase("vnfc")) { String vnfcKey = ctxVnfcKeySet.substring(0, - ctxVnfcKeySet.length() - "related-to".length()); + ctxVnfcKeySet.length() - "related-to".length()); relationshipLength = 0; if (vmCtx.getAttributeKeySet().contains(vnfcKey + "relationship-data_length")) { relationshipLength = Integer.parseInt( - vmCtx.getAttribute(vnfcKey + "relationship-data_length")); + vmCtx.getAttribute(vnfcKey + "relationship-data_length")); } for (int j = 0; j - < relationshipLength; j++) { //loop through relationship data, to get vnfc name + < relationshipLength; j++) { //loop through relationship data, to get vnfc name String key = vmCtx.getAttribute( - vnfcKey + "relationship-data[" + j + "].relationship-key"); + vnfcKey + "relationship-data[" + j + "].relationship-key"); String value = vmCtx.getAttribute( - vnfcKey + "relationship-data[" + j + "].relationship-value"); + vnfcKey + "relationship-data[" + j + "].relationship-value"); if (key.equalsIgnoreCase("vnfc.vnfc-name")) { vnfHierarchyMap.put("VNF.VM[" + vmCount + "].VNFC", value); + vmSet = vnfcHierarchyMap.get(value); + if(vmSet == null){ + vmSet = new HashSet<>(); + } + vmSet.add(vmURL); + vnfcHierarchyMap.put(value,vmSet); break; //VM to VNFC is 1 to 1 relation, once we got the VNFC name we can break the loop } } } } } else { - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); + ctx.setAttribute(DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); vnfHierarchyMap.put("getVnfHierarchy_result", "FAILURE"); logger.error("Failed in getVnfHierarchy, Error retrieving Vserver details. Error message: " - + vmCtx.getAttribute("getResource_result")); + + vmCtx.getAttribute("getResource_result")); logger.warn("Incorrect or Incomplete VNF Hierarchy"); throw new APPCException("Error Retrieving VNFC hierarchy"); } @@ -270,8 +290,14 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { } vnfHierarchyMap.put("VNF.VMCount", vmCount + ""); if (vmCount == 0) { - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "VM count is 0"); + ctx.setAttribute(DG_OUTPUT_STATUS_MESSAGE, "VM count is 0"); } + //code changes for getting vnfcs hirearchy + populateVnfcsDetailsinContext(vnfcHierarchyMap,ctx); + //vnf,vnfcCount + ctx.setAttribute("VNF.VNFCCount", + Integer.toString(vnfcHierarchyMap.size())); + //code changes for getting vnfcs hirearchy ctx.setAttribute("getVnfHierarchy_result", "SUCCESS"); //Finally set all attributes to ctx for (String attribute : vnfHierarchyMap.keySet()) { @@ -279,9 +305,9 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { } } else { ctx.setAttribute("getVnfHierarchy_result", "FAILURE"); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); + ctx.setAttribute(DG_OUTPUT_STATUS_MESSAGE, "Error Retrieving VNFC hierarchy"); logger.error("Failed in getVnfHierarchy, Error retrieving VNF details. Error message: " + ctx - .getAttribute("getResource_result")); + .getAttribute("getResource_result")); logger.warn("Incorrect or Incomplete VNF Hierarchy"); throw new APPCException("Error Retrieving VNFC hierarchy"); } @@ -289,4 +315,45 @@ public class ExecuteNodeActionImpl implements ExecuteNodeAction { logger.debug("exiting getVnfHierarchy======"); } } + + private void populateVnfcsDetailsinContext(Map<String, Set<String>> vnfcHierarchyMap, SvcLogicContext ctx) throws APPCException { +// int vnfcCount = vnfcHierarchyMap.size(); + SvcLogicContext vnfcCtx = new SvcLogicContext(); + int vnfcCounter = 0; + for (String vnfcName : vnfcHierarchyMap.keySet()) { + String vnfcRetrivalKey = "vnfc-name = '" + vnfcName + "'"; + Map<String, String> paramsVnfc = new HashMap<String, String>(); + paramsVnfc.put("resourceType", "vnfc"); + paramsVnfc.put("prefix", "vnfcRetrived"); + paramsVnfc.put("resourceKey", vnfcRetrivalKey); + + logger.debug("Retrieving VM details from A&AI"); + getResource(paramsVnfc, vnfcCtx); + if (vnfcCtx.getAttribute("getResource_result").equals("SUCCESS")) { + if (logger.isDebugEnabled()) { + logger.debug("Parsing VNFC details from VM relations"); + } + //putting required values in the map + //vnf.vnfc[vnfcIndex].type + ctx.setAttribute("VNF.VNFC[" + vnfcCounter + "].TYPE", + vnfcCtx.getAttribute("vnfcRetrived.vnfc-type")); + + // vnf.vnfc[vnfcIndex].name + ctx.setAttribute("VNF.VNFC[" + vnfcCounter + "].NAME", + vnfcCtx.getAttribute("vnfcRetrived.vnfc-name")); + + //vnf.vnfc[vnfcIndex].vmCount + Set<String> vmSet = vnfcHierarchyMap.get(vnfcName); + String vmCountinVnfcs = Integer.toString(vmSet.size()); + ctx.setAttribute("VNF.VNFC[" + vnfcCounter + "].VM_COUNT", + vmCountinVnfcs); + int vmCount =0; + for(String vmURL:vmSet){ + ctx.setAttribute("VNF.VNFC[" + vnfcCounter + "].VM[" + vmCount++ + "].URL",vmURL); + } + + } + vnfcCounter++; + } + } } diff --git a/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 547b8cdfb..0d4c96df8 100644 --- a/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/appc-dg-util/appc-dg-util-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -41,7 +41,7 @@ <property name="eventSender" ref="eventSenderServiceRef"/> </bean--> - <!--reference interface="org.openecomp.appc.adapter.dmaap.EventSender" id="eventSenderServiceRef"/--> + <!--reference interface="org.openecomp.appc.adapter.messaging.dmaap.EventSender" id="eventSenderServiceRef"/--> <!--service id = "DCAEReporterPluginService" interface="org.openecomp.appc.dg.util.DCAEReporterPlugin" ref="DCAEReporterPlugin"/--> <!--bean id="NetconfClientPlugin" class="org.openecomp.appc.dg.util.impl.NetconfClientPluginImpl" scope="prototype" ></bean--> diff --git a/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml b/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml index 7c641661a..044c0c9a6 100644 --- a/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml +++ b/appc-dg-util/appc-dg-util-features/src/main/resources/features.xml @@ -31,6 +31,7 @@ <!--<feature version="${project.version}">appc-aai-adapter</feature>--> <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-dg-util-bundle/${project.version}</bundle> </feature> diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml b/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml index 814386788..db5dcf390 100644 --- a/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-aai/pom.xml @@ -30,6 +30,11 @@ <groupId>org.openecomp.sdnc.adaptors</groupId> <artifactId>aai-service-provider</artifactId> </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-dependency-model</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>junit</groupId> @@ -56,6 +61,11 @@ <version>1.6.2</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> @@ -69,12 +79,12 @@ <instructions> <Bundle-SymbolicName>appc-dg-aai</Bundle-SymbolicName> <Export-Package>org.openecomp.appc.dg.aai</Export-Package> - <Private-Package>org.openecomp.appc.dg.aai.impl.*</Private-Package> + <Private-Package>org.openecomp.appc.dg.aai.exception,org.openecomp.appc.dg.aai.objects,org.openecomp.appc.dg.aai.impl.*</Private-Package> <Import-Package> - !org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional + *;resolution:=optional </Import-Package> <Embed-Dependency> - appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false + appc-dg-domain-model-lib;scope=compile|runtime;inline=false </Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java index e220182f2..7985dc454 100644 --- a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/AAIPlugin.java @@ -27,9 +27,17 @@ import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.SvcLogicContext; import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; - public interface AAIPlugin extends SvcLogicJavaPlugin { void postGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException; void getGenericVnfData(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void getVnfHierarchy(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void getResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void postResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void deleteResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + } diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/exception/AAIQueryException.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/exception/AAIQueryException.java new file mode 100644 index 000000000..f9f781b50 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/exception/AAIQueryException.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.dg.aai.exception; + + +public class AAIQueryException extends Exception{ + public AAIQueryException(String message){ + super(message); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java index 6eae559e8..830147ca2 100644 --- a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/AAIPluginImpl.java @@ -20,10 +20,17 @@ */ package org.openecomp.appc.dg.aai.impl; +import org.openecomp.appc.domainmodel.Vnf; +import org.openecomp.appc.domainmodel.Vnfc; +import org.openecomp.appc.domainmodel.Vserver; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.i18n.EELFResourceManager; import org.openecomp.appc.dg.aai.AAIPlugin; -import org.openecomp.appc.dg.aai.impl.Constants; -import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.dg.aai.exception.AAIQueryException; +import org.openecomp.appc.dg.aai.objects.AAIQueryResult; +import org.openecomp.appc.dg.aai.objects.Relationship; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import org.openecomp.sdnc.sli.SvcLogicContext; @@ -35,8 +42,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; -import java.util.HashMap; -import java.util.Map; +import java.util.*; public class AAIPluginImpl implements AAIPlugin { @@ -68,20 +74,23 @@ public class AAIPluginImpl implements AAIPlugin { try { SvcLogicResource.QueryStatus response = aaiClient.update("generic-vnf", key, data, prefix, ctx); if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { - String errorMessage = String.format("VNF not found for vnf_id = %s", vnf_id); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - throw new APPCException(errorMessage); + String msg = EELFResourceManager.format(Msg.VNF_NOT_FOUND, vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + throw new APPCException(msg); } logger.info("AAIResponse: " + response.toString()); if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { - String errorMessage = String.format("Error Querying AAI with vnfID = %s", vnf_id); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - throw new APPCException(errorMessage); + String msg = EELFResourceManager.format(Msg.AAI_QUERY_FAILED, vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + throw new APPCException(msg); } + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "PostGenericVnfData", "VNF ID " + vnf_id); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + } catch (SvcLogicException e) { - String errorMessage = String.format("Error in postVnfdata %s", e); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - logger.error(errorMessage); + String msg = EELFResourceManager.format(Msg.AAI_QUERY_FAILED, vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + logger.error(msg); throw new APPCException(e); } } @@ -95,13 +104,14 @@ public class AAIPluginImpl implements AAIPlugin { try { SvcLogicResource.QueryStatus response = aaiClient.query("generic-vnf", false, null, key, prefix, null, ctx); if (SvcLogicResource.QueryStatus.NOT_FOUND.equals(response)) { - String errorMessage = String.format("VNF not found for vnf_id = %s", vnf_id); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - throw new APPCException(errorMessage); + String msg = EELFResourceManager.format(Msg.VNF_NOT_FOUND, vnf_id); +// String errorMessage = String.format("VNF not found for vnf_id = %s", vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + throw new APPCException(msg); } else if (SvcLogicResource.QueryStatus.FAILURE.equals(response)) { - String errorMessage = String.format("Error Querying AAI with vnfID = %s", vnf_id); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - throw new APPCException(errorMessage); + String msg = EELFResourceManager.format(Msg.AAI_QUERY_FAILED, vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + throw new APPCException(msg); } String aaiEntitlementPoolUuid = ctx.getAttribute(Constants.AAI_ENTITLMENT_POOL_UUID_NAME); if (null == aaiEntitlementPoolUuid) aaiEntitlementPoolUuid = ""; @@ -110,13 +120,261 @@ public class AAIPluginImpl implements AAIPlugin { ctx.setAttribute(Constants.IS_RELEASE_ENTITLEMENT_REQUIRE, Boolean.toString(!aaiEntitlementPoolUuid.isEmpty())); ctx.setAttribute(Constants.IS_RELEASE_LICENSE_REQUIRE, Boolean.toString(!aaiLicenseKeyGroupUuid.isEmpty())); + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "GetGenericVnfData","VNF ID " + vnf_id); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); logger.info("AAIResponse: " + response.toString()); } catch (SvcLogicException e) { - String errorMessage = String.format("Error in getVnfdata %s", e); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorMessage); - logger.error(errorMessage); + String msg = EELFResourceManager.format(Msg.AAI_QUERY_FAILED, vnf_id); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + logger.error(msg); throw new APPCException(e); } } + + @Override + public void getVnfHierarchy(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + Map<Vnfc,Set<Vserver>> vnfcMap = new HashMap<>(); + String vnfType,vnfVersion = null; + String vnfId = params.get("resourceKey"); + AAIQueryResult vnfQueryResult = null; + int vmCount =0; + try { + vnfQueryResult = readVnf(vnfId); + + vnfType = vnfQueryResult.getAdditionProperties().get("vnf-type"); + vnfVersion = vnfQueryResult.getAdditionProperties().get("persona-model-version"); + + for(Relationship vnfRelationship:vnfQueryResult.getRelationshipList()){ + if("vserver".equalsIgnoreCase(vnfRelationship.getRelatedTo())){ + vmCount++; + String tenantId = vnfRelationship.getRelationShipDataMap().get("tenant.tenant-id"); + String vmId = vnfRelationship.getRelationShipDataMap().get("vserver.vserver-id"); + String vmRelatedLink = vnfRelationship.getRelatedLink(); + String vmName = vnfRelationship.getRelatedProperties().get("vserver.vserver-name"); + String cloudOwner = vnfRelationship.getRelationShipDataMap().get("cloud-region.cloud-owner"); + String cloudRegionId = vnfRelationship.getRelationShipDataMap().get("cloud-region.cloud-region-id"); + + AAIQueryResult vmQueryResult = readVM(vmId,tenantId,cloudOwner,cloudRegionId); + String vmURL = vmQueryResult.getAdditionProperties().get("vserver-selflink"); + + Vserver vm = new Vserver(vmURL,tenantId,vmId,vmRelatedLink,vmName); + for(Relationship vmRelation:vmQueryResult.getRelationshipList()){ + + if("vnfc".equalsIgnoreCase(vmRelation.getRelatedTo())){ + String vnfcName = vmRelation.getRelationShipDataMap().get("vnfc.vnfc-name"); + AAIQueryResult vnfcQueryResult = readVnfc(vnfcName); + String vnfcType = vnfcQueryResult.getAdditionProperties().get("vnfc-type"); + + Vnfc vnfc = new Vnfc(vnfcType,null,vnfcName); + Set<Vserver> vmSet = vnfcMap.get(vnfc); + if(vmSet == null){ + vmSet = new HashSet<>(); + vnfcMap.put(vnfc,vmSet); + } + vmSet.add(vm); + } + } + } + } + ctx.setAttribute("VNF.VMCount",String.valueOf(vmCount)); + } catch (AAIQueryException e) { + ctx.setAttribute("getVnfHierarchy_result", "FAILURE"); + String msg = EELFResourceManager.format(Msg.AAI_QUERY_FAILED, vnfId); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + logger.error("Failed in getVnfHierarchy, Error retrieving VNF details. Error message: " + ctx + .getAttribute("getResource_result")); + logger.warn("Incorrect or Incomplete VNF Hierarchy"); + throw new APPCException("Error Retrieving VNF hierarchy"); + } + + Vnf vnf = new Vnf(vnfId,vnfType,vnfVersion); + for(Vnfc vnfc:vnfcMap.keySet()){ + for(Vserver vm:vnfcMap.get(vnfc)){ + vnfc.addVm(vm); + } + vnf.addVnfc(vnfc); + } + + populateContext(vnf,ctx); + ctx.setAttribute("getVnfHierarchy_result", "SUCCESS"); + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "GetVNFHierarchy","VNF ID " + vnfId); + ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + + } + + private void populateContext(Vnf vnf ,SvcLogicContext ctx) { + ctx.setAttribute("vnf.type",vnf.getVnfType()); + ctx.setAttribute("vnf.version",vnf.getVnfVersion()); + ctx.setAttribute("vnf.vnfcCount",String.valueOf(vnf.getVnfcs().size())); + int vnfcCount =0; + for(Vnfc vnfc:vnf.getVnfcs()){ + ctx.setAttribute("vnf.vnfc["+vnfcCount+"].name",vnfc.getVnfcName()); + ctx.setAttribute("vnf.vnfc["+vnfcCount+"].type",vnfc.getVnfcType()); + ctx.setAttribute("vnf.vnfc["+vnfcCount+"].vm_count",String.valueOf(vnfc.getVserverList().size())); + int vmCount =0; + for(Vserver vm:vnfc.getVserverList()){ + ctx.setAttribute("vnf.vnfc["+vnfcCount+"].vm["+ vmCount++ +"].url",vm.getUrl()); + } + vnfcCount++; + } + } + + private AAIQueryResult readVnfc(String vnfcName) throws AAIQueryException { + String query = "vnfc.vnfc-name = '" + vnfcName + "'"; + String prefix = "VNFC"; + String resourceType = "vnfc"; + SvcLogicContext vnfContext = readResource(query,prefix,resourceType); + String[] additionalProperties = new String[]{"vnfc-type","vnfc-name", + "vnfc-function-code","in-maint","prov-status", + "is-closed-loop-disabled","orchestration-status","resource-version"}; + AAIQueryResult result = readRelationDataAndProperties(prefix, vnfContext,additionalProperties); + return result; + } + + private AAIQueryResult readVM(String vmId,String tenantId,String cloudOwner,String cloudRegionId) throws AAIQueryException { + String query = "vserver.vserver-id = '" + vmId + "' AND tenant.tenant_id = '" + tenantId + "' AND cloud-region.cloud-owner = '" + + cloudOwner + "' AND cloud-region.cloud-region-id = '" + cloudRegionId + "'"; + String prefix = "VM"; + String resourceType = "vserver"; + SvcLogicContext vnfContext = readResource(query,prefix,resourceType); + String[] additionalProperties = new String[]{"vserver-id","vserver-selflink", + "vserver-name","in-maint","prov-status","is-closed-loop-disabled", + "vserver-name2","resource-version",}; + AAIQueryResult result = readRelationDataAndProperties(prefix, vnfContext,additionalProperties); + + return result; + } + + private AAIQueryResult readVnf(String vnfId) throws AAIQueryException { + String query = "generic-vnf.vnf-id = '" + vnfId + "'"; + String prefix = "VNF"; + String resourceType = "generic-vnf"; + SvcLogicContext vnfContext = readResource(query,prefix,resourceType); + + String[] additionalProperties = new String[]{"vnf-type","vnf-name", + "in-maint","prov-status","heat-stack-id", + "is-closed-loop-disabled","orchestration-status","resource-version","persona-model-version"}; + + AAIQueryResult result = readRelationDataAndProperties(prefix, vnfContext,additionalProperties); + + return result; + } + + private AAIQueryResult readRelationDataAndProperties(String prefix, SvcLogicContext context,String[] additionalProperties) { + AAIQueryResult result = new AAIQueryResult(); + + Integer relationsCount = Integer.parseInt(context.getAttribute(prefix + ".relationship-list.relationship_length")); + for(int i=0;i<relationsCount;i++){ + Relationship relationShip = new Relationship(); + relationShip.setRelatedLink(context.getAttribute(prefix + ".relationship-list.relationship["+i+"].related-link")); + relationShip.setRelatedTo(context.getAttribute(prefix + ".relationship-list.relationship["+i+"].related-to")); + Integer relationDataCount = Integer.parseInt(context.getAttribute(prefix + ".relationship-list.relationship["+i+"].relationship-data_length")); + for(int j=0;j<relationDataCount;j++){ + String key = context.getAttribute(prefix+".relationship-list.relationship["+i+"].relationship-data["+j+"].relationship-key"); + String value = context.getAttribute(prefix+".relationship-list.relationship["+i+"].relationship-data["+j+"].relationship-value"); + relationShip.getRelationShipDataMap().put(key,value); + } + Integer relatedPropertyCount = 0; + String relatedPropertyCountStr = null; + try{ + relatedPropertyCountStr =context.getAttribute(prefix + ".relationship-list.relationship["+i+"].related-to-property_length"); + relatedPropertyCount = Integer.parseInt(relatedPropertyCountStr); + } + catch (NumberFormatException e){ + logger.debug("Invalid value in the context for Related Property Count " + relatedPropertyCountStr); + } + + for(int j=0;j<relatedPropertyCount;j++){ + String key = context.getAttribute(prefix+".relationship-list.relationship["+i+"].related-to-property["+j+"].property-key"); + String value = context.getAttribute(prefix+".relationship-list.relationship["+i+"].related-to-property["+j+"].property-value"); + relationShip.getRelatedProperties().put(key,value); + } + result.getRelationshipList().add(relationShip); + } + + for(String key:additionalProperties){ + result.getAdditionProperties().put(key,context.getAttribute(prefix+"."+key)); + } + return result; + } + + private SvcLogicContext readResource(String query, String prefix, String resourceType) throws AAIQueryException { + SvcLogicContext resourceContext = new SvcLogicContext(); + try { + SvcLogicResource.QueryStatus response = aaiClient.query(resourceType,false,null,query,prefix,null,resourceContext); + logger.info("AAIResponse: " + response.toString()); + if(!SvcLogicResource.QueryStatus.SUCCESS.equals(response)){ + throw new AAIQueryException("Error Retrieving VNF hierarchy from A&AI"); + } + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_GET_DATA_FAILED, query, "", e.getMessage())); + throw new AAIQueryException("Error Retrieving VNF hierarchy from A&AI"); + } + return resourceContext; + } + + @Override public void getResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = + params.get("resourceKey"); + if (logger.isDebugEnabled()) { + logger.debug("inside getResorce"); + logger.debug("Retrieving " + resourceType + " details from A&AI for Key : " + resourceKey); + } + try { + SvcLogicResource.QueryStatus response = + aaiClient.query(resourceType, false, null, resourceKey, ctx_prefix, null, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("getResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_GET_DATA_FAILED, resourceKey, "", e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting getResource======"); + } + } + + @Override public void postResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String resourceType = params.get("resourceType"), ctx_prefix = params.get("prefix"), resourceKey = + params.get("resourceKey"), att_name = params.get("attributeName"), att_value = + params.get("attributeValue"); + if (logger.isDebugEnabled()) { + logger.debug("inside postResource"); + logger.debug("Updating " + resourceType + " details in A&AI for Key : " + resourceKey); + logger.debug("Updating " + att_name + " to : " + att_value); + } + Map<String, String> data = new HashMap<String, String>(); + data.put(att_name, att_value); + + try { + SvcLogicResource.QueryStatus response = aaiClient.update(resourceType, resourceKey, data, ctx_prefix, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("postResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_UPDATE_FAILED, resourceKey, att_value, e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting postResource======"); + } + } + + @Override public void deleteResource(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String resourceType = params.get("resourceType"), resourceKey = params.get("resourceKey"); + + if (logger.isDebugEnabled()) { + logger.debug("inside deleteResource"); + logger.debug("Deleting " + resourceType + " details From A&AI for Key : " + resourceKey); + } + try { + SvcLogicResource.QueryStatus response = aaiClient.delete(resourceType, resourceKey, ctx); + logger.info("AAIResponse: " + response.toString()); + ctx.setAttribute("deleteResource_result", response.toString()); + } catch (SvcLogicException e) { + logger.error(EELFResourceManager.format(Msg.AAI_DELETE_FAILED, resourceKey, e.getMessage())); + } + if (logger.isDebugEnabled()) { + logger.debug("exiting deleteResource======"); + } + } } diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java index 3feab4795..8957d3a8f 100644 --- a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/impl/Constants.java @@ -71,7 +71,7 @@ public class Constants { public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; public static final String UPGRADE_VERSION = "upgrade-version"; public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; - public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; public static final String RESOURCEKEY = "resourceKey"; public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/AAIQueryResult.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/AAIQueryResult.java new file mode 100644 index 000000000..0ad6292f9 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/AAIQueryResult.java @@ -0,0 +1,49 @@ +/*- + * ============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.dg.aai.objects; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +public class AAIQueryResult { + private List<Relationship> relationshipList; + + private Map<String,String> additionProperties; + + + public AAIQueryResult(){ + relationshipList = new ArrayList<>(); + additionProperties = new HashMap<>(); + } + + + public List<Relationship> getRelationshipList() { + return relationshipList; + } + + public Map<String, String> getAdditionProperties() { + return additionProperties; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/Relationship.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/Relationship.java new file mode 100644 index 000000000..63e6392a5 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/java/org/openecomp/appc/dg/aai/objects/Relationship.java @@ -0,0 +1,66 @@ +/*- + * ============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.dg.aai.objects; + +import java.util.HashMap; +import java.util.Map; + + +public class Relationship { + + private String relatedTo; + + private String relatedLink; + + private Map<String,String> relationShipDataMap; + + private Map<String,String> relatedProperties; + + public Relationship(){ + relationShipDataMap = new HashMap<>(); + relatedProperties = new HashMap<>(); + } + + public String getRelatedTo() { + return relatedTo; + } + + public String getRelatedLink() { + return relatedLink; + } + + public Map<String, String> getRelationShipDataMap() { + return relationShipDataMap; + } + + public Map<String, String> getRelatedProperties() { + return relatedProperties; + } + + public void setRelatedTo(String relatedTo) { + this.relatedTo = relatedTo; + } + + public void setRelatedLink(String relatedLink) { + this.relatedLink = relatedLink; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java index 8d6fea0cf..eae221bc4 100644 --- a/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java +++ b/appc-dg/appc-dg-shared/appc-dg-aai/src/main/test/java/org/openecomp/appc/dg/aai/impl/AAIPluginImplTest.java @@ -21,9 +21,7 @@ package org.openecomp.appc.dg.aai.impl; -import org.junit.*; import org.junit.runner.RunWith; -import org.mockito.*; import org.openecomp.appc.dg.aai.Constants; import org.openecomp.appc.dg.aai.impl.AAIPluginImpl; import org.openecomp.appc.dg.common.dao.DAOService; @@ -40,12 +38,10 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.*; -import static org.powermock.api.support.SuppressCode.suppressConstructor; @RunWith(PowerMockRunner.class) @@ -119,7 +115,7 @@ public class AAIPluginImplTest { aaiPlugin.postGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } @@ -143,7 +139,7 @@ public class AAIPluginImplTest { aaiPlugin.postGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } @@ -167,7 +163,7 @@ public class AAIPluginImplTest { aaiPlugin.postGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } @@ -219,7 +215,7 @@ public class AAIPluginImplTest { aaiPlugin.getGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } @@ -236,7 +232,7 @@ public class AAIPluginImplTest { aaiPlugin.getGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } @@ -253,7 +249,7 @@ public class AAIPluginImplTest { aaiPlugin.getGenericVnfData(params, ctx); Assert.assertTrue(false); } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE)); + Assert.assertNotNull(ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); } } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/pom.xml b/appc-dg/appc-dg-shared/appc-dg-common/pom.xml index 6ad459162..ae59b07dc 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-common/pom.xml @@ -17,18 +17,25 @@ </dependency> <dependency> <groupId>org.openecomp.appc</groupId> - <artifactId>appc-dmaap-adapter-bundle</artifactId> + <artifactId>appc-message-adapter-api</artifactId> <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + <scope>provided</scope> </dependency> <dependency> <groupId>org.openecomp.sdnc.core</groupId> <artifactId>sli-common</artifactId> - <scope>compile</scope> + <scope>provided</scope> </dependency> <dependency> <groupId>org.openecomp.sdnc.core</groupId> <artifactId>sli-provider</artifactId> - <scope>compile</scope> + <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> @@ -43,13 +50,11 @@ <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> - <version>1.6.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> - <version>1.6.2</version> <scope>test</scope> </dependency> <dependency> @@ -57,6 +62,31 @@ <artifactId>powermock-api-easymock</artifactId> <version>1.6.2</version> </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-dependency-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-ranking-framework-lib</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>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-mdsal-store</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> <build> @@ -70,8 +100,11 @@ <Bundle-SymbolicName>appc-dg-common</Bundle-SymbolicName> <Export-Package>org.openecomp.appc.dg.common,org.openecomp.appc.dg.common.objects,org.openecomp.appc.dg.common.utils</Export-Package> <Private-Package>org.openecomp.appc.dg.common.impl.*</Private-Package> - <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional</Import-Package> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Import-Package>org.openecomp.appc.adapter.message.*,org.openecomp.appc.adapter.factory.*,org.openecomp.appc.adapter.messaging.*, + *;resolution:=optional</Import-Package> + <Embed-Dependency>appc-dg-mdsal-store,appc-dg-domain-model-lib,appc-dg-dependency-model,jackson-dataformat-yaml,jackson-databind;scope=compile|runtime;inline=false;artifactId=!org.eclipse.osgi</Embed-Dependency> + + <!--Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency--> <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DgResolverPlugin.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DgResolverPlugin.java new file mode 100644 index 000000000..e2fabaa20 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/DgResolverPlugin.java @@ -0,0 +1,32 @@ +/*- + * ============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.dg.common; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +public interface DgResolverPlugin extends SvcLogicJavaPlugin { + void resolveDg(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/IntermediateMessageSender.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/IntermediateMessageSender.java new file mode 100644 index 000000000..f391c36ec --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/IntermediateMessageSender.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.dg.common; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +/** + * This interface provides api for sending intermediate messages from DG to initiator + */ +public interface IntermediateMessageSender extends SvcLogicJavaPlugin{ + + /** + * DG plugin which sends intermediate messages generated from DG to the initiator + * @param params expects 1. code, (mandatory) + * 2. message, (mandatory) + * 3. payload, + * 4. prefix + * @param context expects 1. input.common-header.timestamp, + * 2. input.common-header.api-ver, + * 3. input.common-header.originator-id, + * 4. input.common-header.request-id, (mandatory) + * 5. input.common-header.sub-request-id, + * 6. input.action + */ + void sendMessage(Map<String, String> params, SvcLogicContext context); +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java index 2b3fbf793..ecdaea0dd 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/JsonDgUtil.java @@ -30,4 +30,22 @@ import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; public interface JsonDgUtil extends SvcLogicJavaPlugin { void flatAndAddToContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + void generateOutputPayloadFromContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + /** + * Creates filename and content in Json format. + * @param params + * @param ctx + * @throws APPCException + */ + void cvaasFileNameAndFileContentToContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + + /** + * Checks if a file is created. + * @param params + * @param ctx + * @throws APPCException + */ + void checkFileCreated(Map<String, String> params, SvcLogicContext ctx) throws APPCException; } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/OutputMessagePlugin.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/OutputMessagePlugin.java new file mode 100644 index 000000000..35e7b2263 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/OutputMessagePlugin.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.dg.common; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; + +public interface OutputMessagePlugin extends SvcLogicJavaPlugin { + + void outputMessageBuilder(Map<String, String> params, SvcLogicContext ctx) throws APPCException; + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFCDgResolverPlugin.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFCDgResolverPlugin.java new file mode 100644 index 000000000..0dd79998f --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFCDgResolverPlugin.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.dg.common; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +import org.openecomp.appc.exceptions.APPCException; + + +public interface VNFCDgResolverPlugin extends SvcLogicJavaPlugin { + void resolveVNFCDg(Map<String, String> params, SvcLogicContext ctx) throws APPCException; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFConfigurator.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFConfigurator.java new file mode 100644 index 000000000..57acf5223 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VNFConfigurator.java @@ -0,0 +1,43 @@ +/*- + * ============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.dg.common; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; +/** + * DG plugin created for VNF configuration operation to store data in MD-SAL store + **/ +public interface VNFConfigurator extends SvcLogicJavaPlugin{ + /** + * it is invoked from the DG, and it performs following operations + * 1. checks whether given yang module is present in the MD-SAL store + * 2. if it is absent, loads it into MD-SAL store + * 3. Stores the VNF configuration into MD-SAL store + * @param params should have 1. uniqueId, 2. yang, 3.configJSON, 4.requestId + * @param context - DG context + * @throws APPCException + */ + void storeConfig(Map<String, String> params, SvcLogicContext context) throws APPCException; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VnfExecutionFlow.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VnfExecutionFlow.java new file mode 100644 index 000000000..f69985f03 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/VnfExecutionFlow.java @@ -0,0 +1,31 @@ +/*- + * ============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.dg.common; + +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; + +import java.util.Map; + +public interface VnfExecutionFlow extends SvcLogicJavaPlugin { + void getVnfExecutionFlowData(Map<String,String> params, SvcLogicContext context); +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolver.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolver.java new file mode 100644 index 000000000..1d7766fb2 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolver.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.dg.common.impl; + +import org.openecomp.appc.rankingframework.RankedAttributesResolver; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.concurrent.locks.ReentrantLock; + +abstract class AbstractResolver { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AbstractResolver.class); + + private long interval; + + private volatile long lastUpdate = 0l; + private volatile boolean isUpdateInProgress = false; + private volatile RankedAttributesResolver<FlowKey> dgResolver; + + private final ReentrantLock INIT_LOCK = new ReentrantLock(); + + AbstractResolver(int interval) { + this.interval = interval * 1000; + } + + private RankedAttributesResolver<FlowKey> createResolver(String resolverType) { + AbstractResolverDataReader reader = ResolverDataReaderFactory.createResolverDataReader(resolverType); + return reader.read(); + } + + private boolean isExpired() { + return (System.currentTimeMillis() - lastUpdate) > interval; + } + + protected RankedAttributesResolver<FlowKey> resolver(String resolverType) { + + /* + * In general case, the method implementation is non-blocking. The first + * thread that identifies data expiration will be used to refresh it. In + * meanwhile, any other thread will get the old instance without waiting + * for the updated one. The only exception is the very first time when + * previous instance doesn't exist - in such a cases all the threads + * will be waiting on INIT_LOCK while one of them initializes the + * resolver instance. NOTE: The initialization is intentionally + * implemented in lazy manner to make sure the bundle is initialized + * properly on startup regardless whether or not the data is correct. + * Afterwards, the resolver may be instantiated as many times as needed. + */ + + try { + + if (dgResolver == null) { + INIT_LOCK.lock(); + if (dgResolver != null) { + INIT_LOCK.unlock(); + } + } + + if (!isUpdateInProgress && isExpired()) { + + boolean doUpgrade = false; + + synchronized (this) { + if (!isUpdateInProgress) { + isUpdateInProgress = true; + doUpgrade = true; + } + } + + if (doUpgrade) { + + logger.info("DG resolver configuration data has expired - initiating refresh"); + + try { + RankedAttributesResolver<FlowKey> temp = createResolver(resolverType); + dgResolver = temp; + lastUpdate = System.currentTimeMillis(); + + logger.info("DG resolver configuration data has been refreshed successfully"); + } finally { + isUpdateInProgress = false; + } + } + } + } finally { + if (INIT_LOCK.isHeldByCurrentThread()) { + INIT_LOCK.unlock(); + } + } + + return dgResolver; + } + protected abstract FlowKey resolve(final String...args); +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolverDataReader.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolverDataReader.java new file mode 100644 index 000000000..edfc8f4b8 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/AbstractResolverDataReader.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.dg.common.impl; + +import org.openecomp.appc.dao.util.DBUtils; +import org.openecomp.appc.rankingframework.AbstractRankedAttributesResolverFactory; +import org.openecomp.appc.rankingframework.ConfigurationEntry; +import org.openecomp.appc.rankingframework.ConfigurationSet; +import org.openecomp.appc.rankingframework.RankedAttributesResolver; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.Iterator; + +abstract class AbstractResolverDataReader { + + private class ConfigurationSetAdaptor implements ConfigurationSet<FlowKey> { + + private final ResultSet resultSet; + + private class ResultSetIterator implements Iterator<ConfigurationEntry<FlowKey>>, ConfigurationEntry<FlowKey> { + @Override + public boolean hasNext() { + try { + return resultSet.next(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Override + public ConfigurationEntry<FlowKey> next() { + return this; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public Object getAttributeValue(String name) { + try { + return resultSet.getObject(name); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + @Override + public FlowKey getResult() { + try { + return new FlowKey(resultSet.getString("dg_name"), resultSet.getString("dg_version"), resultSet.getString("dg_module")); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + ConfigurationSetAdaptor(ResultSet resultSet) { + this.resultSet = resultSet; + } + + @Override + public Iterable<ConfigurationEntry<FlowKey>> getEntries() { + return new Iterable<ConfigurationEntry<FlowKey>>() { + + @Override + public Iterator<ConfigurationEntry<FlowKey>> iterator() { + return new ResultSetIterator(); + } + }; + } + + @Override + public Collection<String> getRankedAttributeNames() { + return getAttributeNames(); + } + } + + protected abstract Collection<String> getAttributeNames(); + protected abstract String getQueryStmt(); + + + + RankedAttributesResolver<FlowKey> read() { + try { + try (Connection conn = DBUtils.getConnection("sdnctl")) { + try (PreparedStatement stmt = conn.prepareStatement(getQueryStmt())) { + try (ResultSet res = stmt.executeQuery()) { + if (res.next()) { + res.beforeFirst(); + ConfigurationSet<FlowKey> resolverConfig = new ConfigurationSetAdaptor(res); + return AbstractRankedAttributesResolverFactory.getInstance().create(resolverConfig); + } else { + throw new IllegalStateException(); + } + } + } + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java index 92d23e3a6..3a5bb91ac 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/Constants.java @@ -27,15 +27,35 @@ class Constants { public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; + public static final String EVENT_MESSAGE = "event-message"; + public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message"; + public static final String ATTRIBUTE_SUCCESS_MESSAGE = "success-message"; + public static final String DG_ERROR_CODE = "output.status.dgerror.code"; public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; public static final String PAYLOAD = "payload"; + public static final String OUTPUT_PAYLOAD = "output.payload"; + + //Added for VnfExecution Flow + public static final String FLOW_STRATEGY = "FlowStrategy" ; + public static final String DEPENDENCY_TYPE = "DependencyType"; + public static final String VNF_TYPE = "vnfType"; + public static final String VNF_VERION = "vnfVersion"; + + + public static final String APPC_INSTANCE_ID= "appc-instance-id"; + + //Added for Cvaas + public static final String CVAAS_DIRECTORY_PATH = "cvaas-directory-path"; + public static final String CVAAS_FILE_NAME = "cvaas-file-name"; + public static final String CVAAS_FILE_CONTENT = "cvaas-file-content"; enum LegacyAttributes { Action("org.openecomp.appc.action"), VMID("org.openecomp.appc.vmid"), IdentityURL("org.openecomp.appc.identity.url"), - TenantID("org.openecomp.appc.tenant.id"); + TenantID("org.openecomp.appc.tenant.id"), + SkipHypervisorCheck("org.openecomp.appc.skiphypervisorcheck"); private String value; LegacyAttributes(String value) {this.value = value;} @@ -47,11 +67,30 @@ class Constants { Payload("input.payload"), VMID("vm-id"), IdentityURL("identity-url"), - TenantID("tenant.id"); + TenantID("tenant.id"), + SkipHypervisorCheck("skip-hypervisor-check"); private String value; LCMAttributes(String value) {this.value = value;} String getValue() {return value;} }; + // DG Resolver Constants + public static final String IN_PARAM_VNF_TYPE = "vnfType"; + public static final String IN_PARAM_VNFC_TYPE = "vnfcType"; + public static final String IN_PARAM_ACTION = "action"; + public static final String IN_PARAM_API_VERSION = "api-ver"; + + public static final String OUT_PARAM_DG_NAME = "dg_name"; + public static final String OUT_PARAM_DG_VERSION= "dg_version"; + public static final String OUT_PARAM_DG_MODULE = "dg_module"; + + public static final String TABLE_NAME = "VNFC_DG_MAPPING"; + public static final String TABLE_COLUMN_VNF_TYPE = "VNF_TYPE"; + public static final String TABLE_COLUMN_VNFC_TYPE = "VNFC_TYPE"; + public static final String TABLE_COLUMN_ACTION = "ACTION"; + public static final String TABLE_COLUMN_API_VERSION = "API_VERSION"; + public static final String TABLE_COLUMN_DG_NAME = "DG_NAME"; + public static final String TABLE_COLUMN_DG_VERSION= "DG_VERSION"; + public static final String TABLE_COLUMN_DG_MODULE = "DG_MODULE"; } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java index 4458de10b..8081a6ff3 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImpl.java @@ -22,11 +22,11 @@ package org.openecomp.appc.dg.common.impl; import org.apache.commons.lang3.StringUtils; -import org.openecomp.appc.adapter.dmaap.EventSender; -import org.openecomp.appc.adapter.dmaap.DmaapDestination; -import org.openecomp.appc.adapter.dmaap.event.EventHeader; -import org.openecomp.appc.adapter.dmaap.event.EventMessage; -import org.openecomp.appc.adapter.dmaap.event.EventStatus; +import org.openecomp.appc.adapter.message.EventSender; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.event.EventHeader; +import org.openecomp.appc.adapter.message.event.EventMessage; +import org.openecomp.appc.adapter.message.event.EventStatus; import org.openecomp.appc.dg.common.DCAEReporterPlugin; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.SvcLogicContext; @@ -48,74 +48,108 @@ public class DCAEReporterPluginImpl implements DCAEReporterPlugin { @Override public void report(Map<String, String> params, SvcLogicContext ctx) throws APPCException { - Integer errorReportCode = 501; - boolean bwcMode = Boolean.parseBoolean(ctx.getAttribute("isBwcMode")); String errorDescription,apiVersion,eventId ; - errorDescription = getErrorDescriptionAndAddToCtx(bwcMode,params,ctx); - if(!bwcMode){ - apiVersion = ctx.getAttribute("input.common-header.api-ver"); - eventId = ctx.getAttribute("input.common-header.request-id"); - }else { - apiVersion = ctx.getAttribute(Constants.API_VERSION_FIELD_NAME); - eventId = ctx.getAttribute(Constants.REQ_ID_FIELD_NAME); - } - EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(errorReportCode, errorDescription)); - eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); - } + Integer errorCode = readErrorCode(params,ctx); + errorDescription = params.get(Constants.EVENT_MESSAGE); - private String getErrorDescriptionAndAddToCtx(boolean bwcMode, Map<String, String> params, SvcLogicContext ctx) { - String errorDescription; - if(!bwcMode) { - errorDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); - if(StringUtils.isEmpty(errorDescription)) { - errorDescription = ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE); - }else { - addToContextIfNotContains(bwcMode,errorDescription,ctx); - } + if(StringUtils.isEmpty(errorDescription)) { + reportLegacy(params , ctx); }else{ - errorDescription = params.get(Constants.DG_ERROR_FIELD_NAME); - if(StringUtils.isEmpty(errorDescription)) { - errorDescription = ctx.getAttribute("org.openecomp.appc.dg.error"); + apiVersion = ctx.getAttribute("input.common-header.api-ver"); + eventId = ctx.getAttribute("input.common-header.request-id"); + + EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(errorCode, errorDescription)); + String eventWriteTopic = params.get("event-topic-name"); + if(!StringUtils.isEmpty(eventWriteTopic) && eventWriteTopic!=null){ + eventSender.sendEvent(MessageDestination.DCAE, eventMessage,eventWriteTopic); }else { - addToContextIfNotContains(bwcMode, errorDescription,ctx); + eventSender.sendEvent(MessageDestination.DCAE, eventMessage); } } - - if(StringUtils.isEmpty(errorDescription)) { - errorDescription = "Unknown"; - } - return errorDescription; } - private void addToContextIfNotContains(boolean bwcMode, String errorDescription, SvcLogicContext ctx) { - String errorDescriptionFromCtx; - if(!StringUtils.isEmpty(errorDescription)) { - String outputStatusMessageProperty = bwcMode ? "org.openecomp.appc.dg.error" : Constants.DG_OUTPUT_STATUS_MESSAGE; - errorDescriptionFromCtx = ctx.getAttribute(outputStatusMessageProperty); - if(StringUtils.isEmpty(errorDescriptionFromCtx)){ - ctx.setAttribute(outputStatusMessageProperty, errorDescription); - }else if (!errorDescriptionFromCtx.contains(errorDescription)){ - ctx.setAttribute(outputStatusMessageProperty, errorDescriptionFromCtx+ " | "+ errorDescription); - } + private Integer readErrorCode(Map<String, String> params, SvcLogicContext ctx) { + Integer errorReportCode = 501; + String errorCodeStr = params.get(Constants.DG_ERROR_CODE); + errorCodeStr = StringUtils.isEmpty(errorCodeStr)? + ctx.getAttribute(Constants.DG_ERROR_CODE):errorCodeStr; + try{ + errorReportCode = Integer.parseInt(errorCodeStr); } + catch (NumberFormatException e){ + // Ignore Exception + } + return errorReportCode; } - @Override public void reportSuccess(Map<String, String> params, SvcLogicContext ctx) throws APPCException { Integer successReportCode = 500; String successDescription, apiVersion, eventId; - successDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); + successDescription = params.get(Constants.EVENT_MESSAGE); + + if(StringUtils.isEmpty(successDescription)) { + successDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); + } + apiVersion = ctx.getAttribute("input.common-header.api-ver"); eventId = ctx.getAttribute("input.common-header.request-id"); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, successDescription); if (null == successDescription) { successDescription = "Success"; } EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(successReportCode, successDescription)); - eventSender.sendEvent(DmaapDestination.DCAE, eventMessage); + String eventWriteTopic = params.get("event-topic-name"); + if(!StringUtils.isEmpty(eventWriteTopic) && eventWriteTopic!=null){ + eventSender.sendEvent(MessageDestination.DCAE, eventMessage,eventWriteTopic); + }else { + eventSender.sendEvent(MessageDestination.DCAE, eventMessage); + } + } + + private void reportLegacy(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String errorDescription,apiVersion,eventId ; + + Integer errorCode = readErrorCode(params,ctx); + errorDescription = getErrorDescriptionAndAddToCtx(params,ctx); + + apiVersion = ctx.getAttribute("input.common-header.api-ver"); + eventId = ctx.getAttribute("input.common-header.request-id"); + + EventMessage eventMessage = new EventMessage(new EventHeader((new java.util.Date()).toString(), apiVersion, eventId), new EventStatus(errorCode, errorDescription)); + String eventWriteTopic = params.get("event-topic-name"); + if(!StringUtils.isEmpty(eventWriteTopic) && eventWriteTopic!=null){ + eventSender.sendEvent(MessageDestination.DCAE, eventMessage,eventWriteTopic); + }else { + eventSender.sendEvent(MessageDestination.DCAE, eventMessage); + } + } + + private String getErrorDescriptionAndAddToCtx(Map<String, String> params, SvcLogicContext ctx) { + String errorDescription; + errorDescription = params.get(Constants.DG_OUTPUT_STATUS_MESSAGE); + if(StringUtils.isEmpty(errorDescription)) { + errorDescription = ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE); + } + if(StringUtils.isEmpty(errorDescription)) { + errorDescription = "Unknown"; + } + addToContextIfNotContains(errorDescription,ctx); + return errorDescription; + } + + private void addToContextIfNotContains(String errorDescription, SvcLogicContext ctx) { + String errorDescriptionFromCtx; + errorDescriptionFromCtx = ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE); + if(StringUtils.isEmpty(errorDescriptionFromCtx)){ + errorDescriptionFromCtx = ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE); + } + if(StringUtils.isEmpty(errorDescriptionFromCtx)){ + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorDescription); + }else if (!errorDescriptionFromCtx.contains(errorDescription)){ + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorDescriptionFromCtx+ " | "+ errorDescription); + } } } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DgResolverPluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DgResolverPluginImpl.java new file mode 100644 index 000000000..497cb7f66 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/DgResolverPluginImpl.java @@ -0,0 +1,68 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; +import com.att.eelf.i18n.EELFResourceManager; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.Map; + +import org.openecomp.appc.dg.common.DgResolverPlugin; + +public class DgResolverPluginImpl implements DgResolverPlugin { + + @Override + public void resolveDg(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + + String DGName, DGVersion, DGModule = null; + String prefix = params.containsKey("prefix") ? params.get("prefix") + "." : ""; + AbstractResolver resolver = ResolverFactory.createResolver(params.get("DGResolutionType")); + FlowKey flowKey = null; + try { + + if(params.get("DGResolutionType").equalsIgnoreCase("VNFC")) { + flowKey = resolver.resolve(params.get(Constants.IN_PARAM_ACTION), params.get(Constants.IN_PARAM_VNF_TYPE), params.get(Constants.IN_PARAM_VNFC_TYPE), params.get(Constants.IN_PARAM_API_VERSION)); + }else if(params.get("DGResolutionType").equalsIgnoreCase("VNF")){ + flowKey = resolver.resolve(params.get(Constants.IN_PARAM_ACTION), params.get(Constants.IN_PARAM_VNF_TYPE), params.get("vnfVersion"), params.get(Constants.IN_PARAM_API_VERSION)); + } + if (flowKey != null) { + DGName = flowKey.name(); + ctx.setAttribute(prefix + Constants.OUT_PARAM_DG_NAME, DGName); + DGVersion = flowKey.version(); + ctx.setAttribute(prefix + Constants.OUT_PARAM_DG_VERSION, DGVersion); + DGModule = flowKey.module(); + ctx.setAttribute(prefix + Constants.OUT_PARAM_DG_MODULE, DGModule); + } else { + throw new RuntimeException(params.get("DGResolutionType")+ " DG not found for vnf type :" + params.get(Constants.IN_PARAM_VNF_TYPE) + + " vnfc type : " + params.get(Constants.IN_PARAM_VNFC_TYPE) + + " action : " + params.get(Constants.IN_PARAM_ACTION) + + " api version : " + params.get(Constants.IN_PARAM_API_VERSION)); + } + } catch (Exception e) { + String msg = EELFResourceManager.format(Msg.FAILURE_RETRIEVE_VNFC_DG,params.get(Constants.IN_PARAM_VNFC_TYPE), e.getMessage()); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg); + throw new RuntimeException(e); + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/FlowKey.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/FlowKey.java new file mode 100644 index 000000000..416f90786 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/FlowKey.java @@ -0,0 +1,59 @@ +/*- + * ============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.dg.common.impl; + +class FlowKey { + private final String name; + private final String version; + private final String module; + + FlowKey(String name, String version, String module) { + this.name = name; + this.version = version; + this.module = module; + } + + String name() { + return name; + } + + String version() { + return version; + } + + String module() { + return module; + } + + @Override + public String toString() { + StringBuilder buff = new StringBuilder(128); + buff.append("{"); + buff.append("module = ").append(module); + buff.append(", "); + buff.append("name = ").append(name); + buff.append(", "); + buff.append("version = ").append(version); + buff.append("}"); + return buff.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/IntermediateMessageSenderImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/IntermediateMessageSenderImpl.java new file mode 100644 index 000000000..3732ded04 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/IntermediateMessageSenderImpl.java @@ -0,0 +1,169 @@ +/*- + * ============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.dg.common.impl; + + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.lang.StringUtils; +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.dg.common.IntermediateMessageSender; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public class IntermediateMessageSenderImpl implements IntermediateMessageSender { + + + private Producer producer; + + private Configuration configuration; + + private final EELFLogger logger = EELFManager.getInstance().getLogger(IntermediateMessageSenderImpl.class); + + private static final String STATUS = "STATUS"; + private static final String FAILURE = "FAILURE"; + private static final String SUCCESS = "SUCCESS"; + private static final String ERROR_MESSAGE = "ERROR_MESSAGE"; + + private static final String RESPONSE = "response"; + private static final String MSO = "MSO"; + + public void init(){ + configuration = ConfigurationFactory.getConfiguration(); + Properties properties=configuration.getProperties(); + + String writeTopic = properties.getProperty("appc.LCM.topic.write"); + String apiKey = properties.getProperty("appc.LCM.client.key"); + String apiSecret = properties.getProperty("appc.LCM.client.secret"); + String hostNames = properties.getProperty("appc.LCM.poolMembers"); + + logger.debug("Configuration Read : writeTopic = " + writeTopic +", " + + "hostNames = " + hostNames); + + Set<String> pool = new HashSet<>(); + if (!StringUtils.isEmpty(hostNames)) { + for (String name : hostNames.split(",")) { + pool.add(name); + } + } + + BundleContext ctx = FrameworkUtil.getBundle(IntermediateMessageSenderImpl.class).getBundleContext(); + if (ctx != null) { + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef != null) { + producer = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopic,apiKey, apiSecret); + } + } + } + + @Override + public void sendMessage(Map<String, String> params, SvcLogicContext context) { + String prefix = params.get("prefix"); + prefix = StringUtils.isEmpty(prefix)? "":prefix+"."; + try{ + validateInputs(params,context); + String jsonMessage = getJsonMessage(params, context); + logger.debug("Constructed JSON Message : " + jsonMessage); + producer.post("",jsonMessage); + context.setAttribute(prefix + STATUS, SUCCESS); + } + catch(Exception e){ + String errorMessage = "Error sending intermediate message to initiator " + e.getMessage(); + context.setAttribute(prefix + STATUS, FAILURE); + context.setAttribute(prefix + ERROR_MESSAGE, errorMessage); + logger.error(errorMessage,e); + } + } + + private void validateInputs(Map<String, String> params, SvcLogicContext context) throws APPCException { + String code = params.get("code"); + String message = params.get("message"); + if(StringUtils.isEmpty(code) || StringUtils.isEmpty(message)){ + throw new APPCException("code or message is empty"); + } + String requestId = context.getAttribute("input.common-header.request-id"); + if(StringUtils.isEmpty(requestId)){ + throw new APPCException("requestId is empty"); + } + } + + private String getJsonMessage(Map<String, String> params, SvcLogicContext context) { + ObjectMapper objectMapper = new ObjectMapper(); + + ObjectNode commonHeader = getCommonHeader(context); + ObjectNode status = getStatus(params); + + ObjectNode output = objectMapper.createObjectNode(); + output.put("common-header",commonHeader); + output.put("status",status); + + ObjectNode body = objectMapper.createObjectNode(); + body.put("output",output); + + ObjectNode root = objectMapper.createObjectNode(); + root.put("type", RESPONSE); + root.put("rpc-name",context.getAttribute("input.action")); + root.put("cambria.partition", MSO); + root.put("correlation-id",getCorrelationId(context)); + root.put("body",body); + + return root.toString(); + } + + private String getCorrelationId(SvcLogicContext context) { + String requestId = context.getAttribute("input.common-header.request-id"); + String subRequestId = context.getAttribute("input.common-header.sub-request-id"); + return requestId + (StringUtils.isEmpty(subRequestId)?"":("-"+subRequestId)); + } + + private ObjectNode getStatus(Map<String,String> params) { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode status = objectMapper.createObjectNode(); + status.put("code",params.get("code")); + status.put("message",params.get("message")); + return status; + } + + private ObjectNode getCommonHeader(SvcLogicContext context) { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode commonHeader = objectMapper.createObjectNode(); + commonHeader.put("api-ver",context.getAttribute("input.common-header.api-ver")); + commonHeader.put("timestamp",context.getAttribute("input.common-header.timestamp")); + commonHeader.put("originator-id",context.getAttribute("input.common-header.originator-id")); + commonHeader.put("request-id",context.getAttribute("input.common-header.request-id")); + commonHeader.put("sub-request-id",context.getAttribute("input.common-header.sub-request-id")); + return commonHeader; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java index 95191132a..1ba2b5b07 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImpl.java @@ -21,21 +21,36 @@ package org.openecomp.appc.dg.common.impl; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Map; +import java.util.Set; + import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.openecomp.appc.dg.common.JsonDgUtil; import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; import org.openecomp.appc.util.JsonUtil; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; import org.openecomp.sdnc.sli.SvcLogicContext; -import java.util.Map; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; public class JsonDgUtilImpl implements JsonDgUtil { private static final EELFLogger logger = EELFManager.getInstance().getLogger(JsonDgUtilImpl.class); + private static final ThreadLocal<SimpleDateFormat> DATE_TIME_PARSER_THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() { + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + @Override public void flatAndAddToContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException { @@ -59,8 +74,123 @@ public class JsonDgUtilImpl implements JsonDgUtil { } } catch (Exception e) { logger.error(e.toString()); + String msg = EELFResourceManager.format(Msg.INPUT_PAYLOAD_PARSING_FAILED,params.get(Constants.PAYLOAD)); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); + throw new APPCException(e); + } + } + + @Override + public void generateOutputPayloadFromContext(Map<String, String> params, SvcLogicContext ctx) throws APPCException{ + if (logger.isTraceEnabled()) { + logger.trace("Entering to generateOutputPayloadFromContext with SvcLogicContext = "+ObjectUtils.toString(ctx)); + } + + try { + Set<String> keys = ctx.getAttributeKeySet(); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode JsonNode = objectMapper.createObjectNode(); + for (String key : keys) { + if(key.startsWith(Constants.OUTPUT_PAYLOAD+".")){ + String objkey= key.replaceFirst(Constants.OUTPUT_PAYLOAD + ".", ""); + if(objkey.contains("[") && objkey.contains("]")){ + ArrayNode arrayNode; + String arrayKey = objkey.substring(0,objkey.indexOf('[')); + int arrayIndex = Integer.parseInt(objkey.substring(objkey.indexOf('[')+1,objkey.indexOf(']'))); + if(JsonNode.has(arrayKey)){ + arrayNode = (ArrayNode)JsonNode.get(arrayKey); + arrayNode.insert(arrayIndex,ctx.getAttribute(key)); + }else { + arrayNode = objectMapper.createArrayNode(); + arrayNode.insert(arrayIndex,ctx.getAttribute(key)); + JsonNode.put(arrayKey,arrayNode); + } + }else { + JsonNode.put(objkey, ctx.getAttribute(key)); + } + } + } + if(JsonNode.size()>0) { + ctx.setAttribute(Constants.OUTPUT_PAYLOAD, objectMapper.writeValueAsString(JsonNode)); + } + } catch (Exception e) { + logger.error(e.toString()); ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.toString()); throw new APPCException(e); } + + } + + @Override + public void cvaasFileNameAndFileContentToContext(Map<String, String> params, SvcLogicContext ctx) + throws APPCException { + + if (logger.isTraceEnabled()) { + logger.trace("Entering to caasFileNameAndFileContentToContext with SvcLogicContext = " + + ObjectUtils.toString(ctx)); + } + + String vnfId = null; + try { + String cvassDirectoryPath = params.get(Constants.CVAAS_DIRECTORY_PATH); + String appcInstanceId = params.get(Constants.APPC_INSTANCE_ID); + + /* + * File name + */ + vnfId = params.get("vnf-id"); + long timestampAsLongRepresentingFileCreationTime = System.currentTimeMillis(); + + ctx.setAttribute(Constants.CVAAS_FILE_NAME, cvassDirectoryPath + File.separator + vnfId + "_" + + timestampAsLongRepresentingFileCreationTime + "_" + appcInstanceId + ".json"); + + /* + * File content + */ + + String uploadDate = ctx.getAttribute("running-config.upload-date"); + long epochUploadTimestamp = DATE_TIME_PARSER_THREAD_LOCAL.get().parse(uploadDate).getTime(); + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode jsonNode = objectMapper.createObjectNode(); + jsonNode.put("UPLOAD_CONFIG_ID", ctx.getAttribute("running-config.upload-config-id")); + jsonNode.put("REQUEST_ID", ctx.getAttribute("running-config.request-id")); + jsonNode.put("ORIGINATOR_ID", ctx.getAttribute("running-config.originator-id")); + jsonNode.put("SERVICE_DESCRIPTION", ctx.getAttribute("running-config.service-description")); + jsonNode.put("ACTION", ctx.getAttribute("running-config.action")); + jsonNode.put("UPLOAD_TIMESTAMP", epochUploadTimestamp); + jsonNode.put("UPLOAD_DATE", uploadDate); + jsonNode.put("VNF_ID", vnfId); + jsonNode.put("VNF_NAME", ctx.getAttribute("running-config.vnf-name")); + jsonNode.put("VM_NAME", ctx.getAttribute("running-config.vm-name")); + jsonNode.put("VNF_TYPE", ctx.getAttribute("running-config.vnf-type")); + jsonNode.put("VNFC_TYPE", ctx.getAttribute("running-config.vnfc-type")); + jsonNode.put("HOST_IP_ADDRESS", ctx.getAttribute("running-config.host-ip-address")); + jsonNode.put("CONFIG_INDICATOR", ctx.getAttribute("running-config.config-indicator")); + jsonNode.put("PENDING_DELETE", ctx.getAttribute("running-config.pending-delete")); + jsonNode.put("CONTENT", ctx.getAttribute("running-config.content")); + + ctx.setAttribute(Constants.CVAAS_FILE_CONTENT, + objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode)); + + } catch (Exception e) { + String errorMessage = "Failed to parse create cvass file for vnf with id : " + vnfId; + logger.error(errorMessage, e); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, errorMessage); + throw new APPCException(e); + } + } + + @Override + public void checkFileCreated(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String filePath = ctx.getAttribute(Constants.CVAAS_FILE_NAME); + File file = new File(filePath); + + if (!file.exists()) { + String vnfId = params.get("vnf-id"); + String errorMessage = "Cvass file could not be created for vnf with id : " + vnfId; + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, errorMessage); + throw new APPCException(errorMessage); + } } } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java index 6354b2044..3ab8ee28f 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/LegacyUtilImpl.java @@ -37,11 +37,13 @@ public class LegacyUtilImpl implements LegacyUtil { String payloadStr = ctx.getAttribute(Constants.LCMAttributes.Payload.getValue()); Map<String,String> payloads = JSONUtil.extractPlainValues(payloadStr, - Constants.LCMAttributes.VMID.getValue(), Constants.LCMAttributes.IdentityURL.getValue(), Constants.LCMAttributes.TenantID.getValue()); + Constants.LCMAttributes.VMID.getValue(), Constants.LCMAttributes.IdentityURL.getValue(), Constants.LCMAttributes.TenantID.getValue(), + Constants.LCMAttributes.SkipHypervisorCheck.getValue()); ctx.setAttribute(Constants.LegacyAttributes.VMID.getValue(), payloads.get(Constants.LCMAttributes.VMID.getValue())); ctx.setAttribute(Constants.LegacyAttributes.IdentityURL.getValue(), payloads.get(Constants.LCMAttributes.IdentityURL.getValue())); ctx.setAttribute(Constants.LegacyAttributes.TenantID.getValue(), payloads.get(Constants.LCMAttributes.TenantID.getValue())); + ctx.setAttribute(Constants.LegacyAttributes.SkipHypervisorCheck.getValue(), payloads.get(Constants.LCMAttributes.SkipHypervisorCheck.getValue())); } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/OutputMessagePluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/OutputMessagePluginImpl.java new file mode 100644 index 000000000..c70c754ca --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/OutputMessagePluginImpl.java @@ -0,0 +1,70 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.Map; + +import org.openecomp.appc.dg.common.OutputMessagePlugin; +import org.openecomp.appc.exceptions.APPCException; + +import static org.apache.commons.lang3.StringUtils.isEmpty; + +public class OutputMessagePluginImpl implements OutputMessagePlugin { + + @Override + public void outputMessageBuilder(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + String errorDescription, eventDescription; + + //making output.status.message + errorDescription = params.get(Constants.ATTRIBUTE_ERROR_MESSAGE); + eventDescription = params.get(Constants.EVENT_MESSAGE); + + addToContextIfNotContains(errorDescription , eventDescription, ctx); + + //making event-message + + if (!isEmpty(eventDescription)) { + ctx.setAttribute(Constants.EVENT_MESSAGE, eventDescription); + } else { + ctx.setAttribute(Constants.EVENT_MESSAGE, ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE)); + } + } + + public static void addToContextIfNotContains(String errorDescription, String eventDescription, SvcLogicContext ctx) { + if (!isEmpty(errorDescription)){ + if (isEmpty(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE))) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, errorDescription); + }else if (!ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE).contains(errorDescription)) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE) + " | " + errorDescription); + } + } + if (!isEmpty(eventDescription)){ + if (isEmpty(ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE))) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, eventDescription); + }else if (!ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE).contains(eventDescription)) { + ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, ctx.getAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE) + " | " + eventDescription); + } + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverDataReaderFactory.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverDataReaderFactory.java new file mode 100644 index 000000000..9dc43abee --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverDataReaderFactory.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.dg.common.impl; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class ResolverDataReaderFactory { + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + private static class ReferenceHolder{ + private static final AbstractResolverDataReader VNFC_RESOLVER_DATA_READER = new VNFCResolverDataReader(); + + private static final AbstractResolverDataReader VNF_RESOLVER_DATA_READER = new VNFResolverDataReader(); + } + + public static AbstractResolverDataReader createResolverDataReader(String resolverType){ + if(resolverType.equalsIgnoreCase("VNF")){ + return ReferenceHolder.VNF_RESOLVER_DATA_READER; + }else if(resolverType.equalsIgnoreCase("VNFC")){ + return ReferenceHolder.VNFC_RESOLVER_DATA_READER; + }else { + return null; + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverFactory.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverFactory.java new file mode 100644 index 000000000..afc7907db --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/ResolverFactory.java @@ -0,0 +1,43 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; + +public class ResolverFactory { + private static final Configuration configuration = ConfigurationFactory.getConfiguration(); + private static class ReferenceHolder{ + private static final AbstractResolver VNFC_RESOLVER = new VNFCResolver(configuration.getIntegerProperty("org.openecomp.appc.workflow.resolver.refresh_interval", 300)); + private static final AbstractResolver VNF_RESOLVER = new VNFResolver(configuration.getIntegerProperty("org.openecomp.appc.workflow.resolver.refresh_interval", 300)); + } + + public static AbstractResolver createResolver(String resolverType){ + if(resolverType.equalsIgnoreCase("VNF")){ + return ReferenceHolder.VNF_RESOLVER; + }else if(resolverType.equalsIgnoreCase("VNFC")){ + return ReferenceHolder.VNFC_RESOLVER; + }else { + return null; + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCDgResolverPluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCDgResolverPluginImpl.java new file mode 100644 index 000000000..404d9087b --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCDgResolverPluginImpl.java @@ -0,0 +1,36 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.sdnc.sli.SvcLogicContext; + +import java.util.Map; + +public class VNFCDgResolverPluginImpl implements org.openecomp.appc.dg.common.VNFCDgResolverPlugin { + @Override + public void resolveVNFCDg(Map<String, String> params, SvcLogicContext ctx) throws APPCException { + DgResolverPluginImpl dgResolverPlugin = new DgResolverPluginImpl(); + params.put("DGResolutionType" , "VNFC"); + dgResolverPlugin.resolveDg(params,ctx); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolver.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolver.java new file mode 100644 index 000000000..7c90b57f9 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolver.java @@ -0,0 +1,64 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; + + +public class VNFCResolver extends AbstractResolver { + VNFCResolver(int interval) { + super(interval); + } + + @Override + protected FlowKey resolve(String... args) { + if(args.length !=4){ + throw new IllegalStateException(args.toString()); + } + return resolve(args[0],args[1],args[2],args[3]); + } + + protected FlowKey resolve(final String action, final String vnfType, final String vnfcType, final String apiVersion) { + RankedAttributesContext context = new RankedAttributesContext() { + @Override + public Object getAttributeValue(String name) { + switch (name) { + case "action": + return action; + case "api_version": + return apiVersion; + case "vnf_type": + return vnfType; + case "vnfc_type": + return vnfcType; + default: + throw new IllegalStateException(name); + } + } + }; + + FlowKey wfKey = resolver("VNFC").resolve(context); + + return wfKey; + } +} + diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolverDataReader.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolverDataReader.java new file mode 100644 index 000000000..b49d1fa54 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFCResolverDataReader.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.dg.common.impl; + +import java.util.Arrays; +import java.util.Collection; + +public class VNFCResolverDataReader extends AbstractResolverDataReader { + @Override + protected Collection<String> getAttributeNames() { + return Arrays.asList("action","api_version", "vnf_type", "vnfc_type"); + } + + @Override + protected String getQueryStmt() { + return "select vnf_type,vnfc_type,api_version,action,dg_name,dg_version,dg_module FROM VNFC_DG_MAPPING"; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFConfiguratorImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFConfiguratorImpl.java new file mode 100644 index 000000000..169114330 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFConfiguratorImpl.java @@ -0,0 +1,112 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.dg.common.VNFConfigurator; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.mdsal.MDSALStore; +import org.openecomp.appc.mdsal.exception.MDSALStoreException; +import org.openecomp.appc.mdsal.impl.MDSALStoreFactory; +import org.openecomp.appc.mdsal.objects.BundleInfo; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.apache.commons.lang.StringUtils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + + +public class VNFConfiguratorImpl implements VNFConfigurator { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(VNFConfiguratorImpl.class); + private static final String STATUS = "STATUS"; + private static final String FAILURE = "FAILURE"; + private static final String SUCCESS = "SUCCESS"; + private static final String ERROR_MESSAGE = "ERROR_MESSAGE"; + + @Override + public void storeConfig(Map<String, String> params, SvcLogicContext context) throws APPCException { + String uniqueId = params.get("uniqueId"); + String yang = params.get("yang"); + String configJSON = params.get("configJSON"); + String requestId = params.get("requestId"); + String prefix = params.get("prefix"); + prefix = StringUtils.isEmpty(prefix)? "":prefix+"."; + + MDSALStore store = MDSALStoreFactory.createMDSALStore(); + + logger.debug("Inputs Received : uniqueId = " + uniqueId + + " , yang = " + yang + + " , configJSON = " + configJSON + + " , requestId = " + requestId + + " , prefix = " +prefix); + + try { + + if(StringUtils.isEmpty(uniqueId) + ||StringUtils.isEmpty(yang) + || StringUtils.isEmpty(configJSON) + || StringUtils.isEmpty(requestId)){ + throw new APPCException("One or more input parameters are empty : uniqueId = " + uniqueId + " " + + ", yang = " + yang + + " , configJSON = " + configJSON + + " , requestId = " + requestId); + } + + Date revision = new SimpleDateFormat(Constants.YANG_REVISION_FORMAT).parse(Constants.YANG_REVISION); + + boolean isYangAlreadyLoaded = store.isModulePresent(uniqueId,revision); + + if(!isYangAlreadyLoaded){ + BundleInfo bundleInfo = getBundleInfo(uniqueId); + store.storeYangModule(yang,bundleInfo); + } + store.storeJson(uniqueId, requestId , configJSON); + context.setAttribute(prefix + STATUS, SUCCESS); + } catch (ParseException e) { + String errorMessage ="Error parsing the date : " + Constants.YANG_REVISION + " into format " + Constants.YANG_REVISION_FORMAT; + logger.error(errorMessage,e); + context.setAttribute(prefix + STATUS, FAILURE); + context.setAttribute(prefix + ERROR_MESSAGE, errorMessage); + throw new APPCException(e.getMessage()); + }catch (MDSALStoreException e){ + String errorMessage = "Error while adding yang to MD-SAL store." + e.getMessage(); + logger.error(errorMessage,e); + context.setAttribute(prefix + STATUS,FAILURE); + context.setAttribute(prefix + ERROR_MESSAGE, errorMessage); + throw new APPCException(e.getMessage()); + } + + } + + private BundleInfo getBundleInfo(String uniqueId) { + BundleInfo bundleInfo = new BundleInfo(); + bundleInfo.setDescription(uniqueId); + bundleInfo.setName(uniqueId); + bundleInfo.setLocation(uniqueId); + return bundleInfo; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolver.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolver.java new file mode 100644 index 000000000..b6002c65e --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolver.java @@ -0,0 +1,60 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.rankingframework.RankedAttributesContext; + +public class VNFResolver extends AbstractResolver { + VNFResolver(int interval) { + super(interval); + } + + @Override + protected FlowKey resolve(String... args) { + return resolve(args[0],args[1],args[2],args[3]); + } + + + protected FlowKey resolve(final String action, final String vnfType, final String vnfVersion, final String apiVersion) { + RankedAttributesContext context = new RankedAttributesContext() { + @Override + public Object getAttributeValue(String name) { + switch (name) { + case "action": + return action; + case "api_version": + return apiVersion; + case "vnf_type": + return vnfType; + case "vnf_version": + return vnfVersion; + default: + throw new IllegalStateException(name); + } + } + }; + + FlowKey wfKey = resolver("VNF").resolve(context); + + return wfKey; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolverDataReader.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolverDataReader.java new file mode 100644 index 000000000..7d91bee15 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VNFResolverDataReader.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.dg.common.impl; + +import java.util.Arrays; +import java.util.Collection; + +/** + * @since January 19,2017 + */ +public class VNFResolverDataReader extends AbstractResolverDataReader { + @Override + protected Collection<String> getAttributeNames() { + return Arrays.asList("action","api_version", "vnf_type", "vnf_version"); + } + + @Override + protected String getQueryStmt() { + return "select vnf_type,vnf_version,api_version,action,dg_name,dg_version,dg_module FROM VNF_DG_MAPPING"; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VnfExecutionFlowImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VnfExecutionFlowImpl.java new file mode 100644 index 000000000..e8975da0f --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/java/org/openecomp/appc/dg/common/impl/VnfExecutionFlowImpl.java @@ -0,0 +1,268 @@ +/*- + * ============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.dg.common.impl; + +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 java.util.*; + +import org.openecomp.appc.dg.common.VnfExecutionFlow; +import org.openecomp.appc.dg.dependencymanager.DependencyManager; +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.dependencymanager.impl.DependencyModelFactory; +import org.openecomp.appc.dg.flowbuilder.FlowBuilder; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.flowbuilder.impl.FlowBuilderFactory; +import org.openecomp.appc.dg.objects.*; +import org.openecomp.appc.domainmodel.Vnf; +import org.openecomp.appc.domainmodel.Vnfc; +import org.openecomp.appc.domainmodel.Vserver; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; + +public class VnfExecutionFlowImpl implements VnfExecutionFlow { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(VnfExecutionFlowImpl.class); + + public VnfExecutionFlowImpl(){ + + } + + @Override + public void getVnfExecutionFlowData(Map<String, String> params, SvcLogicContext context) { + String dependencyType = params.get(Constants.DEPENDENCY_TYPE); + String flowStrategy = params.get(Constants.FLOW_STRATEGY); + DependencyModelIdentifier modelIdentifier = readDependencyModelIdentifier(params); + VnfcDependencyModel dependencyModel = null; + try { + validateInput(dependencyType, flowStrategy, params); + + if (logger.isTraceEnabled()) { + logger.trace("Input received from DG Node : dependencyType = " + dependencyType + + " , flowStrategy = " + flowStrategy + + ", DependencyModelIdentifier = " + modelIdentifier.toString()); + } + + DependencyManager dependencyManager = DependencyModelFactory.createDependencyManager(); + + + dependencyModel = dependencyManager.getVnfcDependencyModel( + modelIdentifier, DependencyTypes.findByString(dependencyType)); + } catch (DependencyModelNotFound e) { + String msg = EELFResourceManager.format(Msg.DEPENDENCY_MODEL_NOT_FOUND,params.get(Constants.VNF_TYPE), e.getMessage()); + logger.error(msg); + context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg); + context.setAttribute("dependencyModelFound","false"); + return; + } catch (InvalidDependencyModel e){ + String msg = EELFResourceManager.format(Msg.INVALID_DEPENDENCY_MODEL,params.get(Constants.VNF_TYPE), e.getMessage()); + logger.error(msg); + context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg); + throw e; + }catch (RuntimeException e){ + logger.error(e.getMessage()); + context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage()); + throw e; + } + + + context.setAttribute("dependencyModelFound","true"); + if(logger.isDebugEnabled()){ + logger.debug("Dependency Model = " +dependencyModel); + } + logger.info("Building Inventory Model from DG context"); + InventoryModel inventoryModel = readInventoryModel(context); + if(logger.isDebugEnabled()){ + logger.debug("Inventory Model = " +inventoryModel); + } + + if(logger.isDebugEnabled()){ + logger.debug("Validating inventory model with dependency model"); + } + try { + validateInventoryModelWithDependencyModel(dependencyModel, inventoryModel); + }catch (RuntimeException e){ + logger.error(e.getMessage()); + context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,e.getMessage()); + throw e; + } + logger.info("Creating flow builder"); + FlowBuilder flowBuilder = FlowBuilderFactory.getInstance().getFlowBuilder( + FlowStrategies.findByString(flowStrategy)); + + logger.info("Building Vnf flow model"); + VnfcFlowModel flowModel = null; + try{ + flowModel = flowBuilder.buildFlowModel(dependencyModel,inventoryModel); + } + catch (InvalidDependencyModel e){ + String msg = EELFResourceManager.format(Msg.INVALID_DEPENDENCY_MODEL,params.get(Constants.VNF_TYPE), e.getMessage()); + logger.error(msg); + context.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg); + throw e; + } + + // remove VNFCs from the flow model where vserver list is empty + reconcileFlowModel(flowModel); + populateContext(flowModel,context); + if(logger.isDebugEnabled()){ + logContext(context); + } + String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "GetVnfExecutionFlowData","VNF ID " + params.get(Constants.VNF_TYPE)); + context.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg); + } + + private void validateInput(String dependencyType, String flowStrategy, Map<String, String> params) { + DependencyTypes dependencyTypes = DependencyTypes.findByString(dependencyType); + if(dependencyTypes == null){ + throw new RuntimeException("Dependency type from the input : " + dependencyType +" is invalid."); + } + FlowStrategies flowStrategies = FlowStrategies.findByString(flowStrategy); + if(flowStrategies == null){ + throw new RuntimeException("Flow Strategy from the input : " + flowStrategy +" is invalid."); + } + String vnfType = params.get(Constants.VNF_TYPE); + if(vnfType ==null || vnfType.length() ==0){ + throw new RuntimeException("Vnf Type is not passed in the input"); + } + String vnfVersion = params.get(Constants.VNF_VERION); + if(vnfVersion == null || vnfVersion.length() ==0){ + throw new RuntimeException("Vnf Version not found"); + } + } + + private void logContext(SvcLogicContext context) { + for(String key:context.getAttributeKeySet()){ + logger.debug(key + " = " + context.getAttribute(key) + "\n" ); + } + } + + private void populateContext(VnfcFlowModel flowModel, SvcLogicContext context) { + int flowIndex=0; + Iterator<List<Vnfc>> iterator = flowModel.getModelIterator(); + while (iterator.hasNext()){ + for(Vnfc vnfc:iterator.next()){ + context.setAttribute("vnfcFlow["+flowIndex+"].vnfcName",vnfc.getVnfcName()); + context.setAttribute("vnfcFlow["+flowIndex+"].vnfcType",vnfc.getVnfcType()); + context.setAttribute("vnfcFlow["+flowIndex+"].resilienceType",vnfc.getResilienceType()); + context.setAttribute("vnfcFlow["+flowIndex+"].vmCount",Integer.toString(vnfc.getVserverList().size())); + int vmIndex =0; + for(Vserver vm :vnfc.getVserverList()){ + context.setAttribute("vnfcFlow["+flowIndex+"].vm["+vmIndex+"].url",vm.getUrl()); + vmIndex++; + } + flowIndex++; + } + } + context.setAttribute("vnfcFlowCount",Integer.toString(flowIndex)); + } + + private InventoryModel readInventoryModel(SvcLogicContext context) { + String vnfId = context.getAttribute("input.action-identifiers.vnf-id"); + String vnfType = context.getAttribute("vnf.type"); + String vnfVersion = context.getAttribute("vnf.version"); + String vnfcCountStr = context.getAttribute("vnf.vnfcCount"); + Integer vnfcCount = Integer.parseInt(vnfcCountStr); + + Vnf vnf = new Vnf(vnfId,vnfType,vnfVersion); + + for(Integer i=0;i<vnfcCount;i++){ + String vnfcName = context.getAttribute("vnf.vnfc["+ i+"].name"); + String vnfcType = context.getAttribute("vnf.vnfc["+ i+"].type"); + String vmCountStr = context.getAttribute("vnf.vnfc["+ i+"].vm_count"); + if(vnfcType ==null || vnfcType.length() ==0){ + throw new RuntimeException("Could not retrieve VNFC Type from DG Context for vnf.vnfc["+ i+"].type"); + } + Integer vmCount = Integer.parseInt(vmCountStr); + Vnfc vnfc = new Vnfc(vnfcType,null,vnfcName); + for(Integer j=0;j<vmCount;j++){ + String vmURL = context.getAttribute("vnf.vnfc["+i+"].vm["+j+"].url"); + Vserver vm = new Vserver(vmURL); + vnfc.addVm(vm); + } + vnf.addVnfc(vnfc); + } + return new InventoryModel(vnf); + } + + private DependencyModelIdentifier readDependencyModelIdentifier(Map<String, String> params) { + String vnfType = params.get(Constants.VNF_TYPE); + String catalogVersion = params.get(Constants.VNF_VERION); + return new DependencyModelIdentifier(vnfType,catalogVersion); + } + + private void validateInventoryModelWithDependencyModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) { + Set<String> dependencyModelVnfcSet = new HashSet<String>(); + Set<String> dependencyModelMandatoryVnfcSet = new HashSet<String>(); + Set<String> inventoryModelVnfcsSet = new HashSet<String>(); + + for (Node<Vnfc> node : dependencyModel.getDependencies()) { + dependencyModelVnfcSet.add(node.getChild().getVnfcType().toLowerCase()); + if (node.getChild().isMandatory()) { + dependencyModelMandatoryVnfcSet.add(node.getChild().getVnfcType().toLowerCase()); + } + } + + for (Vnfc vnfc : inventoryModel.getVnf().getVnfcs()) { + inventoryModelVnfcsSet.add(vnfc.getVnfcType().toLowerCase()); + } + + // if dependency model and inventory model contains same set of VNFCs, validation succeed and hence return + if (dependencyModelVnfcSet.equals(inventoryModelVnfcsSet)) { + return; + } + + if (inventoryModelVnfcsSet.size() >= dependencyModelVnfcSet.size()) { + Set<String> difference = new HashSet<String>(inventoryModelVnfcsSet); + difference.removeAll(dependencyModelVnfcSet); + logger.error("Dependency model is missing following vnfc type(s): " + difference); + throw new RuntimeException("Dependency model is missing following vnfc type(s): " + difference); + } else { + Set<String> difference = new HashSet<String>(dependencyModelVnfcSet); + difference.removeAll(inventoryModelVnfcsSet); + difference.retainAll(dependencyModelMandatoryVnfcSet); + if (difference.size() > 0) { + logger.error("Inventory model is missing following mandatory vnfc type(s): " + difference); + throw new RuntimeException("Inventory model is missing following mandatory vnfc type(s): " + difference); + } + } + } + + private void reconcileFlowModel(VnfcFlowModel flowModel) { + Iterator<List<Vnfc>> flowIterator = flowModel.getModelIterator(); + while (flowIterator.hasNext()) { + Iterator<Vnfc> vnfcIterator = flowIterator.next().iterator(); + while (vnfcIterator.hasNext()) { + Vnfc vnfc = vnfcIterator.next(); + if (vnfc.getVserverList().size() == 0) { + if (logger.isDebugEnabled()) { + logger.debug("No vservers present for Vnfc type: " + vnfc.getVnfcType() + ". Hence, removing it from the flow model."); + } + vnfcIterator.remove(); + } + } + } + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 53b5367e4..fcbaaf776 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -30,12 +30,35 @@ <bean id="JsonDgUtilBean" class="org.openecomp.appc.dg.common.impl.JsonDgUtilImpl"/> <service id="JsonDgUtil" interface="org.openecomp.appc.dg.common.JsonDgUtil" ref="JsonDgUtilBean"/> - <reference id="eventSenderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.dmaap.EventSender" /> + <!-- <reference id="eventSenderRef" availability="mandatory" activation="eager" interface="org.openecomp.appc.adapter.message.EventSender" /> --> <bean id="DCAEReporterPluginBean" class="org.openecomp.appc.dg.common.impl.DCAEReporterPluginImpl" scope="singleton"/> <service id="DCAEReporterPlugin" interface="org.openecomp.appc.dg.common.DCAEReporterPlugin" ref="DCAEReporterPluginBean"/> + <bean id="OutputMessagePluginBean" class="org.openecomp.appc.dg.common.impl.OutputMessagePluginImpl" scope="singleton"/> + <service id="OutputMessagePlugin" interface="org.openecomp.appc.dg.common.OutputMessagePlugin" ref="OutputMessagePluginBean"/> + <bean id="legacyUtilBean" class="org.openecomp.appc.dg.common.impl.LegacyUtilImpl" scope="singleton"/> <service id="legacyUtil" interface="org.openecomp.appc.dg.common.LegacyUtil" ref="legacyUtilBean"/> + <bean id="DgResolverPluginBean" class="org.openecomp.appc.dg.common.impl.DgResolverPluginImpl" scope="singleton"> + </bean> + + <service id="DgResolverPlugin" interface="org.openecomp.appc.dg.common.DgResolverPlugin" ref="DgResolverPluginBean"/> + + <bean id="vnfExecutionFlowBean" class="org.openecomp.appc.dg.common.impl.VnfExecutionFlowImpl" scope="singleton"/> + <service id="vnfExecutionFlowService" interface="org.openecomp.appc.dg.common.VnfExecutionFlow" ref="vnfExecutionFlowBean"/> + + <bean id="VNFCDgResolverPluginBean" class="org.openecomp.appc.dg.common.impl.VNFCDgResolverPluginImpl" scope="singleton"> + </bean> + + <service id="VNFCDgResolverPlugin" interface="org.openecomp.appc.dg.common.VNFCDgResolverPlugin" ref="VNFCDgResolverPluginBean"/> + + <bean id="vnfConfiguratorBean" class="org.openecomp.appc.dg.common.impl.VNFConfiguratorImpl" scope="singleton"/> + + <service id="vnfConfigurationService" interface="org.openecomp.appc.dg.common.VNFConfigurator" ref="vnfConfiguratorBean"/> + + <bean id="interimMessageSender" class="org.openecomp.appc.dg.common.impl.IntermediateMessageSenderImpl" init-method="init" scope="singleton"/> + <service id="interimMessageSenderService" ref="interimMessageSender" interface="org.openecomp.appc.dg.common.IntermediateMessageSender"/> + </blueprint> diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java index 834bd8655..44b71fb4d 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/DCAEReporterPluginImplTest.java @@ -24,10 +24,9 @@ package org.openecomp.appc.dg.common.impl; import org.junit.*; import org.junit.runner.RunWith; import org.mockito.*; -import org.openecomp.appc.adapter.dmaap.EventSender; -import org.openecomp.appc.adapter.dmaap.DmaapDestination; -import org.openecomp.appc.adapter.dmaap.event.EventMessage; -import org.openecomp.appc.dg.common.impl.Constants; +import org.openecomp.appc.adapter.message.EventSender; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.event.EventMessage; import org.openecomp.appc.dg.common.impl.DCAEReporterPluginImpl; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.SvcLogicContext; @@ -44,7 +43,6 @@ import java.util.Map; @RunWith(PowerMockRunner.class) @PrepareForTest({DCAEReporterPluginImpl.class, FrameworkUtil.class}) -@Ignore public class DCAEReporterPluginImplTest { private SvcLogicContext ctx; private Map<String, String> params; @@ -75,39 +73,11 @@ public class DCAEReporterPluginImplTest { - - @Test - public void testReportBwcTrue() throws Exception { - - ctx = new SvcLogicContext(); - params = new HashMap<>(); - ctx.setAttribute("isBwcMode", "true"); - params.put(Constants.DG_ERROR_FIELD_NAME, error); - ctx.setAttribute(Constants.API_VERSION_FIELD_NAME, apiVer); - ctx.setAttribute(Constants.REQ_ID_FIELD_NAME, requestId); - - positiveAssert(); - } - - @Test - public void testReportErrorDescriptionNullBwcModeTrue() throws Exception { - - ctx = new SvcLogicContext(); - params = new HashMap<>(); - ctx.setAttribute("isBwcMode", "true"); - params.put(Constants.DG_ERROR_FIELD_NAME, null); - ctx.setAttribute(Constants.API_VERSION_FIELD_NAME, apiVer); - ctx.setAttribute(Constants.REQ_ID_FIELD_NAME, requestId); - - errorReasonNullAssert(); - } - @Test public void testReportErrorDescriptionNullBwcModeFalse() throws Exception { ctx = new SvcLogicContext(); params = new HashMap<>(); - ctx.setAttribute("isBwcMode", "false"); params.put("output.status.message", null); ctx.setAttribute("input.common-header.api-ver", apiVer); ctx.setAttribute("input.common-header.request-id", requestId); @@ -118,7 +88,7 @@ public class DCAEReporterPluginImplTest { private void errorReasonNullAssert() throws APPCException { dcaeReporterPlugin.report(params, ctx); - DmaapDestination destination = eventSender.getDestination(); + MessageDestination destination = eventSender.getDestination(); EventMessage msg = eventSender.getMsg(); Assert.assertEquals("wrong API version", apiVer, msg.getEventHeader().getApiVer()); Assert.assertEquals("wrong requestId", requestId, msg.getEventHeader().getEventId()); @@ -130,7 +100,7 @@ public class DCAEReporterPluginImplTest { private void positiveAssert() throws APPCException { dcaeReporterPlugin.report(params, ctx); - DmaapDestination destination = eventSender.getDestination(); + MessageDestination destination = eventSender.getDestination(); EventMessage msg = eventSender.getMsg(); Assert.assertEquals("wrong API version", apiVer, msg.getEventHeader().getApiVer()); Assert.assertEquals("wrong requestId", requestId, msg.getEventHeader().getEventId()); diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java index 0e6b1651b..86532922d 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/EventSenderMock.java @@ -23,19 +23,19 @@ package org.openecomp.appc.dg.common.impl; import java.util.Map; -import org.openecomp.appc.adapter.dmaap.EventSender; -import org.openecomp.appc.adapter.dmaap.DmaapDestination; -import org.openecomp.appc.adapter.dmaap.event.EventMessage; +import org.openecomp.appc.adapter.message.EventSender; +import org.openecomp.appc.adapter.message.MessageDestination; +import org.openecomp.appc.adapter.message.event.EventMessage; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.sdnc.sli.SvcLogicContext; public class EventSenderMock implements EventSender { EventMessage msg; - DmaapDestination destination; + MessageDestination destination; @Override - public boolean sendEvent(DmaapDestination destination, EventMessage msg) { + public boolean sendEvent(MessageDestination destination, EventMessage msg) { if (destination != null && msg != null){ this.msg = msg; this.destination = destination; @@ -47,7 +47,12 @@ public class EventSenderMock implements EventSender { } @Override - public boolean sendEvent(DmaapDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException { + public boolean sendEvent(MessageDestination destination, EventMessage msg, String eventTopicName) { + return false; + } + + @Override + public boolean sendEvent(MessageDestination destination, Map<String, String> params, SvcLogicContext ctx) throws APPCException { return false; } @@ -55,7 +60,7 @@ public class EventSenderMock implements EventSender { return msg; } - public DmaapDestination getDestination() { + public MessageDestination getDestination() { return destination; } } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java index 70534872d..0a49d5326 100644 --- a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/JsonDgUtilImplTest.java @@ -32,7 +32,6 @@ import org.openecomp.sdnc.sli.SvcLogicContext; import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.*; import static org.mockito.Mockito.mock; public class JsonDgUtilImplTest { @@ -83,7 +82,7 @@ public class JsonDgUtilImplTest { } catch (APPCException e) { Assert.assertNull(ctx.getAttribute(testValueKey)); Assert.assertNull(ctx.getAttribute(testValueKey2)); - Assert.assertNotNull(ctx.getAttribute("output.status.message")); + Assert.assertNotNull(ctx.getAttribute("error-message")); } @@ -142,4 +141,29 @@ public class JsonDgUtilImplTest { Assert.assertNull(ctx.getAttribute(testValueKey)); Assert.assertNull(ctx.getAttribute(testValueKey2)); } + + + @Test + public void testGenerateOutputPayloadFromContext() throws Exception { + + JsonDgUtilImpl jsonDgUtil = new JsonDgUtilImpl(); + String key = "output.payload"; + String key1 = "output.payload.test-key[0]"; + String key2 = "output.payload.test-key[1]"; + String testValueKey1 = "value1"; + String testValueKey2 = "value2"; + + String key3 = "output.payload.test-key3"; + String testValueKey3 = "value3"; + + SvcLogicContext ctx = new SvcLogicContext(); + Map<String, String> params = new HashMap<>(); + ctx.setAttribute(key1, testValueKey1); + ctx.setAttribute(key2, testValueKey2); + ctx.setAttribute(key3, testValueKey3); + jsonDgUtil.generateOutputPayloadFromContext(params, ctx); + + Assert.assertNotNull(ctx.getAttribute(key)); + + } } diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVNFConfiguratorImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVNFConfiguratorImpl.java new file mode 100644 index 000000000..0ee06362e --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVNFConfiguratorImpl.java @@ -0,0 +1,105 @@ +/*- + * ============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.dg.common.impl; + +import org.openecomp.appc.dg.common.VNFConfigurator; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.mdsal.MDSALStore; +import org.openecomp.appc.mdsal.impl.MDSALStoreFactory; +import org.openecomp.appc.mdsal.impl.MDSALStoreImpl; +import org.openecomp.appc.mdsal.objects.BundleInfo; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +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.HashMap; +import java.util.Map; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MDSALStoreImpl.class,MDSALStoreFactory.class}) +public class TestVNFConfiguratorImpl { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestVNFConfiguratorImpl.class); + + @Before + public void setUp() { + logger.setLevel(EELFLogger.Level.DEBUG); + } + + @Test(expected = APPCException.class) + public void testValidations() throws APPCException { + VNFConfigurator configurator = new VNFConfiguratorImpl(); + Map<String,String> params = new HashMap<String, String>(); + params.put("uniqueId","uniqueId"); + params.put("yang","yang"); + params.put("configJSON","configJSON"); + configurator.storeConfig(params,new SvcLogicContext()); + } + + @Test + public void testYangPresentScenario() throws APPCException { + + VNFConfigurator configurator = new VNFConfiguratorImpl(); + PowerMockito.mockStatic(MDSALStoreFactory.class); + MDSALStore mdsalStore = PowerMockito.mock(MDSALStoreImpl.class); + PowerMockito.when(MDSALStoreFactory.createMDSALStore()).thenReturn(mdsalStore); + PowerMockito.when(mdsalStore.isModulePresent(Matchers.anyString(),(Date) Matchers.anyObject())).thenReturn(true); + + Map<String,String> params = new HashMap<String, String>(); + params.put("uniqueId","uniqueId"); + params.put("yang","yang"); + params.put("configJSON","configJSON"); + params.put("requestId","requestId"); + configurator.storeConfig(params,new SvcLogicContext()); + } + + @Test + public void testYangAbsentScenario() throws Exception { + + VNFConfigurator configurator = new VNFConfiguratorImpl(); + PowerMockito.mockStatic(MDSALStoreFactory.class); + + MDSALStore mdsalStore = PowerMockito.mock(MDSALStoreImpl.class); + + PowerMockito.when(MDSALStoreFactory.createMDSALStore()).thenReturn(mdsalStore); + + PowerMockito.when(mdsalStore.isModulePresent(Matchers.anyString(),(Date) Matchers.anyObject())).thenReturn(false); + + PowerMockito.doNothing().when(mdsalStore).storeYangModule(Matchers.anyString(),(BundleInfo)Matchers.anyObject()); + + Map<String,String> params = new HashMap<>(); + params.put("uniqueId","uniqueId"); + params.put("yang","yang"); + params.put("configJSON","configJSON"); + params.put("requestId","requestId"); + configurator.storeConfig(params,new SvcLogicContext()); + + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVnfExecutionFlowImpl.java b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVnfExecutionFlowImpl.java new file mode 100644 index 000000000..773b6b61a --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-common/src/test/java/org/openecomp/appc/dg/common/impl/TestVnfExecutionFlowImpl.java @@ -0,0 +1,417 @@ +/*- + * ============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.dg.common.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.openecomp.sdnc.sli.SvcLogicContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.openecomp.appc.dg.common.VnfExecutionFlow; +import org.openecomp.appc.dg.common.impl.Constants; +import org.openecomp.appc.dg.common.impl.VnfExecutionFlowImpl; +import org.openecomp.appc.dg.dependencymanager.DependencyManager; +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.dependencymanager.impl.DependencyModelFactory; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.DependencyTypes; +import org.openecomp.appc.dg.objects.Node; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.openecomp.appc.domainmodel.Vnfc; +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; +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.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({TestVnfExecutionFlowImpl.class, FrameworkUtil.class,DependencyManager.class,DependencyModelFactory.class}) +public class TestVnfExecutionFlowImpl { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestVnfExecutionFlowImpl.class); + + @Before + public void setUp() { + logger.setLevel(EELFLogger.Level.DEBUG); + } + + @Test + public void testPositiveFlow() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContext(); + VnfcDependencyModel dependencyModel = readDependencyModel(); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + @Test + public void testComplexFlow() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContextForComplexDependency(); + VnfcDependencyModel dependencyModel = readComplexDependencyModel(); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + @Test(expected = InvalidDependencyModel.class) + public void testCycleFlow() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContextForComplexDependency(); + VnfcDependencyModel dependencyModel = readCyclicDependencyModel(); + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + private VnfcDependencyModel readCyclicDependencyModel() { + + Vnfc a = new Vnfc("A","Active-Passive",null); + Vnfc b = new Vnfc("B","Active-Active",null); + Vnfc c = new Vnfc("C","Active-Active",null); + Vnfc d = new Vnfc("D","Active-Active",null); + Vnfc e = new Vnfc("E","Active-Active",null); + Vnfc f = new Vnfc("F","Active-Active",null); + Vnfc g = new Vnfc("G","Active-Active",null); + + Node aNode = new Node(a); + Node bNode = new Node(b); + Node cNode = new Node(c); + Node dNode = new Node(d); + Node eNode = new Node(e); + Node fNode = new Node(f); + Node gNode = new Node(g); + + bNode.addParent(a); + cNode.addParent(a); + cNode.addParent(b); + + bNode.addParent(d); + dNode.addParent(c); + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(aNode); + dependencies.add(bNode); + dependencies.add(cNode); + dependencies.add(dNode); + dependencies.add(eNode); + dependencies.add(fNode); + dependencies.add(gNode); + + return new VnfcDependencyModel(dependencies); + + } + + private SvcLogicContext prepareContextForComplexDependency() { + SvcLogicContext context = new SvcLogicContext(); + context.setAttribute("input.action-identifiers.vnf-id","1"); + context.setAttribute("vnf.type","vSCP"); + context.setAttribute("vnf.vnfcCount","7"); + + context.setAttribute("vnf.vnfc[0].name","A"); + context.setAttribute("vnf.vnfc[0].type","A"); + context.setAttribute("vnf.vnfc[0].vm_count","2"); + context.setAttribute("vnf.vnfc[0].vm[0].url","A1"); + context.setAttribute("vnf.vnfc[0].vm[1].url","A2"); + + context.setAttribute("vnf.vnfc[1].name","B"); + context.setAttribute("vnf.vnfc[1].type","B"); + context.setAttribute("vnf.vnfc[1].vm_count","5"); + context.setAttribute("vnf.vnfc[1].vm[0].url","B1"); + context.setAttribute("vnf.vnfc[1].vm[1].url","B2"); + context.setAttribute("vnf.vnfc[1].vm[2].url","B3"); + context.setAttribute("vnf.vnfc[1].vm[3].url","B4"); + context.setAttribute("vnf.vnfc[1].vm[4].url","B5"); + + context.setAttribute("vnf.vnfc[2].name","C"); + context.setAttribute("vnf.vnfc[2].type","C"); + context.setAttribute("vnf.vnfc[2].vm_count","4"); + context.setAttribute("vnf.vnfc[2].vm[0].url","C1"); + context.setAttribute("vnf.vnfc[2].vm[1].url","C2"); + context.setAttribute("vnf.vnfc[2].vm[2].url","C3"); + context.setAttribute("vnf.vnfc[2].vm[3].url","C4"); + + context.setAttribute("vnf.vnfc[3].name","D"); + context.setAttribute("vnf.vnfc[3].type","D"); + context.setAttribute("vnf.vnfc[3].vm_count","3"); + context.setAttribute("vnf.vnfc[3].vm[0].url","D1"); + context.setAttribute("vnf.vnfc[3].vm[1].url","D2"); + context.setAttribute("vnf.vnfc[3].vm[2].url","D3"); + + context.setAttribute("vnf.vnfc[4].name","E"); + context.setAttribute("vnf.vnfc[4].type","E"); + context.setAttribute("vnf.vnfc[4].vm_count","2"); + context.setAttribute("vnf.vnfc[4].vm[0].url","E1"); + context.setAttribute("vnf.vnfc[4].vm[1].url","E2"); + + context.setAttribute("vnf.vnfc[5].name","F"); + context.setAttribute("vnf.vnfc[5].type","F"); + context.setAttribute("vnf.vnfc[5].vm_count","1"); + context.setAttribute("vnf.vnfc[5].vm[0].url","F1"); + + context.setAttribute("vnf.vnfc[6].name","G"); + context.setAttribute("vnf.vnfc[6].type","G"); + context.setAttribute("vnf.vnfc[6].vm_count","1"); + context.setAttribute("vnf.vnfc[6].vm[0].url","G1"); + + + return context; + } + + private VnfcDependencyModel readComplexDependencyModel() { + Vnfc a = new Vnfc("A","Active-Passive",null); + Vnfc b = new Vnfc("B","Active-Active",null); + Vnfc c = new Vnfc("C","Active-Active",null); + Vnfc d = new Vnfc("D","Active-Active",null); + Vnfc e = new Vnfc("E","Active-Active",null); + Vnfc f = new Vnfc("F","Active-Active",null); + Vnfc g = new Vnfc("G","Active-Active",null); + + + Node aNode = new Node(a); + Node bNode = new Node(b); + Node cNode = new Node(c); + Node dNode = new Node(d); + Node eNode = new Node(e); + Node fNode = new Node(f); + Node gNode = new Node(g); + + bNode.addParent(a); + cNode.addParent(a); + + dNode.addParent(b); + eNode.addParent(b); + gNode.addParent(b); + + fNode.addParent(c); + + gNode.addParent(f); + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(aNode); + dependencies.add(bNode); + dependencies.add(cNode); + dependencies.add(dNode); + dependencies.add(eNode); + dependencies.add(fNode); + dependencies.add(gNode); + + return new VnfcDependencyModel(dependencies); + } + + private VnfcDependencyModel readDependencyModel() { + + Vnfc smp = new Vnfc("SMP","Active-Passive",null); + Vnfc be = new Vnfc("BE","Active-Active",null); + Vnfc fe = new Vnfc("FE","Active-Active",null); + + + Node smpNode = new Node(smp); + Node beNode = new Node(be); + Node feNode = new Node(fe); + + beNode.addParent(smp); + feNode.addParent(be); +// smpNode.addParent(fe); + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(smpNode); + dependencies.add(feNode); + dependencies.add(beNode); + + return new VnfcDependencyModel(dependencies); + } + + private Map<String, String> prepareParams() { + Map<String,String> params = new HashMap<>(); + params.put(Constants.DEPENDENCY_TYPE,"RESOURCE"); + params.put(Constants.FLOW_STRATEGY,"FORWARD"); + + params.put(Constants.VNF_TYPE,"vSCP"); + params.put(Constants.VNF_VERION,"1.00"); + return params; + } + + private SvcLogicContext prepareContext() { + SvcLogicContext context = new SvcLogicContext(); + context.setAttribute("input.action-identifiers.vnf-id","1"); + context.setAttribute("vnf.type","vSCP"); + context.setAttribute("vnf.vnfcCount","3"); + + context.setAttribute("vnf.vnfc[0].name","SMPname"); + context.setAttribute("vnf.vnfc[0].type","SMP"); + context.setAttribute("vnf.vnfc[0].vm_count","2"); + context.setAttribute("vnf.vnfc[0].vm[0].url","SMP_URL1"); + context.setAttribute("vnf.vnfc[0].vm[1].url","SMP_URL2"); + + context.setAttribute("vnf.vnfc[1].name","BEname"); + context.setAttribute("vnf.vnfc[1].type","BE"); + context.setAttribute("vnf.vnfc[1].vm_count","5"); + context.setAttribute("vnf.vnfc[1].vm[0].url","BE_URL1"); + context.setAttribute("vnf.vnfc[1].vm[1].url","BE_URL2"); + context.setAttribute("vnf.vnfc[1].vm[2].url","BE_URL3"); + context.setAttribute("vnf.vnfc[1].vm[3].url","BE_URL4"); + context.setAttribute("vnf.vnfc[1].vm[4].url","BE_URL5"); + + context.setAttribute("vnf.vnfc[2].name","FEname"); + context.setAttribute("vnf.vnfc[2].type","FE"); + context.setAttribute("vnf.vnfc[2].vm_count","2"); + context.setAttribute("vnf.vnfc[2].vm[0].url","FE_URL1"); + context.setAttribute("vnf.vnfc[2].vm[1].url","FE_URL2"); + + return context; + } + + @Test(expected = RuntimeException.class) + public void testMissingVnfcTypeInDependencyModel() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContext(); + context.setAttribute("vnf.vnfc[3].name","XEname"); + context.setAttribute("vnf.vnfc[3].type","XE"); + context.setAttribute("vnf.vnfc[3].vm_count","2"); + context.setAttribute("vnf.vnfc[3].vm[0].url","XE_URL1"); + context.setAttribute("vnf.vnfc[3].vm[1].url","XE_URL2"); + context.setAttribute("vnf.vnfcCount","4"); + + VnfcDependencyModel dependencyModel = readDependencyModel(); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + @Test(expected = RuntimeException.class) + public void testMissingMandatoryVnfcTypeInInventoryModel() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContext(); + VnfcDependencyModel dependencyModel = readDependencyModel(); + + Vnfc xe = new Vnfc("XE","Active-Active",null, true); + Node xeNode = new Node(xe); + dependencyModel.getDependencies().add(xeNode); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + @Test + public void testMissingOptionalVnfcTypeInInventoryModel() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContext(); + VnfcDependencyModel dependencyModel = readDependencyModel(); + + Vnfc xe = new Vnfc("XE","Active-Active",null, false); + Node xeNode = new Node(xe); + dependencyModel.getDependencies().add(xeNode); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } + + @Test + public void testMissingOptionalVnfcTypeInInventoryModelWithDependentChild() throws DependencyModelNotFound { + Map<String, String> params = prepareParams(); + SvcLogicContext context = prepareContext(); + context.setAttribute("vnf.vnfc[3].name","YEname"); + context.setAttribute("vnf.vnfc[3].type","YE"); + context.setAttribute("vnf.vnfc[3].vm_count","2"); + context.setAttribute("vnf.vnfc[3].vm[0].url","YE_URL1"); + context.setAttribute("vnf.vnfc[3].vm[1].url","YE_URL2"); + context.setAttribute("vnf.vnfcCount","4"); + + VnfcDependencyModel dependencyModel = readDependencyModel(); + + Vnfc xe = new Vnfc("XE","Active-Active",null, false); + Vnfc ye = new Vnfc("YE","Active-Active",null, true); + Node xeNode = new Node(xe); + Node yeNode = new Node(ye); + yeNode.addParent(xe); + + dependencyModel.getDependencies().add(yeNode); + dependencyModel.getDependencies().add(xeNode); + + PowerMockito.mockStatic(DependencyModelFactory.class); + DependencyManager dependencyManager = PowerMockito.mock(DependencyManager.class); + + PowerMockito.when(DependencyModelFactory.createDependencyManager()).thenReturn(dependencyManager); + PowerMockito.when(dependencyManager.getVnfcDependencyModel(( + DependencyModelIdentifier) Matchers.any(),(DependencyTypes) Matchers.any())) + .thenReturn(dependencyModel); + + VnfExecutionFlow vnfExecutionFlow = new VnfExecutionFlowImpl(); + vnfExecutionFlow.getVnfExecutionFlowData(params,context); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/.gitignore b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.core.resources.prefs b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..cdfe4f1b6 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/<project>=UTF-8 diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.m2e.core.prefs b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/.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-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml b/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml new file mode 100644 index 000000000..20dbc6b46 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/pom.xml @@ -0,0 +1,78 @@ +<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-dg-shared</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-dg-dependency-model</artifactId> + <packaging>jar</packaging> + + <name>appc-dg-dependency-model</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-yaml</artifactId> + <version>2.3.2</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>1.6.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-domain-model-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyManager.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyManager.java new file mode 100644 index 000000000..5b5b3451b --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyManager.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.dg.dependencymanager; + +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.DependencyTypes; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; + +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; + +public interface DependencyManager { + VnfcDependencyModel getVnfcDependencyModel(DependencyModelIdentifier modelIdentifier, DependencyTypes dependencyType) throws InvalidDependencyModel, DependencyModelNotFound; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyType.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyType.java new file mode 100644 index 000000000..06a29cd1d --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/DependencyType.java @@ -0,0 +1,32 @@ +/*- + * ============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.dg.dependencymanager; + +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; + +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; + +public interface DependencyType { + VnfcDependencyModel getVnfcDependencyModel(DependencyModelIdentifier modelIdentifier) throws InvalidDependencyModel, DependencyModelNotFound; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/exception/DependencyModelNotFound.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/exception/DependencyModelNotFound.java new file mode 100644 index 000000000..521e0edb3 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/exception/DependencyModelNotFound.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.dg.dependencymanager.exception; + + +public class DependencyModelNotFound extends Exception { + public DependencyModelNotFound(String message){ + super(message); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/helper/DependencyModelParser.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/helper/DependencyModelParser.java new file mode 100644 index 000000000..397042ecd --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/helper/DependencyModelParser.java @@ -0,0 +1,183 @@ +/*- + * ============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.dg.dependencymanager.helper; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import org.apache.commons.lang3.StringUtils; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.Node; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.openecomp.appc.domainmodel.Vnfc; + +import java.io.IOException; +import java.util.*; + + +public class DependencyModelParser { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(DependencyModelParser.class); + private static Map<String, String> dependencyMap; + private static final String PROPERTIES = "properties"; + private static final String ACTIVE_ACTIVE = "Active-Active"; + private static final String ACTIVE_PASSIVE = "Active-Passive"; + private static final String HIGH_AVAILABLITY = "high_availablity"; + private static final String MANDATORY = "mandatory"; + private static final String TOPOLOGY_TEMPLATE = "topology_template"; + + static { + Map<String, String> dependencyTypeMappingMap =new HashMap<>(); + dependencyTypeMappingMap.put("geo-activeactive", ACTIVE_ACTIVE); + dependencyTypeMappingMap.put("geo-activestandby", ACTIVE_PASSIVE); + dependencyTypeMappingMap.put("local-activeactive", ACTIVE_ACTIVE); + dependencyTypeMappingMap.put("local-activestandby", ACTIVE_PASSIVE); + dependencyMap = Collections.unmodifiableMap(dependencyTypeMappingMap); + } + + public VnfcDependencyModel generateDependencyModel(String vnfModel,String vnfType) { + Set<Node<Vnfc>> dependencies = new HashSet<>(); + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + boolean mandatory; + String resilienceType; + String prefix = "org.openecomp.resource.vfc."+vnfType+".abstract.nodes."; + try { + ObjectNode root = (ObjectNode) mapper.readTree(vnfModel); + logger.debug("VNF Model after parsing: " + root); + + if(root.get(TOPOLOGY_TEMPLATE) == null || root.get(TOPOLOGY_TEMPLATE).get("node_templates") == null) { + throw new InvalidDependencyModel("Dependency model is missing 'topology_template' or 'node_templates' elements"); + } + + JsonNode topologyTemplateNode = root.get(TOPOLOGY_TEMPLATE); + JsonNode nodeTemplateNode = topologyTemplateNode.get("node_templates"); + Iterator<Map.Entry<String, JsonNode>> itretor = nodeTemplateNode.fields(); + for (JsonNode yamlNode : nodeTemplateNode) { + logger.debug("Processing node: " + yamlNode); + String vnfcType = itretor.next().getKey(); + String type = yamlNode.get("type").textValue(); + type = type.substring(0,type.lastIndexOf(".")+1); + if(type.concat(vnfcType).toLowerCase().startsWith(prefix.concat(vnfcType).toLowerCase())) { + + if(yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY) == null || yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY).asText().isEmpty()) { + resilienceType = ACTIVE_ACTIVE; + }else { + resilienceType = dependencyMap.get(yamlNode.get(PROPERTIES).findValue(HIGH_AVAILABLITY).textValue()); + } + + if(yamlNode.get(PROPERTIES).findValue(MANDATORY) == null || yamlNode.get(PROPERTIES).findValue(MANDATORY).asText().isEmpty()) { + mandatory = false; + }else { + mandatory = yamlNode.get(PROPERTIES).findValue(MANDATORY).booleanValue(); + } + String[] parentList = getDependencyArray(yamlNode); + Node<Vnfc> vnfcNode = getNode(dependencies, vnfcType); + if (vnfcNode != null) { + logger.debug("Dependency node already exists for vnfc Type: " + vnfcType); + if (StringUtils.isEmpty(vnfcNode.getChild().getResilienceType())) { + logger.debug("Updating resilience type, dependencies and mandatory attribute for VNFC type: " + vnfcType); + vnfcNode.getChild().setResilienceType(resilienceType); + if (parentList != null && parentList.length > 0) { + addDependencies(dependencies, vnfcNode, parentList); + } + vnfcNode.getChild().setMandatory(mandatory); + } + + } else { + logger.debug("Creating dependency node for : " + vnfcType); + vnfcNode = new Node<>(new Vnfc(vnfcType, resilienceType, null, mandatory)); + if (parentList != null && parentList.length > 0) + addDependencies(dependencies, vnfcNode, parentList); + logger.debug("Adding VNFC to dependency model : " + vnfcNode); + dependencies.add(vnfcNode); + } + } + } + } catch (IOException e) { + logger.error("Error parsing dependency model : " + vnfModel); + logger.error("Error message : " + e); + throw new InvalidDependencyModel("Error parsing dependency model. " + e.getMessage()); + } + return new VnfcDependencyModel(dependencies); + } + + private void addDependencies(Set<Node<Vnfc>> nodes, Node node, String[] parentList) { + for (String type : parentList) { + String parentType = getVnfcType(type); + Node<Vnfc> parentNode = getNode(nodes, parentType); + if (parentNode != null) { + logger.debug("VNFC already exists for VNFC type: " + parentType + ". Adding it to parent list "); + node.addParent(parentNode.getChild()); + } else { + logger.debug("VNFC does not exist for VNFC type: " + parentType + ". Creating new VNFC "); + parentNode = new Node<>(new Vnfc(parentType, null)); + node.addParent(parentNode.getChild()); + logger.debug("Adding VNFC to dependency model : " + parentNode); + nodes.add(parentNode); + } + } + } + + private String[] getDependencyArray(JsonNode node) { + JsonNode requirementsNode = node.get("requirements"); + List<String> dependencyList = new ArrayList(); + if(requirementsNode!=null) { + for (JsonNode internalNode : requirementsNode) { + if (nodeNullCheck(internalNode) &&"tosca.capabilities.Node".equalsIgnoreCase(internalNode.get("capability").asText()) + && "tosca.relationships.DependsOn".equalsIgnoreCase(internalNode.get("relationship").asText())) { + if(internalNode.get("node") != null) { + dependencyList.add(internalNode.get("node").asText()); + }else{ + throw new InvalidDependencyModel("Error parsing dependency model. " + "Dependent Node not found for "+ node.get("type")); + } + } + } + return dependencyList.toArray(new String[0]); + }else{ + return new String[0]; + } + } + + private boolean nodeNullCheck(JsonNode internalNode) { + return internalNode.get("dependency") != null && internalNode.get("capability") != null && internalNode.get("relationship") != null; + } + + private Node<Vnfc> getNode(Set<Node<Vnfc>> nodes, String vnfcType) { + Iterator itr = nodes.iterator(); + Node<Vnfc> node; + while (itr.hasNext()) { + node = (Node<Vnfc>) itr.next(); + if (node.getChild().getVnfcType().equalsIgnoreCase(vnfcType)) { + return node; + } + } + return null; + } + + private String getVnfcType(String type) { + return type.substring(type.lastIndexOf('.') + 1, type.length()); + } + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyManagerImpl.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyManagerImpl.java new file mode 100644 index 000000000..758d5ee7e --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyManagerImpl.java @@ -0,0 +1,71 @@ +/*- + * ============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.dg.dependencymanager.impl; + +import org.openecomp.appc.dg.dependencymanager.DependencyManager; +import org.openecomp.appc.dg.dependencymanager.DependencyType; +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.DependencyTypes; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; + +import org.openecomp.appc.cache.MetadataCache; +import org.openecomp.appc.cache.impl.MetadataCacheFactory; +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +public class DependencyManagerImpl implements DependencyManager { + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(DependencyManagerImpl.class); + + MetadataCache<DependencyModelIdentifier,VnfcDependencyModel> cache; + + DependencyManagerImpl(){ + cache = MetadataCacheFactory.getInstance().getMetadataCache(); + } + + public VnfcDependencyModel getVnfcDependencyModel(DependencyModelIdentifier modelIdentifier,DependencyTypes dependencyType) throws InvalidDependencyModel, DependencyModelNotFound { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfcDependencyModel with DependencyModelIdentifier = "+ modelIdentifier + + " , DependencyTypes = " + dependencyType); + } + VnfcDependencyModel dependencyModel = cache.getObject(modelIdentifier); + if(dependencyModel == null){ + logger.debug("Dependency model not found in cache, creating strategy for reading it"); + DependencyType strategy = getStrategy(dependencyType); + dependencyModel = strategy.getVnfcDependencyModel(modelIdentifier); + } + if (logger.isTraceEnabled()) { + logger.trace("Returning getVnfcDependencyModel with dependency model = "+ dependencyModel); + } + return dependencyModel; + } + + private DependencyType getStrategy(DependencyTypes dependencyType) { + switch (dependencyType){ + case RESOURCE: + return new ResourceDependency(); + } + return null; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyModelFactory.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyModelFactory.java new file mode 100644 index 000000000..87bdd32fa --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/DependencyModelFactory.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.dg.dependencymanager.impl; + +import org.openecomp.appc.dg.dependencymanager.DependencyManager; + + +public class DependencyModelFactory { + + private static class ReferenceHolder{ + private static final DependencyManagerImpl INSTANCE = new DependencyManagerImpl(); + } + + public static DependencyManager createDependencyManager(){ + return ReferenceHolder.INSTANCE; + } + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/ResourceDependency.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/ResourceDependency.java new file mode 100644 index 000000000..0cb9eebb4 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/dependencymanager/impl/ResourceDependency.java @@ -0,0 +1,83 @@ +/*- + * ============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.dg.dependencymanager.impl; + +import org.openecomp.appc.metadata.MetadataService; +import org.openecomp.appc.metadata.objects.DependencyModelIdentifier; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import org.openecomp.appc.dg.dependencymanager.DependencyType; +import org.openecomp.appc.dg.dependencymanager.exception.DependencyModelNotFound; +import org.openecomp.appc.dg.dependencymanager.helper.DependencyModelParser; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + + +public class ResourceDependency implements DependencyType{ + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(ResourceDependency.class); + + + private MetadataService metadataService; + + public ResourceDependency(){ + getMetadataServiceRef(); + } + + private void getMetadataServiceRef() { + BundleContext bctx = FrameworkUtil.getBundle(MetadataService.class).getBundleContext(); + // Get MetadataService reference + ServiceReference sref = bctx.getServiceReference(MetadataService.class.getName()); + if (sref != null) { + logger.info("MetadataService from bundlecontext"); + metadataService = (MetadataService) bctx.getService(sref); + + } else { + logger.info("MetadataService error from bundlecontext"); + logger.warn("Cannot find service reference for org.openecomp.appc.metadata.MetadataService"); + } + } + + public void setMetadataService(MetadataService metadataService) { + this.metadataService = metadataService; + } + + public VnfcDependencyModel getVnfcDependencyModel(DependencyModelIdentifier modelIdentifier) throws InvalidDependencyModel, DependencyModelNotFound { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getVnfcDependencyModel with DependencyModelIdentifier = "+ modelIdentifier); + } + String vnfModel = metadataService.getVnfModel(modelIdentifier); + if(vnfModel ==null){ + logger.debug("Vnf model not found from metadata service"); + throw new DependencyModelNotFound("Invalid or Empty VNF Model"); + } + if (logger.isTraceEnabled()) { + logger.trace("Building dependency model for Vnf Model : " + vnfModel); + } + DependencyModelParser modelParser = new DependencyModelParser(); + return modelParser.generateDependencyModel(vnfModel,modelIdentifier.getVnfType()); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowBuilder.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowBuilder.java new file mode 100644 index 000000000..6b87e6621 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowBuilder.java @@ -0,0 +1,31 @@ +/*- + * ============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.dg.flowbuilder; + +import org.openecomp.appc.dg.objects.InventoryModel; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.openecomp.appc.dg.objects.VnfcFlowModel; + + +public interface FlowBuilder { + VnfcFlowModel buildFlowModel(VnfcDependencyModel dependencyModel,InventoryModel inventoryModel); +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowStrategy.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowStrategy.java new file mode 100644 index 000000000..3c3488f70 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/FlowStrategy.java @@ -0,0 +1,32 @@ +/*- + * ============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.dg.flowbuilder; + +import org.openecomp.appc.dg.objects.InventoryModel; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.openecomp.appc.dg.objects.VnfcFlowModel; + + +public interface FlowStrategy { + + VnfcFlowModel buildFlowModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel); +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/exception/InvalidDependencyModel.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/exception/InvalidDependencyModel.java new file mode 100644 index 000000000..8bec80a47 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/exception/InvalidDependencyModel.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.dg.flowbuilder.exception; + + +public class InvalidDependencyModel extends RuntimeException { + public InvalidDependencyModel(String message){ + super(message); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/helper/Graph.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/helper/Graph.java new file mode 100644 index 000000000..b9115187c --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/helper/Graph.java @@ -0,0 +1,64 @@ +/*- + * ============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.dg.flowbuilder.helper; + +import java.util.*; + +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; + + +public class Graph<T> { + private int size; + private List<T> vertexList; + + private int[][] dependencyMatrix; + + public Graph(int size){ + this.size =size; + vertexList = new ArrayList<>(); + dependencyMatrix = new int[size][size]; + } + + public void addVertex(T vertex){ + vertexList.add(vertex); + } + + public int getIndex(T vertex){ + return vertexList.indexOf(vertex); + } + + public void addEdge(T vertex1,T vertex2){ + dependencyMatrix[vertexList.indexOf(vertex1)][vertexList.indexOf(vertex2)] = 1; + } + + public int[][] getDependencyMatrix() { + return dependencyMatrix; + } + + public int getSize() { + return size; + } + + public List<T> getVertexList() { + return vertexList; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/AbstractFlowStrategy.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/AbstractFlowStrategy.java new file mode 100644 index 000000000..15ff20083 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/AbstractFlowStrategy.java @@ -0,0 +1,133 @@ +/*- + * ============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.dg.flowbuilder.impl; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.openecomp.appc.dg.flowbuilder.FlowStrategy; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.flowbuilder.helper.Graph; +import org.openecomp.appc.dg.objects.*; +import org.openecomp.appc.domainmodel.Vnfc; + + +public abstract class AbstractFlowStrategy implements FlowStrategy { + + protected Graph<Vnfc> graph; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(AbstractFlowStrategy.class); + + public VnfcFlowModel buildFlowModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) { + if(logger.isTraceEnabled()){ + logger.trace("Entering into buildFlowModel with dependency model = " + dependencyModel + + "inventory model = " +inventoryModel); + } + + if(dependencyModel == null + || dependencyModel.getDependencies() ==null + || dependencyModel.getDependencies().size() ==0){ + logger.debug("Dependency model not available, building flow model with sequence"); + throw new InvalidDependencyModel("Dependency model either null or does not contain any dependency"); + } + + VnfcFlowModel flowModel = buildFlowModel(dependencyModel); + if(logger.isDebugEnabled()){ + logger.debug("Flow Model without instance data: \n" + flowModel); + } + + logger.info("Populating flow model with A&AI data"); + populateFlowModel(flowModel,inventoryModel); + if(logger.isDebugEnabled()){ + logger.debug("Flow Model with instance data: \n" + flowModel); + } + + return flowModel; + } + + private void populateFlowModel(VnfcFlowModel flowModel, InventoryModel inventoryModel) { + Iterator<List<Vnfc>> flowIterator = null; + + for(Vnfc vnfcFromInventory:inventoryModel.getVnf().getVnfcs()){ + flowIterator = flowModel.getModelIterator(); + String vnfcType = vnfcFromInventory.getVnfcType(); + while (flowIterator.hasNext()){ + for(Vnfc vnfcFromFlowModel:flowIterator.next() ){ + if(vnfcType.equalsIgnoreCase(vnfcFromFlowModel.getVnfcType())){ + vnfcFromFlowModel.setVnfcName(vnfcFromInventory.getVnfcName()); + vnfcFromFlowModel.addVms(vnfcFromInventory.getVserverList()); + } + } + } + + } + + } + + private VnfcFlowModel buildFlowModel(VnfcDependencyModel dependencyModel) throws InvalidDependencyModel { + Set<Node<Vnfc>> dependencies = dependencyModel.getDependencies(); + graph = new Graph(dependencies.size()); + + for(Node<Vnfc> node:dependencies){ + graph.addVertex(node.getChild()); + } + + for(Node node:dependencies){ + Vnfc child = (Vnfc)node.getChild(); + List<Vnfc> parents = node.getParents(); + for(Vnfc parent:parents){ + graph.addEdge(child,parent); + } + } + List<List<Vnfc>> dependencyList = orderDependencies(); + + VnfcFlowModel.VnfcFlowModelBuilder builder = new VnfcFlowModel.VnfcFlowModelBuilder(); + int count=0; + int flowModelSize = 0; + for(List<Vnfc> vnfcList:dependencyList){ + builder.addMetadata(count,vnfcList); + flowModelSize += vnfcList.size(); + count++; + } + if(flowModelSize != dependencies.size()){ + throw new InvalidDependencyModel("Cycle detected in the VNFC dependencies"); + } + + return builder.build(); + } + + protected abstract List<List<Vnfc>> orderDependencies(); + + /*private VnfcFlowModel buildFlowModelWithoutSequence(InventoryModel inventoryModel) { + VnfcFlowModel.VnfcFlowModelBuilder builder = new VnfcFlowModel.VnfcFlowModelBuilder(); + + for(Vnfc vnfc:inventoryModel.getVnf().getVnfcs()){ + builder = builder.addMetadata(0,vnfc); + } + + return builder.build(); + }*/ +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderFactory.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderFactory.java new file mode 100644 index 000000000..7b9759852 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderFactory.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.dg.flowbuilder.impl; + +import org.openecomp.appc.dg.flowbuilder.FlowBuilder; +import org.openecomp.appc.dg.objects.FlowStrategies; + + +public class FlowBuilderFactory { + private static class ReferenceHolder{ + private static final FlowBuilderFactory FACTORY = new FlowBuilderFactory(); + } + + public static FlowBuilderFactory getInstance(){ + return ReferenceHolder.FACTORY; + } + + public FlowBuilder getFlowBuilder(FlowStrategies flowStrategy){ + + switch (flowStrategy){ + case FORWARD: + return new FlowBuilderImpl(new ForwardFlowStrategy()); + case REVERSE: + return new FlowBuilderImpl(new ReverseFlowStrategy()); + } + return null; + + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderImpl.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderImpl.java new file mode 100644 index 000000000..80bd3eec2 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/FlowBuilderImpl.java @@ -0,0 +1,49 @@ +/*- + * ============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.dg.flowbuilder.impl; + +import org.openecomp.appc.dg.flowbuilder.FlowBuilder; +import org.openecomp.appc.dg.flowbuilder.FlowStrategy; +import org.openecomp.appc.dg.objects.InventoryModel; +import org.openecomp.appc.dg.objects.VnfcDependencyModel; +import org.openecomp.appc.dg.objects.VnfcFlowModel; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + + +public class FlowBuilderImpl implements FlowBuilder { + + + + private FlowStrategy strategy; + + FlowBuilderImpl(FlowStrategy strategy){ + this.strategy = strategy; + } + + public VnfcFlowModel buildFlowModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) { + return strategy.buildFlowModel(dependencyModel, inventoryModel); + } + + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ForwardFlowStrategy.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ForwardFlowStrategy.java new file mode 100644 index 000000000..486e942a7 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ForwardFlowStrategy.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.dg.flowbuilder.impl; + +import java.util.*; + +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.domainmodel.Vnfc; + + +public class ForwardFlowStrategy extends AbstractFlowStrategy { + @Override + protected List<List<Vnfc>> orderDependencies() { + ArrayList<List<Vnfc>> arrayList = new ArrayList<>(); + + Queue<Vnfc> queue1 = new LinkedList(); + Set<Vnfc> queue2 = new LinkedHashSet<>(); + + Set<Vnfc> uniqueElementSet = new HashSet<>(); + Set<Vnfc> duplicateElementSet = new HashSet<>(); + + // identifying independent nodes in queue1 + for(int rowIndex=0;rowIndex<graph.getSize();rowIndex++){ + Integer sum = 0; + for(int colIndex=0;colIndex<graph.getSize();colIndex++){ + sum+= graph.getDependencyMatrix()[rowIndex][colIndex]; + } + if(sum==0){ + Vnfc vnfc = graph.getVertexList().get(rowIndex); + queue1.add(vnfc); + } + } + if(queue1.isEmpty()){ + throw new InvalidDependencyModel("There seems to be no Root/Independent node for Vnfc dependencies"); + } + arrayList.add((List<Vnfc>)queue1); + queue1 = new LinkedList<>(queue1); + + boolean flag = true; + + while(flag){ + // iterating over queue1 and for each node in it finding all dependent nodes and putting them on queue2 + while(!queue1.isEmpty()){ + Vnfc listItem = queue1.remove(); + Integer colIndex = graph.getIndex(listItem); + for(Integer index =0;index<graph.getSize();index++){ + Integer value = graph.getDependencyMatrix()[index][colIndex]; + if(value ==1){ + Vnfc vnfc = graph.getVertexList().get(index); + queue2.add(vnfc); + } + } + } + for(Vnfc vnfc:queue2){ + if(!uniqueElementSet.add(vnfc)){ + duplicateElementSet.add(vnfc); + } + } + if(queue2.isEmpty()){ + flag= false; // empty queue2 indicates that all leaf nodes have been identified, i.e. stop the iteration + } + else{ + arrayList.add(new ArrayList<Vnfc>(queue2)); + if(arrayList.size()>graph.getSize()){ + // dependency list cannot be larger than total number of nodes + // if it happens indicates cycle in the dependency + throw new InvalidDependencyModel("Cycle detected in the VNFC dependencies"); + } + queue1.addAll(queue2); + queue2 = new LinkedHashSet<>(); + } + } + // If any node depends on multiple nodes present in different execution sequence, + // its execution should happen on the higher order, removing its presence on lower execution sequence + if(!duplicateElementSet.isEmpty()){ + for(Vnfc vnfc:duplicateElementSet){ + boolean firstOccurrence= true; + for(int i=arrayList.size()-1;i>=0;i--){ + List<Vnfc> list = arrayList.get(i); + if(list.contains(vnfc)){ + if(firstOccurrence){ + firstOccurrence =false; + continue; + } + else{ + list.remove(vnfc); + } + } + + } + } + } + return arrayList; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ReverseFlowStrategy.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ReverseFlowStrategy.java new file mode 100644 index 000000000..2ef051da1 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/flowbuilder/impl/ReverseFlowStrategy.java @@ -0,0 +1,115 @@ +/*- + * ============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.dg.flowbuilder.impl; + +import java.util.*; + +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.domainmodel.Vnfc; + + +public class ReverseFlowStrategy extends AbstractFlowStrategy { + + @Override + protected List<List<Vnfc>> orderDependencies() { + ArrayList<List<Vnfc>> arrayList = new ArrayList<>(); + + Queue<Vnfc> queue1 = new LinkedList(); + Set<Vnfc> queue2 = new LinkedHashSet<>(); + + Set<Vnfc> uniqueElementSet = new HashSet<>(); + Set<Vnfc> duplicateElementSet = new HashSet<>(); + + // identifying independent nodes in queue1 + for(int colIndex=0;colIndex<graph.getSize();colIndex++){ + Integer sum = 0; + for(int rowIndex=0;rowIndex<graph.getSize();rowIndex++){ + sum+= graph.getDependencyMatrix()[rowIndex][colIndex]; + } + if(sum==0){ + Vnfc vnfc = graph.getVertexList().get(colIndex); + queue1.add(vnfc); + } + } + if(queue1.isEmpty()){ + throw new InvalidDependencyModel("There seems to be no leaf node for Vnfc dependencies"); + } + arrayList.add((List<Vnfc>)queue1); + queue1 = new LinkedList<>(queue1); + + boolean flag = true; + + while(flag){ + // iterating over queue1 and for each node in it finding all dependent nodes and putting them on queue2 + while(!queue1.isEmpty()){ + Vnfc listItem = queue1.remove(); + Integer rowIndex = graph.getIndex(listItem); + for(Integer index =0;index<graph.getSize();index++){ + Integer value = graph.getDependencyMatrix()[rowIndex][index]; + if(value ==1){ + Vnfc vnfc = graph.getVertexList().get(index); + queue2.add(vnfc); + } + } + } + for(Vnfc vnfc:queue2){ + if(!uniqueElementSet.add(vnfc)){ + duplicateElementSet.add(vnfc); + } + } + if(queue2.isEmpty()){ + flag= false; // empty queue2 indicates that all leaf nodes have been identified, i.e. stop the iteration + } + else{ + arrayList.add(new ArrayList<Vnfc>(queue2)); + if(arrayList.size()>graph.getSize()){ + // dependency list cannot be larger than total number of nodes + // if it happens indicates cycle in the dependency + throw new InvalidDependencyModel("Cycle detected in the VNFC dependencies"); + } + queue1.addAll(queue2); + queue2 = new LinkedHashSet<>(); + } + } + // If any node depends on multiple nodes present in different execution sequence, + // its execution should happen on the higher order, removing its presence on lower execution sequence + if(!duplicateElementSet.isEmpty()){ + for(Vnfc vnfc:duplicateElementSet){ + boolean firstOccurrence= true; + for(int i=0;i<arrayList.size();i++){ + List<Vnfc> list = arrayList.get(i); + if(list.contains(vnfc)){ + if(firstOccurrence){ + firstOccurrence =false; + list.remove(vnfc); + } + else{ + continue; + } + } + + } + } + } + return arrayList; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/DependencyTypes.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/DependencyTypes.java new file mode 100644 index 000000000..e8b8c2591 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/DependencyTypes.java @@ -0,0 +1,36 @@ +/*- + * ============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.dg.objects; + + +public enum DependencyTypes { + RESOURCE; + + public static DependencyTypes findByString(String dependencyTypeStr){ + for(DependencyTypes dependencyType : DependencyTypes.values()){ + if(dependencyType.name().equalsIgnoreCase(dependencyTypeStr)){ + return dependencyType; + } + } + return null; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/FlowStrategies.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/FlowStrategies.java new file mode 100644 index 000000000..8c3126bb5 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/FlowStrategies.java @@ -0,0 +1,36 @@ +/*- + * ============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.dg.objects; + + +public enum FlowStrategies { + FORWARD,REVERSE; + + public static FlowStrategies findByString(String flowStrategyStr){ + for(FlowStrategies flowStrategy:FlowStrategies.values()){ + if(flowStrategy.name().equalsIgnoreCase(flowStrategyStr)){ + return flowStrategy; + } + } + return null; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/InventoryModel.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/InventoryModel.java new file mode 100644 index 000000000..ffd3a35ba --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/InventoryModel.java @@ -0,0 +1,43 @@ +/*- + * ============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.dg.objects; + +import org.openecomp.appc.domainmodel.Vnf; + + +public class InventoryModel { + + private Vnf vnf; + + public InventoryModel(Vnf vnf){ + this.vnf= vnf; + } + + public Vnf getVnf() { + return vnf; + } + + @Override + public String toString() { + return "InventoryModel = " + vnf.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/Node.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/Node.java new file mode 100644 index 000000000..a751504b8 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/Node.java @@ -0,0 +1,74 @@ +/*- + * ============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.dg.objects; + +import java.util.LinkedList; +import java.util.List; + + +public class Node<T> { + T child; + List<T> parents; + + @Override + public int hashCode(){ + return child.hashCode(); + } + + @Override + public boolean equals(Object object){ + if(object == null){ + return false; + } + if(!(object instanceof Node)){ + return false; + } + Node node = (Node)object; + return this.child.equals(node.getChild()); + } + + public Node(T child){ + this.child = child; + this.parents = new LinkedList<>(); + } + + public T getChild() { + return child; + } + + public List<T> getParents() { + return parents; + } + + public void addParent(T parent){ + this.parents.add(parent); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("Node : child = " + child + " , parents = "); + for(T parent:parents){ + stringBuilder.append(parent).append(","); + } + return stringBuilder.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcDependencyModel.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcDependencyModel.java new file mode 100644 index 000000000..12b5c15a5 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcDependencyModel.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.dg.objects; + +import java.util.Set; + +import org.openecomp.appc.domainmodel.Vnfc; + + +public class VnfcDependencyModel { + private Set<Node<Vnfc>> dependencies; + + public VnfcDependencyModel(Set<Node<Vnfc>> dependencies){ + this.dependencies = dependencies; + } + + public Set<Node<Vnfc>> getDependencies() { + return dependencies; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("dependencies = "); + for(Node node:dependencies){ + stringBuilder.append(node.toString()).append(", "); + } + return super.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcFlowModel.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcFlowModel.java new file mode 100644 index 000000000..ef3934162 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/main/java/org/openecomp/appc/dg/objects/VnfcFlowModel.java @@ -0,0 +1,89 @@ +/*- + * ============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.dg.objects; + +import java.util.*; + +import org.openecomp.appc.domainmodel.Vnfc; + + +public class VnfcFlowModel { + private Map<Integer,List<Vnfc>> flowModelMap; + + private VnfcFlowModel(VnfcFlowModelBuilder builder){ + this.flowModelMap = builder.map; + + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("Flow Model : "); + Iterator<List<Vnfc>> iterator = getModelIterator(); + while(iterator.hasNext()){ + for(Vnfc vnfc:iterator.next()){ + stringBuilder.append(vnfc.toString()).append(", \n"); + } + } + + return stringBuilder.toString(); + } + + public Iterator<List<Vnfc>> getModelIterator(){ + return flowModelMap.values().iterator(); + } + + public static class VnfcFlowModelBuilder{ + + Map<Integer,List<Vnfc>> map; + + public VnfcFlowModelBuilder(){ + map = new HashMap<>(); + } + + public VnfcFlowModelBuilder addMetadata(Integer index,Vnfc vnfc){ + List<Vnfc> vnfcList = this.map.get(index); + if(vnfcList == null){ + vnfcList = new LinkedList<>(); + map.put(index,vnfcList); + } + vnfcList.add(vnfc); + return this; + } + + public VnfcFlowModelBuilder addMetadata(Integer index,List<Vnfc> vnfcs){ + List<Vnfc> vnfcList = this.map.get(index); + if(vnfcList == null){ + vnfcList = new LinkedList<>(); + map.put(index,vnfcList); + } + vnfcList.addAll(vnfcs); + return this; + } + + public VnfcFlowModel build(){ + return new VnfcFlowModel(this); + } + + } + + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/openecomp/appc/dg/flowbuilder/TestFlowBuilder.java b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/openecomp/appc/dg/flowbuilder/TestFlowBuilder.java new file mode 100644 index 000000000..c6b36da86 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-dependency-model/src/test/java/org/openecomp/appc/dg/flowbuilder/TestFlowBuilder.java @@ -0,0 +1,329 @@ +/*- + * ============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.dg.flowbuilder; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.dg.flowbuilder.FlowBuilder; +import org.openecomp.appc.dg.flowbuilder.exception.InvalidDependencyModel; +import org.openecomp.appc.dg.flowbuilder.impl.FlowBuilderFactory; +import org.openecomp.appc.dg.objects.*; +import org.openecomp.appc.domainmodel.Vnf; +import org.openecomp.appc.domainmodel.Vnfc; +import org.openecomp.appc.domainmodel.Vserver; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +public class TestFlowBuilder { + + @Test + public void testForwardFlowBuilder(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.FORWARD); + VnfcDependencyModel dependencyModel = readDependencyModel(); + InventoryModel inventoryModel = readInventoryModel(); + VnfcFlowModel flowModel = builder.buildFlowModel(dependencyModel,inventoryModel); + Iterator<List<Vnfc>> itr = flowModel.getModelIterator(); + + List<Vnfc> list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("SMP","Active-Passive","SMP_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("BE","Active-Active","BE_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("FE","Active-Active","FE_Name"))); + } + + @Test + public void testReverseFlowBuilder(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.REVERSE); + VnfcDependencyModel dependencyModel = readDependencyModel(); + InventoryModel inventoryModel = readInventoryModel(); + VnfcFlowModel flowModel = builder.buildFlowModel(dependencyModel,inventoryModel); + Iterator<List<Vnfc>> itr = flowModel.getModelIterator(); + + List<Vnfc> list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("FE","Active-Active","FE_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("BE","Active-Active","BE_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("SMP","Active-Passive","SMP_Name"))); + } + + @Test + public void testComplexFlowBuilderForward(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.FORWARD); + VnfcDependencyModel dependencyModel = readComplexDependencyModel(); + InventoryModel inventoryModel = readComplexInventoryModel(); + VnfcFlowModel flowModel = builder.buildFlowModel(dependencyModel,inventoryModel); + Iterator<List<Vnfc>> itr = flowModel.getModelIterator(); + + List<Vnfc> list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("A","Active-Active","A_Name"))); + Assert.assertTrue(list.contains(new Vnfc("E","Active-Active","E_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("B","Active-Active","B_Name"))); + Assert.assertTrue(list.contains(new Vnfc("C","Active-Active","C_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("D","Active-Active","D_Name"))); + Assert.assertTrue(list.contains(new Vnfc("F","Active-Active","F_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("G","Active-Active","G_Name"))); + + } + + @Test + public void testComplexFlowBuilderReverse(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.REVERSE); + VnfcDependencyModel dependencyModel = readComplexDependencyModel(); + InventoryModel inventoryModel = readComplexInventoryModel(); + VnfcFlowModel flowModel = builder.buildFlowModel(dependencyModel,inventoryModel); + Iterator<List<Vnfc>> itr = flowModel.getModelIterator(); + + List<Vnfc> list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("D","Active-Active","D_Name"))); + + Assert.assertTrue(list.contains(new Vnfc("G","Active-Active","G_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("B","Active-Active","B_Name"))); + Assert.assertTrue(list.contains(new Vnfc("F","Active-Active","F_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("C","Active-Active","C_Name"))); + + list = itr.next(); + Assert.assertTrue(list.contains(new Vnfc("E","Active-Active","E_Name"))); + Assert.assertTrue(list.contains(new Vnfc("A","Active-Active","A_Name"))); + + } + + @Test(expected = InvalidDependencyModel.class) + public void testCyclicBuilder(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.FORWARD); + VnfcDependencyModel dependencyModel = readCyclicDependencyModel(); + InventoryModel inventoryModel = readInventoryModel(); + builder.buildFlowModel(dependencyModel,inventoryModel); + } + + @Test(expected = InvalidDependencyModel.class) + public void testCyclicBuilderWithRootNode(){ + FlowBuilder builder = FlowBuilderFactory.getInstance().getFlowBuilder(FlowStrategies.FORWARD); + VnfcDependencyModel dependencyModel = readCyclicDependencyModelWithRootNode(); + InventoryModel inventoryModel = readInventoryModel(); + builder.buildFlowModel(dependencyModel,inventoryModel); + } + + private VnfcDependencyModel readCyclicDependencyModelWithRootNode() { + Vnfc a = new Vnfc("A","Active-Passive",null); + Vnfc b = new Vnfc("B","Active-Active",null); + Vnfc c = new Vnfc("C","Active-Active",null); + + + Node aNode = new Node(a); + Node bNode = new Node(b); + Node cNode = new Node(c); + + bNode.addParent(c); + cNode.addParent(b); + + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(aNode); + dependencies.add(bNode); + dependencies.add(cNode); + + return new VnfcDependencyModel(dependencies); + } + + private InventoryModel readComplexInventoryModel() { + Vnf vnf = new Vnf("vnf_1","vABCD","1"); + + Vnfc vnfcA = new Vnfc("A","Active-Active","A_Name"); + Vnfc vnfcB = new Vnfc("B","Active-Active","B_Name"); + Vnfc vnfcC = new Vnfc("C","Active-Active","C_Name"); + Vnfc vnfcD = new Vnfc("D","Active-Active","D_Name"); + Vnfc vnfcE = new Vnfc("E","Active-Active","E_Name"); + Vnfc vnfcF = new Vnfc("F","Active-Active","F_Name"); + Vnfc vnfcG = new Vnfc("G","Active-Active","G_Name"); + + vnfcA.addVm(new Vserver("VM_URL_A1")); + vnfcB.addVm(new Vserver("VM_URL_B1")); + vnfcC.addVm(new Vserver("VM_URL_C1")); + vnfcD.addVm(new Vserver("VM_URL_D1")); + vnfcE.addVm(new Vserver("VM_URL_E1")); + vnfcF.addVm(new Vserver("VM_URL_F1")); + vnfcG.addVm(new Vserver("VM_URL_G1")); + + vnf.addVnfc(vnfcA); + vnf.addVnfc(vnfcB); + vnf.addVnfc(vnfcC); + vnf.addVnfc(vnfcD); + vnf.addVnfc(vnfcE); + vnf.addVnfc(vnfcF); + vnf.addVnfc(vnfcG); + + return new InventoryModel(vnf); + } + + private VnfcDependencyModel readComplexDependencyModel() { + Vnfc a = new Vnfc("A","Active-Active",null); + Vnfc b = new Vnfc("B","Active-Active",null); + Vnfc c = new Vnfc("C","Active-Active",null); + Vnfc d = new Vnfc("D","Active-Active",null); + Vnfc e = new Vnfc("E","Active-Active",null); + Vnfc f = new Vnfc("F","Active-Active",null); + Vnfc g = new Vnfc("G","Active-Active",null); + + + Node aNode = new Node(a); + Node bNode = new Node(b); + Node cNode = new Node(c); + Node dNode = new Node(d); + Node eNode = new Node(e); + Node fNode = new Node(f); + Node gNode = new Node(g); + + bNode.addParent(a); + cNode.addParent(a); + + bNode.addParent(e); + cNode.addParent(e); + + dNode.addParent(b); + gNode.addParent(b); + + fNode.addParent(c); + + gNode.addParent(f); + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(aNode); + dependencies.add(bNode); + dependencies.add(cNode); + dependencies.add(dNode); + dependencies.add(eNode); + dependencies.add(fNode); + dependencies.add(gNode); + + return new VnfcDependencyModel(dependencies); + } + + private VnfcDependencyModel readCyclicDependencyModel() { + + Vnfc a = new Vnfc("A","Active-Passive",null); + Vnfc b = new Vnfc("B","Active-Active",null); + Vnfc c = new Vnfc("C","Active-Active",null); + Vnfc d = new Vnfc("D","Active-Active",null); + + + Node aNode = new Node(a); + Node bNode = new Node(b); + Node cNode = new Node(c); + Node dNode = new Node(d); + + bNode.addParent(a); + + bNode.addParent(d); + dNode.addParent(c); + cNode.addParent(b); + + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(aNode); + dependencies.add(bNode); + dependencies.add(cNode); + dependencies.add(dNode); + + return new VnfcDependencyModel(dependencies); + + } + + private InventoryModel readInventoryModel() { + Vnf vnf = new Vnf("vnf_1","vSCP","1"); + + Vnfc smp = new Vnfc("SMP",null,"SMP_Name"); + Vserver smpVm1 = new Vserver("SMP_URL1"); + Vserver smpVm2 = new Vserver("SMP_URL2"); + + smp.addVm(smpVm1); + smp.addVm(smpVm2); + + Vnfc be = new Vnfc("BE",null,"BE_Name"); + + Vserver beVm1 = new Vserver("BE_URL1"); + Vserver beVm2 = new Vserver("BE_URL2"); + Vserver beVm3 = new Vserver("BE_URL3"); + Vserver beVm4 = new Vserver("BE_URL4"); + Vserver beVm5 = new Vserver("BE_URL5"); + + be.addVm(beVm1); + be.addVm(beVm2); + be.addVm(beVm3); + be.addVm(beVm4); + be.addVm(beVm5); + + Vnfc fe = new Vnfc("FE",null,"FE_Name"); + + Vserver feVm1 = new Vserver("FE_URL1"); + Vserver feVm2 = new Vserver("FE_URL2"); + + fe.addVm(feVm1); + fe.addVm(feVm2); + + vnf.addVnfc(smp); + vnf.addVnfc(be); + vnf.addVnfc(fe); + + return new InventoryModel(vnf); + } + + private VnfcDependencyModel readDependencyModel() { + Vnfc smp = new Vnfc("SMP","Active-Passive",null); + Vnfc be = new Vnfc("BE","Active-Active",null); + Vnfc fe = new Vnfc("FE","Active-Active",null); + + + Node smpNode = new Node(smp); + Node beNode = new Node(be); + Node feNode = new Node(fe); + + beNode.addParent(smp); + feNode.addParent(be); + + Set<Node<Vnfc>> dependencies = new HashSet<>(); + dependencies.add(smpNode); + dependencies.add(feNode); + dependencies.add(beNode); + + return new VnfcDependencyModel(dependencies); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.gitignore b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.gitignore new file mode 100644 index 000000000..b83d22266 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.core.resources.prefs b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 000000000..e9441bb12 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding/<project>=UTF-8 diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.m2e.core.prefs b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..f897a7f1c --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..f4ef8aa0a --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/.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-dg/appc-dg-shared/appc-dg-domain-model-lib/pom.xml b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/pom.xml new file mode 100644 index 000000000..640a4b7e9 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/pom.xml @@ -0,0 +1,29 @@ +<?xml version="1.0"?> +<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-dg-shared</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dg-domain-model-lib</artifactId> + + <name>appc-dg-domain-model-lib</name> + <url>http://maven.apache.org</url> + + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>3.8.1</version> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnf.java b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnf.java new file mode 100644 index 000000000..60e9a9fb2 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnf.java @@ -0,0 +1,69 @@ +/*- + * ============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.domainmodel; + +import java.util.LinkedList; +import java.util.List; + +public class Vnf { + private String vnfId; + private String vnfType; + private String vnfVersion; + + private List<Vnfc> vnfcs; + + public Vnf(String vnfId,String vnfType,String vnfVersion){ + this.vnfId = vnfId; + this.vnfType = vnfType; + this.vnfVersion = vnfVersion; + this.vnfcs = new LinkedList<>(); + } + + public String getVnfVersion() { + return vnfVersion; + } + + public String getVnfId() { + return vnfId; + } + + public String getVnfType() { + return vnfType; + } + + public void addVnfc(Vnfc vnfc){ + this.vnfcs.add(vnfc); + } + + public List<Vnfc> getVnfcs() { + return vnfcs; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("Vnf : vnfId = " + vnfId +" , vnfType = " + vnfType); + for(Vnfc vnfc:vnfcs){ + stringBuilder.append(vnfc.toString()).append(","); + } + return stringBuilder.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnfc.java b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnfc.java new file mode 100644 index 000000000..0064ed62f --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vnfc.java @@ -0,0 +1,145 @@ +/*- + * ============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.domainmodel; + +import java.util.LinkedList; +import java.util.List; + + +public class Vnfc { + + private String vnfcType; + + public void setResilienceType(String resilienceType) { + this.resilienceType = resilienceType; + } + + private String resilienceType; + private boolean mandatory; + private String vnfcName; + private List<Vserver> vserverList; + + public Vnfc(String vnfcType,String resilienceType){ + this(vnfcType,resilienceType,null, false); + } + + public Vnfc(String vnfcType,String resilienceType,String vnfcName){ + this(vnfcType,resilienceType,vnfcName, false); + } + + public Vnfc(String vnfcType,String resilienceType,String vnfcName, boolean mandatory){ + this.vnfcName = vnfcName; + this.vnfcType = vnfcType; + this.resilienceType = resilienceType; + this.mandatory = mandatory; + this.vserverList = new LinkedList<>(); + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder("Vnfc : vnfcType = " + vnfcType + ", vnfcName = " +vnfcName + ", resilienceType = " + resilienceType+", mandatory = " + mandatory); + for(Vserver vserver:vserverList){ + stringBuilder.append(vserver.toString()).append(", \n"); + } + return stringBuilder.toString(); + } + + @Override + public int hashCode(){ + final int prime = 31; + int result = 1; + result = result * prime + (this.vnfcType == null ? 0 :this.vnfcType.hashCode()); + result = result * prime + (this.resilienceType == null ? 0 :this.resilienceType.hashCode()); + result = result * prime + (this.vnfcName == null ? 0 :this.vnfcName.hashCode()); + result = result * prime + (Boolean.valueOf(this.mandatory).hashCode()); + return result; + } + @Override + public boolean equals(Object object){ + if(object == null){ + return false; + } + if(!(object instanceof Vnfc)){ + return false; + } + Vnfc vnfc = (Vnfc)object; + + if(this.vnfcType == null){ + if(vnfc.vnfcType !=null) + return false; + } + else if(!this.vnfcType.equals(vnfc.vnfcType)) + return false; + + if(this.resilienceType == null){ + if(vnfc.resilienceType !=null) + return false; + } + else if(!this.resilienceType.equals(vnfc.resilienceType)) + return false; + + if(this.vnfcName == null){ + if(vnfc.vnfcName !=null) + return false; + } + else if(!this.vnfcName.equals(vnfc.vnfcName)) + return false; + if (this.mandatory != vnfc.mandatory) + return false; + return true; + } + + public void addVm(Vserver vserver){ + this.vserverList.add(vserver); + } + public void addVms(List<Vserver> vserverList){ + this.vserverList.addAll(vserverList); + } + + public void setVnfcName(String vnfcName) { + this.vnfcName = vnfcName; + } + + public String getVnfcType() { + return vnfcType; + } + + public String getResilienceType() { + return resilienceType; + } + + public String getVnfcName() { + return vnfcName; + } + + public List<Vserver> getVserverList() { + return vserverList; + } + + public boolean isMandatory() { + return mandatory; + } + + public void setMandatory(boolean mandatory) { + this.mandatory = mandatory; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vserver.java b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vserver.java new file mode 100644 index 000000000..e536535cb --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/Vserver.java @@ -0,0 +1,75 @@ +/*- + * ============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.domainmodel; + + +public class Vserver { + + private String url; + + private String tenantId; + private String id; + private String relatedLink; + private String name; + + public Vserver(String url){ + this(url,null,null,null,null); + } + + public Vserver(String url, + String tenantId, + String id, + String relatedLink, + String name){ + this.url = url; + this.tenantId =tenantId; + this.id = id; + this.relatedLink =relatedLink; + this.name = name; + + } + + public String getUrl() { + return url; + } + + @Override + public String toString() { + return "Vserver : url = " +url + ", tenantId = " +tenantId +", id = " +id + " ,relatedLink = " +relatedLink +" , name = "+name; + } + + public String getTenantId() { + return tenantId; + } + + public String getId() { + return id; + } + + public String getRelatedLink() { + return relatedLink; + } + + public String getName() { + return name; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml b/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml index d6904babc..78882587b 100644 --- a/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-license-manager/pom.xml @@ -46,9 +46,11 @@ <Export-Package>org.openecomp.appc.dg.licmgr</Export-Package> <Export-Service>org.openecomp.appc.dg.licmgr.LicenseManagerPlugin</Export-Service> <Private-Package>org.openecomp.appc.dg.licmgr.impl</Private-Package> - <Import-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects,!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional</Import-Package> - <Embed-Dependency>appc-license-manager-api,appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> + <Import-Package> + org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects, + org.openecomp.appc.exceptions, com.att.eelf.configuration, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java b/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java index 6ca6b6ab5..1624f448c 100644 --- a/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java +++ b/appc-dg/appc-dg-shared/appc-dg-license-manager/src/main/java/org/openecomp/appc/dg/licmgr/LicenseManagerPlugin.java @@ -28,7 +28,6 @@ import org.openecomp.sdnc.sli.SvcLogicContext; import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; - public interface LicenseManagerPlugin extends SvcLogicJavaPlugin { /** * Retrieves license model from APPC database and populate flags into svc context diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml new file mode 100644 index 000000000..8123d17bb --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/pom.xml @@ -0,0 +1,45 @@ +<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-dg-shared</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-dg-mdsal-store</artifactId> + <packaging>jar</packaging> + + <name>appc-dg-mdsal-store</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-model-api</artifactId> + <version>${odl.yangtools.version}</version> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + </dependency> + </dependencies> +</project> diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java new file mode 100644 index 000000000..cb6e2fd11 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/MDSALStore.java @@ -0,0 +1,62 @@ +/*- + * ============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.mdsal; + +import org.openecomp.appc.mdsal.exception.MDSALStoreException; +import org.openecomp.appc.mdsal.objects.BundleInfo; + +import java.util.Date; + +/** + * Provides APIs for interacting with MD-SAL store + */ +public interface MDSALStore { + + /** + * Checks the presence of any yang module in the MD-SAL store, + * <i>Due to limitation of SchemaContext interface of ODL that it does not + * contain the information about dynamically loaded yang modules, it + * checks the presence of OSGI bundle</i> + * @param moduleName Name of the Module + * @param revision revision of the Module + * @return returns true- module is present, false - module is absent + */ + boolean isModulePresent(String moduleName, Date revision); + + /** + * This method will be used to store yang module to MD-SAL store + * @param yang - yang module that need to be stored. In String format + * @param bundleInfo - Bundle Information that contains name , description, version , location. These parameters used to create bundle which will push yang to MD-SAL store. + * @throws MDSALStoreException + */ + void storeYangModule(String yang, BundleInfo bundleInfo) throws MDSALStoreException; + + /** + * This method is used to store configuration JSON to MD-SAL store. It invokes store configuration Operation with required parameters + * @param moduleName - Yang module name where JSON need to be posted + * @param requestId - Request ID which is used as unique key for configuration JSON + * @param configJSON - String value of configuration JSON that needs to be stored in MD-SAl store + * @throws MDSALStoreException + */ + void storeJson(String moduleName , String requestId , String configJSON ) throws MDSALStoreException; + +} diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java new file mode 100644 index 000000000..0628ef78d --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/exception/MDSALStoreException.java @@ -0,0 +1,69 @@ +/*- + * ============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.mdsal.exception; + +/** + * This is custom exception type defined for MD-SAL store. All exceptions thrown by mdsal store module need to be wrapped in this class. +*/ + public class MDSALStoreException extends Exception { + + private static final long serialVersionUID = 1L; + + public MDSALStoreException(){ + } + + /** + * Create MDSALStoreException using only message. + * @param message -- message to the caller. + */ + public MDSALStoreException (String message){ + super(message); + } + + /** + * Create MDSALStoreException using orignal cause + * @param cause - cause that is being wrapped / suppressed. + */ + public MDSALStoreException (Throwable cause){ + super(cause); + } + + /** + * + * @param message - message to the caller. + * @param cause - cause that is being wrapped / suppressed . + */ + public MDSALStoreException(String message , Throwable cause){ + super(message , cause); + } + + /** + * + * @param message - message to the caller. + * @param cause - cause that is being wrapped / suppressed . + * @param enableSuppression - Indicates if suppression is enabled. + * @param writableStackTrace - Indicates if writable stacktrace is supported + */ + public MDSALStoreException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java new file mode 100644 index 000000000..a41c49de7 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/Constants.java @@ -0,0 +1,108 @@ +/*- + * ============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.mdsal.impl; +/** + * This class contains the definitions of all constant values used in the appc-dg-mdsal-store + * These properties are used for creating osgi bundle zip file. It also defines contents for Blueprint.xml file of bundle +*/ +public class Constants { + + private Constants(){} + /** + * Manifest attribute for OSGI Bundle Name + */ + public static final String MANIFEST_ATTR_BUNDLE_NAME= "Bundle-Name"; + + /** + * Manifest attribute for OSGI Bundle Symbolic Name + */ + public static final String MANIFEST_ATTR_BUNDLE_SYMBOLIC_NAME= "Bundle-SymbolicName"; + + /** + * Manifest attribute for OSGI Bundle Description + */ + public static final String MANIFEST_ATTR_BUNDLE_DESCRIPTION= "Bundle-Description"; + + /** + * Manifest attribute for OSGI Bundle Manifest version + */ + public static final String MANIFEST_ATTR_BUNDLE_MANIFEST_VERSION= "Bundle-ManifestVersion"; + + /** + * Manifest attribute for OSGI Bundle Version + */ + public static final String MANIFEST_ATTR_BUNDLE_VERSION= "Bundle-Version"; + + /** + * Manifest attribute for OSGI Bundle Blueprint + */ + public static final String MANIFEST_ATTR_BUNDLE_BLUEPRINT= "Bundle-Blueprint"; + + /** + * Manifest value for Mainfest Version + */ + public static final String MANIFEST_VALUE_VERSION= "1.0"; + + /** + * Manifest value for OSGI Bundle Vesion + */ + public static final String MANIFEST_VALUE_BUNDLE_MAN_VERSION= "2"; + + /** + * Manifest value for OSGI Bundle Blueprint location + */ + public static final String MANIFEST_VALUE_BUNDLE_BLUEPRINT= "OSGI-INF/blueprint/blueprint.xml"; + + /** + * Base URL for config actions exposed by RESTCONF API + */ + + public static final String CONFIG_URL = "https://localhost:8443/restconf/config"; + + /** + * Content for blueprint.xml used while creation of OSGI bundle. + */ + public static final String BLUEPRINT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + + "<!--\n" + + " Starter Blueprint Camel Definition appc-aai-adapter-blueprint\n" + + "-->\n" + + "<blueprint xmlns=\"http://www.osgi.org/xmlns/blueprint/v1.0.0\"\n" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + + " xsi:schemaLocation=\"http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd\">\n" + + "\n" + + "</blueprint>"; + + /** + * HTTP Header attribute for Content type - JSON + */ + public static final String OPERATION_APPLICATION_JSON= " application/json"; + + /** + * HTTP protocol used for config operations + */ + public static final String OPERATION_HTTPS= "https"; + + /** + * Constant for backslash to be used while formatting URL + */ + public static final String URL_BACKSLASH ="/"; +} diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java new file mode 100644 index 000000000..7550ad9e2 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreFactory.java @@ -0,0 +1,47 @@ +/*- + * ============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.mdsal.impl; + +import org.openecomp.appc.mdsal.MDSALStore; + +/* + * Factory class to create/get instance of MDSALStore + */ +public class MDSALStoreFactory { + private static class ReferenceHolder{ + private static MDSALStore store = new MDSALStoreImpl(); + private ReferenceHolder(){} + } + private MDSALStoreFactory(){ + + } + + /** + * Method for creating MDSALStore instance, It creates an instance of + * MDSALStoreImpl once and returns the same instance everytime it is invoked. + * @return + */ + public static MDSALStore createMDSALStore (){ + return ReferenceHolder.store; + } +} + diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java new file mode 100644 index 000000000..6f43bfc65 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/impl/MDSALStoreImpl.java @@ -0,0 +1,137 @@ +/*- + * ============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.mdsal.impl; + +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.mdsal.MDSALStore; +import org.openecomp.appc.mdsal.exception.MDSALStoreException; +import org.openecomp.appc.mdsal.objects.BundleInfo; +import org.openecomp.appc.mdsal.operation.ConfigOperation; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Date; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +/** + * Implementation of MDSALStore + */ +public class MDSALStoreImpl implements MDSALStore{ + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MDSALStoreImpl.class); + + MDSALStoreImpl(){ + ConfigOperation.setUrl(Constants.CONFIG_URL); + ConfigOperation.setAuthentication(null,null); + } + + + @Override + public boolean isModulePresent(String moduleName, Date revision) { + + if(logger.isDebugEnabled()){ + logger.debug("isModulePresent invoked with moduleName = " +moduleName + " , revision = " +revision); + } + + BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + /** + * SchemaContext interface of ODL provides APIs for querying details of yang modules + * loaded into MD-SAL store, but its limitation is, it only returns information about + * static yang modules loaded on server start up, it does not return information about + * the yang modules loaded dynamically. Due to this limitation, we are checking the + * presence of OSGI bundle instead of yang module. (Note: Assuming OSGI bundle is named + * with the yang module name). + */ + + Bundle bundle = bundleContext.getBundle(moduleName); + if(logger.isDebugEnabled()){ + logger.debug("isModulePresent returned = " + (bundle != null)); + } + return bundle != null; + } + + @Override + public void storeYangModule(String yang, BundleInfo bundleInfo) throws MDSALStoreException { + + BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext(); + byte[] byteArray = createBundleJar(yang, Constants.BLUEPRINT, bundleInfo); + + try (ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray)){ + Bundle bundle = bundleContext.installBundle(bundleInfo.getLocation(), inputStream); + bundle.start(); + } catch (Exception e) { + logger.error("Error storing yang module: " + yang + ". Error message: " + e.getMessage()); + throw new MDSALStoreException("Error storing yang module: " + yang + " " + e.getMessage(), e); + } + } + + @Override + public void storeJson( String module , String requestId ,String configJSON) throws MDSALStoreException { + + try { + ConfigOperation.storeConfig(configJSON , module , org.openecomp.appc.Constants.YANG_BASE_CONTAINER, org.openecomp.appc.Constants.YANG_VNF_CONFIG_LIST,requestId,org.openecomp.appc.Constants.YANG_VNF_CONFIG); + } catch (APPCException e) { + throw new MDSALStoreException("Exception while storing config json to MDSAL store." +e.getMessage(), e); + } + } + + private byte[] createBundleJar(String yang, String blueprint, BundleInfo bundleInfo) throws MDSALStoreException { + + Manifest manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, Constants.MANIFEST_VALUE_VERSION); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_NAME), bundleInfo.getName()); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_SYMBOLIC_NAME), bundleInfo.getName()); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_DESCRIPTION), bundleInfo.getDescription()); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_MANIFEST_VERSION), Constants.MANIFEST_VALUE_BUNDLE_MAN_VERSION); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_VERSION), String.valueOf(bundleInfo.getVersion())); + manifest.getMainAttributes().put(new Attributes.Name(Constants.MANIFEST_ATTR_BUNDLE_BLUEPRINT), Constants.MANIFEST_VALUE_BUNDLE_BLUEPRINT); + + byte[] retunValue; + + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + JarOutputStream jarOutputStream = new JarOutputStream(outputStream, manifest)) { + jarOutputStream.putNextEntry(new JarEntry("META-INF/yang/")); + jarOutputStream.putNextEntry(new JarEntry("META-INF/yang/"+bundleInfo.getName()+".yang")); + jarOutputStream.write(yang.getBytes()); + jarOutputStream.closeEntry(); + + jarOutputStream.putNextEntry(new JarEntry("OSGI-INF/blueprint/")); + jarOutputStream.putNextEntry(new JarEntry(Constants.MANIFEST_VALUE_BUNDLE_BLUEPRINT)); + jarOutputStream.write(blueprint.getBytes()); + jarOutputStream.closeEntry(); + jarOutputStream.close(); + retunValue = outputStream.toByteArray(); + } catch (Exception e) { + logger.error("Error creating bundle jar: " + bundleInfo.getName() + ". Error message: " + e.getMessage()); + throw new MDSALStoreException("Error creating bundle jar: " + bundleInfo.getName() + " " + e.getMessage(), e); + } + return retunValue; + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java new file mode 100644 index 000000000..f4bd1feba --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/objects/BundleInfo.java @@ -0,0 +1,71 @@ +/*- + * ============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.mdsal.objects; +/** + * Holds bundle information which includes name , description , version and location. This information will be used to create osgi bundle. + */ + public class BundleInfo { + + private String name; + private String description; + private Integer version; + private String location; + + /** + * Creates an object of BundleInfo with version initialized to 1 + */ + public BundleInfo(){ + version =1; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } +} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ProviderOperations.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java index 7a53bcdd9..15b632731 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ProviderOperations.java +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperation.java @@ -19,32 +19,20 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL.impl; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.Socket; -import java.net.URL; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; +package org.openecomp.appc.mdsal.operation; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.mdsal.impl.Constants; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.IOUtils; +import org.apache.http.HttpHeaders; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; @@ -57,115 +45,126 @@ import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; -import org.json.JSONObject; -import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.appc.listener.CL.model.IncomingMessage; -import org.openecomp.appc.listener.util.Mapper; -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.URL; +import java.security.*; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Iterator; -public class ProviderOperations { +import org.apache.commons.io.IOUtils; - private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); +/** + * Provides method to store configuration to MD-SAL store. It also exposes doPut operation which can be used to invoke REST Put operation. +*/ +public class ConfigOperation { + private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ConfigOperation.class); private static URL url; + private static String basicAuth; + + ConfigOperation(){} - private static String basic_auth; + private static ConfigOperationRequestFormatter requestFormatter = new ConfigOperationRequestFormatter(); - //@formatter:off - @SuppressWarnings("nls") - private final static String TEMPLATE = "{\"input\": {\"common-request-header\": {\"service-request-id\": \"%s\"},\"vnf-resource\": {\"vm-id\": \"%s\"%s}}}"; - //@formatter:on + private static ObjectMapper mapper = new ObjectMapper(); /** - * Calls the AppcProvider to run a topology directed graph - * - * @param msg - * The incoming message to be run - * @return True if the result is success. Never returns false and throws an exception instead. - * @throws UnsupportedEncodingException - * @throws Exception - * if there was a failure processing the request. The exception message is the failure reason. + * This method stores configuration JSON to MD-SAL store. Following input parameters are expected as input + * @param configJson - configuration JSON as String. This value will be stored in MD-SAL store + * @param module - Module name that contains yang Schema + * @param containerName - yang container name which will be used as base container. + * @param subModules - Sub modules list if any. Order of sub module is top to bottom. + * @throws APPCException */ - @SuppressWarnings("nls") - public static boolean topologyDG(IncomingMessage msg) throws APPCException { - if (msg == null) { + public static void storeConfig(String configJson , String module, String containerName, String... subModules ) throws APPCException { + if (configJson == null) { throw new APPCException("Provided message was null"); } + LOG.debug("Config JSON: " + configJson +"\n" + +"module" + module +"\n" + +"containerName" + containerName +"\n" + +"subModules length : " + subModules.length ); - HttpPost post = null; + int httpCode; + String respBody ; try { - // Concatenate the "action" on the end of the URL - String path = url.getPath() + ":" + msg.getAction().getValue().toLowerCase(); + String path = requestFormatter.buildPath(url, module, containerName, subModules); + LOG.debug("Configuration Path : " + path); URL serviceUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + HttpResponse response = doPut(serviceUrl , configJson); + httpCode = response.getStatusLine().getStatusCode(); + respBody = IOUtils.toString(response.getEntity().getContent()); + } catch (IOException e) { + LOG.error("Error while storing configuration json "+e.getMessage(), e); + throw new APPCException(e); + } - post = new HttpPost(serviceUrl.toExternalForm()); - post.setHeader("Content-Type", "application/json"); - post.setHeader("Accept", "application/json"); - - // Set Auth - if (basic_auth != null) { - post.setHeader("Authorization", "Basic " + basic_auth); + if (httpCode != 200 ) { + try { + ArrayList<String> errorMessage = new ArrayList<>(); + JsonNode responseJson = toJsonNodeFromJsonString(respBody); + if(responseJson!=null && responseJson.get("errors")!=null) { + JsonNode errors = responseJson.get("errors").get("error"); + for (Iterator<JsonNode> i = errors.elements();i.hasNext();){ + JsonNode error = i.next(); + errorMessage.add(error.get("error-message").textValue()); + } + } + throw new APPCException("Failed to load config JSON to MD SAL store. Error Message:" + errorMessage.toString()); + } catch (Exception e) { + LOG.error("Error while loading config JSON to MD SAL store. "+e.getMessage(), e); + throw new APPCException("Error while loading config JSON to MD SAL store. "+ e.getMessage(),e); } + } + } - String body = buildReqest(msg.getId(), msg.getUrl(), msg.getIdentityUrl()); - + /** + * This is Generic method that can be used to perform REST Put operation + * @param url - Destination URL for put + * @param body - payload for put action which will be sent as request body. + * @return - HttpResponse object which is returned from put REST call. + * @throws APPCException + */ + public static HttpResponse doPut (URL url, String body) throws APPCException { + HttpPut put; + try { + put = new HttpPut(url.toExternalForm()); + put.setHeader(HttpHeaders.CONTENT_TYPE, Constants.OPERATION_APPLICATION_JSON); + put.setHeader(HttpHeaders.ACCEPT, Constants.OPERATION_APPLICATION_JSON); - LOG.info(String.format("DMaaP ACTION PATH : %s", path)); - LOG.info(String.format("DMaaP ACTION BODY : %s", body)); + if (basicAuth != null) { + put.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + basicAuth); + } StringEntity entity = new StringEntity(body); - entity.setContentType("application/json"); - post.setEntity(new StringEntity(body)); - } catch (UnsupportedEncodingException | MalformedURLException e) { + entity.setContentType(Constants.OPERATION_APPLICATION_JSON); + put.setEntity(new StringEntity(body)); + } catch (UnsupportedEncodingException e) { throw new APPCException(e); } HttpClient client = getHttpClient(); - int httpCode = 0; - String respBody = null; try { - HttpResponse response = client.execute(post); - httpCode = response.getStatusLine().getStatusCode(); - respBody = IOUtils.toString(response.getEntity().getContent()); + return client.execute(put); } catch (IOException e) { throw new APPCException(e); } - if (httpCode >= 200 && httpCode < 300 && respBody != null) { - JSONObject json; - try { - json = Mapper.toJsonObject(respBody); - } catch (Exception e) { - LOG.error("Error processing response from provider. Could not map response to json", e); - throw new APPCException("APPC has an unknown RPC error"); - } - boolean success; - String reason; - try { - JSONObject header = json.getJSONObject("output").getJSONObject("common-response-header"); - success = header.getBoolean("success"); - reason = header.getString("reason"); - } catch (Exception e) { - LOG.error("Unknown error prcoessing failed response from provider. Json not in expected format", e); - throw new APPCException("APPC has an unknown RPC error"); - } - if (success) { - return true; - } - String reasonStr = reason == null ? "Unknown" : reason; - LOG.warn(String.format("Topology Operation [%s] failed. Reason: %s", msg.getId(), reasonStr)); - throw new APPCException(reasonStr); - - } - throw new APPCException(String.format("Unexpected response from endpoint: [%d] - %s ", httpCode, respBody)); } /** * Updates the static var URL and returns the value; - * + * * @return The new value of URL */ public static String getUrl() { @@ -176,7 +175,7 @@ public class ProviderOperations { try { url = new URL(newUrl); } catch (MalformedURLException e) { - e.printStackTrace(); + LOG.error("Malformed URL " +newUrl + e.getMessage(), e); } } @@ -184,45 +183,24 @@ public class ProviderOperations { * Sets the basic authentication header for the given user and password. If either entry is null then set basic auth * to null * - * @param user - * The user with optional domain name - * @param password - * The password for the user + * @param user The user with optional domain name (for AAF) + * @param password The password for the user * @return The new value of the basic auth string that will be used in the request headers */ public static String setAuthentication(String user, String password) { if (user != null && password != null) { String authStr = user + ":" + password; - basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); + basicAuth = new String(Base64.encodeBase64(authStr.getBytes())); } else { - basic_auth = null; + basicAuth = null; } - return basic_auth; - } - - /** - * Builds the request body for a topology operation - * - * @param id - * The request id - * @param action - * The action in lowercase - * @param url - * The vm's url - * @return A String containing the request body - */ - private static String buildReqest(String id, String url, String ident) { - String extraVmResource = ""; - if (ident != null) { - extraVmResource = String.format(", \"identity-url\": \"%s\"", ident); - } - return String.format(TEMPLATE, id, url, extraVmResource); + return basicAuth; } @SuppressWarnings("deprecation") private static HttpClient getHttpClient() throws APPCException { HttpClient client; - if (url.getProtocol().equals("https")) { + if (url.getProtocol().equals(Constants.OPERATION_HTTPS)) { try { KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); trustStore.load(null, null); @@ -235,55 +213,58 @@ public class ProviderOperations { SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); - registry.register(new Scheme("https", sf, 443)); - registry.register(new Scheme("https", sf, 8443)); + registry.register(new Scheme(Constants.OPERATION_HTTPS, sf, 443)); + registry.register(new Scheme(Constants.OPERATION_HTTPS, sf, 8443)); registry.register(new Scheme("http", sf, 8181)); ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); client = new DefaultHttpClient(ccm, params); } catch (Exception e) { + LOG.error("Error creating HTTP Client. Creating default client." , e); client = new DefaultHttpClient(); } - } else if (url.getProtocol().equals("http")) { + } else if ("http".equals(url.getProtocol())) { client = new DefaultHttpClient(); } else { throw new APPCException( - "The provider.topology.url property is invalid. The url did not start with http[s]"); + "The provider.topology.url property is invalid. The url did not start with http[s]"); } return client; } @SuppressWarnings("deprecation") - public static class MySSLSocketFactory extends SSLSocketFactory { + private static class MySSLSocketFactory extends SSLSocketFactory { private SSLContext sslContext = SSLContext.getInstance("TLS"); - public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, - KeyStoreException, UnrecoverableKeyException { + private MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, + KeyStoreException, UnrecoverableKeyException { super(truststore); TrustManager tm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + LOG.debug("Inside checkClientTrusted"); } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + LOG.debug("Inside checkServerTrusted"); } @Override public X509Certificate[] getAcceptedIssuers() { - return null; + return new X509Certificate[1]; } }; - sslContext.init(null, new TrustManager[] { - tm + sslContext.init(null, new TrustManager[]{ + tm }, null); } @Override public Socket createSocket(Socket socket, String host, int port, boolean autoClose) - throws IOException, UnknownHostException { + throws IOException { return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); } @@ -293,4 +274,16 @@ public class ProviderOperations { } } + private static JsonNode toJsonNodeFromJsonString(String jsonStr) { + JsonNode jsonNode = null; + if(jsonStr != null) { + try { + jsonNode = mapper.readTree(jsonStr); + } catch (IOException e) { + LOG.warn(String.format("Could not map %s to jsonNode.", jsonStr), e); + } + } + return jsonNode; + } + } diff --git a/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java new file mode 100644 index 000000000..13a587477 --- /dev/null +++ b/appc-dg/appc-dg-shared/appc-dg-mdsal-store/src/main/java/org/openecomp/appc/mdsal/operation/ConfigOperationRequestFormatter.java @@ -0,0 +1,51 @@ +/*- + * ============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.mdsal.operation; + +import org.openecomp.appc.mdsal.impl.Constants; + +import java.net.URL; +/** + * Creates request url path for config actions based on parameter like module name , container-name and sub modules if any. + */ + +public class ConfigOperationRequestFormatter { + /** + * Build a request url path for config actions + * @param url - base url + * @param module - yang module name + * @param containerName - yang container name + * @param subModules - sub module /container names as string in varargs ( String ) format + * @return - resultant path in String format + */ + public String buildPath(URL url,String module, String containerName , String... subModules ) { + + StringBuilder path = new StringBuilder( url.getPath()+ Constants.URL_BACKSLASH + module + ":"+containerName + Constants.URL_BACKSLASH); + if(subModules.length >0){ + for(String subModule : subModules){ + path.append(subModule); + path.append("/"); + } + } + return path.toString(); + } +} diff --git a/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml b/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml index 705f425ca..8ccb980e8 100644 --- a/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-netconf/pom.xml @@ -78,8 +78,10 @@ <Bundle-SymbolicName>appc-dg-netconf</Bundle-SymbolicName> <Export-Package>org.openecomp.appc.dg.netconf</Export-Package> <Private-Package>org.openecomp.appc.dg.netconf.impl.*</Private-Package> - <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional</Import-Package> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Import-Package> + *;resolution:=optional + </Import-Package> + <!--Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency--> <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> diff --git a/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java b/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java index 3b75f4070..29334e2f6 100644 --- a/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java +++ b/appc-dg/appc-dg-shared/appc-dg-netconf/src/main/java/org/openecomp/appc/dg/netconf/NetconfClientPlugin.java @@ -28,7 +28,6 @@ import org.openecomp.sdnc.sli.SvcLogicContext; import org.openecomp.sdnc.sli.SvcLogicJavaPlugin; - public interface NetconfClientPlugin extends SvcLogicJavaPlugin { void configure(Map<String, String> params, SvcLogicContext ctx) throws APPCException; void operationStateValidation(Map<String, String> params, SvcLogicContext ctx) throws APPCException; diff --git a/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java b/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java deleted file mode 100644 index 3b4a32385..000000000 --- a/appc-dg/appc-dg-shared/appc-dg-netconf/src/test/java/org/openecomp/appc/dg/netconf/impl/NetconfClientPluginImplTest.java +++ /dev/null @@ -1,679 +0,0 @@ -/*- - * ============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.dg.netconf.impl; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.Ignore; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mockito; -import org.openecomp.appc.adapter.netconf.*; -import org.openecomp.appc.adapter.netconf.util.Constants; -import org.openecomp.appc.dg.netconf.impl.NetconfClientPluginImpl; -import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.sdnc.sli.SvcLogicContext; -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.lang.reflect.Field; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import static org.powermock.api.mockito.PowerMockito.when; - - - -@RunWith(PowerMockRunner.class) -@PrepareForTest({OperationalStateValidatorFactory.class, NetconfClientPluginImpl.class, FrameworkUtil.class, ObjectMapper.class}) -@Ignore -public class NetconfClientPluginImplTest { - private NetconfClientPluginImpl netconfClientPlugin; - private NetconfDataAccessService dao; - private NetconfClientFactory clientFactory; - private Map<String, String> params; - - private final BundleContext bundleContext = Mockito.mock(BundleContext.class); - private final Bundle bundleService = Mockito.mock(Bundle.class); - private final ServiceReference sref1 = Mockito.mock(ServiceReference.class); - private final ServiceReference sref2 = Mockito.mock(ServiceReference.class); - private final ServiceReference sref3 = Mockito.mock(ServiceReference.class); - private static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; - - - String host = "http://www.test.com"; - String host1 = "http://www.test1.com"; - String vnfType = "VNF"; - int port = 8080; - String username = "test"; - String password = "test"; - String connectionDetails = "{\"host\":\"" + host + "\",\"port\":" + port + ",\"username\":\"" + username + "\",\"password\":\"" + password + "\",\"capabilities\":null,\"additionalProperties\":null}"; - String fileContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + - "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + - "\t<get-config>\n" + - "\t\t<source>\n" + - "\t\t\t<running/>\n" + - "\t\t </source>\n" + - "\t</get-config>\n" + - "</rpc>'"; - String operationalState = "<rpc message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + - " <get>\n" + - " <filter>\n" + - " <ManagedElement xmlns=\"urn:org:openecomp:appc:Test\">\n" + - " <VnfFunction xmlns=\"urn:org:openecomop:appc:Test\">\n" + - " <ProcessorManagement>\n" + - " <MatedPair>\n" + - " <operationalState/>\n" + - " <PayloadProcessor>\n" + - " <operationalState/>\n" + - " </PayloadProcessor>\n" + - " </MatedPair>\n" + - " <SystemController>\n" + - " <operationalState/>\n" + - " </SystemController>\n" + - " </ProcessorManagement>\n" + - " </VnfFunction>\n" + - " </ManagedElement>\n" + - " </filter>\n" + - " </get>\n" + - "</rpc>\n"; - - - @Before - public void setUp() throws NoSuchFieldException, IllegalAccessException { - clientFactory = new NetconfClientFactoryMock(); - - } - - - @Test - public void testConfigure() throws Exception { - - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - - params = new HashMap<>(); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); - - netconfClientPlugin.configure(params, ctx); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - - try { - Assert.assertEquals("wrong configuration", fileContent, client.getConf()); - Assert.assertEquals("wrong host", host, client.getLastConnectionDetails().getHost()); - Assert.assertEquals("wrong port", port, client.getLastConnectionDetails().getPort()); - Assert.assertEquals("wrong username", username, client.getLastConnectionDetails().getUsername()); - Assert.assertEquals("wrong password", password, client.getLastConnectionDetails().getPassword()); - Assert.assertFalse(client.isConnection()); - } catch (Exception e) { - Assert.fail("failed with because of " + e.getCause()); - } - - - } - - - @Test - public void testConfigureNegativeIOException() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - - params = new HashMap<>(); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); - params.put(Constants.FILE_CONTENT_FIELD_NAME, fileContent); - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - - - try { - netconfClientPlugin.configure(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertNull(client.getLastConnectionDetails()); - Assert.assertNull(client.getConf()); - } - - } - - @Test - public void testOperationStateValidation() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer(operationalState); - - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - - netconfClientPlugin.operationStateValidation(params, ctx); - - Assert.assertTrue("validation process failed", validatorMock.isValidated()); - Assert.assertEquals(fileContent, client.getLastMessage()); - } - - - @Test - public void testOperationStateValidationNegativeJsonProcessingNullIllegalStateException() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer(operationalState); - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - substituteMapper(true); - - try { - netconfClientPlugin.operationStateValidation(params, ctx); - substituteMapper(false); - } catch (APPCException e) { - substituteMapper(false); - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - Assert.assertFalse(validatorMock.isValidated()); - Assert.assertNull(client.getLastMessage()); - } - } - - @Test - public void testOperationStateValidationNegativeConnectionDetailsAreNullNullPointerException() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer(operationalState); - - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - ObjectMapper mapper = PowerMockito.mock(ObjectMapper.class); - final NetconfConnectionDetails netconfConnectionDetails = null; - when(mapper.readValue(Matchers.anyString(), Matchers.any(Class.class))).thenReturn(netconfConnectionDetails); - - - try { - netconfClientPlugin.operationStateValidation(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - Assert.assertFalse("validation process failed", validatorMock.isValidated()); - - } - } - - - @Test - public void testOperationStateValidationNegativeAppcException() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer("wrong"); - - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - - - try { - netconfClientPlugin.operationStateValidation(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - Assert.assertFalse("validation process failed", validatorMock.isValidated()); - - } - } - - - @Test - public void testOperationStateValidatioConnectionDetailsInParamsAreEmpty() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer(operationalState); - ((DAOServiceMock) dao).setConnection(getConnectionDetails()); - - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, ""); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - - netconfClientPlugin.operationStateValidation(params, ctx); - - Assert.assertTrue("validation process failed", validatorMock.isValidated()); - Assert.assertEquals(fileContent, client.getLastMessage()); - } - - @Test - public void testOperationStateValidatioConnectionDetailsInParamsAreNull() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setAnswer(operationalState); - ((DAOServiceMock) dao).setConnection(getConnectionDetails()); - - - params = new HashMap<>(); - params.put(Constants.VNF_TYPE_FIELD_NAME, vnfType); - params.put(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME, host1); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, null); - MockOperationalStateValidatorImpl validatorMock = new MockOperationalStateValidatorImpl(); - validatorMock.setConfigurationFileName("VnfGetRunningConfig"); - - PowerMockito.mockStatic(OperationalStateValidatorFactory.class); - when(OperationalStateValidatorFactory.getOperationalStateValidator(Matchers.any(VnfType.class))).thenReturn(validatorMock); - - netconfClientPlugin.operationStateValidation(params, ctx); - - Assert.assertTrue("validation process failed", validatorMock.isValidated()); - Assert.assertEquals(fileContent, client.getLastMessage()); - } - - - @Test - public void testBackupConfiguration() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - params = new HashMap<>(); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setConf(fileContent); - netconfClientPlugin.backupConfiguration(params, ctx); - - DAOServiceMock mockdao = (DAOServiceMock) dao; - DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); - Date date = new Date(); - String creationDateExpected = dateFormat.format(date); - String creationDateActual = mockdao.getBackupConf().get("creationDate").substring(0, 10); - - - Assert.assertEquals("wrong configuration in db", fileContent, mockdao.getBackupConf().get("logText")); - Assert.assertEquals(creationDateExpected, creationDateActual); - - - } - - - @Test - public void testBackupConfigurationNegativeDgErrorFieldName() throws Exception { - shortInit(); - SvcLogicContext ctx = new SvcLogicContext(); - params = new HashMap<>(); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setConf(fileContent); - try { - netconfClientPlugin.backupConfiguration(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - - DAOServiceMock mockdao = (DAOServiceMock) dao; - Assert.assertNull(mockdao.getBackupConf()); - } - - } - - @Test - public void testGetConfig() throws Exception { - fullInit(); - String entity = "123"; - - SvcLogicContext ctx = new SvcLogicContext(); - ctx.setAttribute("entity", entity); - - params = new HashMap<>(); - params.put("conf-id", "current"); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setConf(fileContent); - - - netconfClientPlugin.getConfig(params, ctx); - - Assert.assertEquals("Success", ctx.getAttribute("getConfig_Result")); - Assert.assertEquals(fileContent, ctx.getAttribute("fullConfig")); - Assert.assertNotNull(ctx.getAttribute(entity + ".Configuration")); - Assert.assertEquals(fileContent, ctx.getAttribute(entity + ".Configuration")); - } - - - @Test - public void testGetConfigNegativeConfigurationNull() throws Exception { - fullInit(); - String entity = "123"; - - SvcLogicContext ctx = new SvcLogicContext(); - ctx.setAttribute("entity", entity); - - params = new HashMap<>(); - params.put("conf-id", "current"); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - - - netconfClientPlugin.getConfig(params, ctx); - - Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); - Assert.assertNull(ctx.getAttribute("fullConfig")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - } - - - @Test - public void testGetConfigNegativeNotSupportedConfId() throws Exception { - fullInit(); - String entity = "123"; - SvcLogicContext ctx = new SvcLogicContext(); - ctx.setAttribute("entity", entity); - - params = new HashMap<>(); - params.put("conf-id", "current1"); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, connectionDetails); - - - netconfClientPlugin.getConfig(params, ctx); - - Assert.assertNull(ctx.getAttribute("getConfig_Result")); - Assert.assertNull(ctx.getAttribute("fullConfig")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - } - - @Test - public void testGetConfigNegativeWronjJsonConnectionDetailsException() throws Exception { - fullInit(); - String entity = "123"; - - SvcLogicContext ctx = new SvcLogicContext(); - ctx.setAttribute("entity", entity); - - params = new HashMap<>(); - params.put("conf-id", "current"); - params.put(Constants.CONNECTION_DETAILS_FIELD_NAME, "{" + connectionDetails); - - - try { - netconfClientPlugin.getConfig(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertEquals("failure", ctx.getAttribute("getConfig_Result")); - Assert.assertNull(ctx.getAttribute("fullConfig")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - Assert.assertNull(ctx.getAttribute(entity + ".Configuration")); - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - } - - - } - - @Test - public void testGetRunningConfig() throws Exception { - fullInit(); - SvcLogicContext ctx = new SvcLogicContext(); - params = new HashMap<>(); - params.put("host-ip-address", host); - params.put("user-name", username); - params.put("password", password); - params.put("port-number", String.valueOf(port)); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setConf(fileContent); - - netconfClientPlugin.getRunningConfig(params, ctx); - - Assert.assertEquals("Success", ctx.getAttribute("getRunningConfig_Result")); - Assert.assertEquals(fileContent, ctx.getAttribute("running-config")); - Assert.assertEquals("success", ctx.getStatus()); - } - - @Test - public void testGetRunningConfigWithoutPortNumberDgErrorFieldNameException() throws Exception { - fullInit(); - SvcLogicContext ctx = new SvcLogicContext(); - params = new HashMap<>(); - params.put("host-ip-address", host); - params.put("user-name", username); - params.put("password", password); - - NetconfClientJschMock client = (NetconfClientJschMock) clientFactory.GetNetconfClient(NetconfClientType.SSH); - client.setConf(fileContent); - - try { - netconfClientPlugin.getRunningConfig(params, ctx); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); - Assert.assertNull(ctx.getAttribute("running-config")); - Assert.assertNotNull(ctx.getAttribute(DG_OUTPUT_STATUS_MESSAGE)); - } - - - } - - @Test - public void testGetRunningConfigNegativeConfigurationNull() throws Exception { - fullInit(); - SvcLogicContext ctx = new SvcLogicContext(); - params = new HashMap<>(); - params.put("host-ip-address", host); - params.put("user-name", username); - params.put("password", password); - params.put("port-number", String.valueOf(port)); - - netconfClientPlugin.getRunningConfig(params, ctx); - - Assert.assertEquals("failure", ctx.getAttribute("getRunningConfig_Result")); - Assert.assertNull(ctx.getAttribute("running-config")); - } - - @Test - public void testValidateMandatoryParamNegativeEmptyParamValue() throws Exception { - shortInit(); - String paramName = "test"; - String paramValue = ""; - - try { - netconfClientPlugin.validateMandatoryParam(paramName, paramValue); - Assert.assertTrue(false); - } catch (Exception e) { - Assert.assertTrue(true); - } - } - - @Test - public void testRetrieveConnectionDetails() throws Exception { - shortInit(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - ConnectionDetails connectionDetails1 = getConnectionDetails(); - daoServiceMock.setConnection(connectionDetails1); - - NetconfConnectionDetails connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.VNF); - - - Assert.assertEquals("wrong host", connectionDetails1.getHost(), connectionDetailsActual.getHost()); - Assert.assertEquals("wrong password", connectionDetails1.getPassword(), connectionDetailsActual.getPassword()); - Assert.assertEquals("wrong port", connectionDetails1.getPort(), connectionDetailsActual.getPort()); - Assert.assertEquals("wrong usename", connectionDetails1.getUsername(), connectionDetailsActual.getUsername()); - } - - - @Test - public void testRetrieveConnectionDetailsNegativeMissingConfiguration() throws Exception { - shortInit(); - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - ConnectionDetails connectionDetails1 = getConnectionDetails(); - daoServiceMock.setConnection(connectionDetails1); - - NetconfConnectionDetails connectionDetailsActual = null; - try { - connectionDetailsActual = netconfClientPlugin.retrieveConnectionDetails(VnfType.MOCK); - Assert.assertTrue(false); - } catch (APPCException e) { - Assert.assertNull(connectionDetailsActual); - } - - - } - - @Test - public void testRetrieveConfigurationFileContent() throws Exception { - shortInit(); - - DAOServiceMock daoServiceMock = (DAOServiceMock) dao; - daoServiceMock.setConfigFile(fileContent); - - Assert.assertEquals("wrong config in a database", fileContent, netconfClientPlugin.retrieveConfigurationFileContent("VnfGetRunningConfig")); - } - - private ConnectionDetails getConnectionDetails() { - - ConnectionDetails connectionDetails = new ConnectionDetails(); - connectionDetails.setPassword(password); - connectionDetails.setPort(port); - connectionDetails.setUsername(username); - connectionDetails.setHost(host); - return connectionDetails; - } - - - private void initDao() throws NoSuchFieldException, IllegalAccessException { - dao = new DAOServiceMock(); - PowerMockito.mockStatic(FrameworkUtil.class); - when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); - when(bundleService.getBundleContext()).thenReturn(bundleContext); - when(bundleContext.getServiceReference(NetconfDataAccessService.class)).thenReturn(sref1); - when(bundleContext.<NetconfDataAccessService>getService(sref1)).thenReturn(dao); - - - } - - private void fullInit() throws NoSuchFieldException, IllegalAccessException { - initClientFactory(); - initClientFactory2(); - initDao(); - netconfClientPlugin = new NetconfClientPluginImpl(); - netconfClientPlugin.setDao(this.dao); - } - - private void shortInit() throws NoSuchFieldException, IllegalAccessException { - initClientFactory(); - initDao(); - netconfClientPlugin = new NetconfClientPluginImpl(); - netconfClientPlugin.setDao(this.dao); - } - - private void initClientFactory() throws NoSuchFieldException, IllegalAccessException { - - PowerMockito.mockStatic(FrameworkUtil.class); - when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); - when(bundleService.getBundleContext()).thenReturn(bundleContext); - when(bundleContext.getServiceReference(NetconfClientFactory.class)).thenReturn(sref2); - when(bundleContext.<NetconfClientFactory>getService(sref2)).thenReturn(clientFactory); - - } - - private void initClientFactory2() { - PowerMockito.mockStatic(FrameworkUtil.class); - when(FrameworkUtil.getBundle(Matchers.any(Class.class))).thenReturn(bundleService); - when(bundleService.getBundleContext()).thenReturn(bundleContext); - when(bundleContext.getServiceReference(Matchers.anyString())).thenReturn(sref3); - when(bundleContext.<NetconfClientFactory>getService(sref3)).thenReturn(clientFactory); - } - - private void substituteMapper(boolean command) throws NoSuchFieldException, IllegalAccessException { - ObjectMapper mapper = new ObjectMapperMock(); - ObjectMapper mapper2 = new ObjectMapper(); - Field field = NetconfClientPluginImpl.class.getDeclaredField("mapper"); - field.setAccessible(true); - if (command) { - field.set(netconfClientPlugin, mapper); - } else { - field.set(netconfClientPlugin, mapper2); - } - } - -} diff --git a/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml b/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml index 3271f7ab8..c8925fe8f 100644 --- a/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml +++ b/appc-dg/appc-dg-shared/appc-dg-shared-features/src/main/resources/features.xml @@ -29,7 +29,9 @@ <feature name='appc-dg-shared' description="appc-dg-shared" version='${project.version}'> <feature version='${project.version}'>appc-ssh-adapter</feature> <feature version='${project.version}'>appc-netconf-adapter</feature> - <bundle>mvn:org.openecomp.appc/appc-dg-common/${project.version}</bundle> + <feature version='${sdnctl.sli.version}'>sdnc-sli</feature> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> + <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-dg-common/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-dg-ssh/${project.version}</bundle> <bundle start-level="85" start="true">mvn:org.openecomp.appc/appc-dg-netconf/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-dg-license-manager/${project.version}</bundle> diff --git a/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml b/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml index 3f5c51f28..f27c2828e 100644 --- a/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml +++ b/appc-dg/appc-dg-shared/appc-dg-ssh/pom.xml @@ -58,8 +58,10 @@ <Bundle-SymbolicName>appc-dg-ssh</Bundle-SymbolicName> <Export-Package>org.openecomp.appc.dg.ssh</Export-Package> <Private-Package>org.openecomp.appc.dg.ssh.impl.*</Private-Package> - <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*;resolution:=optional</Import-Package> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Import-Package> + *;resolution:=optional + </Import-Package> + <!--Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency--> <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> diff --git a/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java b/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java index 382d41894..89dd424c9 100644 --- a/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java +++ b/appc-dg/appc-dg-shared/appc-dg-ssh/src/main/java/org/openecomp/appc/dg/ssh/impl/SshDBPluginImpl.java @@ -21,6 +21,7 @@ package org.openecomp.appc.dg.ssh.impl; +import com.att.eelf.i18n.EELFResourceManager; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -32,6 +33,8 @@ import org.openecomp.appc.adapter.ssh.SshDataAccessException; import org.openecomp.appc.adapter.ssh.SshDataAccessService; import org.openecomp.appc.dg.ssh.SshDBPlugin; import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.i18n.Msg; + import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import org.openecomp.sdnc.sli.SvcLogicContext; @@ -49,24 +52,29 @@ public class SshDBPluginImpl implements SshDBPlugin { public void retrieveConnectionDetails(Map<String, String> params, SvcLogicContext ctx) throws APPCException { SshConnectionDetails connectionDetails = new SshConnectionDetails(); - String vnfType = ctx.getAttribute("aai.prefix")+"."+"vnf-type"; + //String vnfType = ctx.getAttribute("aai.prefix")+"."+"vnf-type"; + String vnfType = params.get("vnf-type"); try { - if (!dataAccessService.retrieveConnectionDetails(ctx.getAttribute(vnfType), connectionDetails)) { - logger.error("Missing configuration for " + params.get(vnfType)); - throw new APPCException("Missing configuration for " + params.get(vnfType) + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); + if (!dataAccessService.retrieveConnectionDetails(vnfType, connectionDetails)) { + logger.error("Missing connection details for VNF type: " + vnfType); + throw new APPCException("Missing configuration for " + vnfType + " in " + Constants.DEVICE_AUTHENTICATION_TABLE_NAME); } connectionDetails.setHost(params.get(Constants.VNF_HOST_IP_ADDRESS_FIELD_NAME)); ctx.setAttribute(Constants.CONNECTION_DETAILS_FIELD_NAME, mapper.writeValueAsString(connectionDetails)); } catch(APPCException e) { - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + String msg = EELFResourceManager.format(Msg.APPC_EXCEPTION, vnfType, e.getMessage()); + logger.error(msg); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE,msg); throw e; } catch(SshDataAccessException e) { - logger.error("Error " + e.getMessage()); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + String msg = EELFResourceManager.format(Msg.SSH_DATA_EXCEPTION, e.getMessage()); + logger.error(msg); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); throw e; } catch (JsonProcessingException e) { - logger.error("Error " + e.getMessage()); - ctx.setAttribute(Constants.DG_OUTPUT_STATUS_MESSAGE, e.getMessage()); + String msg = EELFResourceManager.format(Msg.JSON_PROCESSING_EXCEPTION, e.getMessage()); + logger.error(msg); + ctx.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg); throw new APPCException(e); } } diff --git a/appc-dg/appc-dg-shared/pom.xml b/appc-dg/appc-dg-shared/pom.xml index 1645866bf..9082e0d0e 100644 --- a/appc-dg/appc-dg-shared/pom.xml +++ b/appc-dg/appc-dg-shared/pom.xml @@ -11,11 +11,14 @@ <modules> <module>appc-dg-common</module> + <module>appc-dg-dependency-model</module> <module>appc-dg-ssh</module> <module>appc-dg-aai</module> <module>appc-dg-netconf</module> <module>appc-dg-license-manager</module> <module>appc-dg-shared-features</module> <module>appc-dg-shared-installer</module> - </modules> + <module>appc-dg-domain-model-lib</module> + <module>appc-dg-mdsal-store</module> + </modules> </project> diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml index 6841b8224..7e6f01b32 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/pom.xml @@ -30,13 +30,13 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> + <scope>compile</scope> </dependency> <!--<dependency>--> <!--<groupId>org.apache.commons</groupId>--> <!--<artifactId>commons-lang3</artifactId>--> <!--<version>3.4</version>--> <!--<scope>provided</scope>--> - <!--<type>bundle</type>--> <!--</dependency>--> </dependencies> <build> @@ -49,9 +49,13 @@ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> <Export-Package>org.openecomp.appc.executor,org.openecomp.appc.executor.objects,org.openecomp.appc.executor.conv,org.openecomp.appc.executor.helper</Export-Package> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Dependency> + javax.json;scope=compile|runtime;inline=false + </Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> - <Import-Package>!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> + <Import-Package> + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java index 14bd8152c..6b1b67481 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-api/src/main/java/org/openecomp/appc/executor/objects/LCMCommandStatus.java @@ -41,7 +41,7 @@ public enum LCMCommandStatus { MISSING_MANDATORY_PARAMETER(302,"MISSING MANDATORY PARAMETER - Parameter/s ${paramName} is/are missing" ), REQUEST_PARSING_FAILED(303,"REQUEST PARSING FAILED - ${errorMsg}"), NO_TRANSITION_DEFINE(304,"ACTION IS NOT ALLOWED - Action ${actionName} is not allowed for VNF in state ${currentState}"), - ACTION_NOT_SUPPORTED(305,"ACTION NOT SUPPORTED - ${actionName} action is not supported" ), + INVALID_VNF_STATE(305,"Request rejected because VNF status in A&AI is - ${currentState}" ), VNF_NOT_FOUND(306,"VNF NOT FOUND - VNF with ID ${vnfId} was not found" ), DG_WORKFLOW_NOT_FOUND(307,"DG WORKFLOW NOT FOUND - No DG workflow found for the combination of ${dgModule} module ${dgName} name and ${dgVersion} version"),//TODO need to support it WORKFLOW_NOT_FOUND(308,"WORKFLOW NOT FOUND - No workflow found for VNF type ${vnfTypeVersion} and ${actionName} action"), @@ -49,6 +49,7 @@ public enum LCMCommandStatus { LOCKING_FAILURE(310,"LOCKING FAILURE - ${errorMsg}" ), EXPIRED_REQUEST(311,"EXPIRED REQUEST"), DUPLICATE_REQUEST(312,"DUPLICATE REQUEST"), + MISSING_VNF_DATA_IN_AAI(313,"MISSING VNF DATA IN A&AI - ${attributeName} not found for VNF ID = ${vnfId}"), SUCCESS(400,"SUCCESS - request has been processed successfully"), diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml b/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml index ef73055f8..d827fba8b 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/pom.xml @@ -40,7 +40,6 @@ <dependency> <groupId>org.openecomp.appc</groupId> <artifactId>appc-command-executor-api</artifactId> - <version>${project.version}</version> </dependency> <dependency> <groupId>org.openecomp.appc</groupId> @@ -92,14 +91,28 @@ <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Dependency>eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Export-Service>org.openecomp.appc.executor.CommandExecutor</Export-Service> - <Import-Package>org.openecomp.appc.executionqueue.*,org.openecomp.appc.executor,org.openecomp.appc.executor.objects,!groovy.lang,!javax.jms,!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.*,*;resolution:=optional</Import-Package> + <Import-Package> + org.openecomp.appc.executionqueue.*, + org.openecomp.appc.executor, + org.openecomp.appc.executor.objects, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> </plugins> </build> + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-command-executor-api</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + </dependencyManagement> </project> diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java index fcc4f9156..7e1281ac4 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandExecutorImpl.java @@ -87,6 +87,34 @@ public class CommandExecutorImpl implements CommandExecutor { } } + private RuntimeContext getCommandRequest(RuntimeContext commandExecutorInput){ + if (logger.isTraceEnabled()) { + logger.trace("Entering to getCommandRequest with CommandExecutorInput = "+ ObjectUtils.toString(commandExecutorInput)); + } + RuntimeContext commandRequest; + commandRequest = commandExecutorInput; + /* + CommandRequest commandRequest; + + switch(commandExecutorInput.getRequestContext().getAction()){ + case Sync: + case Audit: + case ConfigBackup: + case ConfigBackupDelete: + case ConfigExport: + commandRequest = new LCMReadOnlyCommandRequest(commandExecutorInput); + break; + default: + commandRequest = new LCMCommandRequest(commandExecutorInput); + break; + } + */ + if (logger.isTraceEnabled()) { + logger.trace("Exiting from getCommandRequest with (CommandRequest = "+ ObjectUtils.toString(commandRequest)+")"); + } + return commandRequest; + } + @SuppressWarnings("unchecked") private void enqueRequest(RuntimeContext request) throws APPCException{ if (logger.isTraceEnabled()) { diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java index 21a00861e..66b98bb28 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTask.java @@ -21,29 +21,17 @@ package org.openecomp.appc.executor.impl; -import static com.att.eelf.configuration.Configuration.MDC_ALERT_SEVERITY; -import static com.att.eelf.configuration.Configuration.MDC_INSTANCE_UUID; -import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_FQDN; -import static com.att.eelf.configuration.Configuration.MDC_SERVER_IP_ADDRESS; -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; -import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; - -import java.net.InetAddress; - -import org.openecomp.appc.domainmodel.lcm.RuntimeContext; import org.openecomp.appc.domainmodel.lcm.Status; import org.openecomp.appc.executor.objects.CommandResponse; import org.openecomp.appc.executor.objects.LCMCommandStatus; import org.openecomp.appc.executor.objects.Params; -import org.openecomp.appc.logging.LoggingConstants; import org.openecomp.appc.requesthandler.RequestHandler; +import org.openecomp.appc.domainmodel.lcm.RuntimeContext; import org.openecomp.appc.workflow.WorkFlowManager; import org.openecomp.appc.workflow.objects.WorkflowRequest; import org.openecomp.appc.workflow.objects.WorkflowResponse; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; -import org.slf4j.MDC; /** * This abstract class is base class for all Command tasks. All command task must inherit this class. @@ -80,19 +68,6 @@ public abstract class CommandTask implements Runnable { public void execute() { final RuntimeContext runtimeContext = commandRequest; - MDC.put(MDC_KEY_REQUEST_ID, runtimeContext.getRequestContext().getCommonHeader().getRequestId()); - if (runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId() != null) - MDC.put(MDC_SERVICE_INSTANCE_ID, runtimeContext.getRequestContext().getActionIdentifiers().getServiceInstanceId()); - MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, runtimeContext.getRequestContext().getCommonHeader().getOriginatorId()); - MDC.put(MDC_SERVICE_NAME, runtimeContext.getRequestContext().getAction().name()); - try { - MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); //Don't change it to a .getLocalHostName() again please. It's wrong! - MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); - }catch(Exception e){ - logger.debug(e.getMessage()); - } - MDC.put(MDC_INSTANCE_UUID, ""); //TODO make instanse_UUID generation once during APPC-instanse deploying - WorkflowRequest workflowRequest = new WorkflowRequest(); workflowRequest.setRequestContext(runtimeContext.getRequestContext()); workflowRequest.setResponseContext(runtimeContext.getResponseContext()); diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java index 2f9d2c970..5e47860a7 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/CommandTaskFactory.java @@ -51,7 +51,8 @@ public class CommandTaskFactory { public synchronized CommandTask getExecutionTask(String action, RuntimeContext commandRequest){ - if (VNFOperation.Sync.toString().equals(action) || VNFOperation.Audit.toString().equals(action)){ + if (VNFOperation.Sync.toString().equals(action) || VNFOperation.Audit.toString().equals(action) || VNFOperation.ConfigBackup.toString().equals(action) || + VNFOperation.ConfigBackupDelete.toString().equals(action) || VNFOperation.ConfigExport.toString().equals(action)){ return new LCMReadonlyCommandTask(commandRequest, requestHandler,workflowManager); }else { return new LCMCommandTask(commandRequest, requestHandler,workflowManager, diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java index ef25c67bc..be9f94f68 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/java/org/openecomp/appc/executor/impl/LCMCommandTask.java @@ -28,6 +28,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.openecomp.appc.domainmodel.lcm.CommonHeader; import org.openecomp.appc.domainmodel.lcm.RuntimeContext; +import org.openecomp.appc.domainmodel.lcm.Status; import org.openecomp.appc.domainmodel.lcm.VNFOperation; import org.openecomp.appc.executor.UnstableVNFException; import org.openecomp.appc.executor.objects.CommandResponse; @@ -38,6 +39,7 @@ import org.openecomp.appc.lifecyclemanager.LifecycleManager; import org.openecomp.appc.lifecyclemanager.objects.LifecycleException; import org.openecomp.appc.lifecyclemanager.objects.NoTransitionDefinedException; import org.openecomp.appc.lifecyclemanager.objects.VNFOperationOutcome; +import org.openecomp.appc.logging.LoggingConstants; import org.openecomp.appc.requesthandler.RequestHandler; import org.openecomp.appc.workflow.WorkFlowManager; import org.openecomp.appc.workflow.objects.WorkflowResponse; @@ -48,10 +50,16 @@ 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 java.net.InetAddress; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; +import static com.att.eelf.configuration.Configuration.*; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_INSTANCE_ID; +import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; + public class LCMCommandTask extends CommandTask { @@ -103,9 +111,15 @@ public class LCMCommandTask extends CommandTask { isAAIUpdated = updateAAI(request.getVnfContext().getId() , false, isSuccess); } logger.debug("isAAIUpdated = " + isAAIUpdated); + if(!isAAIUpdated){ + throw new Exception(); + } } catch(Exception e1) { logger.error("Exception = " + e1); + // In case of any errors we are updating the response status code and message + Status updatedStatus = new Status(401, "Fail to update VNF status in A&AI"); + request.getResponseContext().setStatus(updatedStatus); throw new RuntimeException(e1); } finally { @@ -115,8 +129,9 @@ public class LCMCommandTask extends CommandTask { @Override public void run() { - final RuntimeContext request = commandRequest; - boolean isAAIUpdated = false; + final RuntimeContext request = commandRequest; + setInitialLogProperties(request); + boolean isAAIUpdated = false; final String vnfId = request.getVnfContext().getId(); final String vnfType = request.getVnfContext().getType(); try { @@ -163,11 +178,12 @@ public class LCMCommandTask extends CommandTask { CommandResponse commandResponse = super.buildCommandResponse(response); this.onRequestCompletion(commandResponse); } - } + clearRequestLogProperties(); + } - private boolean updateAAI(String vnf_id , boolean isTTLEnd , boolean executionStatus) + private boolean updateAAI(String vnf_id, boolean isTTLEnd, boolean executionStatus) { String orchestrationStatus = null; String nextState; @@ -203,7 +219,7 @@ public class LCMCommandTask extends CommandTask { private SvcLogicContext getVnfdata(String vnf_id, String prefix,SvcLogicContext ctx) { - String key="vnf-id = '"+ vnf_id+"'"; + String key="generic-vnf.vnf-id = '"+ vnf_id+"'"+" AND http-header.Real-Time = 'true'"; logger.debug("inside getVnfdata=== "+key); try { SvcLogicResource.QueryStatus response = aaiService.query("generic-vnf", false, null, key,prefix, null, ctx); @@ -245,4 +261,31 @@ public class LCMCommandTask extends CommandTask { return false; } + protected void setInitialLogProperties(RuntimeContext request) + { + MDC.put(MDC_KEY_REQUEST_ID, request.getRequestContext().getCommonHeader().getRequestId()); + if (request.getRequestContext().getActionIdentifiers().getServiceInstanceId() != null) + MDC.put(MDC_SERVICE_INSTANCE_ID, request.getRequestContext().getActionIdentifiers().getServiceInstanceId()); + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, request.getRequestContext().getCommonHeader().getOriginatorId()); + MDC.put(MDC_SERVICE_NAME, request.getRequestContext().getAction().name()); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getCanonicalHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + logger.debug(e.getMessage()); + } + MDC.put(MDC_INSTANCE_UUID, ""); //TODO make instanse_UUID generation once during APPC-instanse deploying + } + + protected 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); + } catch (Exception e) { + + } + } } diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties index 2e5f26a0f..b4cdae5e6 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/main/resources/org/openecomp/appc/default.properties @@ -24,25 +24,12 @@ 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": "And","filters": [{"class": "Assigned","field": "request"},{"class": "Unassigned","field": "response"}]} -dmaap.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-MAIN -dmaap.client.name.id=0 -#dmaap.client.key=random -#dmaap.client.secret=random +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-MAIN +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -dmaap.threads.queuesize.min=1 -dmaap.threads.queuesize.max=1000 -dmaap.threads.poolsize.min=2 -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: diff --git a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties index 74552a9d7..fc0330d75 100644 --- a/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-command-executor/appc-command-executor-core/src/test/resources/org/openecomp/appc/default.properties @@ -76,27 +76,13 @@ 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-CMD-EXECUTOR-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=2 -dmaap.threads.poolsize.max=2 +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-CMD-EXECUTOR-TEST +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -# -# 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: diff --git a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml index cae7eedb1..94a45e31a 100644 --- a/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml +++ b/appc-dispatcher/appc-dispatcher-common/appc-data-access-lib/pom.xml @@ -6,7 +6,7 @@ <version>1.1.0-SNAPSHOT</version> </parent> <artifactId>appc-data-access-lib</artifactId> - <packaging>jar</packaging> + <packaging>bundle</packaging> <name>appc-data-access-lib</name> <url>http://maven.apache.org</url> @@ -35,7 +35,24 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-common</artifactId> <version>${project.version}</version> - <scope>compile</scope> </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Export-Package>org.openecomp.appc.dao.util</Export-Package> + <Import-Package>org.openecomp.appc.configuration,*;resolution:=optional</Import-Package> + <Embed-Dependency>mysql-connector-java</Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + </plugins> + </build> </project> diff --git a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java index c61901eb3..904722fae 100644 --- a/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java +++ b/appc-dispatcher/appc-dispatcher-common/domain-model-lib/src/main/java/org/openecomp/appc/domainmodel/lcm/VNFOperation.java @@ -23,8 +23,9 @@ package org.openecomp.appc.domainmodel.lcm; public enum VNFOperation { - Configure, Test, HealthCheck, Start, Terminate, Restart, Rebuild, Stop, ModifyConfig, Backup, Snapshot, - SoftwareUpload, LiveUpgrade, Rollback, Sync, Audit, Test_lic, Migrate, Evacuate, + Configure, Test, HealthCheck, Start, Terminate, Restart, Rebuild, Stop, ConfigModify, + ConfigScaleOut,ConfigRestore,Backup, Snapshot, + SoftwareUpload, LiveUpgrade, Rollback, Sync, Audit, Test_lic, Migrate, Evacuate,ConfigBackup,ConfigBackupDelete,ConfigExport, Lock(true), Unlock(true), CheckLock(true); private boolean builtIn; diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml index f8b1e5631..d20759f30 100644 --- a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/pom.xml @@ -26,7 +26,7 @@ <artifactId>eelf-core</artifactId> </dependency> </dependencies> - + <build> <plugins> <plugin> @@ -36,10 +36,11 @@ <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Export-Package>org.openecomp.appc.executionqueue,org.openecomp.appc.executionqueue.impl</Export-Package> - <Import-Package>!groovy.lang,!javax.*,!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> + <Import-Package> + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java index 01e4358e9..29de597b1 100644 --- a/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java +++ b/appc-dispatcher/appc-dispatcher-common/execution-queue-management-lib/src/main/java/org/openecomp/appc/executionqueue/impl/ExecutionQueueServiceFactory.java @@ -25,16 +25,11 @@ import org.openecomp.appc.executionqueue.ExecutionQueueService; public class ExecutionQueueServiceFactory { - private static ExecutionQueueService executionQueueService =null; - - public static ExecutionQueueService getExecutionQueueService(){ - if(executionQueueService == null){ - synchronized (ExecutionQueueServiceFactory.class){ - if(executionQueueService == null) - executionQueueService = new ExecutionQueueServiceImpl(); - } - } - return executionQueueService; + private static class ExecutionQueueServiceHolder { + public static final ExecutionQueueService executionQueueService = new ExecutionQueueServiceImpl(); } + public static ExecutionQueueService getExecutionQueueService() { + return ExecutionQueueServiceHolder.executionQueueService; + } } diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml index ed51ca775..8b2131829 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-features/src/main/resources/features.xml @@ -26,6 +26,10 @@ xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> <feature name='lock-manager' description="lock-manager" version='${project.version}'> + <!-- appc-common and appc-data-access-lib bundles are flagged as being a dependency --> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> + <bundle dependency="true">mvn:org.openecomp.appc/appc-data-access-lib/${project.version}</bundle> + <bundle start-level="80" start="true">mvn:org.openecomp.appc/lock-manager-api/${project.version}</bundle> <bundle start-level="85" start="true">mvn:org.openecomp.appc/lock-manager-impl/${project.version}</bundle> </feature> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml index 48befceb8..8da65195d 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/pom.xml @@ -28,7 +28,6 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-data-access-lib</artifactId> <version>${project.version}</version> - <scope>provided</scope> </dependency> <dependency> <groupId>com.att.eelf</groupId> @@ -49,16 +48,16 @@ <configuration> <instructions> <Export-Service>org.openecomp.appc.lockmanager.api.LockManager</Export-Service> - <Import-Package>org.openecomp.appc.lockmanager.api.*,*</Import-Package> + <Import-Package> + org.openecomp.appc.lockmanager.api.*, + org.openecomp.appc.dao.util,com.att.eelf.configuration, *;resolution:=optional + </Import-Package> <Private-Package>org.openecomp.appc.lockmanager.impl.*</Private-Package> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Import-Package>!org.apache.log,!org.apache.commons.logging,!groovy.lang,!javax.jms,!javax.mail.*,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.jasypt.*,*</Import-Package> - <Embed-Dependency>appc-common,appc-data-access-lib,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> </plugin> </plugins> </build> -</project>
\ No newline at end of file +</project> diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java index 0399726b5..62181d4c6 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/Messages.java @@ -28,6 +28,7 @@ public enum Messages { ERR_UNLOCK_NOT_LOCKED("Error unlocking resource [%s]: resource is not locked"), ERR_UNLOCK_LOCKED_BY_OTHER("Error unlocking resource [%s] by [%s]: resource is locked by [%s]"), EXP_LOCK("Error locking resource [%s]."), + EXP_CHECK_LOCK("Error check locking resource [%s]."),//for checklock operation EXP_UNLOCK("Error unlocking resource [%s]."), ; diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java index 52c75d2b2..54622c422 100644 --- a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/optimistic/SqlLockManager.java @@ -91,7 +91,7 @@ abstract class SqlLockManager extends JdbcLockManager { } } } catch (SQLException e) { - throw new LockRuntimeException(Messages.EXP_LOCK.format(resource)); + throw new LockRuntimeException(Messages.EXP_CHECK_LOCK.format(resource)); }finally { closeDbConnection(connection); } diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/LockRecord.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/LockRecord.java new file mode 100644 index 000000000..7d537379b --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/LockRecord.java @@ -0,0 +1,62 @@ +/*- + * ============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.lockmanager.impl.sql.pessimistic; + +class LockRecord { + + private String resource; + private String owner; + private long updated; + private long timeout; + + LockRecord(String resource) { + this.resource = resource; + } + + public String getResource() { + return resource; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public long getUpdated() { + return updated; + } + + public void setUpdated(long updated) { + this.updated = updated; + } + + public long getTimeout() { + return timeout; + } + + public void setTimeout(long timeout) { + this.timeout = timeout; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManager.java new file mode 100644 index 000000000..79d0f6cca --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManager.java @@ -0,0 +1,85 @@ +/*- + * ============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.lockmanager.impl.sql.pessimistic; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.openecomp.appc.lockmanager.api.LockRuntimeException; + +public class MySqlLockManager extends SqlLockManager { + + private static final int DEF_CRITICAL_SECTION_WAIT_TIMEOUT = 3; + + protected int criticalSectionWaitTimeoutSecs = DEF_CRITICAL_SECTION_WAIT_TIMEOUT; + + public void setCriticalSectionWaitTimeoutSecs(int criticalSectionWaitTimeoutSecs) { + this.criticalSectionWaitTimeoutSecs = criticalSectionWaitTimeoutSecs; + } + + @Override + protected void enterCriticalSection(Connection connection, String resource) { + try { + CallableStatement statement = connection.prepareCall("SELECT COALESCE(GET_LOCK(?,?),0)"); + try { + statement.setString(1, resource); + statement.setInt(2, criticalSectionWaitTimeoutSecs); + boolean execRes = statement.execute(); + int result = 0; + if(execRes) { + ResultSet resultSet = statement.getResultSet(); + try { + if(resultSet.next()) { + result = resultSet.getInt(1); + } + } finally { + resultSet.close(); + } + } + if(result != 1) { // lock is not obtained + throw new LockRuntimeException("Cannot obtain critical section lock for resource [" + resource + "]."); + } + } finally { + statement.close(); + } + } catch(SQLException e) { + throw new LockRuntimeException("Cannot obtain critical section lock for resource [" + resource + "].", e); + } + } + + @Override + protected void leaveCriticalSection(Connection connection, String resource) { + try { + CallableStatement statement = connection.prepareCall("SELECT RELEASE_LOCK(?)"); + try { + statement.setString(1, resource); + statement.execute(); + } finally { + statement.close(); + } + } catch(SQLException e) { + throw new LockRuntimeException("Error releasing critical section lock.", e); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/SqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/SqlLockManager.java new file mode 100644 index 000000000..71f649274 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/main/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/SqlLockManager.java @@ -0,0 +1,251 @@ +/*- + * ============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.lockmanager.impl.sql.pessimistic; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockRuntimeException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.Messages; + +abstract class SqlLockManager extends JdbcLockManager { + + private static final String SQL_LOAD_LOCK_RECORD = "SELECT * FROM %s WHERE RESOURCE_ID=?"; + private static final String SQL_INSERT_LOCK_RECORD = "INSERT INTO %s (RESOURCE_ID, OWNER_ID, UPDATED, TIMEOUT) VALUES (?, ?, ?, ?)"; + private static final String SQL_UPDATE_LOCK_RECORD = "UPDATE %s SET OWNER_ID=?, UPDATED=?, TIMEOUT=? WHERE RESOURCE_ID=?"; + private static final String SQL_CURRENT_TIMESTAMP = "SELECT CURRENT_TIMESTAMP()"; + + private String sqlLoadLockRecord; + private String sqlInsertLockRecord; + private String sqlUpdateLockRecord; + + @Override + public boolean acquireLock(String resource, String owner) throws LockException { + return acquireLock(resource, owner, 0); + } + + @Override + public boolean acquireLock(String resource, String owner, long timeout) throws LockException { + if(owner == null) { + throw new LockRuntimeException(Messages.ERR_NULL_LOCK_OWNER.format(resource)); + } + boolean res = false; + Connection connection = openDbConnection(); + try { + enterCriticalSection(connection, resource); + try { + res = lockResource(connection, resource, owner, timeout); + } finally { + leaveCriticalSection(connection, resource); + } + } finally { + closeDbConnection(connection); + } + return res; + } + + @Override + public void releaseLock(String resource, String owner) throws LockException { + Connection connection = openDbConnection(); + try { + enterCriticalSection(connection, resource); + try { + unlockResource(connection, resource, owner); + } finally { + leaveCriticalSection(connection, resource); + } + } finally { + closeDbConnection(connection); + } + } + + @Override + public boolean isLocked(String resource) { + Connection connection=openDbConnection(); + try { + LockRecord lockRecord=loadLockRecord(connection,resource); + if(lockRecord==null){ + return false; + }else{ + if(lockRecord.getOwner()==null){ + return false; + }else if(isLockExpired(lockRecord, connection)){ + return false; + }else{ + return true; + } + } + } catch (SQLException e) { + throw new LockRuntimeException(Messages.EXP_CHECK_LOCK.format(resource)); + }finally { + closeDbConnection(connection); + } + } + + private boolean lockResource(Connection connection, String resource, String owner, long timeout) throws LockException { + try { + boolean res = false; + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // lock record already exists + String currentOwner = lockRecord.getOwner(); + if(currentOwner != null) { + if(isLockExpired(lockRecord, connection)) { + currentOwner = null; + } else if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_LOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + } + // set new owner on the resource lock record + updateLockRecord(connection, resource, owner, timeout); + if(currentOwner == null) { + // no one locked the resource before + res = true; + } + } else { + // resource record does not exist in lock table => create new record + addLockRecord(connection, resource, owner, timeout); + res = true; + } + return res; + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_LOCK.format(resource), e); + } + } + + private void unlockResource(Connection connection, String resource, String owner) throws LockException { + try { + LockRecord lockRecord = loadLockRecord(connection, resource); + if(lockRecord != null) { + // check if expired + if(isLockExpired(lockRecord, connection)) { + // lock is expired => no lock + lockRecord = null; + } + } + if((lockRecord == null) || (lockRecord.getOwner() == null)) { + // resource is not locked + throw new LockException(Messages.ERR_UNLOCK_NOT_LOCKED.format(resource)); + } + String currentOwner = lockRecord.getOwner(); + if(!owner.equals(currentOwner)) { + throw new LockException(Messages.ERR_UNLOCK_LOCKED_BY_OTHER.format(resource, owner, currentOwner)); + } + updateLockRecord(connection, resource, null, 0); + // TODO delete record from table on lock release? +// deleteLockRecord(connection, resource); + } catch(SQLException e) { + throw new LockRuntimeException(Messages.EXP_UNLOCK.format(resource), e); + } + } + + protected abstract void enterCriticalSection(Connection connection, String resource); + + protected abstract void leaveCriticalSection(Connection connection, String resource); + + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res = null; + if(sqlLoadLockRecord == null) { + sqlLoadLockRecord = String.format(SQL_LOAD_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlLoadLockRecord)) { + statement.setString(1, resource); + try(ResultSet resultSet = statement.executeQuery()) { + if(resultSet.next()) { + res = new LockRecord(resource); + res.setOwner(resultSet.getString(2)); + res.setUpdated(resultSet.getLong(3)); + res.setTimeout(resultSet.getLong(4)); + } + } + } + return res; + } + + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(sqlInsertLockRecord == null) { + sqlInsertLockRecord = String.format(SQL_INSERT_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlInsertLockRecord)) { + statement.setString(1, resource); + statement.setString(2, owner); + statement.setLong(3, getCurrentTime(connection)); + statement.setLong(4, timeout); + statement.executeUpdate(); + } + } + + protected void updateLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(sqlUpdateLockRecord == null) { + sqlUpdateLockRecord = String.format(SQL_UPDATE_LOCK_RECORD, tableName); + } + try(PreparedStatement statement = connection.prepareStatement(sqlUpdateLockRecord)) { + statement.setString(1, owner); + statement.setLong(2, getCurrentTime(connection)); + statement.setLong(3, timeout); + statement.setString(4, resource); + statement.executeUpdate(); + } + } + +// protected void deleteLockRecord(Connection connection, String resource) throws SQLException { +// if(sqlDeleteLockRecord == null) { +// sqlDeleteLockRecord = String.format(SQL_DELETE_LOCK_RECORD, tableName); +// } +// try(PreparedStatement statement = connection.prepareStatement(sqlDeleteLockRecord)) { +// statement.setString(1, resource); +// statement.executeUpdate(); +// } +// } + + private boolean isLockExpired(LockRecord lockRecord, Connection connection) throws SQLException { + long timeout = lockRecord.getTimeout(); + if(timeout == 0) { + return false; + } + long updated = lockRecord.getUpdated(); + long now = getCurrentTime(connection); + long expiration = updated + timeout; + return (now > expiration); + } + + 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; + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManagerMock.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManagerMock.java new file mode 100644 index 000000000..a94dc18e4 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/MySqlLockManagerMock.java @@ -0,0 +1,150 @@ +/*- + * ============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.lockmanager.impl.sql.pessimistic; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import org.openecomp.appc.lockmanager.api.LockRuntimeException; +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; +import org.openecomp.appc.lockmanager.impl.sql.SynchronizerReceiver; +import org.openecomp.appc.lockmanager.impl.sql.pessimistic.LockRecord; +import org.openecomp.appc.lockmanager.impl.sql.pessimistic.MySqlLockManager; + +class MySqlLockManagerMock extends MySqlLockManager implements SynchronizerReceiver { + + private final Map<String, LockRecord> locks = new HashMap<>(); + private final Lock lock = new ReentrantLock(); + private boolean useReal; + private Synchronizer synchronizer; + + MySqlLockManagerMock(boolean useReal) { + this.useReal = useReal; + } + + @Override + public void setSynchronizer(Synchronizer synchronizer) { + this.synchronizer = synchronizer; + } + + @Override + protected Connection openDbConnection() { + if(useReal) { + return super.openDbConnection(); + } + return null; + } + + @Override + protected void closeDbConnection(Connection connection) { + if(useReal) { + super.closeDbConnection(connection); + } + } + + @Override + protected LockRecord loadLockRecord(Connection connection, String resource) throws SQLException { + LockRecord res; + if(useReal) { + res = super.loadLockRecord(connection, resource); + } else { + res = locks.get(resource); + } + if(synchronizer != null) { + synchronizer.postLoadLockRecord(resource, (res == null) ? null : res.getOwner()); + } + return res; + } + + @Override + protected void addLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(synchronizer != null) { + synchronizer.preAddLockRecord(resource, owner); + } + try { + if(useReal) { + super.addLockRecord(connection, resource, owner, timeout); + return; + } + LockRecord lockRecord = new LockRecord(resource); + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + locks.put(resource, lockRecord); + } finally { + if(synchronizer != null) { + synchronizer.postAddLockRecord(resource, owner); + } + } + } + + @Override + protected void updateLockRecord(Connection connection, String resource, String owner, long timeout) throws SQLException { + if(synchronizer != null) { + synchronizer.preUpdateLockRecord(resource, owner); + } + try { + if(useReal) { + super.updateLockRecord(connection, resource, owner, timeout); + return; + } + LockRecord lockRecord = loadLockRecord(connection, resource); + lockRecord.setOwner(owner); + lockRecord.setUpdated(System.currentTimeMillis()); + lockRecord.setTimeout(timeout); + locks.put(resource, lockRecord); + } finally { + if(synchronizer != null) { + synchronizer.postUpdateLockRecord(resource, owner); + } + } + } + + @Override + protected void enterCriticalSection(Connection connection, String resource) { + if(useReal) { + super.enterCriticalSection(connection, resource); + return; + } + try { + if(!lock.tryLock(criticalSectionWaitTimeoutSecs, TimeUnit.SECONDS)) { + throw new LockRuntimeException("Cannot obtain critical section lock for resource [" + resource + "]."); + } + } catch(InterruptedException e) { + throw new LockRuntimeException("Cannot obtain critical section lock.", e); + } + } + + @Override + protected void leaveCriticalSection(Connection connection, String resource) { + if(useReal) { + super.leaveCriticalSection(connection, resource); + return; + } + lock.unlock(); + } +} diff --git a/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/TestMySqlLockManager.java b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/TestMySqlLockManager.java new file mode 100644 index 000000000..cf8781b13 --- /dev/null +++ b/appc-dispatcher/appc-dispatcher-common/lock-manager-lib/lock-manager-impl/src/test/java/org/openecomp/appc/lockmanager/impl/sql/pessimistic/TestMySqlLockManager.java @@ -0,0 +1,121 @@ +/*- + * ============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.lockmanager.impl.sql.pessimistic; + +import org.junit.Assert; +import org.junit.Test; +import org.openecomp.appc.lockmanager.api.LockException; +import org.openecomp.appc.lockmanager.api.LockRuntimeException; +import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager; +import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests; +import org.openecomp.appc.lockmanager.impl.sql.Synchronizer; +import org.openecomp.appc.lockmanager.impl.sql.pessimistic.MySqlLockManager; + +import java.util.concurrent.*; + +public class TestMySqlLockManager extends MySqlLockManagerBaseTests { + + private static int CRITICAL_SECTION_WAIT_TIMEOUT = 1; // in secs + + @Override + protected JdbcLockManager createJdbcLockManager(boolean useReal) { + return new MySqlLockManagerMock(useReal); + } + + @Test + public void testConcurrentLock() throws LockException, InterruptedException, ExecutionException, TimeoutException { + try { + callConcurrentTest(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + Assert.assertTrue(lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name())); + return true; + } catch(LockRuntimeException e) { + Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage()); + return false; + } + } + }); + } finally { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + } + } + + @Test + public void testConcurrentUnlock() throws LockException, InterruptedException, ExecutionException, TimeoutException { + lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()); + callConcurrentTest(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + try { + lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name()); + return true; + } catch(LockRuntimeException e) { + Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage()); + return false; + } + } + }); + } + + private void callConcurrentTest(Callable<Boolean> callable) throws LockException, InterruptedException, ExecutionException, TimeoutException { + final int participantsNo = 2; + Synchronizer synchronizer = new Synchronizer(participantsNo) { + + @Override + protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) { + waitOn(this, TimeUnit.MILLISECONDS.convert(1 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS)); // add 1 sec to make sure timeout occured + } + }; + if(!setSynchronizer(synchronizer)) { + return; + } + ((MySqlLockManager)lockManager).setCriticalSectionWaitTimeoutSecs(CRITICAL_SECTION_WAIT_TIMEOUT); + ExecutorService executor = Executors.newFixedThreadPool(participantsNo); + Future<Boolean> future1 = executor.submit(callable); + try { + for(int i = 0; i < 10; i++) { + Thread.sleep(100); + if(synchronizer.getParticipantCount() > 0) { + break; + } + } + // make sure 1st thread gets inside critical section + if(synchronizer.getParticipantCount() < 1) { + Assert.fail(getClass().getName() + " first thread failed to acquireLock()"); + } + Future<Boolean> future2 = executor.submit(callable); + try { + // 1st thread should acquire the lock + Assert.assertTrue(future1.get(3 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS)); + // 2nd thread should fail waiting for critical section + Assert.assertFalse(future2.get(2 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS)); + } finally { + future2.cancel(true); + } + } finally { + future1.cancel(true); + setSynchronizer(null); + } + } +} diff --git a/appc-dispatcher/appc-dispatcher-installer/pom.xml b/appc-dispatcher/appc-dispatcher-installer/pom.xml index a9000454a..29b09f458 100644 --- a/appc-dispatcher/appc-dispatcher-installer/pom.xml +++ b/appc-dispatcher/appc-dispatcher-installer/pom.xml @@ -17,7 +17,7 @@ <features.boot.licenseManager>appc-license-manager</features.boot.licenseManager> <!--<features.repositories>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-lifecycle-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-license-manager-features/${project.version}/xml/features,mvn:org.openecomp.appc/appc-workflow-management-features/${project.version}/xml/features,mvn:org.openecomp.appc/lock-manager-features/${project.version}/xml/features</features.repositories>--> - <!-- SEPARATING FEATURE INSTALLS --> + <!-- SEPARATED FEATURE INSTALLS --> <features.repo.dispatcher>mvn:org.openecomp.appc/appc-dispatcher-features/${project.version}/xml/features</features.repo.dispatcher> <features.repo.requestHandler>mvn:org.openecomp.appc/appc-request-handler-features/${project.version}/xml/features</features.repo.requestHandler> <features.repo.commandExecutor>mvn:org.openecomp.appc/appc-command-executor-features/${project.version}/xml/features</features.repo.commandExecutor> diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml index d4da50767..635e1fc12 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/pom.xml @@ -17,11 +17,6 @@ <dependencies> <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-common</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> <groupId>org.openecomp.sdnc.core</groupId> <artifactId>dblib-provider</artifactId> </dependency> @@ -36,9 +31,6 @@ <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> <Export-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects</Export-Package> - <Embed-Dependency>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> - <Import-Package>!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> diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java index 81ce0e713..5f758e7ae 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/Constants.java @@ -68,7 +68,6 @@ public class Constants { public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address"; public static final String UPGRADE_VERSION = "upgrade-version"; public static final String DG_ERROR_FIELD_NAME = "org.openecomp.appc.dg.error"; - public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message"; public static final String RESOURCEKEY = "resourceKey"; public static final String REQ_ID_FIELD_NAME = "org.openecomp.appc.reqid"; public static final String API_VERSION_FIELD_NAME = "org.openecomp.appc.apiversion"; diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java index 40c7d8bb6..547b8c4f9 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-api/src/main/java/org/openecomp/appc/licmgr/LicenseManager.java @@ -27,6 +27,7 @@ import org.openecomp.appc.licmgr.exception.DataAccessException; import org.openecomp.appc.licmgr.objects.LicenseModel; +@SuppressWarnings("JavaDoc") public interface LicenseManager { /** diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml index 66b314798..99ab538ca 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/pom.xml @@ -58,10 +58,18 @@ <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Embed-Dependency>!dblib-provider,appc-common,eelf-core,logback-core,logback-classic,javax.mail;scope=compile|runtime;inline=false</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> <Export-Service>org.openecomp.appc.licmgr.LicenseManager</Export-Service> - <Import-Package>org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects,javax.mail.internet,!javax.mail,!groovy.lang,!javax.jms,!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> + + <Embed-Dependency> + artifactId=!dblib-provider|slf4j-api|jcl-over-slf4j;scope=compile|runtime;inline=false + </Embed-Dependency> + + <Import-Package> + org.openecomp.appc.licmgr,org.openecomp.appc.licmgr.exception,org.openecomp.appc.licmgr.objects, + *;resolution:=optional + </Import-Package> + + <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java index 2aff1ffb9..2eaf79062 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseDataAccessServiceImpl.java @@ -21,17 +21,14 @@ package org.openecomp.appc.licmgr.impl; +import javax.sql.rowset.CachedRowSet; + import org.openecomp.appc.licmgr.Constants; import org.openecomp.appc.licmgr.LicenseDataAccessService; import org.openecomp.appc.licmgr.exception.DataAccessException; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; import org.openecomp.sdnc.sli.resource.dblib.DbLibService; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; - -import javax.sql.rowset.CachedRowSet; import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS; @@ -42,7 +39,7 @@ import java.util.Map; @SuppressWarnings("JavaDoc") -class LicenseDataAccessServiceImpl implements LicenseDataAccessService { +public class LicenseDataAccessServiceImpl implements LicenseDataAccessService { private static EELFLogger logger = EELFManager.getInstance().getLogger(LicenseDataAccessServiceImpl.class); @@ -52,17 +49,12 @@ class LicenseDataAccessServiceImpl implements LicenseDataAccessService { private String schema; - private DbLibService dbLibService; - - private void checkDbLibService() throws DataAccessException { - if (null != dbLibService) {return;} + public void setDbLibService(DbLibService dbLibService) { + this.dbLibService = dbLibService; + } - //get dblib service and send it to DAService - BundleContext bctx = FrameworkUtil.getBundle(LicenseManagerImpl.class).getBundleContext(); - ServiceReference sref = bctx.getServiceReference(DbLibService.class.getName()); - dbLibService = (DbLibService)bctx.getService(sref); + private DbLibService dbLibService; - } /** * empty constructor @@ -73,8 +65,6 @@ class LicenseDataAccessServiceImpl implements LicenseDataAccessService { public Map<String,String> retrieveLicenseModelData(String vnfType, String vnfVersion, String... fields) throws DataAccessException { - checkDbLibService(); - Map<String,String> result = new HashMap<>(); if (null == fields || 0 == fields.length) fields = new String[]{ASDC_ARTIFACTS_FIELDS.ARTIFACT_CONTENT.name()}; @@ -119,8 +109,6 @@ class LicenseDataAccessServiceImpl implements LicenseDataAccessService { @Override public void storeArtifactPayload(Map<String, String> parameters) throws RuntimeException { - checkDbLibService(); - if(parameters == null || parameters.isEmpty()) { throw new RuntimeException("No parameters for insert are provided"); } diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java index 815bb02ab..86d1eddd9 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/java/org/openecomp/appc/licmgr/impl/LicenseManagerImpl.java @@ -25,7 +25,6 @@ import static org.openecomp.appc.licmgr.Constants.ASDC_ARTIFACTS_FIELDS.ARTIFACT import java.util.Map; -import org.openecomp.appc.licmgr.Constants; import org.openecomp.appc.licmgr.LicenseDataAccessService; import org.openecomp.appc.licmgr.LicenseManager; import org.openecomp.appc.licmgr.exception.DataAccessException; @@ -42,8 +41,6 @@ public class LicenseManagerImpl implements LicenseManager { } public LicenseManagerImpl() { - DAService = new LicenseDataAccessServiceImpl(); - DAService.setSchema(Constants.SDNCTL_SCHEMA); } @Override diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml index c8efb8390..45ef4f179 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -27,7 +27,15 @@ 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="licenseServiceBean" class="org.openecomp.appc.licmgr.impl.LicenseManagerImpl" scope="singleton" activation="lazy"/> - <service id="licenseService" interface="org.openecomp.appc.licmgr.LicenseManager" ref="licenseServiceBean"/> + <reference id="dbLibServiceRef" availability="mandatory" activation="eager" interface="org.openecomp.sdnc.sli.resource.dblib.DbLibService" /> + + <bean id="licenseDataServiceBean" class="org.openecomp.appc.licmgr.impl.LicenseDataAccessServiceImpl" scope="singleton" activation="eager"> + <property name="dbLibService" ref="dbLibServiceRef" /> + <property name="schema" value="sdnctl" /> + </bean> + <bean id="licenseServiceBean" class="org.openecomp.appc.licmgr.impl.LicenseManagerImpl" scope="singleton" activation="lazy"> + <property name="DAService" ref="licenseDataServiceBean"/> + </bean> + <service id="licenseService" interface="org.openecomp.appc.licmgr.LicenseManager" ref="licenseServiceBean"/> </blueprint> diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties index 9d9e1d787..a3b064f90 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/main/resources/org/openecomp/appc/default.properties @@ -23,27 +23,12 @@ # 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-LIC-MGR-MAIN -dmaap.client.name.id=0 -#dmaap.client.key=random -#dmaap.client.secret=random +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-LIC-MGR-TEST +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -dmaap.threads.queuesize.min=1 -dmaap.threads.queuesize.max=1000 -dmaap.threads.poolsize.min=2 -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: diff --git a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java index e496da7b5..9760cef54 100644 --- a/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java +++ b/appc-dispatcher/appc-license-manager/appc-license-manager-core/src/test/java/org/openecomp/appc/licmgr/LicenseServiceMock.java @@ -20,7 +20,6 @@ */ package org.openecomp.appc.licmgr; - import java.util.HashMap; import java.util.Map; diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml index e2231e8a6..859e4a514 100644 --- a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml +++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/pom.xml @@ -25,7 +25,6 @@ <artifactId>appc-lifecycle-management</artifactId> <version>1.1.0-SNAPSHOT</version> </parent> - <groupId>org.openecomp.appc</groupId> <artifactId>appc-lifecycle-management-core</artifactId> <packaging>bundle</packaging> @@ -69,10 +68,12 @@ <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Export-Service>org.openecomp.appc.lifecyclemanager.LifecycleManager</Export-Service> - <Import-Package>org.openecomp.appc.lifecyclemanager.*,!groovy.lang,!javax.*,!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> + <Import-Package> + org.openecomp.appc.lifecyclemanager.*, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java index 82c497d58..965d61a7b 100644 --- a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java +++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/java/org/openecomp/appc/lifecyclemanager/helper/MetadataReader.java @@ -32,8 +32,22 @@ import org.openecomp.appc.statemachine.objects.StateMachineMetadata; public class MetadataReader { private enum VNFStates { - Not_Instantiated, Instantiated, Configuring, Configured, Testing, Tested, Rebuilding, Restarting, Error, Running, Unknown, Terminating, Stopping, Stopped, - Backing_Up, Snapshotting, Software_Uploading, Upgrading, Rollbacking, Licensing, Migrating, Evacuating; + Not_Instantiated, Instantiated, Configuring, Configured, Testing, Tested, Rebuilding, Restarting, Starting, Error, Running, Unknown, Terminating, Stopping, Stopped, + Backing_Up, Snapshotting, Software_Uploading, Upgrading, Rollbacking, Licensing, Migrating, Evacuating , NOT_ORCHESTRATED("NOT ORCHESTRATED"); + + String stateName; + + VNFStates(String name){ + this.stateName = name; + } + + VNFStates(){ + this.stateName = name(); + } + + public String toString(){ + return this.stateName; + } } @SuppressWarnings("unused") @@ -46,12 +60,14 @@ public class MetadataReader { State TESTED = new State(VNFStates.Tested.toString()); State REBUILDING = new State(VNFStates.Rebuilding.toString()); State RESTARTING = new State(VNFStates.Restarting.toString()); + State STARTING = new State(VNFStates.Starting.toString()); State ERROR = new State(VNFStates.Error.toString()); State RUNNING = new State(VNFStates.Running.toString()); State UNKNOWN = new State(VNFStates.Unknown.toString()); State TERMINATING = new State(VNFStates.Terminating.toString()); State STOPPING = new State(VNFStates.Stopping.toString()); State STOPPED = new State(VNFStates.Stopped.toString()); + State NOT_ORCHESTRATED = new State(VNFStates.NOT_ORCHESTRATED.toString()); State BACKING_UP = new State(VNFStates.Backing_Up.toString()); State SNAPSHOTTING = new State(VNFStates.Snapshotting.toString()); @@ -70,7 +86,9 @@ public class MetadataReader { Event RESTART = new Event(VNFOperation.Restart.toString()); Event REBUILD = new Event(VNFOperation.Rebuild.toString()); Event STOP = new Event(VNFOperation.Stop.toString()); - Event MODIFY_CONFIG = new Event(VNFOperation.ModifyConfig.toString()); + Event CONFIG_MODIFY = new Event(VNFOperation.ConfigModify.toString()); + Event CONFIG_SCALEOUT = new Event(VNFOperation.ConfigScaleOut.toString()); + Event CONFIG_RESTORE = new Event(VNFOperation.ConfigRestore.toString()); Event BACKUP = new Event(VNFOperation.Backup.toString()); Event SNAPSHOT = new Event(VNFOperation.Snapshot.toString()); Event SOFTWARE_UPLOAD = new Event(VNFOperation.SoftwareUpload.toString()); @@ -80,6 +98,9 @@ public class MetadataReader { Event AUDIT = new Event(VNFOperation.Audit.toString()); Event MIGRATE = new Event(VNFOperation.Migrate.toString()); Event EVACUATE = new Event(VNFOperation.Evacuate.toString()); + Event CONFIG_BACKUP = new Event(VNFOperation.ConfigBackup.toString()); + Event CONFIG_BACKUP_DELETE = new Event(VNFOperation.ConfigBackupDelete.toString()); + Event CONFIG_EXPORT = new Event(VNFOperation.ConfigExport.toString()); Event LOCK = new Event(VNFOperation.Lock.toString()); Event UNLOCK = new Event(VNFOperation.Unlock.toString()); @@ -99,6 +120,7 @@ public class MetadataReader { builder = builder.addState(TESTED); builder = builder.addState(REBUILDING); builder = builder.addState(RESTARTING); + builder = builder.addState(STARTING); builder = builder.addState(ERROR); builder = builder.addState(RUNNING); builder = builder.addState(UNKNOWN); @@ -112,6 +134,7 @@ public class MetadataReader { builder = builder.addState(ROLLBACKING); builder = builder.addState(MIGRATING); builder = builder.addState(EVACUATING); + builder = builder.addState(NOT_ORCHESTRATED); builder = builder.addEvent(CONFIGURE); builder = builder.addEvent(TEST); @@ -122,7 +145,9 @@ public class MetadataReader { builder = builder.addEvent(SUCCESS); builder = builder.addEvent(FAILURE); builder = builder.addEvent(STOP); - builder = builder.addEvent(MODIFY_CONFIG); + builder = builder.addEvent(CONFIG_MODIFY); + builder = builder.addEvent(CONFIG_SCALEOUT); + builder = builder.addEvent(CONFIG_RESTORE); builder = builder.addEvent(HEALTHCHECK); builder = builder.addEvent(BACKUP); builder = builder.addEvent(SNAPSHOT); @@ -136,15 +161,22 @@ public class MetadataReader { builder = builder.addEvent(LOCK); builder = builder.addEvent(UNLOCK); builder = builder.addEvent(CHECKLOCK); + builder = builder.addEvent(CONFIG_BACKUP); + builder = builder.addEvent(CONFIG_BACKUP_DELETE); + builder = builder.addEvent(CONFIG_EXPORT); + + builder = builder.addTransition(NOT_ORCHESTRATED,CONFIGURE,CONFIGURING); builder = builder.addTransition(INSTANTIATED,CONFIGURE,CONFIGURING); builder = builder.addTransition(INSTANTIATED,TEST,TESTING); - builder = builder.addTransition(INSTANTIATED,START,RESTARTING); + builder = builder.addTransition(INSTANTIATED,START,STARTING); builder = builder.addTransition(INSTANTIATED,TERMINATE,TERMINATING); builder = builder.addTransition(INSTANTIATED,RESTART,RESTARTING); builder = builder.addTransition(INSTANTIATED,REBUILD,REBUILDING); builder = builder.addTransition(INSTANTIATED,STOP,STOPPING); - builder = builder.addTransition(INSTANTIATED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(INSTANTIATED,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(INSTANTIATED,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(INSTANTIATED,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(INSTANTIATED,HEALTHCHECK,TESTING); builder = builder.addTransition(INSTANTIATED,BACKUP,BACKING_UP); builder = builder.addTransition(INSTANTIATED,SNAPSHOT,SNAPSHOTTING); @@ -159,12 +191,14 @@ public class MetadataReader { builder = builder.addTransition(CONFIGURED,CONFIGURE,CONFIGURING); builder = builder.addTransition(CONFIGURED,TEST,TESTING); - builder = builder.addTransition(CONFIGURED,START,RESTARTING); + builder = builder.addTransition(CONFIGURED,START,STARTING); builder = builder.addTransition(CONFIGURED,TERMINATE,TERMINATING); builder = builder.addTransition(CONFIGURED,RESTART,RESTARTING); builder = builder.addTransition(CONFIGURED,REBUILD,REBUILDING); builder = builder.addTransition(CONFIGURED,STOP,STOPPING); - builder = builder.addTransition(CONFIGURED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(CONFIGURED,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(CONFIGURED,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(CONFIGURED,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(CONFIGURED,HEALTHCHECK,TESTING); builder = builder.addTransition(CONFIGURED,BACKUP,BACKING_UP); builder = builder.addTransition(CONFIGURED,SNAPSHOT,SNAPSHOTTING); @@ -178,15 +212,20 @@ public class MetadataReader { builder = builder.addTransition(CONFIGURED,LOCK,CONFIGURED); builder = builder.addTransition(CONFIGURED,UNLOCK,CONFIGURED); builder = builder.addTransition(CONFIGURED,CHECKLOCK,CONFIGURED); + builder = builder.addTransition(CONFIGURED,CONFIG_BACKUP,CONFIGURED); + builder = builder.addTransition(CONFIGURED,CONFIG_BACKUP_DELETE,CONFIGURED); + builder = builder.addTransition(CONFIGURED,CONFIG_EXPORT,CONFIGURED); builder = builder.addTransition(TESTED,CONFIGURE,CONFIGURING); builder = builder.addTransition(TESTED,TEST,TESTING); - builder = builder.addTransition(TESTED,START,RESTARTING); + builder = builder.addTransition(TESTED,START,STARTING); builder = builder.addTransition(TESTED,TERMINATE,TERMINATING); builder = builder.addTransition(TESTED,RESTART,RESTARTING); builder = builder.addTransition(TESTED,REBUILD,REBUILDING); builder = builder.addTransition(TESTED,STOP,STOPPING); - builder = builder.addTransition(TESTED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(TESTED,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(TESTED,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(TESTED,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(TESTED,HEALTHCHECK,TESTING); builder = builder.addTransition(TESTED,BACKUP,BACKING_UP); builder = builder.addTransition(TESTED,SNAPSHOT,SNAPSHOTTING); @@ -200,15 +239,20 @@ public class MetadataReader { builder = builder.addTransition(TESTED,LOCK,TESTED); builder = builder.addTransition(TESTED,UNLOCK,TESTED); builder = builder.addTransition(TESTED,CHECKLOCK,TESTED); + builder = builder.addTransition(TESTED,CONFIG_BACKUP,TESTED); + builder = builder.addTransition(TESTED,CONFIG_BACKUP_DELETE,TESTED); + builder = builder.addTransition(TESTED,CONFIG_EXPORT,TESTED); builder = builder.addTransition(RUNNING,CONFIGURE,CONFIGURING); builder = builder.addTransition(RUNNING,TEST,TESTING); - builder = builder.addTransition(RUNNING,START,RESTARTING); + builder = builder.addTransition(RUNNING,START,STARTING); builder = builder.addTransition(RUNNING,TERMINATE,TERMINATING); builder = builder.addTransition(RUNNING,RESTART,RESTARTING); builder = builder.addTransition(RUNNING,REBUILD,REBUILDING); builder = builder.addTransition(RUNNING,STOP,STOPPING); - builder = builder.addTransition(RUNNING,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(RUNNING,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(RUNNING,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(RUNNING,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(RUNNING,HEALTHCHECK,TESTING); builder = builder.addTransition(RUNNING,BACKUP,BACKING_UP); builder = builder.addTransition(RUNNING,SNAPSHOT,SNAPSHOTTING); @@ -222,15 +266,20 @@ public class MetadataReader { builder = builder.addTransition(RUNNING,LOCK,RUNNING); builder = builder.addTransition(RUNNING,UNLOCK,RUNNING); builder = builder.addTransition(RUNNING,CHECKLOCK,RUNNING); + builder = builder.addTransition(RUNNING,CONFIG_BACKUP,RUNNING); + builder = builder.addTransition(RUNNING,CONFIG_BACKUP_DELETE,RUNNING); + builder = builder.addTransition(RUNNING,CONFIG_EXPORT,RUNNING); builder = builder.addTransition(ERROR,CONFIGURE,CONFIGURING); builder = builder.addTransition(ERROR,TEST,TESTING); - builder = builder.addTransition(ERROR,START,RESTARTING); + builder = builder.addTransition(ERROR,START,STARTING); builder = builder.addTransition(ERROR,TERMINATE,TERMINATING); builder = builder.addTransition(ERROR,RESTART,RESTARTING); builder = builder.addTransition(ERROR,REBUILD,REBUILDING); builder = builder.addTransition(ERROR,STOP,STOPPING); - builder = builder.addTransition(ERROR,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(ERROR,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(ERROR,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(ERROR,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(ERROR,HEALTHCHECK,TESTING); builder = builder.addTransition(ERROR,BACKUP,BACKING_UP); builder = builder.addTransition(ERROR,SNAPSHOT,SNAPSHOTTING); @@ -244,15 +293,20 @@ public class MetadataReader { builder = builder.addTransition(ERROR,LOCK,ERROR); builder = builder.addTransition(ERROR,UNLOCK,ERROR); builder = builder.addTransition(ERROR,CHECKLOCK,ERROR); + builder = builder.addTransition(ERROR,CONFIG_BACKUP,ERROR); + builder = builder.addTransition(ERROR,CONFIG_BACKUP_DELETE,ERROR); + builder = builder.addTransition(ERROR,CONFIG_EXPORT,ERROR); builder = builder.addTransition(UNKNOWN,CONFIGURE,CONFIGURING); builder = builder.addTransition(UNKNOWN,TEST,TESTING); - builder = builder.addTransition(UNKNOWN,START,RESTARTING); + builder = builder.addTransition(UNKNOWN,START,STARTING); builder = builder.addTransition(UNKNOWN,TERMINATE,TERMINATING); builder = builder.addTransition(UNKNOWN,RESTART,RESTARTING); builder = builder.addTransition(UNKNOWN,REBUILD,REBUILDING); builder = builder.addTransition(UNKNOWN,STOP,STOPPING); - builder = builder.addTransition(UNKNOWN,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(UNKNOWN,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(UNKNOWN,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(UNKNOWN,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(UNKNOWN,HEALTHCHECK,TESTING); builder = builder.addTransition(UNKNOWN,BACKUP,BACKING_UP); builder = builder.addTransition(UNKNOWN,SNAPSHOT,SNAPSHOTTING); @@ -266,14 +320,19 @@ public class MetadataReader { builder = builder.addTransition(UNKNOWN,LOCK,UNKNOWN); builder = builder.addTransition(UNKNOWN,UNLOCK,UNKNOWN); builder = builder.addTransition(UNKNOWN,CHECKLOCK,UNKNOWN); + builder = builder.addTransition(UNKNOWN,CONFIG_BACKUP,UNKNOWN); + builder = builder.addTransition(UNKNOWN,CONFIG_BACKUP_DELETE,UNKNOWN); + builder = builder.addTransition(UNKNOWN,CONFIG_EXPORT,UNKNOWN); builder = builder.addTransition(STOPPED,CONFIGURE,CONFIGURING); builder = builder.addTransition(STOPPED,TEST,TESTING); - builder = builder.addTransition(STOPPED,START,RESTARTING); + builder = builder.addTransition(STOPPED,START,STARTING); builder = builder.addTransition(STOPPED,TERMINATE,TERMINATING); builder = builder.addTransition(STOPPED,RESTART,RESTARTING); builder = builder.addTransition(STOPPED,REBUILD,REBUILDING); - builder = builder.addTransition(STOPPED,MODIFY_CONFIG,CONFIGURING); + builder = builder.addTransition(STOPPED,CONFIG_MODIFY,CONFIGURING); + builder = builder.addTransition(STOPPED,CONFIG_SCALEOUT,CONFIGURING); + builder = builder.addTransition(STOPPED,CONFIG_RESTORE,CONFIGURING); builder = builder.addTransition(STOPPED,HEALTHCHECK,TESTING); builder = builder.addTransition(STOPPED,BACKUP,BACKING_UP); builder = builder.addTransition(STOPPED,SNAPSHOT,SNAPSHOTTING); @@ -295,6 +354,9 @@ public class MetadataReader { builder = builder.addTransition(RESTARTING,SUCCESS,RUNNING); builder = builder.addTransition(RESTARTING,FAILURE,ERROR); + builder = builder.addTransition(STARTING,SUCCESS,RUNNING); + builder = builder.addTransition(STARTING,FAILURE,ERROR); + builder = builder.addTransition(TERMINATING,SUCCESS,NOT_INSTANTIATED); builder = builder.addTransition(TERMINATING,FAILURE,ERROR); diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties index 63711c27f..2fbb0daab 100644 --- a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/main/resources/org/openecomp/appc/default.properties @@ -25,24 +25,12 @@ 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 +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-LC-MGMT-MAIN +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -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-LC-MGMT-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 - -# -# 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: diff --git a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java index 4c14e90bd..50b434956 100644 --- a/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java +++ b/appc-dispatcher/appc-lifecycle-management/appc-lifecycle-management-core/src/test/java/org/openecomp/appc/TestLifecycleManager.java @@ -103,6 +103,19 @@ public class TestLifecycleManager { } } + @Test + public void testNotOrchestratedState() throws LifecycleException, NoTransitionDefinedException { + LifecycleManager lifecycleManager = new LifecycleManagerImpl(); + String nextState = lifecycleManager.getNextState(null,"NOT ORCHESTRATED",VNFOperation.Configure.toString()); + Assert.assertEquals(nextState,"Configuring"); + } + + @Test(expected = NoTransitionDefinedException.class) + public void testBakckingUpState() throws LifecycleException, NoTransitionDefinedException { + LifecycleManager lifecycleManager = new LifecycleManagerImpl(); + String nextState = lifecycleManager.getNextState(null,"Software_Uploading",VNFOperation.Configure.toString()); + } + private List<Event> getNegativeEvents(State state,Set<Event> events) { List<Event> negativeEventList = new ArrayList<>(); negativeEventList.addAll(events); 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 index 62d046501..e4008a605 100644 --- a/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/pom.xml @@ -17,9 +17,8 @@ <dependencies> <dependency> - <groupId>com.fasterxml.jackson.core</groupId> + <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> -<!-- <version>${jackson.version}</version> --> </dependency> <dependency> @@ -48,9 +47,14 @@ <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-Dependency> + 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> + <Import-Package> + org.openecomp.appc.domainmodel.lcm, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/LCMStateManager.java b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/LCMStateManager.java new file mode 100644 index 000000000..6a63b1050 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-api/src/main/java/org/openecomp/appc/requesthandler/LCMStateManager.java @@ -0,0 +1,42 @@ +/*- + * ============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; + +/** + */ +public interface LCMStateManager { + /** + * This method checks if the LCM operations are enabled or not + * * @return true if enabled else false + */ + boolean isLCMOperationEnabled(); + + /** + * This method disables the LCM operations + */ + void disableLCMOperations(); + + /** + * This method disables the LCM operations + */ + void enableLCMOperations(); +} 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 index d0d54c9db..23b5d372f 100644 --- 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 @@ -74,4 +74,10 @@ public interface RequestHandler { * @param updateAAI boolean flag which indicate AAI upodate status after request completion. */ void onRequestTTLEnd(RuntimeContext runtimeContext, boolean updateAAI); + + /** + * This method returns the count of in progress requests + * * @return in progress requests count + */ + int getInprogressRequestCount(); } 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 index dcc73f2f1..da223089b 100644 --- a/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/pom.xml @@ -1,6 +1,5 @@ <?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"> +<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 @@ -40,6 +39,19 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-dmaap-adapter-bundle</artifactId> <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + <scope>provided</scope> </dependency> <dependency> @@ -97,6 +109,11 @@ <artifactId>transaction-recorder</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> @@ -108,10 +125,15 @@ <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.*,*;resolution:=optional</Import-Package> + <Import-Package> + org.openecomp.appc.adapter.messaging.*, + org.openecomp.appc.adapter.message.*, + org.openecomp.appc.adapter.factory.*, + org.openecomp.appc.lockmanager.api.*,org.openecomp.appc.requesthandler,org.openecomp.appc.requesthandler.objects,org.openecomp.appc.transactionrecorder, + org.openecomp.appc.transactionrecorder.objects, org.openecomp.appc.dao.util, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> 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/MessageAdapterImpl.java index 21c21db93..676c62871 100644 --- 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/MessageAdapterImpl.java @@ -21,26 +21,33 @@ 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.adapter.factory.DmaapMessageAdapterFactoryImpl; +import org.openecomp.appc.adapter.factory.MessageService; +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.message.Producer; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.commons.lang.ObjectUtils; 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 org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; -import com.fasterxml.jackson.core.JsonProcessingException; +import java.util.HashSet; +import java.util.Properties; -public class MessageAdapterDmaapImpl implements MessageAdapter{ +public class MessageAdapterImpl implements MessageAdapter{ - private Producer dmaapProducer; + private MessageService messageService; + private Producer producer; private String partition ; private Configuration configuration; private HashSet<String> pool; @@ -48,21 +55,28 @@ public class MessageAdapterDmaapImpl implements MessageAdapter{ private String apiKey; private String apiSecret; - private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapterDmaapImpl.class); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapterImpl.class); /** - * Initialize dmaapProducer client to post messages using configuration properties + * Initialize producer client to post messages using configuration properties */ @Override public void init(){ - this.dmaapProducer = getDmaapProducer(); + this.producer = getProducer(); } - private Producer getDmaapProducer() { + + private Producer getProducer() { configuration = ConfigurationFactory.getConfiguration(); Properties properties=configuration.getProperties(); updateProperties(properties); - Producer producer=new DmaapProducer(pool,writeTopic); - producer.updateCredentials(apiKey, apiSecret); + + BundleContext ctx = FrameworkUtil.getBundle(MessageAdapterImpl.class).getBundleContext(); + if (ctx != null) { + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef != null) { + producer = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopic,apiKey, apiSecret); + } + } return producer; } @@ -73,10 +87,13 @@ public class MessageAdapterDmaapImpl implements MessageAdapter{ } pool = new HashSet<>(); if (props != null) { - writeTopic = props.getProperty("dmaap.topic.write"); - apiKey = props.getProperty("dmaap.client.key"); - apiSecret = props.getProperty("dmaap.client.secret"); - String hostnames = props.getProperty("dmaap.poolMembers"); + // readTopic = props.getProperty("dmaap.topic.read"); + writeTopic = props.getProperty("appc.LCM.topic.write"); + apiKey = props.getProperty("appc.LCM.client.key"); + apiSecret = props.getProperty("appc.LCM.client.secret"); + messageService = MessageService.parse(props.getProperty("message.service.type")); + // READ_TIMEOUT = Integer.valueOf(props.getProperty("dmaap.topic.read.timeout", String.valueOf(READ_TIMEOUT))); + String hostnames = props.getProperty("appc.LCM.poolMembers"); if (hostnames != null && !hostnames.isEmpty()) { for (String name : hostnames.split(",")) { pool.add(name); @@ -103,9 +120,9 @@ public class MessageAdapterDmaapImpl implements MessageAdapter{ if (logger.isDebugEnabled()) { logger.debug("DMaaP Response = " + jsonMessage); } - success = dmaapProducer.post(this.partition, jsonMessage); + success = producer.post(this.partition, jsonMessage); } catch (JsonProcessingException e1) { - logger.error("Error generating Jason from DMaaP message "+ e1.getMessage()); + logger.error("Error generating Json from DMaaP message "+ e1.getMessage()); success= false; }catch (Exception e){ logger.error("Error sending message to DMaaP "+e.getMessage()); 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 index 3513516ae..272e02bca 100644 --- 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 @@ -21,38 +21,6 @@ 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; @@ -65,6 +33,23 @@ import com.fasterxml.jackson.databind.MapperFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializationFeature; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.CommonHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.FlagsBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.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 java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; public class Converter { @@ -90,6 +75,7 @@ public class Converter { Action action = Action.valueOf(vnfOperation.name()); CommonHeader commonHeader = convAsyncResponseTorev160108CommonHeader(response); Status status = convAsyncResponseTorev160108Status(response); + Payload payload = convAsyncResponseTorev160108Payload(response); switch (action){ case Rollback: outObj = new RollbackOutputBuilder(); @@ -110,6 +96,7 @@ public class Converter { outObj = new AuditOutputBuilder(); ((AuditOutputBuilder)outObj).setCommonHeader(commonHeader); ((AuditOutputBuilder)outObj).setStatus(status); + ((AuditOutputBuilder)outObj).setPayload(payload); return outObj; case HealthCheck: outObj = new HealthCheckOutputBuilder(); @@ -126,10 +113,29 @@ public class Converter { ((LockOutputBuilder)outObj).setCommonHeader(commonHeader); ((LockOutputBuilder)outObj).setStatus(status); return outObj; - case ModifyConfig: - outObj = new ModifyConfigOutputBuilder(); - ((ModifyConfigOutputBuilder)outObj).setCommonHeader(commonHeader); - ((ModifyConfigOutputBuilder)outObj).setStatus(status); + case Configure: + outObj = new ConfigureOutputBuilder(); + ((ConfigureOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigureOutputBuilder)outObj).setStatus(status); + ((ConfigureOutputBuilder)outObj).setPayload(payload); + return outObj; + case ConfigModify: + outObj = new ConfigModifyOutputBuilder(); + ((ConfigModifyOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigModifyOutputBuilder)outObj).setStatus(status); + ((ConfigModifyOutputBuilder)outObj).setPayload(payload); + return outObj; + case ConfigScaleOut: + outObj = new ConfigScaleoutOutputBuilder(); + ((ConfigScaleoutOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigScaleoutOutputBuilder)outObj).setStatus(status); + ((ConfigScaleoutOutputBuilder)outObj).setPayload(payload); + return outObj; + case ConfigRestore: + outObj = new ConfigRestoreOutputBuilder(); + ((ConfigRestoreOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigRestoreOutputBuilder)outObj).setStatus(status); + ((ConfigRestoreOutputBuilder)outObj).setPayload(payload); return outObj; case SoftwareUpload: outObj = new SoftwareUploadOutputBuilder(); @@ -145,6 +151,7 @@ public class Converter { outObj = new SyncOutputBuilder(); ((SyncOutputBuilder)outObj).setCommonHeader(commonHeader); ((SyncOutputBuilder)outObj).setStatus(status); + ((SyncOutputBuilder)outObj).setPayload(payload); return outObj; case Terminate: outObj = new TerminateOutputBuilder(); @@ -161,12 +168,54 @@ public class Converter { ((UnlockOutputBuilder)outObj).setCommonHeader(commonHeader); ((UnlockOutputBuilder)outObj).setStatus(status); return outObj; + case Restart: + outObj = new RestartOutputBuilder(); + ((RestartOutputBuilder)outObj).setCommonHeader(commonHeader); + ((RestartOutputBuilder)outObj).setStatus(status); + return outObj; + case Rebuild: + outObj = new RebuildOutputBuilder(); + ((RebuildOutputBuilder)outObj).setCommonHeader(commonHeader); + ((RebuildOutputBuilder)outObj).setStatus(status); + return outObj; + case Migrate: + outObj = new MigrateOutputBuilder(); + ((MigrateOutputBuilder)outObj).setCommonHeader(commonHeader); + ((MigrateOutputBuilder)outObj).setStatus(status); + return outObj; + case Evacuate: + outObj = new EvacuateOutputBuilder(); + ((EvacuateOutputBuilder)outObj).setCommonHeader(commonHeader); + ((EvacuateOutputBuilder)outObj).setStatus(status); + return outObj; + case ConfigBackup: + outObj = new ConfigBackupOutputBuilder(); + ((ConfigBackupOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigBackupOutputBuilder)outObj).setStatus(status); + ((ConfigBackupOutputBuilder)outObj).setPayload(payload); + return outObj; + case ConfigBackupDelete: + outObj = new ConfigBackupDeleteOutputBuilder(); + ((ConfigBackupDeleteOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigBackupDeleteOutputBuilder)outObj).setStatus(status); + ((ConfigBackupDeleteOutputBuilder)outObj).setPayload(payload); + return outObj; + case ConfigExport: + outObj = new ConfigExportOutputBuilder(); + ((ConfigExportOutputBuilder)outObj).setCommonHeader(commonHeader); + ((ConfigExportOutputBuilder)outObj).setStatus(status); + return outObj; + case Start: + outObj = new StartOutputBuilder(); + ((StartOutputBuilder)outObj).setCommonHeader(commonHeader); + ((StartOutputBuilder)outObj).setStatus(status); + return outObj; default: throw new IllegalArgumentException(action+" action is not supported"); } } - public static Payload convAsyncResponseTorev160108Payload(ResponseContext inObj) throws ParseException { + public static Payload convAsyncResponseTorev160108Payload(ResponseContext inObj) { Payload payload = null; if(inObj.getPayload() != null) { payload = new Payload(inObj.getPayload()); @@ -208,7 +257,7 @@ public class Converter { } CommonHeaderBuilder commonHeaderBuilder = new CommonHeaderBuilder(); - org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags commonHeaderFlags = null; + org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags commonHeaderFlags = null; if(inObj.getCommonHeader().getFlags() != null){ commonHeaderFlags = Converter.convFlagsMapTorev160108Flags(inObj.getCommonHeader().getFlags()); commonHeaderBuilder.setFlags(commonHeaderFlags); @@ -239,7 +288,7 @@ public class Converter { return isoFormatter.format(timeStamp); } - public static org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.common.header.Flags + public static org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags convFlagsMapTorev160108Flags(org.openecomp.appc.domainmodel.lcm.Flags flags) { Flags rev160108flags = null; boolean anyFlag = false; @@ -249,14 +298,14 @@ public class Converter { */ /* 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()); + org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags.Force force = + org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.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()); + org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags.Mode mode = + org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags.Mode.valueOf(flags.get(MODE_FLAG).toString()); flagsBuilder.setMode(mode); anyFlag = true; } @@ -307,6 +356,9 @@ public class Converter { public static DmaapOutgoingMessage convAsyncResponseToDmaapOutgoingMessage(VNFOperation vnfOperation, String rpcName, ResponseContext asyncResponse) throws JsonProcessingException { DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + String correlationID = getCorrelationID(asyncResponse); + outObj.setCorrelationID(correlationID); + outObj.setType("response"); outObj.setRpcName(rpcName); Builder<?> builder = Converter.convAsyncResponseToBuilder(vnfOperation, rpcName, asyncResponse); Object messageBody = builder.build(); @@ -315,6 +367,12 @@ public class Converter { return outObj; } + private static String getCorrelationID(ResponseContext context) { + return context.getCommonHeader().getRequestId() + + (context.getCommonHeader().getSubRequestId() == null ? + "":"-" + context.getCommonHeader().getSubRequestId()); + } + abstract class MixIn { @JsonIgnore abstract Class<? extends DataContainer> getImplementedInterface(); // to be removed during serialization diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/LCMOperationsDisabledException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/LCMOperationsDisabledException.java new file mode 100644 index 000000000..c067f303f --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/LCMOperationsDisabledException.java @@ -0,0 +1,36 @@ +/*- + * ============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 LCMOperationsDisabledException extends Exception { + + /** + * Constructs a new exception with the specified detail message. + * + * @param message the detail message. + */ + public LCMOperationsDisabledException(String message) { + super(message); + } +} diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/MissingVNFDataInAAIException.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/MissingVNFDataInAAIException.java new file mode 100644 index 000000000..7ffdb3801 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/exceptions/MissingVNFDataInAAIException.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.requesthandler.exceptions; + +public class MissingVNFDataInAAIException extends Exception { + String missingAttributeName; + public MissingVNFDataInAAIException(String attributeName) { + this.missingAttributeName = attributeName; + } + + public String getMissingAttributeName() { + return missingAttributeName; + } +} 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 index 874626c78..e51d4b978 100644 --- 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 @@ -76,4 +76,15 @@ public class RequestRegistry { set.remove(requestIdentifier); } + /** + * This method returns the count of currently registered requests + * in the request registry + * * @return currently registered requests count + */ + public int getRegisteredRequestCount() { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getRegisteredRequestCount"); + } + return set.size(); + } } 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 index 4f2986d74..a4a2beee5 100644 --- 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 @@ -28,10 +28,12 @@ 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.LCMOperationsDisabledException; +import org.openecomp.appc.requesthandler.exceptions.MissingVNFDataInAAIException; 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; + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException; } 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 index 4546726e9..c2455a3b4 100644 --- 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 @@ -36,6 +36,15 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; @JsonIgnoreProperties(ignoreUnknown = true) public class DmaapOutgoingMessage { + @JsonProperty("version") + private String version; + + @JsonProperty("type") + private String type; + + @JsonProperty("correlation-id") + private String correlationID; + private final static String defaultCambriaPartition = "MSO"; @JsonProperty("cambria.partition") private String cambriaPartition = defaultCambriaPartition; @@ -49,6 +58,30 @@ public class DmaapOutgoingMessage { public DmaapOutgoingMessage() { } + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCorrelationID() { + return correlationID; + } + + public void setCorrelationID(String correlationID) { + this.correlationID = correlationID; + } + public String getCambriaPartition() { return cambriaPartition; } diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/LCMStateManagerImpl.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/LCMStateManagerImpl.java new file mode 100644 index 000000000..0c97ebcbe --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/main/java/org/openecomp/appc/requesthandler/impl/LCMStateManagerImpl.java @@ -0,0 +1,62 @@ +/*- + * ============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.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.openecomp.appc.requesthandler.LCMStateManager; + +public class LCMStateManagerImpl implements LCMStateManager { + private static final EELFLogger logger = EELFManager.getInstance().getLogger(LCMStateManagerImpl.class); + private static AtomicBoolean isLCMEnabled = new AtomicBoolean(true); + + /** + * This method checks if the LCM operations are enabled or not + * * @return true if enabled else false + */ + public boolean isLCMOperationEnabled() { + return isLCMEnabled.get(); + } + + /** + * This method disables the LCM operations + */ + public void disableLCMOperations() { + if (logger.isTraceEnabled()) { + logger.trace("Entering to disableLCMOperations"); + } + isLCMEnabled.set(false); + } + + /** + * This method enables the LCM operations + */ + public void enableLCMOperations() { + if (logger.isTraceEnabled()) { + logger.trace("Entering to enableLCMOperations"); + } + isLCMEnabled.set(true); + } +} 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 index d63cb8bb8..e6f7452c9 100644 --- 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 @@ -40,7 +40,7 @@ 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.messageadapter.impl.MessageAdapterImpl; import org.openecomp.appc.metricservice.MetricRegistry; import org.openecomp.appc.metricservice.MetricService; import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; @@ -133,7 +133,7 @@ public class RequestHandlerImpl implements RequestHandler { public RequestHandlerImpl() { requestRegistry = new RequestRegistry(); - messageAdapter = new MessageAdapterDmaapImpl(); + messageAdapter = new MessageAdapterImpl(); messageAdapter.init(); Properties properties = configuration.getProperties(); if (properties != null && properties.getProperty("metric.enabled") != null) { @@ -215,7 +215,7 @@ public class RequestHandlerImpl implements RequestHandler { } 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); + output = buildRequestHandlerOutput(LCMCommandStatus.INVALID_VNF_STATE, params); } catch (UnstableVNFException e) { errorMessage = e.getMessage(); params = new Params().addParam("vnfId", vnfId); @@ -246,6 +246,15 @@ public class RequestHandlerImpl implements RequestHandler { } catch (DuplicateRequestException e) { errorMessage = e.getMessage(); output = buildRequestHandlerOutput(LCMCommandStatus.DUPLICATE_REQUEST, null); + } catch (MissingVNFDataInAAIException e) { + params = new Params().addParam("attributeName",e.getMissingAttributeName()) + .addParam("vnfId",vnfId); + output = buildRequestHandlerOutput(LCMCommandStatus.MISSING_VNF_DATA_IN_AAI,params); + errorMessage = output.getResponseContext().getStatus().getMessage(); + } catch (LCMOperationsDisabledException e) { + errorMessage = e.getMessage(); + params = new Params().addParam("errorMsg", errorMessage); + output = buildRequestHandlerOutput(LCMCommandStatus.REJECTED, params); } catch (Exception e) { storeErrorMessageToLog(runtimeContext, "", "", "Exception = " + e.getMessage()); errorMessage = e.getMessage() != null ? e.getMessage() : e.toString(); @@ -261,7 +270,11 @@ public class RequestHandlerImpl implements RequestHandler { runtimeContext.setResponseContext(output.getResponseContext()); if ((null == output) || !(output.getResponseContext().getStatus().getCode() == LCMCommandStatus.ACCEPTED.getResponseCode())) { if (isMetricEnabled) { - ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementRejectedRequest(); + if((output.getResponseContext().getStatus().getCode() == LCMCommandStatus.SUCCESS.getResponseCode())) { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementAcceptedRequest(); + }else { + ((DispatchingFuntionMetric) metricRegistry.metric("DISPATCH_FUNCTION")).incrementRejectedRequest(); + } } removeRequestFromRegistry(input.getRequestContext().getCommonHeader()); } @@ -580,14 +593,18 @@ public class RequestHandlerImpl implements RequestHandler { 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(!readOnlyActivity || !forceFlag || workingStateManager.isVNFStable(vnfId)) { + boolean updated = false; + try { + updated = workingStateManager.setWorkingState(vnfId, VNFWorkingState.UNSTABLE, requestIdentifierString, forceFlag); + } catch (Exception e) { + logger.error("Error updating working state for vnf " + vnfId + e); + throw new RuntimeException(e); + } 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()) @@ -805,4 +822,16 @@ public class RequestHandlerImpl implements RequestHandler { return null; } } + + /** + * This method returns the count of in progress requests + * * @return in progress requests count + */ + @Override + public int getInprogressRequestCount() { + if (logger.isTraceEnabled()) { + logger.trace("Entering to getInprogressRequestCount"); + } + return requestRegistry.getRegisteredRequestCount(); + } } 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 index 509c351ea..8499937c7 100644 --- 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 @@ -24,6 +24,7 @@ package org.openecomp.appc.requesthandler.impl; import java.time.Instant; import org.apache.commons.lang.ObjectUtils; +import org.apache.commons.lang.StringUtils; import org.openecomp.appc.common.constant.Constants; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; @@ -40,6 +41,8 @@ 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.LCMStateManager; +import org.openecomp.appc.requesthandler.exceptions.*; import org.openecomp.appc.requesthandler.exceptions.DGWorkflowNotFoundException; import org.openecomp.appc.requesthandler.exceptions.DuplicateRequestException; import org.openecomp.appc.requesthandler.exceptions.InvalidInputException; @@ -74,6 +77,7 @@ public class RequestValidatorImpl implements RequestValidator { private WorkFlowManager workflowManager; private WorkingStateManager workingStateManager; + private LCMStateManager lcmStateManager; private final RequestRegistry requestRegistry = new RequestRegistry(); @@ -93,14 +97,26 @@ public class RequestValidatorImpl implements RequestValidator { this.workingStateManager = workingStateManager; } + public void setLcmStateManager(LCMStateManager lcmStateManager) { + this.lcmStateManager = lcmStateManager; + } + public RequestValidatorImpl() { } @Override - public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void validateRequest(RuntimeContext runtimeContext) throws VNFNotFoundException, RequestExpiredException, UnstableVNFException, InvalidInputException, DuplicateRequestException, NoTransitionDefinedException, LifecycleException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { if (logger.isTraceEnabled()){ logger.trace("Entering to validateRequest with RequestHandlerInput = "+ ObjectUtils.toString(runtimeContext)); } + if(!lcmStateManager.isLCMOperationEnabled()) { + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.REQUEST_VALIDATOR, + EELFResourceManager.format(Msg.LCM_OPERATIONS_DISABLED), + this.getClass().getCanonicalName()); + throw new LCMOperationsDisabledException("APPC LCM operations have been administratively disabled"); + } + getAAIservice(); validateInput(runtimeContext.getRequestContext()); checkVNFWorkingState(runtimeContext); @@ -114,9 +130,9 @@ public class RequestValidatorImpl implements RequestValidator { // for built-in operations skip WF presence check queryWFM(vnfContext, runtimeContext.getRequestContext()); } - } + } - private boolean isValidTTL(String ttl) { + private boolean isValidTTL(String ttl) { if (logger.isTraceEnabled()){ logger.trace("Entering to isValidTTL where ttl = "+ ObjectUtils.toString(ttl)); } @@ -206,7 +222,7 @@ public class RequestValidatorImpl implements RequestValidator { } } - private VNFContext queryAAI(String vnfId) throws VNFNotFoundException { + private VNFContext queryAAI(String vnfId) throws VNFNotFoundException, MissingVNFDataInAAIException { SvcLogicContext ctx = new SvcLogicContext(); ctx = getVnfdata(vnfId, "vnf", ctx); @@ -267,9 +283,17 @@ public class RequestValidatorImpl implements RequestValidator { } } - private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) { - vnfContext.setType(ctx.getAttribute("vnf.vnf-type")); - vnfContext.setStatus(ctx.getAttribute("vnf.orchestration-status")); + private void populateVnfContext(VNFContext vnfContext, SvcLogicContext ctx) throws MissingVNFDataInAAIException { + String vnfType = ctx.getAttribute("vnf.vnf-type"); + String orchestrationStatus = ctx.getAttribute("vnf.orchestration-status"); + if(StringUtils.isEmpty(vnfType)){ + throw new MissingVNFDataInAAIException("vnf-type"); + } + else if(StringUtils.isEmpty(orchestrationStatus)){ + throw new MissingVNFDataInAAIException("orchestration-status"); + } + vnfContext.setType(vnfType); + vnfContext.setStatus(orchestrationStatus); vnfContext.setId(ctx.getAttribute("vnf.vnf-id")); // TODO: Uncomment once A&AI supports VNF version //vnfContext.setVersion(ctx.getAttribute("vnf.vnf-version")); 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 index 785b6cb04..984de9878 100644 --- 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 @@ -39,9 +39,13 @@ <property name="lifecyclemanager" ref="lifecyclemanagerRef" /> <property name="workflowManager" ref="workflowManagerRef" /> <property name="workingStateManager" ref="workingStateManagerBean" /> + <property name="lcmStateManager" ref="lcmStateManagerBean" /> </bean> + <bean id="lcmStateManagerBean" class="org.openecomp.appc.requesthandler.impl.LCMStateManagerImpl" scope="singleton" /> + <service id="requestHandlerService" interface="org.openecomp.appc.requesthandler.RequestHandler" ref="requestHandlerBean"/> + <service id="lcmStateManagerService" interface="org.openecomp.appc.requesthandler.LCMStateManager" ref="lcmStateManagerBean"/> <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" /> 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 index 2e2763f9a..ba24304f9 100644 --- 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 @@ -25,21 +25,14 @@ 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 +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-REQ-HLDR-MAIN +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -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 diff --git a/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/LCMStateManagerImplTest.java b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/LCMStateManagerImplTest.java new file mode 100644 index 000000000..2c8d56e51 --- /dev/null +++ b/appc-dispatcher/appc-request-handler/appc-request-handler-core/src/test/java/org/openecomp/appc/requesthandler/LCMStateManagerImplTest.java @@ -0,0 +1,55 @@ +/*- + * ============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.openecomp.appc.requesthandler.impl.LCMStateManagerImpl; + +public class LCMStateManagerImplTest { + + LCMStateManager lcmStateManager; + + @Before + public void init() throws Exception { + lcmStateManager = new LCMStateManagerImpl(); + } + + /** + * Test to check the disable LCM operations method + */ + @Test + public void disableLCMOperations() throws Exception { + lcmStateManager.disableLCMOperations(); + Assert.assertFalse(lcmStateManager.isLCMOperationEnabled()); + } + + /** + * Test to check the enable LCM operations method + */ + @Test + public void enableLCMOperations() throws Exception { + lcmStateManager.enableLCMOperations(); + Assert.assertTrue(lcmStateManager.isLCMOperationEnabled()); + } +} 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 index c54f94750..17a62b17f 100644 --- 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 @@ -28,7 +28,6 @@ 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.time.Instant; import java.util.Date; @@ -37,19 +36,20 @@ 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\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"test\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"rollback\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"snapshot\",\"type\":\"response\"}"; + 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\"},\"payload\":\"{}\",\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"correlation-id\":\"reqid\",\"rpc-name\":\"audit\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"health-check\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"live-upgrade\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"lock\",\"type\":\"response\"}"; + 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\"},\"payload\":\"{}\",\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"correlation-id\":\"reqid\",\"rpc-name\":\"config-modify\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"software-upload\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"stop\",\"type\":\"response\"}"; + 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\"},\"payload\":\"{}\",\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}},\"cambria.partition\":\"MSO\",\"correlation-id\":\"reqid\",\"rpc-name\":\"sync\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"terminate\",\"type\":\"response\"}"; + 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\",\"correlation-id\":\"reqid\",\"rpc-name\":\"unlock\",\"type\":\"response\"}"; + private String expectedJsonBodyStrwithPayload ="{\"output\":{\"common-header\":{\"api-ver\":\"2.0.0\",\"flags\":{},\"originator-id\":\"oid\",\"request-id\":\"reqid\",\"timestamp\":\"1970-01-01T00:00:01.000Z\"},\"payload\":\"{}\",\"status\":{\"code\":400,\"message\":\"SUCCESS - request has been processed successfully\"}}}"; @Test public void convDateToZuluStringTest(){ @@ -126,16 +126,16 @@ public class TestConverter { } @Test public void convAsyncResponseToBuilderAuditTest() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); VNFOperation action = VNFOperation.Audit; String rpcName = action.name().toLowerCase(); String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); - Assert.assertEquals(expectedJsonBodyStr,jsonStr); + Assert.assertEquals(expectedJsonBodyStrwithPayload,jsonStr); } @Test public void convAsyncResponseToDmaapOutgoingMessageJsonStringAuditTest() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); VNFOperation action = VNFOperation.Audit; String rpcName = action.name().toLowerCase(); String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); @@ -199,17 +199,17 @@ public class TestConverter { } @Test public void convAsyncResponseToBuilderModifyConfigTest() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); - VNFOperation action = VNFOperation.ModifyConfig; + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); + VNFOperation action = VNFOperation.ConfigModify; String rpcName = convertActionNameToUrl(action.name()); String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); - Assert.assertEquals(expectedJsonBodyStr,jsonStr); + Assert.assertEquals(expectedJsonBodyStrwithPayload,jsonStr); } @Test public void convAsyncResponseToDmaapOutgoingMessageJsonStringModifyConfigTest() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); - VNFOperation action = VNFOperation.ModifyConfig; + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); + VNFOperation action = VNFOperation.ConfigModify; String rpcName = convertActionNameToUrl(action.name()); String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); System.out.println("jsonStr = " + jsonStr); @@ -254,17 +254,17 @@ public class TestConverter { } @Test public void convAsyncResponseToBuilderSync() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); VNFOperation action = VNFOperation.Sync; String rpcName = convertActionNameToUrl(action.name()); String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); - Assert.assertEquals(expectedJsonBodyStr,jsonStr); + Assert.assertEquals(expectedJsonBodyStrwithPayload,jsonStr); } @Test public void convAsyncResponseToDmaapOutgoingMessageJsonStringSync() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); VNFOperation action = VNFOperation.Sync; String rpcName = convertActionNameToUrl(action.name()); String jsonStr = Converter.convAsyncResponseToDmaapOutgoingMessageJsonString(action, rpcName, asyncResponse); @@ -273,11 +273,11 @@ public class TestConverter { } @Test public void convAsyncResponseToBuilderTerminateTest() throws JsonProcessingException { - ResponseContext asyncResponse = buildAsyncResponse(); + ResponseContext asyncResponse = buildAsyncResponsewithPayload(); VNFOperation action = VNFOperation.Sync; String rpcName = convertActionNameToUrl(action.name()); String jsonStr = Converter.convAsyncResponseToJsonStringBody(action, rpcName, asyncResponse); - Assert.assertEquals(expectedJsonBodyStr,jsonStr); + Assert.assertEquals(expectedJsonBodyStrwithPayload,jsonStr); } @Test @@ -334,6 +334,17 @@ public class TestConverter { return asyncResponse; } + private ResponseContext buildAsyncResponsewithPayload() { + ResponseContext asyncResponse = createResponseContextWithSubObjects(); + asyncResponse.setStatus(LCMCommandStatus.SUCCESS.toStatus(null)); + asyncResponse.getCommonHeader().setOriginatorId("oid"); + asyncResponse.getCommonHeader().setApiVer("2.0.0"); + asyncResponse.getCommonHeader().setRequestId("reqid"); + asyncResponse.getCommonHeader().setTimestamp(Instant.ofEpochMilli(1000L)); + asyncResponse.setPayload("{}"); + return asyncResponse; + } + private ResponseContext createResponseContextWithSubObjects() { ResponseContext responseContext = new ResponseContext(); 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 index 1af658f0a..112965575 100644 --- 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 @@ -38,6 +38,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mockito; +import org.openecomp.appc.adapter.factory.DmaapMessageAdapterFactoryImpl; +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.messaging.dmaap.impl.DmaapProducerImpl; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.domainmodel.lcm.*; +import org.openecomp.appc.domainmodel.lcm.Flags.Mode; import org.openecomp.appc.domainmodel.lcm.ActionIdentifiers; import org.openecomp.appc.domainmodel.lcm.CommonHeader; import org.openecomp.appc.domainmodel.lcm.Flags; @@ -56,6 +63,8 @@ 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.messageadapter.impl.MessageAdapterImpl; +import org.openecomp.appc.requesthandler.exceptions.*; import org.openecomp.appc.requesthandler.exceptions.DGWorkflowNotFoundException; import org.openecomp.appc.requesthandler.exceptions.DuplicateRequestException; import org.openecomp.appc.requesthandler.exceptions.InvalidInputException; @@ -73,7 +82,15 @@ 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 org.openecomp.sdnc.sli.aai.AAIService; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; + +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; @@ -82,7 +99,7 @@ import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; @RunWith(PowerMockRunner.class) -@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) +@PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class, MessageAdapterImpl.class}) public class TestRequestHandler { private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); @@ -92,10 +109,29 @@ public class TestRequestHandler { private WorkFlowManager workflowManager; private WorkingStateManager workingStateManager ; private LockManager lockManager; + private Configuration configuration; + private final BundleContext bundleContext=Mockito.mock(BundleContext.class); + private final Bundle bundleService=Mockito.mock(Bundle.class); + private final ServiceReference sref=Mockito.mock(ServiceReference.class); + MessageAdapterFactory factory = new DmaapMessageAdapterFactoryImpl(); + + @Before public void init() throws Exception { - + configuration = ConfigurationFactory.getConfiguration(); + + configuration.setProperty("appc.LCM.topic.write" , "TEST"); + configuration.setProperty("appc.LCM.client.key" , "TEST"); + configuration.setProperty("appc.LCM.client.secret" , "TEST"); + + PowerMockito.mockStatic(FrameworkUtil.class); + PowerMockito.when(FrameworkUtil.getBundle(MessageAdapterImpl.class)).thenReturn(bundleService); + PowerMockito.when(bundleService.getBundleContext()).thenReturn(bundleContext); + PowerMockito.when(bundleContext.getServiceReference(MessageAdapterFactory.class.getName())).thenReturn(sref); + PowerMockito.when(bundleContext.getService(sref)).thenReturn(factory); + + requestHandler = new RequestHandlerImpl(); LifecycleManager lifecyclemanager= mock(LifecycleManager.class); workflowManager= mock(WorkFlowManager.class); @@ -161,7 +197,7 @@ public class TestRequestHandler { } @Test - public void testInvalidVNFExceptionRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testInvalidVNFExceptionRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -174,7 +210,7 @@ public class TestRequestHandler { } @Test - public void testLifecycleException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testLifecycleException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -183,12 +219,12 @@ public class TestRequestHandler { RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID, Instant.now()); 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()); + Assert.assertEquals(LCMCommandStatus.INVALID_VNF_STATE.getResponseCode(), output.getResponseContext().getStatus().getCode()); } @Test - public void testRequestExpiredException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testRequestExpiredException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -200,7 +236,19 @@ public class TestRequestHandler { } @Test - public void testWorkflowNotFoundException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testMissingVNFdata() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { + String originatorID = UUID.randomUUID().toString(); + String requestID = UUID.randomUUID().toString(); + String subRequestID = UUID.randomUUID().toString(); + + RequestHandlerInput input = this.getRequestHandlerInput("3009", VNFOperation.Configure,0,false,originatorID, requestID, subRequestID,Instant.now()); + PowerMockito.doThrow(new MissingVNFDataInAAIException("vnf-type")).when(requestValidator).validateRequest(Matchers.any(RuntimeContext.class)); + RequestHandlerOutput output = requestHandler.handleRequest(input); + Assert.assertEquals(LCMCommandStatus.MISSING_VNF_DATA_IN_AAI.getResponseCode(), output.getResponseContext().getStatus().getCode()); + } + + @Test + public void testWorkflowNotFoundException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -224,7 +272,7 @@ public class TestRequestHandler { } @Test - public void testInvalidInputException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testInvalidInputException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID1 = UUID.randomUUID().toString(); String requestID1 = UUID.randomUUID().toString(); String subRequestID1 = UUID.randomUUID().toString(); @@ -236,7 +284,7 @@ public class TestRequestHandler { } @Test - public void testNoTransitionDefinedException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testNoTransitionDefinedException() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -249,7 +297,7 @@ public class TestRequestHandler { } @Test - public void rejectInvalidRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void rejectInvalidRequest() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); @@ -331,7 +379,6 @@ public class TestRequestHandler { } - @Test public void testOnRequestExecutionEndFailureForWorkingState() throws Exception { logger.debug("=====================testOnRequestExecutionEndFailureForWorkingState============================="); 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 index 16caf5860..6d2b4a168 100644 --- 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 @@ -34,31 +34,17 @@ import java.util.Map; import java.util.UUID; import org.junit.Before; -import org.junit.Ignore; 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.ActionIdentifiers; -import org.openecomp.appc.domainmodel.lcm.CommonHeader; -import org.openecomp.appc.domainmodel.lcm.Flags; -import org.openecomp.appc.domainmodel.lcm.RequestContext; -import org.openecomp.appc.domainmodel.lcm.ResponseContext; -import org.openecomp.appc.domainmodel.lcm.RuntimeContext; -import org.openecomp.appc.domainmodel.lcm.Status; -import org.openecomp.appc.domainmodel.lcm.VNFContext; -import org.openecomp.appc.domainmodel.lcm.VNFOperation; +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.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; +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; @@ -84,7 +70,6 @@ import com.att.eelf.configuration.EELFManager; @RunWith(PowerMockRunner.class) @PrepareForTest( {WorkingStateManager.class,FrameworkUtil.class, TransactionRecorder.class, RequestHandlerImpl.class,RequestValidatorImpl.class, TransactionRecorder.class}) -@Ignore public class TestRequestValidator { private static final EELFLogger logger = EELFManager.getInstance().getLogger(TestRequestHandler.class); @@ -97,6 +82,7 @@ public class TestRequestValidator { LifecycleManager lifecyclemanager; WorkFlowManager workflowManager; WorkingStateManager workingStateManager ; + LCMStateManager lcmStateManager; // AppcDAOImpl dao ; private final BundleContext bundleContext= Mockito.mock(BundleContext.class); @@ -147,6 +133,7 @@ public class TestRequestValidator { lifecyclemanager= Mockito.mock(LifecycleManager.class); workflowManager= Mockito.mock(WorkFlowManager.class); workingStateManager = Mockito.mock(WorkingStateManager.class); + lcmStateManager = Mockito.mock(LCMStateManager.class); // transactionRecorder= spy(TransactionRecorder.class); requestValidator = new RequestValidatorImpl(); @@ -154,8 +141,9 @@ public class TestRequestValidator { requestValidator.setWorkflowManager(workflowManager); requestValidator.setLifecyclemanager(lifecyclemanager); requestValidator.setWorkingStateManager(workingStateManager); + requestValidator.setLcmStateManager(lcmStateManager); - + Mockito.when(lcmStateManager.isLCMOperationEnabled()).thenReturn(true); /* Mockito.when(workingStateManager.isVNFStable("1")).thenReturn(true); Mockito.when(aaiAdapter.requestGenericVnfData("1")).thenReturn(getGenericVnf("FIREWALL","INSTNATIATED"));*/ // Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(true); @@ -254,7 +242,7 @@ public class TestRequestValidator { return input; } @Test - public void testNullVnfID() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testNullVnfID() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { logger.debug("=====================testNullVnfID============================="); Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); RequestHandlerInput input = this.getRequestHandlerInput(null, VNFOperation.Configure, 30, @@ -309,8 +297,8 @@ public class TestRequestValidator { - @Test - public void testNullCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + @Test + public void testNullCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { logger.debug("=====================testNullCommand============================="); Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); RequestHandlerInput input = this.getRequestHandlerInput("7", null,30, @@ -327,7 +315,7 @@ public class TestRequestValidator { } @Test - public void testNullVnfIDAndCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException,DGWorkflowNotFoundException { + public void testNullVnfIDAndCommand() throws NoTransitionDefinedException, LifecycleException, InvalidInputException, RequestExpiredException, UnstableVNFException, DuplicateRequestException, VNFNotFoundException, WorkflowNotFoundException, DGWorkflowNotFoundException, MissingVNFDataInAAIException, LCMOperationsDisabledException { logger.debug("=====================testNullVnfIDAndCommand============================="); Mockito.when(workflowManager.workflowExists((WorkflowRequest)anyObject())).thenReturn(new WorkflowExistsOutput(true,true)); RequestHandlerInput input = this.getRequestHandlerInput(null, null,30, @@ -545,45 +533,50 @@ public class TestRequestValidator { } @Test - public void testLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException { + public void testLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + public void testUnlockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + public void testCheckLockOperation() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + public void testLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + public void testUnlockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + public void testCheckLockOperationNegative() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { 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 { + @Test(expected = LCMOperationsDisabledException.class) + public void testLCMOperationsDisabled() throws RequestExpiredException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, WorkflowNotFoundException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, InvalidInputException, MissingVNFDataInAAIException, LCMOperationsDisabledException { + Mockito.when(lcmStateManager.isLCMOperationEnabled()).thenReturn(false); + testOperation("no-matter", VNFOperation.Configure); + } + private void testOperation(String resource, VNFOperation operation) throws WorkflowNotFoundException, DuplicateRequestException, DGWorkflowNotFoundException, VNFNotFoundException, InvalidInputException, LifecycleException, UnstableVNFException, NoTransitionDefinedException, RequestExpiredException, MissingVNFDataInAAIException, LCMOperationsDisabledException { String originatorID = UUID.randomUUID().toString(); String requestID = UUID.randomUUID().toString(); String subRequestID = UUID.randomUUID().toString(); 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 index 2d75df419..0659d4dc5 100644 --- 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 @@ -77,27 +77,15 @@ 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 +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-REQ-HDLR-TEST +appc.LCM.provider.user=test +appc.LCM.provider.pass=test + -# -# 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 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 index cc8fe1192..f2e79ed43 100644 --- 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 @@ -27,10 +27,15 @@ <feature name='appc-request-handler' description="appc-request-handler" version='${project.version}'> <bundle>mvn:org.openecomp.appc/transaction-recorder/${project.version}</bundle> + + <!-- appc-data-access-lib bundle is flagged as being a dependency --> + <bundle dependency="true">mvn:org.openecomp.appc/appc-data-access-lib/${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-workflow-management/appc-workflow-management-core/pom.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml index 33c83974c..c3ced2131 100644 --- a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml +++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/pom.xml @@ -52,6 +52,11 @@ <artifactId>appc-ranking-framework-lib</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>equinoxSDK381</groupId> + <artifactId>org.eclipse.osgi</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> @@ -63,10 +68,14 @@ <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-Version>${project.version}</Bundle-Version> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic,appc-data-access-lib,javax.json;scope=compile|runtime;inline=false</Embed-Dependency> + <Embed-Dependency>javax.json;scope=compile|runtime;inline=false</Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> <Export-Service>org.openecomp.appc.workflow.WorkFlowManager</Export-Service> - <Import-Package>org.openecomp.appc.workflow,org.openecomp.appc.workflow.objects,!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> + <Import-Package> + org.openecomp.appc.workflow,org.openecomp.appc.workflow.objects, org.openecomp.appc.configuration, + org.openecomp.appc.util,com.att.eelf.configuration, org.openecomp.appc.dao.util, + *;resolution:=optional + </Import-Package> </instructions> </configuration> </plugin> diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java index 4ed575567..e40dc6254 100644 --- a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java +++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/java/org/openecomp/appc/workflow/impl/WorkFlowManagerImpl.java @@ -21,11 +21,6 @@ package org.openecomp.appc.workflow.impl; -import java.text.SimpleDateFormat; -import java.util.Enumeration; -import java.util.Map; -import java.util.Properties; - import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.openecomp.appc.common.constant.Constants; @@ -44,6 +39,11 @@ import com.att.eelf.configuration.EELFManager; import org.openecomp.sdnc.sli.SvcLogicException; import org.openecomp.sdnc.sli.provider.SvcLogicService; +import java.text.SimpleDateFormat; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; + public class WorkFlowManagerImpl implements WorkFlowManager{ private SvcLogicService svcLogic = null; @@ -166,7 +166,7 @@ public class WorkFlowManagerImpl implements WorkFlowManager{ workflowParams.put("input.common-header.api-ver",workflowRequest.getRequestContext().getCommonHeader().getApiVer()); workflowParams.put("input.common-header.request-id",workflowRequest.getRequestContext().getCommonHeader().getRequestId()); workflowParams.put("input.common-header.originator-id",workflowRequest.getRequestContext().getCommonHeader().getOriginatorId()); - workflowParams.put("input.common-header.sub-request-id",workflowRequest.getRequestContext().getCommonHeader().getSubRequestId()); + workflowParams.put("input.common-header.sub-request-id",workflowRequest.getRequestContext().getCommonHeader().getSubRequestId()!=null ? workflowRequest.getRequestContext().getCommonHeader().getSubRequestId():""); workflowParams.put("input.action",workflowRequest.getRequestContext().getAction().toString()); workflowParams.put("input.payload",null != workflowRequest.getRequestContext().getPayload() ? workflowRequest.getRequestContext().getPayload() : ""); workflowParams.put("input.action-identifiers.vnf-id",workflowRequest.getVnfContext().getId()); diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties index 44745d049..947e81ccd 100644 --- a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/main/resources/org/openecomp/appc/default.properties @@ -24,29 +24,17 @@ 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 +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-WF-MGMT-MAIN +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -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-WF-MGMT-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 # Tolerance interval (in seconds) between invalidation of DG resolver configuration org.openecomp.appc.workflow.resolver.refresh_interval=300 -# -# 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: diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties index 713e03430..14200d668 100644 --- a/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties +++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-core/src/test/resources/org/openecomp/appc/default.properties @@ -76,25 +76,12 @@ org.openecomp.appc.db.url.%s", schema), ""); org.openecomp.appc.db.user.%s", schema), ""); org.openecomp.appc.db.pass.%s", schema), ""); -# This value is provided in 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 -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=2 -dmaap.threads.poolsize.max=2 +#Property below provided by appc.properties +appc.LCM.provider.url=https://localhost:8443/restconf/operations/appc-provider-lcm +appc.LCM.poolMembers=<DMAAP_IP>:3904 +appc.LCM.service=dmaap +appc.LCM.topic.write=APPC-TEST2 +appc.LCM.client.name=APPC-TEST-CLIENT-WF-MGMT-MAIN +appc.LCM.provider.user=test +appc.LCM.provider.pass=test -# -# 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: diff --git a/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml index ae1105d2b..dc50a4c6f 100644 --- a/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml +++ b/appc-dispatcher/appc-workflow-management/appc-workflow-management-features/src/main/resources/features.xml @@ -23,9 +23,11 @@ <features name="appc-workflow-management-${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"> - + xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0"> + <feature name='appc-workflow-management' description="application executor" version='${project.version}'> + <bundle dependency="true">mvn:org.openecomp.appc/appc-data-access-lib/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-workflow-management-api/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-workflow-management-core/${project.version}</bundle> <bundle start="true" dependency="true">mvn:org.openecomp.appc/appc-ranking-framework-lib/${project.version}</bundle> diff --git a/appc-dispatcher/pom.xml b/appc-dispatcher/pom.xml index 58bfd5bec..e54c5a744 100644 --- a/appc-dispatcher/pom.xml +++ b/appc-dispatcher/pom.xml @@ -55,7 +55,6 @@ <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> - <version>2.3.7</version> <extensions>true</extensions> </plugin> </plugins> diff --git a/appc-event-listener/appc-event-listener-bundle/pom.xml b/appc-event-listener/appc-event-listener-bundle/pom.xml index 7b2285ad2..52dccf043 100644 --- a/appc-event-listener/appc-event-listener-bundle/pom.xml +++ b/appc-event-listener/appc-event-listener-bundle/pom.xml @@ -32,6 +32,19 @@ <groupId>org.openecomp.appc</groupId> <artifactId>appc-dmaap-adapter-bundle</artifactId> <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + <scope>provided</scope> </dependency> <!-- <dependency> @@ -58,6 +71,12 @@ <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>1.2</version> + <scope>compile</scope> + </dependency> <dependency> <groupId>junit</groupId> @@ -78,28 +97,15 @@ <Bundle-SymbolicName>org.openecomp.appc.listener</Bundle-SymbolicName> <Bundle-Activator>org.openecomp.appc.listener.AppcEventListenerActivator</Bundle-Activator> <Export-Package>org.openecomp.appc.listener</Export-Package> - <Import-Package> - !com.datastax.*, - !com.ibm.icu.text, - !com.jcraft.jzlib, - !groovy.lang, - !javax.jms, - !net.sf.ehcache, - !net.spy.memcached, - !org.apache.commons.lang3, - !org.apache.log, - !org.apache.log4j.*, - !org.apache.zookeeper.*, - !org.jasypt.*, - !org.codehaus.commons.compiler, - !org.codehaus.groovy.*, - !org.codehaus.jackson.*, - !org.codehaus.jackson.map.*, - !org.codehaus.janino, - !org.I0Itec.*, - !com.sun.faces.*, - *;resolution:=optional</Import-Package> - <Embed-Dependency>*;scope=compile|runtime;artifactId=!appc-metric-bundle|sli-common|org.eclipse.osgi|slf4j-api|jcl-over-slf4j|mysql-connector-java|xml-apis|pax-*</Embed-Dependency> + <Import-Package>org.openecomp.appc.adapter.message.*,org.openecomp.appc.adapter.factory.*,org.openecomp.appc.adapter.messaging.* + org.openecomp.appc.exceptions, org.openecomp.appc.util, + com.att.eelf.configuration, com.att.eelf.i18n, + *;resolution:=optional + </Import-Package> + <Embed-Dependency> + jasypt,commons-lang,commons-lang3,appc-common, + logback-core,logback-classic,eelf-core,commons-logging;scope=compile|runtime;inline=false + </Embed-Dependency> <Embed-Transitive>true</Embed-Transitive> </instructions> </configuration> diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java index b5f0af598..e9e4bd936 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/AppcEventListenerActivator.java @@ -117,11 +117,13 @@ public class AppcEventListenerActivator implements BundleActivator { Properties props = configuration.getProperties(); Set<ListenerProperties> listeners = new HashSet<ListenerProperties>(); - - // Configure App-C 1607 Closed Loop Listener - ListenerProperties cl1607Props = new ListenerProperties("appc.ClosedLoop1607", props); - cl1607Props.setListenerClass(org.openecomp.appc.listener.CL1607.impl.ListenerImpl.class); - listeners.add(cl1607Props); + + // Configure event listener for the demo use case + ListenerProperties demoProps = new ListenerProperties("appc.demo", props); + demoProps.setListenerClass(org.openecomp.appc.listener.demo.impl.ListenerImpl.class); + listeners.add(demoProps); + + // =========================================================================== adapter = new ControllerImpl(listeners); if (ctx != null && registration == null) { diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java deleted file mode 100644 index 3f0f8a112..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/ListenerImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -/*- - * ============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.listener.CL.impl; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; -import java.util.concurrent.RejectedExecutionException; - -import org.openecomp.appc.listener.AbstractListener; -import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.CL.model.IncomingMessage; -import org.openecomp.appc.listener.CL.model.Status; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; -import com.att.eelf.i18n.EELFResourceManager; - -public class ListenerImpl extends AbstractListener { - - private final EELFLogger LOG = EELFManager.getInstance().getLogger(ListenerImpl.class); - - private long startTime = 0; - - public ListenerImpl(ListenerProperties props) { - super(props); - String url = props.getProperty("provider.url"); - LOG.info("DMaaP Provider Endpoint: " + url); - ProviderOperations.setUrl(url); - - // Set Basic Auth - String user = props.getProperty("provider.user"); - String pass = props.getProperty("provider.pass"); - ProviderOperations.setAuthentication(user, pass); - } - - @Override - public void run() { - // Some vars for benchmarking - startTime = System.currentTimeMillis(); - - LOG.info("Running DMaaP Listener"); - - while (run.get()) { - // Only update if the queue is low. otherwise we read in more - // messages than we need - try { - if (executor.getQueue().size() <= QUEUED_MIN) { - LOG.debug("DMaaP queue running low. Querying for more jobs"); - List<IncomingMessage> messages = dmaap.getIncomingEvents(IncomingMessage.class, QUEUED_MAX); - LOG.debug(String.format("Read %d messages from dmaap", messages.size())); - for (IncomingMessage incoming : messages) { - // Acknowledge that we read the event - LOG.info("Acknowledging Message: " + incoming.getId()); - dmaap.postStatus(incoming.toOutgoing(Status.PENDING, null).toString()); - } - for (IncomingMessage incoming : messages) { - // Add to pool if still running - if (run.get()) { - LOG.info(String.format("Adding DMaaP message to pool queue [%s]", incoming.getId())); - if (incoming.isValid()) { - try { - executor.execute(new WorkerImpl(incoming, dmaap)); - } catch (RejectedExecutionException rejectEx) { - LOG.error("Task Rejected: ", rejectEx); - } - } else { - // Badly formed message - LOG.error("Message was not valid. Rejecting"); - } - } else { - LOG.info("Run stopped. Orphaning Message: " + incoming.getId()); - } - } - } - } catch (Exception e) { - LOG.error("Exception " + e.getClass().getSimpleName() + " caught in DMaaP listener"); - LOG.error(EELFResourceManager.format(e)); - LOG.error("DMaaP Listener logging and ignoring the exception, continue..."); - } - } - - LOG.info("Stopping DMaaP Listener thread"); - - // We've told the listener to stop - // TODO - Should we: - // 1) Put a message back on the queue indicating that APP-C never got to - // the message - // or - // 2) Let downstream figure it out after timeout between PENDING and - // ACTIVE messages - } - - @Override - public String getBenchmark() { - long time = System.currentTimeMillis(); - DateFormat df = new SimpleDateFormat("HH:mm:ss"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); - String runningTime = df.format(new Date(time - startTime)); - - String out = String.format("Running for %s and completed %d jobs using %d threads.", runningTime, - executor.getCompletedTaskCount(), executor.getPoolSize()); - LOG.info("***BENCHMARK*** " + out); - return out; - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java deleted file mode 100644 index 1eb13f736..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/impl/WorkerImpl.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ============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.listener.CL.impl; - -import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.appc.listener.EventHandler; -import org.openecomp.appc.listener.CL.model.IncomingMessage; -import org.openecomp.appc.listener.CL.model.Status; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; - -public class WorkerImpl implements Runnable { - - private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class); - - // Should have all of the data we need for processing - private IncomingMessage event; - - // So we can post messages from inside the worker. - private EventHandler dmaap; - - public WorkerImpl(IncomingMessage message, EventHandler dmaap) { - this.event = message; - this.dmaap = dmaap; - } - - @Override - public void run() { - LOG.debug(String.format("Started working on %s", event.getId())); - dmaap.postStatus(event.toOutgoing(Status.ACTIVE, null)); - // Run the dg in a try catch to handle all exceptions and update the - // message at the end - try { - if (doDG(event)) { - dmaap.postStatus(event.toOutgoing(Status.SUCCESS, null)); - LOG.debug(String.format("Event %s finished successfully", event.getId())); - } else { - // Should never happen. Exception with message should be thrown instead. - LOG.error(String.format( - "We somehow returned false from doDG() instead of throwing exception. Incoming event [%s]", - event.toJson().toString())); - dmaap.postStatus(event.toOutgoing(Status.FAILURE)); - } - - } catch (Exception e) { - // Unknown exception from DG method. Fail and pass the exception - // along - String msg = "Exception: " + e.getMessage(); - LOG.warn(String.format("Event %s finished with failure. %s", event.getId(), msg)); - dmaap.postStatus(event.toOutgoing(Status.FAILURE, msg)); - } - - LOG.debug("Done working on " + event.getId()); - } - - private boolean doDG(IncomingMessage msg) throws APPCException { - return ProviderOperations.topologyDG(msg); - } -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java deleted file mode 100644 index 76a112618..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/CommonMessage.java +++ /dev/null @@ -1,181 +0,0 @@ -/*- - * ============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.listener.CL.model; - -import java.io.Serializable; - -import org.json.JSONObject; -import org.openecomp.appc.listener.util.Mapper; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; - -/** - * This class holds attributes that are common to DMaaP messages both coming in from DCAE and being sent out by APPC - * - */ -@JsonSerialize(include = Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class CommonMessage implements Serializable { - - private static final long serialVersionUID = 1L; - - /* - * The unique id of the event as of 1602 - */ - @JsonProperty("eventID") - private String id; - - /* - * The time that the request was sent out. - */ - @JsonProperty("requestTime") - private String requestTime; - - /* - * The originator of the event - */ - @JsonProperty("requestClient") - private String requestClient; - - /* - * The system that sent the message - */ - @JsonProperty("from") - private String fromSystem; - - /* - * The actual trap message - */ - @JsonProperty("message") - private String message; - - /* - * The vm name associated with the event - */ - @JsonProperty("VMName") - private String vmName; - - /* - * The policy name on the incoming event - */ - @JsonProperty("policyName") - private String policyName; - - /* - * The policy version on the incoming event - */ - @JsonProperty("policyVersion") - private String policyVersion; - - @JsonIgnore - private long startTime = System.currentTimeMillis(); - - /* - * Getters and Setters - */ - - public String getId() { - return id; - } - - public String getRequestTime() { - return requestTime; - } - - public String getRequestClient() { - return requestClient; - } - - public String getFromSystem() { - return fromSystem; - } - - public String getMessage() { - return message; - } - - public String getPolicyName() { - return policyName; - } - - public String getPolicyVersion() { - return policyVersion; - } - - public String getVmName() { - return vmName; - } - - public long getStartTime() { - return startTime; - } - - public void setId(String eventId) { - id = eventId; - } - - public void setRequestTime(String requestTime) { - this.requestTime = requestTime; - } - - public void setRequestClient(String requestClient) { - this.requestClient = requestClient; - } - - public void setFromSystem(String fromSystem) { - this.fromSystem = fromSystem; - } - - public void setMessage(String message) { - this.message = message; - } - - public void setPolicyName(String name) { - policyName = name; - } - - public void setPolicyVersion(String version) { - policyVersion = version; - } - - public void setVmName(String vmName) { - this.vmName = vmName; - } - - public void setStartTime(long startTime) { - this.startTime = startTime; - } - - /** - * Convenience method to return a json representation of this object. - * - * @return The json representation of this object - */ - public JSONObject toJson() { - return Mapper.toJsonObject(this); - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java deleted file mode 100644 index 60d1d004b..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/IncomingMessage.java +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * ============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.listener.CL.model; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; - -/** - * This class reperesnts a message coming in from DCAE. - * - */ -@JsonSerialize(include = Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class IncomingMessage extends CommonMessage { - - private static final long serialVersionUID = 1L; - - /* - * The action being requested. Its presence signals that it is an incoming message and it is not present on outgoing - * messages - */ - @JsonProperty("request") - private String request; - - /* - * The url for the server used for auth. http://<compute>:<port>/<tenentId>/server/<serverID> - */ - @JsonProperty("VServerSelfLink") - private String Url; - - /* - * The tenant Id in OpenStack that the server belongs to - */ - @JsonProperty("TenantID") - private String TenantId; - - /* - * The VM's UUID in - */ - @JsonProperty("VMID") - private String VmId; - - @JsonProperty("Identity") - private String identityUrl; - - public String getRequest() { - return request; - } - - @JsonIgnore - public Action getAction() { - return Action.toAction(request); - } - - public String getUrl() { - return Url; - } - - public String getTenantId() { - return TenantId; - } - - public String getVmId() { - return VmId; - } - - public String getIdentityUrl() { - return identityUrl; - } - - public void setUrl(String Url) { - this.Url = Url; - } - - public void setTenantId(String TenantId) { - this.TenantId = TenantId; - } - - public void setVmId(String VmId) { - this.VmId = VmId; - } - - public void setRequest(String request) { - this.request = request; - } - - public void setIdentityUrl(String identityUrl) { - this.identityUrl = identityUrl; - } - - @Override - public String toString() { - String time = getRequestTime() != null ? getRequestTime() : "N/A"; - // String req = request != null ? request : "N/A"; - return String.format("[%s - %s]", time, getId()); - } - - public String toOutgoing(Status status) { - return toOutgoing(status, getMessage()); - } - - public String toOutgoing(Status status, String msg) { - OutgoingMessage out = new OutgoingMessage(this); - out.setResponse(status); - out.setMessage(msg); - return out.toResponse().toString(); - } - - /** - * Determines if this message should be parsed parsed. Will eventually check that the message is well formed, has - * all required fields, and had not exceeded any timing restrictions. - * - * @return True if the message should be parsed. False otherwise - */ - public boolean isValid() { - return true; - } -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java deleted file mode 100644 index fa8560ed2..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/OutgoingMessage.java +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * ============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.listener.CL.model; - -import java.net.InetAddress; -import java.security.SecureRandom; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -import org.json.JSONObject; -import org.openecomp.appc.listener.util.Mapper; -import org.openecomp.appc.util.Time; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion; - -/** - * This class represents a message being sent out to DMaaP by APPC to update listeners on the status of a request - * - */ -@JsonSerialize(include = Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class OutgoingMessage extends CommonMessage { - - private static final long serialVersionUID = -5447940920271469613L; - - @JsonProperty("response") - private Status response; - - @JsonProperty("responseTime") - private String responseTime; - - @JsonProperty("originalRequest") - private String originalRequest; - - public OutgoingMessage() { - - } - - public OutgoingMessage(IncomingMessage msg) { - setId(msg.getId()); - setOriginalRequest(msg.getRequest()); - setRequestClient(msg.getRequestClient()); - setRequestTime(msg.getRequestTime()); - setVmName(msg.getVmName()); - setFromSystem(generateFrom()); - setResponse(Status.PENDING); - setPolicyName(msg.getPolicyName()); - setPolicyVersion(msg.getPolicyVersion()); - setStartTime(msg.getStartTime()); - } - - @JsonProperty("duration") - public long getDuration() { - return System.currentTimeMillis() - getStartTime(); - } - - public Status getResponse() { - return response; - } - - public String getResponseTime() { - return responseTime; - } - - public String getOriginalRequest() { - return originalRequest; - } - - @JsonIgnore - public void setResponse(Status response) { - this.response = response; - } - - public void setResponse(String responseString) { - this.response = Status.valueOf(responseString); - } - - public void setResponseTime(String responseTime) { - this.responseTime = responseTime; - } - - public void setOriginalRequest(String originalRequest) { - this.originalRequest = originalRequest; - } - - public void updateResponseTime() { - SecureRandom rand = new SecureRandom(); - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS"); - df.setTimeZone(TimeZone.getTimeZone("UTC")); - String date = df.format(new Date(Time.utcTime())); - this.responseTime = String.format("%s%03d", date, rand.nextInt(1000)); - } - - public String generateFrom() { - String name; - try { - InetAddress iAddress = InetAddress.getLocalHost(); - name = iAddress.getCanonicalHostName(); - } catch (Exception e) { - // Could not get anything from the InetAddress - name = "UnknownHost"; - } - return "appc@" + name; - } - - public JSONObject toResponse() { - updateResponseTime(); - JSONObject json = Mapper.toJsonObject(this); - - if (!json.has("message")) { - // If there is no message, parrot the status (response field) - // TODO - Can this be removed for 1602 making message truely optional? - json.put("message", this.getResponse().toString()); - } - - // Removed duplication of status from message for 1602 - // json.put("message", String.format("%s: %s", request, json.get("message"))); - - return json; - } - - @Override - public String toString() { - return String.format("%s - %s", getId(), getResponse()); - } -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java deleted file mode 100644 index d8e8b5c64..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL/model/Status.java +++ /dev/null @@ -1,74 +0,0 @@ -/*- - * ============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.listener.CL.model; - -public enum Status { - /* - * APP-C acknowledges that it has read the event off of the wire. This is the initial status of an OutgoingEvent - */ - PENDING("PENDING"), - - /* - * APP-C has started processing the event - */ - ACTIVE("ACTIVE"), - - /* - * APP-C has finished processing the event without errors - */ - SUCCESS("SUCCESS"), - - /* - * APP-C has finished processing the event with errors - */ - FAILURE("FAILURE"); - - /** - * Converts the string to an Status - * - * @param value - * The string to try and convert. Is case insensitive - * @return The status matching the string or null if no match was found. - */ - public static Status toStatus(String value) { - if (value != null) { - for (Status e : values()) { - if (e.getValue().toUpperCase().equals(value.toUpperCase())) { - return e; - } - } - } - - return null; - } - - private String value; - - private Status(String valueToUse) { - value = valueToUse; - } - - public final String getValue() { - return value; - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java index 021dfefc8..29e0fc723 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/conv/Converter.java @@ -30,14 +30,15 @@ import org.openecomp.appc.listener.LCM.model.DmaapMessage; import org.openecomp.appc.listener.LCM.model.DmaapOutgoingMessage; import org.openecomp.appc.listener.util.Mapper; - public class Converter { - - - public static DmaapOutgoingMessage convJsonNodeToDmaapOutgoingMessage(JsonNode inObj, String rpcName) { - DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + + public static DmaapOutgoingMessage convJsonNodeToDmaapOutgoingMessage(DmaapMessage event, JsonNode inObj) { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); outObj.setBody(inObj); - outObj.setRpcName(rpcName); + outObj.setRpcName(event.getRpcName()); + outObj.setVersion(event.getVersion()); + outObj.setType("response"); + outObj.setCorrelationID(event.getCorrelationID()); return outObj; } @@ -50,13 +51,16 @@ public class Converter { } - public static DmaapOutgoingMessage buildDmaapOutgoingMessageWithUnexpectedError(JsonNode dmaapInputBody, String rpcName,Exception inputException) { - DmaapOutgoingMessage dmaapOutgoingMessage = null; + public static DmaapOutgoingMessage buildDmaapOutgoingMessageWithUnexpectedError(DmaapMessage event,Exception inputException) { + DmaapOutgoingMessage dmaapOutgoingMessage = null; String errMsg = StringUtils.isEmpty(inputException.getMessage())? inputException.toString() : inputException.getMessage(); - JSONObject commonHeaderJsonObject = Mapper.toJsonObject(dmaapInputBody.get("input").get("common-header")); + JSONObject commonHeaderJsonObject = Mapper.toJsonObject(event.getBody().get("input").get("common-header")); JSONObject jsonObjectOutput = new JSONObject().accumulate("common-header", commonHeaderJsonObject).accumulate("status", new JSONObject().accumulate("code",200).accumulate("value",errMsg)); dmaapOutgoingMessage = new DmaapOutgoingMessage(); - dmaapOutgoingMessage.setRpcName(rpcName); + dmaapOutgoingMessage.setRpcName(event.getRpcName()); + dmaapOutgoingMessage.setCorrelationID(event.getCorrelationID()); + dmaapOutgoingMessage.setType("error"); + dmaapOutgoingMessage.setVersion(event.getVersion()); JSONObject jsonObjectBody = new JSONObject().accumulate("output",jsonObjectOutput); JsonNode jsonNodeBody = Mapper.toJsonNodeFromJsonString(jsonObjectBody.toString()); dmaapOutgoingMessage.setBody(jsonNodeBody); @@ -64,12 +68,10 @@ public class Converter { } public static String extractRequestIdWithSubId(JsonNode dmaapBody) { - String requestId; //TODO: null pointer exception if dmaapBody is null, check if null or ensure is not null before calling JsonNode commonHeaderJsonNode = dmaapBody.get("input").get("common-header"); - requestId = commonHeaderJsonNode.get("request-id").asText(); - requestId = requestId != null ? requestId : ""; - String subRequestId = commonHeaderJsonNode.get("sub-request-id").asText(); + String requestId = getValue(commonHeaderJsonNode,"request-id",""); + String subRequestId = getValue(commonHeaderJsonNode,"sub-request-id",""); if(!StringUtils.isEmpty(subRequestId)){ requestId = requestId +"-"+subRequestId; } @@ -82,4 +84,19 @@ public class Converter { return statusCode; } + private static String getValue(JsonNode jsonNode,String name,String defaultValue){ + if(jsonNode == null){ + return defaultValue; + } + JsonNode childJsonNode = jsonNode.get(name); + if(childJsonNode == null){ + return defaultValue; + } + String value = childJsonNode.asText(); + if(value == null){ + return defaultValue; + } + return value; + } + } diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java index dd877e98a..408e97a13 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/ListenerImpl.java @@ -46,17 +46,20 @@ public class ListenerImpl extends AbstractListener { private long startTime = 0; + private final ProviderOperations providerOperations; + public ListenerImpl(ListenerProperties props) { super(props); String url = props.getProperty("provider.url"); LOG.info("DMaaP Provider Endpoint: " + url); - ProviderOperations.setUrl(url); + providerOperations = new ProviderOperations(); + providerOperations.setUrl(url); // Set Basic Auth String user = props.getProperty("provider.user"); String pass = props.getProperty("provider.pass"); - ProviderOperations.setAuthentication(user, pass); + providerOperations.setAuthentication(user, pass); } @Override @@ -91,7 +94,7 @@ public class ListenerImpl extends AbstractListener { if (isValid(incoming)) { LOG.info(String.format("Adding DMaaP message to pool queue [%s]", requestIdWithSubId)); try { - executor.execute(new WorkerImpl(incoming.getRpcName(),incoming.getBody(), dmaap)); + executor.execute(new WorkerImpl(incoming, dmaap, providerOperations)); } catch (RejectedExecutionException rejectEx) { LOG.error("Task Rejected: ", rejectEx); } diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java index af8334ee4..41a77c7fc 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/impl/WorkerImpl.java @@ -24,6 +24,7 @@ package org.openecomp.appc.listener.LCM.impl; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.appc.listener.EventHandler; import org.openecomp.appc.listener.LCM.conv.Converter; +import org.openecomp.appc.listener.LCM.model.DmaapMessage; import org.openecomp.appc.listener.LCM.model.DmaapOutgoingMessage; import org.openecomp.appc.listener.LCM.operation.ProviderOperations; @@ -38,28 +39,31 @@ public class WorkerImpl implements Runnable { private final EELFLogger LOG = EELFManager.getInstance().getLogger(WorkerImpl.class); // Should have all of the data we need for processing - private JsonNode event; + private DmaapMessage event; // So we can post messages from inside the worker. private EventHandler dmaap; - private String rpcName; - public WorkerImpl(String rpcName,JsonNode message, EventHandler dmaap) { - this.rpcName = rpcName; + //so we know were to post the messages + private final ProviderOperations providerOperations; + + + public WorkerImpl(DmaapMessage message, EventHandler dmaap, ProviderOperations providerOperations) { this.event = message; this.dmaap = dmaap; + this.providerOperations = providerOperations; } @Override public void run() { - String requestIdWithSubId = extractRequestIdWithSubId(event); + String requestIdWithSubId = extractRequestIdWithSubId(event.getBody()); LOG.debug(String.format("Started working on %s", requestIdWithSubId)); // Run the dg in a try catch to handle all exceptions and update the // message at the end try { - JsonNode outputJsonNode = doDG(rpcName, event); - DmaapOutgoingMessage dmaapOutgoingMessage= Converter.convJsonNodeToDmaapOutgoingMessage(outputJsonNode,rpcName); + JsonNode outputJsonNode = doDG(event.getRpcName(), event.getBody()); + DmaapOutgoingMessage dmaapOutgoingMessage= Converter.convJsonNodeToDmaapOutgoingMessage(event, outputJsonNode); postMessageToDMaaP(dmaapOutgoingMessage,requestIdWithSubId); Integer statusCode = extractStatusCode(dmaapOutgoingMessage.getBody()); if (ProviderOperations.isSucceeded(statusCode)) { @@ -73,7 +77,7 @@ public class WorkerImpl implements Runnable { // along String msg = "Exception: " + e.getMessage(); LOG.error(String.format("Event %s finished with failure. %s", requestIdWithSubId, msg)); - DmaapOutgoingMessage dmaapOutgoingMessage= Converter.buildDmaapOutgoingMessageWithUnexpectedError(event,rpcName,e); + DmaapOutgoingMessage dmaapOutgoingMessage= Converter.buildDmaapOutgoingMessageWithUnexpectedError(event, e); postMessageToDMaaP(dmaapOutgoingMessage,requestIdWithSubId); } @@ -115,6 +119,6 @@ public class WorkerImpl implements Runnable { } private JsonNode doDG(String rpcName, JsonNode msg) throws APPCException { - return ProviderOperations.topologyDG(rpcName,msg); + return providerOperations.topologyDG(rpcName,msg); } } diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java index 56099cb7e..95453ad9c 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/model/DmaapMessage.java @@ -31,6 +31,15 @@ import com.fasterxml.jackson.databind.JsonNode; @JsonIgnoreProperties(ignoreUnknown = true) public class DmaapMessage{ + @JsonProperty("version") + private String version; + + @JsonProperty("type") + private String type; + + @JsonProperty("correlation-id") + private String correlationID; + @JsonProperty("cambria.partition") private String cambriaPartition; @@ -43,6 +52,30 @@ public class DmaapMessage{ public DmaapMessage() { } + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCorrelationID() { + return correlationID; + } + + public void setCorrelationID(String correlationID) { + this.correlationID = correlationID; + } + public String getCambriaPartition() { return cambriaPartition; } @@ -70,10 +103,14 @@ public class DmaapMessage{ @Override public String toString() { return "DmaapMessage{" + - "cambriaPartition='" + cambriaPartition + '\'' + + "version='" + version + '\'' + + ", type='" + type + '\'' + + ", correlationId='" + correlationID + '\'' + + ", cambriaPartition='" + cambriaPartition + '\'' + ", rpcName='" + rpcName + '\'' + ", body=" + body + '}'; } + } diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java index f5672a575..32118d4e8 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/LCM/operation/ProviderOperations.java @@ -65,8 +65,8 @@ public class ProviderOperations { private static final EELFLogger LOG = EELFManager.getInstance().getLogger(ProviderOperations.class); - private static URL url; - private static String basic_auth; + private URL url; + private String basic_auth; private static ProviderOperationRequestFormatter requestFormatter = new GenericProviderOperationRequestFormatter(); @@ -79,7 +79,7 @@ public class ProviderOperations { * @throws Exception if there was a failure processing the request. The exception message is the failure reason. */ @SuppressWarnings("nls") - public static JsonNode topologyDG(String rpcName, JsonNode msg) throws APPCException { + public JsonNode topologyDG(String rpcName, JsonNode msg) throws APPCException { if (msg == null) { throw new APPCException("Provided message was null"); } @@ -146,11 +146,11 @@ public class ProviderOperations { * * @return The new value of URL */ - public static String getUrl() { + public String getUrl() { return url.toExternalForm(); } - public static void setUrl(String newUrl) { + public void setUrl(String newUrl) { try { url = new URL(newUrl); } catch (MalformedURLException e) { @@ -166,7 +166,7 @@ public class ProviderOperations { * @param password The password for the user * @return The new value of the basic auth string that will be used in the request headers */ - public static String setAuthentication(String user, String password) { + public String setAuthentication(String user, String password) { if (user != null && password != null) { String authStr = user + ":" + password; basic_auth = new String(Base64.encodeBase64(authStr.getBytes())); @@ -177,7 +177,7 @@ public class ProviderOperations { } @SuppressWarnings("deprecation") - private static HttpClient getHttpClient() throws APPCException { + private HttpClient getHttpClient() throws APPCException { HttpClient client; if (url.getProtocol().equals("https")) { try { diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java index c6c374eb0..2ff76b311 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/ListenerProperties.java @@ -156,43 +156,6 @@ public class ListenerProperties { return String.format("%s", prefix); } - /** - * The message service types that are available. Choices are DMaaP and DMaaP. - * - * @since Apr 25, 2016 - * @version $Id$ - */ - public enum MessageService { - DMaaP("dmaap"); - - private String val; - - private MessageService(String val) { - this.val = val; - } - - public String getValue() { - return val; - } - - /** - * Tries to match a string to a MessageService. If no match is found, returns the default (DMaaP) - * - * @param input - * the string to try and match - * @return A MessasgeService - */ - public static MessageService parse(String input) { - if (input != null) { - for (MessageService ms : MessageService.values()) { - if (ms.getValue().equals(input.toLowerCase())) { - return ms; - } - } - } - return MessageService.DMaaP; // Default - } - } /** * Set of common properties that will be used by most systems. Primarily relating to DMaaP and ThreadPools diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ListenerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/ListenerImpl.java index 5d3b741ff..04fbe6982 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ListenerImpl.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/ListenerImpl.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.impl; +package org.openecomp.appc.listener.demo.impl; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -30,8 +30,7 @@ import java.util.concurrent.RejectedExecutionException; import org.openecomp.appc.listener.AbstractListener; import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.CL1607.model.IncomingMessage; -import org.openecomp.appc.listener.CL1607.model.Status; +import org.openecomp.appc.listener.demo.model.IncomingMessage; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ProviderOperations.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/ProviderOperations.java index c300df154..23a6f41ae 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/ProviderOperations.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/ProviderOperations.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.impl; +package org.openecomp.appc.listener.demo.impl; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -59,7 +59,7 @@ import org.apache.http.params.HttpProtocolParams; import org.apache.http.protocol.HTTP; import org.json.JSONObject; import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.appc.listener.CL1607.model.IncomingMessage; +import org.openecomp.appc.listener.demo.model.IncomingMessage; import org.openecomp.appc.listener.util.Mapper; import com.att.eelf.configuration.EELFLogger; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/WorkerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/WorkerImpl.java index 52bcd2f5e..69db9cd3f 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/impl/WorkerImpl.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/impl/WorkerImpl.java @@ -19,12 +19,12 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.impl; +package org.openecomp.appc.listener.demo.impl; import org.openecomp.appc.exceptions.APPCException; import org.openecomp.appc.listener.EventHandler; -import org.openecomp.appc.listener.CL1607.model.IncomingMessage; -import org.openecomp.appc.listener.CL1607.model.Status; +import org.openecomp.appc.listener.demo.model.IncomingMessage; +import org.openecomp.appc.listener.demo.model.Status; import com.att.eelf.configuration.EELFLogger; import com.att.eelf.configuration.EELFManager; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Action.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/Action.java index 9e7e923be..413be61aa 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Action.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/Action.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; public enum Action { Restart("Restart"), Rebuild("Rebuild"), Migrate("Migrate"), Evacuate("Evacuate"), Snapshot("Snapshot"),modifyconfig("ModifyConfig"); diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/CommonMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/CommonMessage.java index 80a78095b..aa056d3a7 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/CommonMessage.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/CommonMessage.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; import java.io.Serializable; import java.util.Collection; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/IncomingMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/IncomingMessage.java index 62d4d1b7d..6a345ea82 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/IncomingMessage.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/IncomingMessage.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/OutgoingMessage.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/OutgoingMessage.java index 7b766212d..24b40c78e 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/OutgoingMessage.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/OutgoingMessage.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; import java.net.InetAddress; import java.security.SecureRandom; diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Status.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/Status.java index f7ec8febd..3cf2c5991 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/CL1607/model/Status.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/demo/model/Status.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; public enum Status { /* diff --git a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java index 590afbe8b..ee9f30ea7 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java +++ b/appc-event-listener/appc-event-listener-bundle/src/main/java/org/openecomp/appc/listener/impl/EventHandlerImpl.java @@ -20,29 +20,25 @@ */ package org.openecomp.appc.listener.impl; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.openecomp.appc.adapter.dmaap.Consumer; -import org.openecomp.appc.adapter.dmaap.DmaapConsumer; -import org.openecomp.appc.adapter.dmaap.DmaapProducer; -import org.openecomp.appc.adapter.dmaap.Producer; -import org.openecomp.appc.adapter.dmaap.DmaapConsumer; -import org.openecomp.appc.adapter.dmaap.DmaapProducer; +import org.openecomp.appc.adapter.factory.DmaapMessageAdapterFactoryImpl; +import org.openecomp.appc.adapter.factory.MessageService; +import org.openecomp.appc.adapter.message.Consumer; +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.message.Producer; import org.openecomp.appc.listener.EventHandler; import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.ListenerProperties.MessageService; import org.openecomp.appc.listener.util.Mapper; import org.openecomp.appc.logging.LoggingConstants; - -import com.att.eelf.configuration.EELFLogger; -import com.att.eelf.configuration.EELFManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; import org.slf4j.MDC; +import java.util.*; + /** * This class is a wrapper for the DMaaP client provided in appc-dmaap-adapter. Its aim is to ensure that only well formed * messages are sent and received on DMaaP. @@ -154,7 +150,16 @@ public class EventHandlerImpl implements EventHandler { LOG.info("Getting Consumer..."); reader = getConsumer(); } - for (String item : reader.fetch(READ_TIMEOUT * 1000, limit)) { + + List<String> items = null; + try{ + items = reader.fetch(READ_TIMEOUT * 1000, limit); + }catch(Error r){ + LOG.error("EvenHandlerImpl.getIncomingEvents",r); + } + + + for (String item : items) { out.add(item); } LOG.info(String.format("Read %d messages from %s as %s/%s.", out.size(), readTopic, clientName, clientId)); @@ -198,13 +203,25 @@ public class EventHandlerImpl implements EventHandler { LOG.error( "*****We will be writing and reading to the same topic without a filter. This will cause an infinite loop.*****"); } - Consumer out; - out = new DmaapConsumer(pool, readTopic, clientName, clientId, filter_json, apiKey, apiSecret); - for (String url : pool) { - if (url.contains("3905") || url.contains("https")) { - out.useHttps(true); - break; - } + + Consumer out=null; + BundleContext ctx = FrameworkUtil.getBundle(EventHandlerImpl.class).getBundleContext(); + if (ctx != null) { + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef != null) { + try{ + out = ((MessageAdapterFactory) ctx.getService(svcRef)).createConsumer(pool, readTopic, clientName, clientId, filter_json, apiKey, apiSecret); + }catch(Error e){ + //TODO:create eelf message + LOG.error("EvenHandlerImp.getConsumer calling MessageAdapterFactor.createConsumer",e); + } + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + out.useHttps(true); + break; + } + } + } } return out; } @@ -217,18 +234,19 @@ public class EventHandlerImpl implements EventHandler { protected Producer getProducer() { LOG.debug(String.format("Getting Producer: %s %s", pool, readTopic)); - Producer out; - out = new DmaapProducer(pool,writeTopics); - - if (apiKey != null && apiSecret != null) { - out.updateCredentials(apiKey, apiSecret); - } - - for (String url : pool) { - if (url.contains("3905") || url.contains("https")) { - out.useHttps(true); - break; - } + Producer out = null; + BundleContext ctx = FrameworkUtil.getBundle(EventHandlerImpl.class).getBundleContext(); + if (ctx != null) { + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef != null) { + out = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopics,apiKey, apiSecret); + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + out.useHttps(true); + break; + } + } + } } return out; } @@ -236,23 +254,11 @@ public class EventHandlerImpl implements EventHandler { @Override public void closeClients() { LOG.debug("Closing Consumer and Producer DMaaP clients"); - switch (messageService) { - case DMaaP: - if (reader != null) { - ((DmaapConsumer) reader).close(); - } - if (producer != null) { - ((DmaapProducer) producer).close(); - } - break; - default: - // close DMaaP clients - if (reader != null) { - ((DmaapConsumer) reader).close(); - } - if (producer != null) { - ((DmaapProducer) producer).close(); - } + if (reader != null) { + reader.close(); + } + if (producer != null) { + producer.close(); } } diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java deleted file mode 100644 index 3d7a7182f..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestProviderOperations.java +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * ============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.listener.CL.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - -import java.util.Properties; - -import org.eclipse.osgi.internal.signedcontent.Base64; -import org.junit.Before; -import org.junit.Test; -import org.openecomp.appc.configuration.ConfigurationFactory; -import org.openecomp.appc.exceptions.APPCException; -import org.openecomp.appc.listener.CL.impl.ProviderOperations; -import org.openecomp.appc.listener.CL.model.IncomingMessage; - -public class TestProviderOperations { - - private String ACTIVE_ENDPOINT; - - @Before - public void setup() { - Properties props = ConfigurationFactory.getConfiguration().getProperties(); - ACTIVE_ENDPOINT = props.getProperty("appc.ClosedLoop.provider.url"); - assertNotNull(ACTIVE_ENDPOINT); - ProviderOperations.setUrl(ACTIVE_ENDPOINT); - - props.getProperty("test.vm_url"); - assertNotNull("VM_URL"); - } - - @Test - public void testTopologyOperation() { - IncomingMessage msg = new IncomingMessage(); - // Client and Time are for ID - msg.setRequestClient("APPC"); - msg.setRequestTime("TEST"); - msg.setRequest("Restart"); - - // Null Input - try { - ProviderOperations.topologyDG(null); - fail("Topology Operation with null input should fail"); - } catch (APPCException e) { - assertNotNull(e.getMessage()); - } - - // Bad URL - msg.setUrl("some bad url here"); - try { - ProviderOperations.topologyDG(msg); - // Could also be issue in IaaS Adapter - fail("Topology Operation with bad url should fail"); - } catch (APPCException e) { - assertNotNull(e.getMessage()); - } - - // Will be tested in worker - // msg.setUrl(VM_URL); - // System.out.println("Rebooting real VM. Test can take up to 90s"); - // try { - // assertTrue(ProviderOperations.topologyDG(msg)); - // } catch (APPCException e) { - // fail("Topology Operation with good url should succeed. Check url in gui first"); - // } - - } - - @Test - public void testConfigurationOperation() { - try { - ProviderOperations.topologyDG(null); - fail("Configuration Operation should throw execption. Not yet supported"); - } catch (APPCException e) { - assertNotNull(e.getMessage()); - } - } - - @Test - public void testBasicAuthFormating() { - String user = "user"; - String pass = "pass"; - - String result = ProviderOperations.setAuthentication(user, pass); - - assertNotNull(result); - String decode = new String(Base64.decode(result.getBytes())); - assertEquals(user + ":" + pass, decode); - } - - @Test - public void testGetSet() { - // Every test URL will get reset - assertEquals(ACTIVE_ENDPOINT, ProviderOperations.getUrl()); - - String newUrl = "http://example.com"; - ProviderOperations.setUrl(newUrl); - assertEquals(newUrl, ProviderOperations.getUrl()); - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java deleted file mode 100644 index 1cd9cdc44..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/impl/TestWorker.java +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * ============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.listener.CL.impl; - -import static org.junit.Assert.assertNotNull; - -import java.util.Properties; - -import org.junit.Before; -import org.junit.Test; -import org.openecomp.appc.configuration.ConfigurationFactory; -import org.openecomp.appc.listener.EventHandler; -import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.CL.impl.ProviderOperations; -import org.openecomp.appc.listener.CL.impl.WorkerImpl; -import org.openecomp.appc.listener.CL.model.IncomingMessage; -import org.openecomp.appc.listener.impl.EventHandlerImpl; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class TestWorker { - - private static final Logger LOG = LoggerFactory.getLogger(WorkerImpl.class); - - private IncomingMessage msg; - private EventHandler dmaap; - - @Before - public void setup() { - Properties props = ConfigurationFactory.getConfiguration().getProperties(); - String activeEndpoint = props.getProperty("appc.ClosedLoop.provider.url"); - assertNotNull(activeEndpoint); - ProviderOperations.setUrl(activeEndpoint); - - String vmUrl = props.getProperty("test.vm_url"); - assertNotNull(vmUrl); - msg = new IncomingMessage(); - // Client and Time are for ID - msg.setRequestClient("APPC"); - msg.setRequestTime("TEST"); - msg.setRequest("Restart"); - msg.setUrl(vmUrl); - - dmaap = new EventHandlerImpl(new ListenerProperties("appc.ClosedLoop", props)); - } - - @Test - public void testWorker() { - WorkerImpl w = new WorkerImpl(msg, dmaap); - w.run(); - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java deleted file mode 100644 index e9fa1ace8..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestMessages.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.listener.CL.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import org.apache.commons.io.IOUtils; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.openecomp.appc.listener.CL.model.IncomingMessage; -import org.openecomp.appc.listener.CL.model.OutgoingMessage; -import org.openecomp.appc.listener.CL.model.Status; -import org.openecomp.appc.listener.util.Mapper; - -public class TestMessages { - private IncomingMessage in; - private OutgoingMessage out; - - private String incomingStr; - private String outgoingStr; - - @Before - public void setup() { - try { - incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessage.txt"), "UTF-8"); - outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessage.txt"), "UTF-8"); - assertNotNull(incomingStr); - assertNotNull(outgoingStr); - - in = Mapper.mapOne(incomingStr, IncomingMessage.class); - - out = Mapper.mapOne(in.toOutgoing(Status.PENDING), OutgoingMessage.class); - out.updateResponseTime(); - - assertNotNull(in); - assertNotNull(out); - } catch (Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - // NOTE Test Mapper will be used to test an event from dmaap. - @Test - public void testGetterSetter() { - assertNotNull(in); - assertNotNull(in.getRequestClient()); - assertNotNull(in.getRequestTime()); - assertNotNull(in.getMessage()); - assertNotNull(in.getTenantId()); - assertNotNull(in.getVmId()); - assertNotNull(in.getVmName()); - assertNotNull(in.getAction()); - assertNotNull(in.getId()); - assertNotNull(in.getPolicyName()); - assertNotNull(in.getPolicyVersion()); - assertNotNull(in.getRequest()); - - out = Mapper.mapOne(in.toOutgoing(null), OutgoingMessage.class); - assertNotNull(out.getRequestClient()); - assertEquals(in.getRequestClient(), out.getRequestClient()); - assertNotNull(out.getRequestTime()); - assertEquals(in.getRequestTime(), out.getRequestTime()); - assertNotNull(out.getMessage()); - assertEquals(in.getMessage(), out.getMessage()); - assertNotNull(out.getVmName()); - assertEquals(in.getVmName(), out.getVmName()); - assertNotNull(out.getPolicyName()); - assertEquals(in.getPolicyName(), out.getPolicyName()); - assertNotNull(out.getPolicyVersion()); - assertEquals(in.getPolicyVersion(), out.getPolicyVersion()); - assertNotNull(out.getOriginalRequest()); - assertNotNull(in.getRequest(), out.getOriginalRequest()); - } - - @Test - public void testToString() { - in = new IncomingMessage(); - assertNotNull(in.toString()); - String id = "test"; - in.setId(id); - assertNotNull(in.toString()); - assertTrue(in.toString().contains(id)); - } - - @Test - public void testOutgoingUpdateTime() { - String old = out.getResponseTime(); - out.updateResponseTime(); - assertFalse(old.equals(out.getResponseTime())); - } - - // Testing for 1510 - @Test - public void testOutgoingToJson() { - // Message Set - String message = "MSG"; - out.setMessage(message); - JSONObject json = out.toResponse(); - assertNotNull(json); - String respStr = json.getString("response"); - assertTrue(respStr.contains(out.getResponse().getValue())); - - String msgStr = json.getString("message"); - assertNotNull(msgStr); - assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 - assertTrue(msgStr.contains(out.getMessage())); - - // Null Message - out.setMessage(null); - json = out.toResponse(); - assertNotNull(json); - msgStr = json.getString("message"); - assertNotNull(msgStr); - assertFalse(msgStr.contains(out.getOriginalRequest())); // False for 1602 - assertTrue(msgStr.contains(out.getResponse().getValue())); - - // Echoing request - assertNotNull(out.getOriginalRequest()); - } - - @Test - public void testOutgoingToString() { - String s = out.toString(); - assertTrue(s.contains(out.getId())); - } -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java deleted file mode 100644 index 73e38aa4f..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestEnums.java +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * ============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.listener.CL1607.model; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import org.junit.Test; -import org.openecomp.appc.listener.CL.model.Action; -import org.openecomp.appc.listener.CL.model.Status; - -public class TestEnums { - - @Test - public void testAction() { - assertEquals(Action.Rebuild, Action.toAction("Rebuild")); - assertEquals(Action.Restart, Action.toAction("restart")); - assertEquals(Action.Migrate, Action.toAction("MIGRATE")); - assertEquals(Action.Evacuate, Action.toAction("Evacuate")); - assertNull(Action.toAction("Unknown")); - assertNull(Action.toAction(null)); - - assertEquals(4, Action.values().length); - } - - @Test - public void testStatus() { - - assertEquals(Status.PENDING, Status.toStatus("Pending")); - assertEquals(Status.ACTIVE, Status.toStatus("active")); - assertEquals(Status.SUCCESS, Status.toStatus("SuCcEsS")); - assertEquals(Status.FAILURE, Status.toStatus("Failure")); - assertNull(Status.toStatus("Unknown")); - assertNull(Status.toStatus(null)); - - assertEquals(4, Status.values().length); - - } - -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java index 2062e80d8..35042ba95 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/LCM/TestConverter.java @@ -39,7 +39,7 @@ public class TestConverter { public void buildDmaapOutgoingMessageWithUnexpectedErrorTest() throws JsonProcessingException { DmaapIncomingMessage dmaapIncomingMessage = buildDmaapIncomingMessage(); String errMsg = "TestException"; - DmaapOutgoingMessage dmaapOutgoingMessage = Converter.buildDmaapOutgoingMessageWithUnexpectedError(dmaapIncomingMessage.getBody(), "test", new Exception(errMsg)); + DmaapOutgoingMessage dmaapOutgoingMessage = Converter.buildDmaapOutgoingMessageWithUnexpectedError(dmaapIncomingMessage, new Exception(errMsg)); int code = dmaapOutgoingMessage.getBody().get("output").get("status").get("code").asInt(); String value = dmaapOutgoingMessage.getBody().get("output").get("status").get("value").asText(); Assert.assertEquals(200,code); diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java index 9a70a8427..a2ce827a5 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/TestListenerProperties.java @@ -32,6 +32,7 @@ import java.util.Properties; import org.junit.Before; import org.junit.Test; +import org.openecomp.appc.adapter.factory.MessageService; import org.openecomp.appc.listener.AbstractListener; import org.openecomp.appc.listener.ListenerProperties; import org.openecomp.appc.listener.ListenerProperties.KEYS; @@ -101,19 +102,18 @@ public class TestListenerProperties { @Test public void testMessageServices() { // Hardcode count so tests must be updated when values are added - assertEquals(1, ListenerProperties.MessageService.values().length); + assertEquals(1, MessageService.values().length); // Bad Input - ListenerProperties.MessageService def = ListenerProperties.MessageService.DMaaP; - assertEquals(def, ListenerProperties.MessageService.parse(null)); - assertEquals(def, ListenerProperties.MessageService.parse("")); - assertEquals(def, ListenerProperties.MessageService.parse("NotDmaapOrDMaaP")); + MessageService def = MessageService.DMaaP; + assertEquals(def, MessageService.parse(null)); + assertEquals(def, MessageService.parse("")); + assertEquals(def, MessageService.parse("NotDMaaP")); - // DMaaP case sensitivity - assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("dmaap")); - assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("DMAAP")); - assertEquals(ListenerProperties.MessageService.DMaaP, ListenerProperties.MessageService.parse("DMaaP")); + assertEquals(MessageService.DMaaP, MessageService.parse("dmaap")); + assertEquals(MessageService.DMaaP, MessageService.parse("DMAAP")); + assertEquals(MessageService.DMaaP, MessageService.parse("DMaaP")); } @Test diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestEnums.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/demo/model/TestEnums.java index a934cb432..2170af46c 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL/model/TestEnums.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/demo/model/TestEnums.java @@ -19,14 +19,14 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL.model; +package org.openecomp.appc.listener.demo.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import org.junit.Test; -import org.openecomp.appc.listener.CL.model.Action; -import org.openecomp.appc.listener.CL1607.model.Status; +import org.openecomp.appc.listener.demo.model.Action; +import org.openecomp.appc.listener.demo.model.Status; public class TestEnums { @@ -39,13 +39,13 @@ public class TestEnums { assertNull(Action.toAction("Unknown")); assertNull(Action.toAction(null)); - assertEquals(4, Action.values().length); + assertEquals(6, Action.values().length); } @Test public void testStatus() { - assertEquals(Status.ACCEPTED, Status.toStatus("ACCEPTED")); + assertEquals(Status.ACCEPTED, Status.toStatus("accepted")); assertEquals(Status.SUCCESS, Status.toStatus("SuCcEsS")); assertEquals(Status.FAILURE, Status.toStatus("Failure")); assertNull(Status.toStatus("Unknown")); diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestMessages.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/demo/model/TestMessages.java index c7bc86300..98dc91b7d 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/CL1607/model/TestMessages.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/demo/model/TestMessages.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.openecomp.appc.listener.CL1607.model; +package org.openecomp.appc.listener.demo.model; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -32,9 +32,9 @@ import org.json.JSONObject; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import org.openecomp.appc.listener.CL1607.model.IncomingMessage; -import org.openecomp.appc.listener.CL1607.model.OutgoingMessage; -import org.openecomp.appc.listener.CL1607.model.Status; +import org.openecomp.appc.listener.demo.model.IncomingMessage; +import org.openecomp.appc.listener.demo.model.OutgoingMessage; +import org.openecomp.appc.listener.demo.model.Status; import org.openecomp.appc.listener.util.Mapper; public class TestMessages { @@ -47,8 +47,8 @@ public class TestMessages { @Before public void setup() { try { - incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessage1607.txt"), "UTF-8"); - outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessage1607.txt"), "UTF-8"); + incomingStr = IOUtils.toString(getClass().getResourceAsStream("/IncomingMessagedemo.txt"), "UTF-8"); + outgoingStr = IOUtils.toString(getClass().getResourceAsStream("/OutgoingMessagedemo.txt"), "UTF-8"); assertNotNull(incomingStr); assertNotNull(outgoingStr); diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java index 788aa961a..a5a6e1e7f 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestEventHandler.java @@ -126,8 +126,7 @@ public class TestEventHandler { } - @Test - @Ignore +// @Test public void testRun() { // Runoff any old data List<String> result1 = adapter.getIncomingEvents(); @@ -144,7 +143,7 @@ public class TestEventHandler { // Get data back List<DummyObj> result2 = adapter.getIncomingEvents(DummyObj.class); assertNotNull(result2); - assertEquals(1, result2.size()); +// assertEquals(1, result2.size()); assertEquals(data.toJson(), result2.get(0).toJson()); } diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java index a1c7917f9..af50e6d3d 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java +++ b/appc-event-listener/appc-event-listener-bundle/src/test/java/org/openecomp/appc/listener/impl/TestListener.java @@ -31,7 +31,7 @@ import org.junit.Ignore; import org.junit.Test; import org.openecomp.appc.listener.Listener; import org.openecomp.appc.listener.ListenerProperties; -import org.openecomp.appc.listener.CL.impl.ListenerImpl; +import org.openecomp.appc.listener.demo.impl.ListenerImpl; @Ignore public class TestListener { diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt b/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt deleted file mode 100644 index 0771a790a..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage.txt +++ /dev/null @@ -1,24 +0,0 @@ -{ -"eventID": "SomeEventID-TBD", - -"APPCVDCName": "Delete this field not needed by App-C", -"requestTime": "0000-00-00 00:00:00.000000", -"policyVersion": "1", -"VMName": "123", -"from": "test", -"msgOid": ".1.3.6.1.4.1.193.183.4.1.3.5.1.4", -"VMID": "abc12345-1234-5678-890a-abcdefg12345", -"trapID": "1234567", -"requestClient": "test", -"message": "Abnormal condition detected", -"time": "123567890", -"policyName": "RESTART", -"trapIDOID": ".1.3.6.1.4.1.193.183.4.1.3.5.1.3", -"request": "Restart", -"OPS_CL_timer": "15", -"nOID": ".1.3.6.1.4.1.193.183.4.2.0.4", -"AgentAddress": "192.168.1.2", -"vmOID": ".1.3.6.1.4.1.193.183.4.1.2.1", -"TenantID": "abcde12345fghijk6789lmnopq123rst", -"VServerSelfLink": "http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345" -}
\ No newline at end of file diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage1607.txt b/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessagedemo.txt index 667cfae8c..667cfae8c 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessage1607.txt +++ b/appc-event-listener/appc-event-listener-bundle/src/test/resources/IncomingMessagedemo.txt diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt b/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt deleted file mode 100644 index c5d6c5b56..000000000 --- a/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ -"eventID": "SomeEventID-TBD", - -"VMName": "test", -"from": "appc@test", -"message": "Some Text Here", -"requestClient": "test", -"requestTime": "0000-00-00 00:00:00.000000", -"response": "PENDING", -"responseTime": "0000-00-00 00:00:00.000000", - -"policyName": "RESTART", -"policyVersion": "1" -} diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage1607.txt b/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessagedemo.txt index 898eb622e..898eb622e 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessage1607.txt +++ b/appc-event-listener/appc-event-listener-bundle/src/test/resources/OutgoingMessagedemo.txt diff --git a/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties b/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties index 7a65b7195..9aa518a29 100644 --- a/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties +++ b/appc-event-listener/appc-event-listener-bundle/src/test/resources/org/openecomp/appc/default.properties @@ -38,7 +38,7 @@ ### ### test.prefix=appc.ClosedLoop appc.ClosedLoop.disabled=false -appc.ClosedLoop.service=UEB +appc.ClosedLoop.service=dmaap appc.ClosedLoop.poolMembers=192.168.1.2:3904 appc.ClosedLoop.topic.read=APPC-TEST1 appc.ClosedLoop.topic.read.timeout=5 diff --git a/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml b/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml index 4d4d24fd3..14fa8ad25 100644 --- a/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml +++ b/appc-event-listener/appc-event-listener-features/src/main/resources/features.xml @@ -32,8 +32,9 @@ <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> <!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> + <bundle dependency="true">mvn:org.openecomp.appc/appc-metric-bundle/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-event-listener-bundle/${project.version}</bundle> - </feature> </features> diff --git a/appc-event-listener/pom.xml b/appc-event-listener/pom.xml index e99c71477..b21042a96 100644 --- a/appc-event-listener/pom.xml +++ b/appc-event-listener/pom.xml @@ -102,4 +102,4 @@ <module>appc-event-listener-features</module> <module>appc-event-listener-installer</module> </modules> -</project>
\ No newline at end of file +</project> diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java index b75ca2a30..83ff1f7e4 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/MetricService.java @@ -22,8 +22,17 @@ package org.openecomp.appc.metricservice; +import java.util.Map; + public interface MetricService { MetricRegistry registry(String name); MetricRegistry createRegistry(String name); void dispose(); + + /** + * This API will be used to get the Map of all the registered Registry for the Metric Service + * @return Map<String,MetricRegistry> where String will be the name of the Metric Registry + * and MetricRegistry will be the actual object for that Registry + */ + Map<String,MetricRegistry> getAllRegistry(); } diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java index 6e5ca9d10..128110e91 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/impl/MetricServiceImpl.java @@ -21,6 +21,7 @@ package org.openecomp.appc.metricservice.impl; +import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -43,6 +44,12 @@ public class MetricServiceImpl implements MetricService { } @Override + public Map<String,MetricRegistry> getAllRegistry(){ + return Collections.unmodifiableMap(concurrentRegistryMap); + + } + + @Override public void dispose() { //TODO } diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java index 10b8daacf..625d3218e 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/Metric.java @@ -21,6 +21,8 @@ package org.openecomp.appc.metricservice.metric; +import java.util.HashMap; + /** * * a measure of system parameter at the current moment. Each metric is identified by name. @@ -34,4 +36,17 @@ public interface Metric { String name(); void reset(); MetricType type(); + /** + * This API will be used to get all the running Metrics Output. + * @return HashMap <String,String> in which + * the First String(Key) will be the name of the KPI property + * and another String(Value of the Key) will be the Value of + * that property for that KPI + */ + HashMap<String,String> getMetricsOutput(); + /** + * Return last modified date for KPI in string format + * @return - last modified date for KPI + */ + String getLastModified(); } diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java index c41def981..71c601c0a 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DefaultPrimitiveCounter.java @@ -24,20 +24,28 @@ package org.openecomp.appc.metricservice.metric.impl; import org.openecomp.appc.metricservice.metric.MetricType; import org.openecomp.appc.metricservice.metric.PrimitiveCounter; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicLong; -public class DefaultPrimitiveCounter implements PrimitiveCounter{ - private String name; - private MetricType metricType; - private long counter; + +public class DefaultPrimitiveCounter implements PrimitiveCounter { + private String name; + private MetricType metricType; + private AtomicLong counter = new AtomicLong(); + + private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("YYYY-MM-dd:HH:mm:ss"); + private String lastResetTime = dateTimeFormat.format(Calendar.getInstance().getTime()); public DefaultPrimitiveCounter(String name, MetricType metricType, long counter) { this.name = name; this.metricType = metricType; - this.counter = counter; + this.counter.set(counter); } public DefaultPrimitiveCounter(String name, MetricType metricType) { - this.counter=0; + this.counter.set(0); this.name = name; this.metricType = metricType; } @@ -49,7 +57,7 @@ public class DefaultPrimitiveCounter implements PrimitiveCounter{ @Override public void increment(long value) { - this.counter+=value; + this.counter.incrementAndGet(); } @Override @@ -59,12 +67,12 @@ public class DefaultPrimitiveCounter implements PrimitiveCounter{ @Override public void decrement(long value) { - this.counter-=value; + this.counter.decrementAndGet(); } @Override public long value() { - return this.counter; + return this.counter.get(); } @Override @@ -74,20 +82,29 @@ public class DefaultPrimitiveCounter implements PrimitiveCounter{ @Override public void reset() { - this.counter=0 ; + this.counter.set(0); + Calendar cal = Calendar.getInstance(); + lastResetTime = dateTimeFormat.format(cal.getTime()); } @Override public String toString() { - return "DefaultPrimitiveCounter{" + - "name='" + name + '\'' + - ", metricType=" + metricType + - ", counter=" + counter + - '}'; + return "DefaultPrimitiveCounter{" + "name='" + name + '\'' + ", metricType=" + metricType + ", counter=" + + counter.get() + '}'; } @Override public MetricType type() { return this.metricType; } + + @Override + public HashMap<String, String> getMetricsOutput() { + return new HashMap<>(); + } + + @Override + public String getLastModified() { + return lastResetTime; + } } diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java index 0dd3b97bf..c41fab61f 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DispatchingFuntionMetricImpl.java @@ -23,8 +23,9 @@ package org.openecomp.appc.metricservice.metric.impl; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.Date; +import java.util.HashMap; import java.util.TimeZone; +import java.util.concurrent.atomic.AtomicLong; import org.openecomp.appc.metricservice.metric.DispatchingFuntionMetric; import org.openecomp.appc.metricservice.metric.MetricType; @@ -33,45 +34,51 @@ import com.att.eelf.configuration.EELFManager; public class DispatchingFuntionMetricImpl implements DispatchingFuntionMetric { - private String name; - private MetricType metricType; - private long acceptedRequested; - private long rejectedRequest; - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); - private static final EELFLogger logger = EELFManager.getInstance().getLogger(DmaapRequestCounterMetricImpl.class); - - public DispatchingFuntionMetricImpl(String name, MetricType metricType, long acceptedRequested, long rejectedRequest) { + private String name; + private MetricType metricType; + private AtomicLong acceptedRequested = new AtomicLong(); + private AtomicLong rejectedRequest = new AtomicLong(); + + private final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); + private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("YYYY-MM-dd:HH:mm:ss"); + + private String lastResetTime = dateTimeFormat.format(Calendar.getInstance().getTime()); + private static final EELFLogger logger = EELFManager.getInstance().getLogger(DispatchingFuntionMetricImpl.class); + + public DispatchingFuntionMetricImpl(String name, MetricType metricType, long acceptedRequested, + long rejectedRequest) { this.name = name; this.metricType = metricType; - this.acceptedRequested = acceptedRequested; - this.rejectedRequest = rejectedRequest; + this.acceptedRequested.set(acceptedRequested); + this.rejectedRequest.set(rejectedRequest); } @Override public void incrementAcceptedRequest() { - this.acceptedRequested+=1; + this.acceptedRequested.incrementAndGet(); } @Override public void incrementRejectedRequest() { - this.rejectedRequest+=1; + this.rejectedRequest.incrementAndGet(); } @Override public String value() { logger.debug("Value is getting calculated for metric :" + this.name); - try{ + try { Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("UTC")); - String date=dateFormat.format(cal.getTime()); - String value=date+"["+acceptedRequested+","+rejectedRequest+"]"+"@"+(acceptedRequested+rejectedRequest); - logger.debug("Current value of the metric "+this.name+" :"+value); - return value ; + String date = dateFormat.format(cal.getTime()); + String value = date + "[" + acceptedRequested.get() + "," + rejectedRequest.get() + "]" + "@" + + (acceptedRequested.get() + rejectedRequest.get()); + logger.debug("Current value of the metric " + this.name + " :" + value); + return value; - }catch (Exception e){ - logger.debug("Cant format the date."); + } catch (Exception e) { + logger.debug("Cant format the date.",e); } - return null; + return null; } @@ -82,16 +89,33 @@ public class DispatchingFuntionMetricImpl implements DispatchingFuntionMetric { @Override public void reset() { - this.acceptedRequested=0; - this.rejectedRequest=0; + this.acceptedRequested.set(0); + this.rejectedRequest.set(0); + Calendar cal = Calendar.getInstance(); + lastResetTime = dateTimeFormat.format(cal.getTime()); } @Override public MetricType type() { return this.metricType; } + + @Override + public HashMap<String, String> getMetricsOutput() { + HashMap<String, String> dispatcherMetricResult = new HashMap<>(); + dispatcherMetricResult.put("Total Received messages", + Long.toString(acceptedRequested.get() + rejectedRequest.get())); + dispatcherMetricResult.put("Total Rejected messages", Long.toString(rejectedRequest.get())); + return dispatcherMetricResult; + } + @Override public String toString() { return this.value(); } + + @Override + public String getLastModified() { + return lastResetTime; + } } diff --git a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java index 877fa6e31..dd0588afb 100644 --- a/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java +++ b/appc-metric/appc-metric-bundle/src/main/java/org/openecomp/appc/metricservice/metric/impl/DmaapRequestCounterMetricImpl.java @@ -23,8 +23,9 @@ package org.openecomp.appc.metricservice.metric.impl; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.Date; +import java.util.HashMap; import java.util.TimeZone; +import java.util.concurrent.atomic.AtomicLong; import org.openecomp.appc.metricservice.metric.MetricType; import org.openecomp.appc.metricservice.metric.DmaapRequestCounterMetric; @@ -34,41 +35,47 @@ import com.att.eelf.configuration.EELFManager; public class DmaapRequestCounterMetricImpl implements DmaapRequestCounterMetric { - private String name; - private MetricType metricType; - private long recievedMessage; - private long publishedMessage; - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); + private String name; + private MetricType metricType; + private AtomicLong recievedMessage = new AtomicLong(); + private AtomicLong publishedMessage = new AtomicLong(); + + private final SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd"); + private final SimpleDateFormat dateTimeFormat = new SimpleDateFormat("YYYY-MM-dd:HH:mm:ss"); + + private String lastResetTime = dateTimeFormat.format(Calendar.getInstance().getTime()); private static final EELFLogger logger = EELFManager.getInstance().getLogger(DmaapRequestCounterMetricImpl.class); - public DmaapRequestCounterMetricImpl(String name, MetricType metricType, long recievedMessage, long publishedMessage) { + + public DmaapRequestCounterMetricImpl(String name, MetricType metricType, long recievedMessage, + long publishedMessage) { this.name = name; this.metricType = metricType; - this.recievedMessage = recievedMessage; - this.publishedMessage=publishedMessage; + this.recievedMessage.set(recievedMessage); + this.publishedMessage.set(publishedMessage); } @Override public void incrementRecievedMessage() { - this.recievedMessage+=1; + this.recievedMessage.incrementAndGet(); } @Override public void incrementPublishedMessage() { - this.publishedMessage+=1; + this.publishedMessage.incrementAndGet(); } @Override public String value() { logger.debug("Value is getting calculated for metric :" + this.name); - try{ + try { Calendar cal = Calendar.getInstance(); cal.setTimeZone(TimeZone.getTimeZone("UTC")); - String date=dateFormat.format(cal.getTime()); - String value=date+"["+recievedMessage+"],["+publishedMessage+"]"; - logger.debug("Current value of the metric "+this.name+" :"+value); + String date = dateFormat.format(cal.getTime()); + String value = date + "[" + recievedMessage.get() + "],[" + publishedMessage.get() + "]"; + logger.debug("Current value of the metric " + this.name + " :" + value); return value; - }catch (Exception e){ - logger.debug("Cant format the date."); + } catch (Exception e) { + logger.debug("Cant format the date.",e); } return null; } @@ -80,8 +87,10 @@ public class DmaapRequestCounterMetricImpl implements DmaapRequestCounterMetric @Override public void reset() { - this.recievedMessage=0; - this.publishedMessage=0; + this.recievedMessage.set(0); + this.publishedMessage.set(0); + Calendar cal = Calendar.getInstance(); + lastResetTime = dateTimeFormat.format(cal.getTime()); } @Override @@ -90,7 +99,20 @@ public class DmaapRequestCounterMetricImpl implements DmaapRequestCounterMetric } @Override + public HashMap<String, String> getMetricsOutput() { + HashMap<String, String> dmaapMetricResult = new HashMap<>(); + dmaapMetricResult.put("Total Received messages", Long.toString(recievedMessage.get())); + dmaapMetricResult.put("Total Published messages", Long.toString(publishedMessage.get())); + return dmaapMetricResult; + } + + @Override public String toString() { return this.value(); } + + @Override + public String getLastModified() { + return lastResetTime; + } } diff --git a/appc-metric/appc-metric-features/src/main/resources/features.xml b/appc-metric/appc-metric-features/src/main/resources/features.xml index e7d134a17..20a3272ab 100644 --- a/appc-metric/appc-metric-features/src/main/resources/features.xml +++ b/appc-metric/appc-metric-features/src/main/resources/features.xml @@ -32,6 +32,10 @@ <feature name='appc-metric' description="application executor" version='${project.version}'> <!--<feature version="${project.version}">appc-aai-adapter</feature>--> <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> + + <!-- appc-common bundle is flagged as being a dependency --> + <bundle dependency="true">mvn:org.openecomp.appc/appc-common/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-metric-bundle/${project.version}</bundle> </feature> diff --git a/appc-metric/pom.xml b/appc-metric/pom.xml index 6faee63c0..36aed1ba6 100644 --- a/appc-metric/pom.xml +++ b/appc-metric/pom.xml @@ -8,7 +8,6 @@ <artifactId>appc-metric</artifactId> <packaging>pom</packaging> <name>APPC Metric</name> - <!--<version>1.1.16-SNAPSHOT</version>--> <description>APPC Metric</description> <!-- ================================================================================== --> diff --git a/appc-oam/appc-oam-bundle/pom.xml b/appc-oam/appc-oam-bundle/pom.xml new file mode 100644 index 000000000..1da4a7eee --- /dev/null +++ b/appc-oam/appc-oam-bundle/pom.xml @@ -0,0 +1,244 @@ +<?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-oam</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-oam-bundle</artifactId> + <packaging>bundle</packaging> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.opendaylight.controller.config.yang.config.sample_oam.impl</Export-Package> + <Export-Package>org.openecomp.appc.oam</Export-Package> + <Import-Package> + org.openecomp.appc.i18n, + org.openecomp.appc.logging, + org.openecomp.appc.util, + com.att.eelf.configuration, + com.att.eelf.i18n, + org.openecomp.appc.adapter.messaging.*, + org.openecomp.appc.adapter.message.*, + org.openecomp.appc.adapter.factory.*, + org.openecomp.appc.listener.*, + *;resolution:=optional + </Import-Package> + <Embed-Dependency> + appc-common;scope=compile|runtime;inline=false + </Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <executions> + <execution> + <id>config</id> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <codeGenerators> + <generator> + <codeGeneratorClass> + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + </codeGeneratorClass> + <outputBaseDir>${jmxGeneratorPath}</outputBaseDir> + <additionalConfiguration> + <namespaceToPackage1> + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + </namespaceToPackage1> + </additionalConfiguration> + </generator> + <generator> + <codeGeneratorClass> + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + </codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.sal.api.gen.plugin.version}</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>yang-jmx-generator-plugin</artifactId> + <version>${odl.yang.jmx.generator.version}</version> + </dependency> + </dependencies> + </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/initial/appc-oam.xml</file> + <type>xml</type> + <classifier>config</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <versionRange>[1.9.1,)</versionRange> + <goals> + <goal>add-source</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore/> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-model</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-request-handler-api</artifactId> + <version>${project.version}</version> + </dependency> + + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>config-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-config</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-common-util</artifactId> + </dependency> + <dependency> + <artifactId>sal-test-model</artifactId> + <groupId>org.opendaylight.controller</groupId> + <scope>test</scope> + </dependency> + <dependency> + <artifactId>sal-rest-connector</artifactId> + <groupId>org.opendaylight.netconf</groupId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <classifier>tests</classifier> + <version>${odl.mdsal.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <!-- TEMP CODE --> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-api</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-message-adapter-factory</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-dmaap-adapter-bundle</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-event-listener-bundle</artifactId> + <version>${project.version}</version> + <scope>provided</scope> + </dependency> + + </dependencies> + +</project> diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java new file mode 100644 index 000000000..93af4582f --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModule.java @@ -0,0 +1,52 @@ +/*- + * ============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.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303; + +import org.openecomp.appc.oam.AppcOam; + +public class AppcOamModule extends org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303.AbstractAppcOamModule { + public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public AppcOamModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303.AppcOamModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final AppcOam oam = new AppcOam(getDataBrokerDependency(), getNotificationServiceDependency(), getRpcRegistryDependency()); + return new AutoCloseable() { + + @Override + public void close() throws Exception { + oam.close(); + } + }; + } + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.java new file mode 100644 index 000000000..9bbd38e2f --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/opendaylight/yang/gen/v1/org/openecomp/appc/oam/impl/rev170303/AppcOamModuleFactory.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========================================================= + */ + +/* +* Generated file +* +* Generated from: yang module name: appc-oam-impl yang module local name: appc-oam-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Apr 24 16:25:46 IST 2017 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303; +public class AppcOamModuleFactory extends org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.impl.rev170303.AbstractAppcOamModuleFactory { + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java new file mode 100644 index 000000000..d255f5072 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/AppcOam.java @@ -0,0 +1,582 @@ +/*- + * ============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.oam; + +import org.openecomp.appc.Constants; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.exceptions.APPCException; +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.i18n.Msg; +import org.openecomp.appc.logging.LoggingConstants; +import org.openecomp.appc.logging.LoggingUtils; +import org.openecomp.appc.metricservice.MetricRegistry; +import org.openecomp.appc.metricservice.MetricService; +import org.openecomp.appc.metricservice.metric.Metric; +import org.openecomp.appc.requesthandler.LCMStateManager; +import org.openecomp.appc.requesthandler.RequestHandler; +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.att.eelf.i18n.EELFResourceManager; +import com.google.common.util.concurrent.Futures; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.Metrics; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.MetricsBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.metrics.KpiValues; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.get.metrics.output.metrics.KpiValuesBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.StatusBuilder; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.slf4j.MDC; + +import java.net.InetAddress; +import java.util.*; +import java.util.concurrent.*; + +import org.openecomp.appc.oam.messageadapter.*; + + +import static com.att.eelf.configuration.Configuration.*; + +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + + +public class AppcOam implements AutoCloseable, AppcOamService { + + private Configuration configuration = ConfigurationFactory.getConfiguration(); + private final EELFLogger logger = EELFManager.getInstance().getLogger(AppcOam.class); + + private boolean isMetricEnabled = false; + + + private final ScheduledExecutorService scheduledExecutorService; + + private volatile ScheduledFuture<?> outstandingLCMRequestMonitorSheduledFuture; + + + private MessageAdapter messageAdapter; + + + /** + * The ODL data store broker. Provides access to a conceptual data tree store and also provides the ability to + * subscribe for changes to data under a given branch of the tree. + */ + private DataBroker dataBroker; + + /** + * ODL Notification Service that provides publish/subscribe capabilities for YANG modeled notifications. + */ + private NotificationProviderService notificationService; + + /** + * Provides a registry for Remote Procedure Call (RPC) service implementations. The RPCs are defined in YANG models. + */ + private RpcProviderRegistry rpcRegistry; + + /** + * Represents our RPC implementation registration + */ + private BindingAwareBroker.RpcRegistration<AppcOamService> rpcRegistration; + + + /** + * The yang rpc names + */ + public enum RPC { + start, + stop, + ; + } + + + /** + * @param dataBroker + * @param notificationProviderService + * @param rpcProviderRegistry + */ + @SuppressWarnings({ + "javadoc", "nls" + }) + public AppcOam(DataBroker dataBroker, NotificationProviderService notificationProviderService, + RpcProviderRegistry rpcProviderRegistry) { + + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "oam"); + + this.dataBroker = dataBroker; + this.notificationService = notificationProviderService; + this.rpcRegistry = rpcProviderRegistry; + + if (this.rpcRegistry != null) { + rpcRegistration = rpcRegistry.addRpcImplementation(AppcOamService.class, this); + } + + Properties properties = configuration.getProperties(); + if (properties != null && properties.getProperty("metric.enabled") != null) { + isMetricEnabled = Boolean.valueOf(properties.getProperty("metric.enabled")); + } + + + messageAdapter = new MessageAdapter(); + messageAdapter.init(); + + + scheduledExecutorService = Executors.newSingleThreadScheduledExecutor( + new ThreadFactory(){ + + @Override + public Thread newThread(Runnable runnable) { + Bundle bundle = FrameworkUtil.getBundle(AppcOam.class); + return new Thread(runnable,bundle.getSymbolicName() + " scheduledExecutor"); + } + } + ); + + logger.info(Msg.COMPONENT_INITIALIZED, appName, "oam"); + } + + /** + * Implements the close of the service + * + * @see AutoCloseable#close() + */ + @SuppressWarnings("nls") + @Override + public void close() throws Exception { + String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + logger.info(Msg.COMPONENT_TERMINATING, appName, "oam"); + scheduledExecutorService.shutdown(); + if (rpcRegistration != null) { + rpcRegistration.close(); + } + logger.info(Msg.COMPONENT_TERMINATED, appName, "oam"); + } + + @Override + public Future<RpcResult<GetMetricsOutput>> getMetrics() { + + GetMetricsOutputBuilder outputBuilder = new GetMetricsOutputBuilder(); + + if (!isMetricEnabled){ + logger.error("Metric Service not enabled returning failure"); + RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"Metric Service not enabled").build(); + return Futures.immediateFuture(result); + } + + MetricService metricService = null; + try { + metricService = getService(MetricService.class); + } catch (APPCException e){ + logger.error("MetricService not found",e); + RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"Metric Service not found").build(); + return Futures.immediateFuture(result); + } + Map<String,MetricRegistry> allMetricRegitry = metricService.getAllRegistry(); + + if(allMetricRegitry == null || allMetricRegitry.isEmpty()){ + logger.error("No metrics registered returning failure"); + RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(false).withError(RpcError.ErrorType.APPLICATION,"No metrics Registered").build(); + return Futures.immediateFuture(result); + } + List<Metrics> metricsList = new ArrayList<>(); + + logger.debug("Iterating metric registry list"); + for (MetricRegistry metricRegistry : allMetricRegitry.values() ) { + logger.debug("Iterating metric registry :" + metricRegistry.toString()); + Metric[] metrics = metricRegistry.metrics() ; + if(metrics!= null && metrics.length >0) { + logger.debug("Iterating though metrics in registry"); + for (Metric metric : metrics) { + logger.debug("Iterating though metrics: "+ metric.name()); + MetricsBuilder metricsBuilder = new MetricsBuilder(); + metricsBuilder.setKpiName(metric.name()); + metricsBuilder.setLastResetTime(metric.getLastModified()); + List<KpiValues> kpiList = new ArrayList<>(); + Map<String, String> metricsOutput = metric.getMetricsOutput(); + for (Map.Entry<String, String> kpi : metricsOutput.entrySet()) { + KpiValuesBuilder kpiValuesBuilder = new KpiValuesBuilder(); + kpiValuesBuilder.setName(kpi.getKey()); + kpiValuesBuilder.setValue(kpi.getValue()); + kpiList.add(kpiValuesBuilder.build()); + } + metricsBuilder.setKpiValues(kpiList); + metricsList.add(metricsBuilder.build()); + } + } + } + outputBuilder.setMetrics(metricsList); + RpcResult<GetMetricsOutput> result = RpcResultBuilder.<GetMetricsOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<StopOutput>> stop(StopInput stopInput){ + logger.debug("Input received : " + stopInput); + final Date startTime = new Date(); + Status status = this.buildStatus(OAMCommandStatus.ACCEPTED); + final CommonHeader commonHeader = stopInput.getCommonHeader(); + + try { + setInitialLogProperties(commonHeader,RPC.stop); + + //Close the gate so that no more new LCM request will be excepted. + LCMStateManager lcmStateManager = getService(LCMStateManager.class); + lcmStateManager.disableLCMOperations(); + //Begin monitoring outstanding LCM request + scheduleOutstandingLCMRequestMonitor(commonHeader,startTime); + } catch(Throwable t) { + status = unexpectedOAMError(t,RPC.stop); + } + finally { + LoggingUtils.auditWarn(startTime.toInstant(), + new Date(System.currentTimeMillis()).toInstant(), + String.valueOf(status.getCode()), + status.getMessage(), + this.getClass().getCanonicalName(), + Msg.OAM_OPERATION_STOPPING, + getAppcName() + ); + this.clearRequestLogProperties(); + } + + StopOutputBuilder stopOutputBuilder = new StopOutputBuilder(); + stopOutputBuilder.setStatus(status); + stopOutputBuilder.setCommonHeader(commonHeader); + StopOutput stopOutput = stopOutputBuilder.build(); + return RpcResultBuilder.success(stopOutput).buildFuture(); + } + + @Override + public Future<RpcResult<StartOutput>> start(StartInput startInput){ + logger.debug("Input received : " + startInput); + final Date startTime = new Date(); + Status status = this.buildStatus(OAMCommandStatus.ACCEPTED); + final CommonHeader commonHeader = startInput.getCommonHeader(); + + try { + + + setInitialLogProperties(commonHeader,RPC.start); + + this.scheduleStartingAPPC(commonHeader,startTime); + } catch(Throwable t) { + status = unexpectedOAMError(t,RPC.start); + } + finally { + LoggingUtils.auditWarn(startTime.toInstant(), + new Date(System.currentTimeMillis()).toInstant(), + String.valueOf(status.getCode()), + status.getMessage(), + this.getClass().getCanonicalName(), + Msg.OAM_OPERATION_STARTING, + getAppcName() + ); + this.clearRequestLogProperties(); + } + + StartOutputBuilder startOutputBuilder = new StartOutputBuilder(); + startOutputBuilder.setStatus(status); + startOutputBuilder.setCommonHeader(commonHeader); + StartOutput startOutput = startOutputBuilder.build(); + return RpcResultBuilder.success(startOutput).buildFuture(); + } + + private <T> T getService(Class<T> _class) throws APPCException { + BundleContext bctx = FrameworkUtil.getBundle(_class).getBundleContext(); + ServiceReference sref = bctx.getServiceReference(_class.getName()); + if (sref != null) { + if(logger.isTraceEnabled()) { + logger.debug("Using the BundleContext to fetched the service reference for " + _class.getName()); + + } + return (T) bctx.getService(sref); + } else { + throw new APPCException("Using the BundleContext failed to to fetch service reference for " + _class.getName()); + } + } + + private Status buildStatus(OAMCommandStatus osmCommandStatus){ + StatusBuilder status = new StatusBuilder(); + status.setCode(osmCommandStatus.getResponseCode()); + status.setMessage(osmCommandStatus.getResponseMessage()); + return status.build(); + } + + private Status buildStatus(OAMCommandStatus osmCommandStatus,Params params){ + StatusBuilder status = new StatusBuilder(); + status.setCode(osmCommandStatus.getResponseCode()); + status.setMessage(osmCommandStatus.getFormattedMessage(params)); + return status.build(); + } + + + + 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 setInitialLogProperties(CommonHeader commonHeader,RPC action) { + + try { + MDC.put(MDC_KEY_REQUEST_ID, commonHeader.getRequestId()); + MDC.put(LoggingConstants.MDCKeys.PARTNER_NAME, commonHeader.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, action.name()); + } catch (Exception e) { + logger.debug("MDC constant error",e); + } + } catch (RuntimeException e) { + //ignore + } + } + + + private void storeErrorMessageToLog(Status status, String additionalMessage) { + LoggingUtils.logErrorMessage( + String.valueOf(status.getCode()), + status.getMessage(), + LoggingConstants.TargetNames.APPC, + LoggingConstants.TargetNames.APPC_OAM_PROVIDER, + additionalMessage, + this.getClass().getCanonicalName()); + } + + private String getAppcName(){ + return configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); + } + + private Status unexpectedOAMError(Throwable t,RPC action){ + final String appName = getAppcName(); + + String exceptionMessage = t.getMessage() != null ? t.getMessage() : t.toString(); + + String errorMessage = EELFResourceManager.format(Msg.OAM_OPERATION_EXCEPTION, t, appName, t.getClass().getSimpleName(), action.name(), exceptionMessage); + + Params params = new Params().addParam("errorMsg", exceptionMessage); + Status status = buildStatus( + OAMCommandStatus.UNEXPECTED_ERROR, + params + ); + + storeErrorMessageToLog(status,errorMessage); + return status; + } + + + private int getInprogressLCMRequestCount() throws APPCException { + RequestHandler requestHandler = getService(RequestHandler.class); + + if(requestHandler == null) { + return 0; + } + + int inprogressRequestCount = requestHandler.getInprogressRequestCount(); + return inprogressRequestCount; + } + + + + private void scheduleOutstandingLCMRequestMonitor(final CommonHeader commonHeader,final Date startTime){ + + + class MyCommand implements Runnable{ + + public ScheduledFuture<?> myScheduledFuture = null; + + @Override + public void run() { + try { + setInitialLogProperties(commonHeader, RPC.stop); + + + logDebug("Executing stopping task "); + + ScheduledFuture<?> currentScheduledFuture = AppcOam.this.outstandingLCMRequestMonitorSheduledFuture; + + //cancel myself if I am not the current outstandingLCMRequestMonitor + if(currentScheduledFuture != myScheduledFuture){ + myScheduledFuture.cancel(false); + return; + } + + Status status = buildStatus(OAMCommandStatus.SUCCESS); + + + try { + + //log status and return if there are still LCM request in progress + int inprogressRequestCount = getInprogressLCMRequestCount(); + if (inprogressRequestCount > 0) { + logDebug("The application '%s' has '%s' outstanding LCM request to complete before coming to a complete stop. ", + getAppcName(), + inprogressRequestCount + ); + return; + } + + } catch (Throwable t) { + status = unexpectedOAMError(t, RPC.stop); + myScheduledFuture.cancel(false); + } + + try { + OAMContext oamContext = new OAMContext(); + oamContext.setRpcName(RPC.stop); + oamContext.setCommonHeader(commonHeader); + oamContext.setStatus(status); + messageAdapter.post(oamContext); + } catch(Throwable t) { + status = unexpectedOAMError(t,RPC.stop); + } + + LoggingUtils.auditWarn(startTime.toInstant(), + new Date(System.currentTimeMillis()).toInstant(), + String.valueOf(status.getCode()), + status.getMessage(), + this.getClass().getCanonicalName(), + Msg.OAM_OPERATION_STOPPED, + getAppcName() + ); + myScheduledFuture.cancel(false); + + } finally { + clearRequestLogProperties(); + } + } + }; + + MyCommand command = new MyCommand(); + + long initialDelay = 10000; + long delay = initialDelay; + + + command.myScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay( + command, + initialDelay, + delay, + TimeUnit.MILLISECONDS + ); + this.outstandingLCMRequestMonitorSheduledFuture = command.myScheduledFuture; + } + + + + + private void scheduleStartingAPPC(final CommonHeader commonHeader,final Date startTime){ + + + class MyCommand implements Runnable{ + + + @Override + public void run() { + try { + setInitialLogProperties(commonHeader, RPC.start); + + logDebug("Executing starting task "); + + Status status = buildStatus(OAMCommandStatus.SUCCESS); + + try { + LCMStateManager lcmStateManager = getService(LCMStateManager.class); + lcmStateManager.enableLCMOperations(); + //cancel the current outstandingLCMRequestMonitor + outstandingLCMRequestMonitorSheduledFuture = null; + } catch(Throwable t) { + status = unexpectedOAMError(t,RPC.start); + } + + try { + OAMContext oamContext = new OAMContext(); + oamContext.setRpcName(RPC.start); + oamContext.setCommonHeader(commonHeader); + oamContext.setStatus(status); + messageAdapter.post(oamContext); + } catch(Throwable t) { + status = unexpectedOAMError(t,RPC.start); + } + + LoggingUtils.auditWarn(startTime.toInstant(), + new Date(System.currentTimeMillis()).toInstant(), + String.valueOf(status.getCode()), + status.getMessage(), + this.getClass().getCanonicalName(), + Msg.OAM_OPERATION_STARTED, + getAppcName() + ); + } finally { + clearRequestLogProperties(); + } + } + }; + + MyCommand command = new MyCommand(); + long initialDelay = 1000; + + scheduledExecutorService.schedule( + command, + initialDelay, + TimeUnit.MILLISECONDS + ); + } + + + private void logDebug(String message,Object... args){ + if (logger.isDebugEnabled()) { + logger.debug(String.format(message,args)); + } + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java new file mode 100644 index 000000000..aebfaf113 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/OAMCommandStatus.java @@ -0,0 +1,87 @@ +/*- + * ============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.oam; + + +import org.openecomp.appc.executor.objects.Params; +import org.openecomp.appc.util.MessageFormatter; + +import java.util.Map; + +public enum OAMCommandStatus { + + ACCEPTED(100,"ACCEPTED - request accepted"), + + //ERROR(2xx) – request can’t be handled due to some technical error + UNEXPECTED_ERROR(200,"UNEXPECTED ERROR - ${errorMsg}"), + + SUCCESS(400,"SUCCESS - request has been processed successfully"), + ; + + + public static final String errorDgMessageParamName = "errorDgMessage"; + + private int responseCode; + private String responseMessage; + + + + + OAMCommandStatus(int responseCode, String responseMessage) { + this.responseCode = responseCode; + this.responseMessage = responseMessage; + } + + public String getResponseMessage() { + return responseMessage; + } + + public int getResponseCode() { + return responseCode; + } + + + /** + * + * @return messageTemplate + */ + + + public String getFormattedMessage(Params params){ + Map<String,Object> paramsMap = params != null ? params.getParams() : null; + return MessageFormatter.format(getResponseMessage(),paramsMap); + + } + + public String getFormattedMessageWithCode(Params params){ + return getResponseCode()+"-" + getFormattedMessage(params); + } + + @Override + public String toString() { + return "OAMCommandStatus{" + + "responseCode=" + responseCode + + ", responseMessage='" + responseMessage + '\'' + + '}'; + } +} + diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java new file mode 100644 index 000000000..4895e23fa --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/Converter.java @@ -0,0 +1,133 @@ +/*- + * ============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.oam.messageadapter; + +import org.openecomp.appc.oam.AppcOam; +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 org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataContainer; + + +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class Converter { + private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; + 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")); + } + + + private static Builder<?> convAsyncResponseToBuilder1(AppcOam.RPC rpcName, CommonHeader commonHeader, Status status) { + Builder<?> outObj = null; + if(rpcName == null){ + throw new IllegalArgumentException("empty asyncResponse.rpcName"); + } + if(commonHeader == null){ + throw new IllegalArgumentException("empty asyncResponse.commonHeader"); + } + if(status == null){ + throw new IllegalArgumentException("empty asyncResponse.status"); + } + switch (rpcName){ + case stop: + outObj = new StopOutputBuilder(); + ((StopOutputBuilder)outObj).setCommonHeader(commonHeader); + ((StopOutputBuilder)outObj).setStatus(status); + return outObj; + + case start: + outObj = new StartOutputBuilder(); + ((StartOutputBuilder)outObj).setCommonHeader(commonHeader); + ((StartOutputBuilder)outObj).setStatus(status); + return outObj; + default: + throw new IllegalArgumentException(rpcName+" action is not supported"); + } + } + + public static String convAsyncResponseToUebOutgoingMessageJsonString(OAMContext oamContext) throws JsonProcessingException { + AppcOam.RPC rpcName = oamContext.getRpcName(); + CommonHeader commonHeader = oamContext.getCommonHeader(); + Status status = oamContext.getStatus(); + + DmaapOutgoingMessage dmaapOutgoingMessage = convAsyncResponseToUebOutgoingMessage(rpcName,commonHeader,status); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.addMixInAnnotations(dmaapOutgoingMessage.getBody().getOutput().getClass(), MixInFlagsMessage.class); + objectMapper.addMixInAnnotations(Status.class, MixIn.class); + objectMapper.addMixInAnnotations(CommonHeader.class, MixInCommonHeader.class); + ObjectWriter writer = objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL).configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true).writer(); + return writer.writeValueAsString(dmaapOutgoingMessage); + } + + private static DmaapOutgoingMessage convAsyncResponseToUebOutgoingMessage(AppcOam.RPC rpcName, CommonHeader commonHeader, Status status) throws JsonProcessingException { + DmaapOutgoingMessage outObj = new DmaapOutgoingMessage(); + String correlationID = commonHeader.getRequestId(); + outObj.setCorrelationID(correlationID); + outObj.setType("response"); + outObj.setRpcName(rpcName.name()); + Builder<?> builder = Converter.convAsyncResponseToBuilder1(rpcName,commonHeader,status); + 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("request-id") + abstract java.lang.String getRequestId(); + + @JsonProperty("originator-id") + abstract java.lang.String getOriginatorId(); + + } + abstract class MixInFlagsMessage extends MixIn { + @JsonProperty("common-header") + abstract CommonHeader getCommonHeader(); + } + + + +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java new file mode 100644 index 000000000..351984d13 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/DmaapOutgoingMessage.java @@ -0,0 +1,134 @@ +/*- + * ============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.oam.messageadapter; + +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 represented in org.openecomp.appc.listener.LCM.domainmodel.DmaapOutgoingMessage + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DmaapOutgoingMessage { + + @JsonProperty("type") + private String type; + + @JsonProperty("correlation-id") + private String correlationID; + + 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 getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCorrelationID() { + return correlationID; + } + + public void setCorrelationID(String correlationID) { + this.correlationID = correlationID; + } + + 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-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java new file mode 100644 index 000000000..2ba76d46e --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/MessageAdapter.java @@ -0,0 +1,131 @@ +/*- + * ============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.oam.messageadapter; + +import org.openecomp.appc.adapter.message.MessageAdapterFactory; +import org.openecomp.appc.adapter.message.Producer; +import org.openecomp.appc.configuration.Configuration; +import org.openecomp.appc.configuration.ConfigurationFactory; +import org.openecomp.appc.listener.impl.EventHandlerImpl; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; + +import com.att.eelf.configuration.EELFLogger; +import com.att.eelf.configuration.EELFManager; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.apache.commons.lang.ObjectUtils; + +import java.util.HashSet; +import java.util.Properties; + +public class MessageAdapter { + + private Producer producer; + private String partition ; + private Configuration configuration; + private HashSet<String> pool; + private String writeTopic; + private String apiKey; + private String apiSecret; + + private static final EELFLogger logger = EELFManager.getInstance().getLogger(MessageAdapter.class); + + /** + * Initialize producer client to post messages using configuration properties + */ + public void init(){ + this.producer = getProducer(); + } + + private Producer getProducer() { + configuration = ConfigurationFactory.getConfiguration(); + Properties properties=configuration.getProperties(); + updateProperties(properties); + Producer localProducer = null; + + BundleContext ctx = FrameworkUtil.getBundle(EventHandlerImpl.class).getBundleContext(); + if (ctx != null) { + ServiceReference svcRef = ctx.getServiceReference(MessageAdapterFactory.class.getName()); + if (svcRef != null) { + localProducer = ((MessageAdapterFactory) ctx.getService(svcRef)).createProducer(pool, writeTopic, apiKey, apiSecret); + for (String url : pool) { + if (url.contains("3905") || url.contains("https")) { + localProducer.useHttps(true); + break; + } + } + } + } + + return localProducer; + } + + private void updateProperties(Properties props) { + if (logger.isTraceEnabled()) { + logger.trace("Entering to updateProperties with Properties = "+ ObjectUtils.toString(props)); + } + pool = new HashSet<>(); + if (props != null) { + writeTopic = props.getProperty("appc.OAM.topic.write"); + apiKey = props.getProperty("appc.OAM.client.key"); + apiSecret = props.getProperty("appc.OAM.client.secret"); + String hostnames = props.getProperty("appc.OAM.poolMembers"); + if (hostnames != null && !hostnames.isEmpty()) { + for (String name : hostnames.split(",")) { + pool.add(name); + } + } + } + } + + /** + * Posts message to UEB. As UEB accepts only json messages this method first convert uebMessage to json format and post it to UEB. + * @param oamContext response data that based on it a message will be send to UEB (the format of the message that will be sent to UEB based on the action and its YANG domainmodel). + * @return True if message is postes successfully else False + */ + public boolean post(OAMContext oamContext){ + boolean success; + if (logger.isTraceEnabled()) { + logger.trace("Entering to post with AsyncResponse = " + ObjectUtils.toString(oamContext)); + } + + String jsonMessage; + try { + jsonMessage = Converter.convAsyncResponseToUebOutgoingMessageJsonString(oamContext); + if (logger.isDebugEnabled()) { + logger.debug("UEB Response = " + jsonMessage); + } + success = producer.post(this.partition, jsonMessage); + } catch (JsonProcessingException e1) { + logger.error("Error generating Jason from UEB message "+ e1.getMessage()); + success= false; + }catch (Exception e){ + logger.error("Error sending message to UEB "+e.getMessage()); + success= false; + } + if (logger.isTraceEnabled()) { + logger.trace("Exiting from post with (success = "+ ObjectUtils.toString(success)+")"); + } + return success; + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java new file mode 100644 index 000000000..68ea95ba7 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/java/org/openecomp/appc/oam/messageadapter/OAMContext.java @@ -0,0 +1,72 @@ +/*- + * ============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.oam.messageadapter; + + + + +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.common.header.CommonHeaderBuilder; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.oam.rev170303.status.Status;import org.openecomp.appc.oam.AppcOam; + +public class OAMContext { + + private AppcOam.RPC rpcName; + private CommonHeader commonHeader; + private Status status; + + + public AppcOam.RPC getRpcName() { + return rpcName; + } + + public void setRpcName(AppcOam.RPC rpcName) { + this.rpcName = rpcName; + } + + public CommonHeader getCommonHeader() { + return commonHeader; + } + + public void setCommonHeader(CommonHeader commonHeader) { + this.commonHeader = commonHeader; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + + @Override + public String toString() { + return "OAMContext {" + + "rpcName=" + rpcName + + ", commonHeader=" + commonHeader + + ", status=" + status + + '}'; + } +} diff --git a/appc-oam/appc-oam-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/appc-oam/appc-oam-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml new file mode 100644 index 000000000..607348892 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -0,0 +1,30 @@ +<?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"> + +</blueprint> diff --git a/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml b/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml new file mode 100644 index 000000000..6b4cd3c75 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/initial/appc-oam.xml @@ -0,0 +1,77 @@ +<?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========================================================= + --> + +<!-- vi: set et smarttab sw=4 tabstop=4: --> +<snapshot> + <configuration> + <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> + <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"> + <module> + + <!-- This xmlns:prefix should match the namespace in the *-oam-impl.yang + file The prefix: inside type should match the prefix of the yang file. --> + <type xmlns:prefix="org:openecomp:appc:oam:impl"> + prefix:appc-oam-impl + </type> + <name>appc-oam-impl</name> + + <!-- The following sections contain bindings to services defined in + the *-oam-impl yang file. For example the rpc-registry is required because + we have a dependency (or augmentation) named "rpc-registry" and which binds + to the md-sa-binding-registry. If you remove those dependencies from the + yang file then you can remove them from here. --> + <rpc-registry> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type> + <name>binding-rpc-broker</name> + </rpc-registry> + + <data-broker> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type> + <name>binding-data-broker</name> + </data-broker> + + <notification-service> + <type + xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding"> + binding:binding-notification-service + </type> + <name>binding-notification-broker</name> + </notification-service> + </module> + + </modules> + </data> + + </configuration> + + <!-- Required capabilities are basically a listing of all modules that need + to be imported before our service can be resolved. Capabilities for dependencies + defined above are implied which is why we do not have define a required capability + for the data broker, for example. --> + <required-capabilities> + <capability>org:openecomp:appc:oam:impl?module=appc-oam-impl&revision=2017-03-03 + </capability> + </required-capabilities> + +</snapshot> diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties new file mode 100644 index 000000000..b22ced00d --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/default.properties @@ -0,0 +1,49 @@ +### +# ============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========================================================= +### + +# +# This property file supplies the configuration defaults for the APP-C controller +# +# Default values are supplied so that all defined properties have well-known values and are +# valid even if a configuration file is not supplied. This is done to ensure that a runnable, +# stable, and defined configuration exists at all times. The reason the defaults are supplied +# via this property file and not in the code is so that the properties can be changed +# easily if needed in the future. Use of the "getProperty(name, default)" method is +# discouraged because if the default value needs to be changed, everywhere in the code it +# is used would have to be changed. By loading the defaults in this property file, all +# values can be defined in one place and support is easier. This does mean that all +# properties that are defined must have a default value supplied here. Which also means +# this file documents all defined properties (not a bad thing either). +# +#-------------------------------------------------------------------------------------------- +# The path and file used to load user-supplied configuration settings, if any +org.openecomp.appc.bootstrap.path=/opt/openecomp/appc/data/properties,${user.home},. +org.openecomp.appc.bootstrap.file=appc.properties + +appc.application.name=APPC + +# +# The path to search for logging configuration document, and the name of the document +# +org.openecomp.appc.logging.path=${user.home},etc,../etc,. +org.openecomp.appc.logging.file=logback.xml + + diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml new file mode 100644 index 000000000..8d47c6cae --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/logback.xml @@ -0,0 +1,284 @@ +<!-- + ============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========================================================= + --> + +<configuration scan="true" scanPeriod="3 seconds" debug="true"> + <!--<jmxConfigurator /> --> + <property name="logDirectory" value="logs" /> + <property name="debugLogDirectory" value="debug-logs" /> + <!-- Example evaluator filter applied against console appender --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + + <!-- ============================================================================ --> + <!-- CDP Appenders --> + <!-- ============================================================================ --> + + <!-- The CDPAppender is used to record events to the general CDP application + log. This is the log file used by default as the application root log, if + no other log is defined or the application creates specialized loggers of + the form com.att.cdp.x.y.z where the name occupied by the "x" is NOT security, + perf, server, coordinator, gui, or policy. These are defined as specialization + loggers for various business purposes. --> + <appender name="CDP" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDP" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDP" /> + </appender> + + <!-- CDP Security Appender. This appender is used to record security events + to the security log file. Security events are separate from other loggers + in CDP so that security log records can be captured and managed in a secure + way separate from the other logs. This appender is set to never discard any + events. --> + <appender name="CDPSecurity" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-security.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-security.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPSecurity" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <discardingThreshold>0</discardingThreshold> + <appender-ref ref="CDPSecurity" /> + </appender> + + <!-- CDP Performance Appender. This appender is used to record performance + records. --> + <appender name="CDPPerformance" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-performance.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-performance.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <outputPatternAsHeader>true</outputPatternAsHeader> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPPerformance" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPPerformance" /> + </appender> + + <!-- CDP Server Appender. This appender is used to record Server related + logging events. The Server logger and appender are specializations of the + CDP application root logger and appender. This can be used to segregate Server + events from other components, or it can be eliminated to record these events + as part of the application root log. --> + <appender name="CDPServer" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-server.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-server.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger [%X{User} %X{RemoteHost} %X{RequestId} %X{Method} + %X{Path}] - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPServer" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPServer" /> + </appender> + + <!-- CDP Coordinator Appender. This appender is used to record Coordinator + related logging events. The Coordinator logger and appender are specializations + of the CDP application root logger and appender. This can be used to segregate + Coordinator events from other components, or it can be eliminated to record + these events as part of the application root log. --> + <appender name="CDPCoordinator" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-coordinator.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-coordinator.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPCoordinator" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPCoordinator" /> + </appender> + + <!-- CDP Policy Appender. This appender is used to record Policy engine + related logging events. The Policy logger and appender are specializations + of the CDP application root logger and appender. This can be used to segregate + Policy engine events from other components, or it can be eliminated to record + these events as part of the application root log. --> + <appender name="CDPPolicy" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${logDirectory}/cdp-policy.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/cdp-policy.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!-- <pattern>"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - + %msg%n"</pattern> --> + <pattern>%d{MM/dd-HH:mm:ss.SSS} [%-16thread] %.-5level + %-36.36logger - %msg%n</pattern> + </encoder> + </appender> + <appender name="asyncCDPPolicy" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>256</queueSize> + <appender-ref ref="CDPPolicy" /> + </appender> + <appender name="CommandExecutor" + class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${debugLogDirectory}/appc-debug.log</file> + <rollingPolicy + class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/command-executor.%i.log.zip + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>9</maxIndex> + </rollingPolicy> + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>5MB</maxFileSize> + </triggeringPolicy> + <encoder> + <!--<Pattern> + %d{yyyy-MM-dd'T'HH:mm:ss.SSSZ}|%X{RequestID}|%X{ServiceInstanceID}|%thread|%X{ServerName}|%X{ServiceName}|%X{UUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{Server}|%X{IPAddress}|[%c{3}]|%X{Timer}| - %msg%n + </Pattern>--> + <Pattern> + %d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%X{InstanceUUID}|%-5.5p|%X{AlertSeverity}|%X{ServerIPAddress}|%X{ServerFQDN}|%X{RemoteHost}|%X{Timer}|[%c{3}]|%m%n + </Pattern> + </encoder> + </appender> + + <logger name="org.openecomp.appc" level="DEBUG" additivity="false"> + <appender-ref ref="CommandExecutor" /> + </logger> + + <!-- ============================================================================ --> + <!-- CDP loggers --> + <!-- ============================================================================ --> + <logger name="com.att.cdp" level="info" additivity="false"> + <appender-ref ref="asyncCDP" /> + </logger> + <logger name="com.att.cdp.security" level="info" additivity="false"> + <appender-ref ref="asyncCDPSecurity" /> + </logger> + <logger name="com.att.cdp.perf" level="info" additivity="false"> + <appender-ref ref="asyncCDPPerformance" /> + </logger> + <logger name="com.att.cdp.server" level="debug" additivity="false"> + <appender-ref ref="asyncCDPServer" /> + </logger> + <logger name="com.att.cdp.coordinator" level="info" additivity="false"> + <appender-ref ref="asyncCDPCoordinator" /> + </logger> + <logger name="com.att.cdp.policy" level="info" additivity="false"> + <appender-ref ref="asyncCDPPolicy" /> + </logger> + + <!-- The OpenStack connector logger --> + <logger name="os" level="debug" additivity="false"> + <appender-ref ref="asyncCDPServer" /> + </logger> + + <root level="WARN"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration> diff --git a/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg new file mode 100644 index 000000000..be5863291 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/resources/org/openecomp/appc/org.ops4j.pax.logging.cfg @@ -0,0 +1,144 @@ + ################################################################################ + # + # 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, + # WITH WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + # + ################################################################################ + + # Root + #log4j.rootLogger=TRACE, osgi:VmLogAppender + log4j.rootLogger=TRACE, out, sift, osgi:* + log4j.throwableRenderer=org.apache.log4j.OsgiThrowableRenderer + + # CONSOLE appender not used by default + log4j.appender.stdout=org.apache.log4j.ConsoleAppender + log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + + # Async appender forwarding to file appender + log4j.appender.async=org.apache.log4j.AsyncAppender + log4j.appender.async.appenders=out + + # Karaf appenders + # File appender + log4j.appender.out=org.apache.log4j.RollingFileAppender + log4j.appender.out.layout=org.apache.log4j.PatternLayout + log4j.appender.out.layout.ConversionPattern=%d{ISO8601} | %-5.5p | %-16.16t | %-32.32c{1} | %X{bundle.id} - %X{bundle.name} - %X{bundle.version} | %m%n + log4j.appender.out.file=${karaf.data}/log/karaf.log + log4j.appender.out.append=true + log4j.appender.out.maxFileSize=10MB + log4j.appender.out.maxBackupIndex=100 + + + # Sift appender + log4j.appender.sift=org.apache.log4j.sift.MDCSiftingAppender + log4j.appender.sift.key=bundle.name + log4j.appender.sift.default=karaf + log4j.appender.sift.appender=org.apache.log4j.RollingFileAppender + log4j.appender.sift.appender.layout=org.apache.log4j.PatternLayout + log4j.appender.sift.appender.layout.ConversionPattern=%d{MM/dd-HH:mm:ss.SSS}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServiceName} - %X{bundle.id} - %X{bundle.name} - %X{bundle.version}|%-5.5p|%X{AlertSeverity}|%X{ServerFQDN}|%X{ServerIPAddress}|[%c{3}]|%m%n + log4j.appender.sift.appender.file=${karaf.data}/log/eelf/karaf.log + log4j.appender.sift.appender.append=true + + log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPusherImpl=DEBUG + log4j.category.org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator=DEBUG + + + #ECOMP Debug appender + log4j.appender.debug=org.apache.log4j.RollingFileAppender + log4j.appender.debug.key=bundle.name + log4j.appender.debug.default=karaf + + log4j.appender.debug.appName=EELFDebug + log4j.appender.debug.layout=org.apache.log4j.PatternLayout + log4j.appender.debug.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%m%n + #log4j.appender.debug.filter.f1=org.apache.log4j.varia.LevelRangeFilter + #log4j.appender.debug.filter.f1.LevelMax=WARN + #log4j.appender.debug.filter.f1.LevelMin=TRACE + + + log4j.appender.debug.file=${karaf.data}/log/APPC/appc-debug.log + log4j.appender.debug.append=true + log4j.appender.debug.maxFileSize=100MB + log4j.appender.debug.maxBackupIndex=10 + + + #Error appender + log4j.appender.error=org.apache.log4j.RollingFileAppender + log4j.appender.error.appName=EELFError + log4j.appender.error.File=${karaf.data}/log/APPC/appc-error.log + log4j.appender.error.Threshold=ERROR + log4j.appender.error.MaxBackupIndex=1 + log4j.appender.error.MaxFileSize=100MB + log4j.appender.error.layout=org.apache.log4j.PatternLayout + log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd'T'hh:mm:ss.SSSXXX}|%X{RequestId}|%t|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%-5.5p|%X{ErrorCode}|%X{ErrorDescription}|%m%n + + #Metrics appender + log4j.appender.metric=org.apache.log4j.RollingFileAppender + log4j.appender.metric.appName=EELFMetrics + log4j.appender.metric.File=${karaf.data}/log/APPC/appc-metric.log + log4j.appender.metric.MaxBackupIndex=1 + log4j.appender.metric.MaxFileSize=100MB + log4j.appender.metric.layout=org.apache.log4j.PatternLayout + log4j.appender.metric.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{TargetVirtualEntity}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n + + #Audit appender + log4j.appender.audit=org.apache.log4j.RollingFileAppender + log4j.appender.audit.appName=EELFAudit + log4j.appender.audit.File=${karaf.data}/log/APPC/appc-audit.log + log4j.appender.audit.MaxBackupIndex=1 + log4j.appender.audit.MaxFileSize=100MB + log4j.appender.audit.layout=org.apache.log4j.PatternLayout + log4j.appender.audit.layout.ConversionPattern=%X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%t|%X{ServerName}|%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceUUID}|%-5.5p|%X{Severity}|%X{ServerIPAddress}|%X{ElapsedTime}|%X{ServerFQDN}|%X{ClientIPAddress}|%X{ClassName}||%X{ProcessKey}|%X{CustomField1}|%X{CustomField2}|%X{CustomField3}|%X{CustomField4}|%m%n + + #Loggers + #Routing of all messages from root logger + log4j.logger.com.att=TRACE, debug, error + #Store to the same log file messages from upper level appender or not + log4j.additivity.com.att=false + + #EELFManager loggers + #EELF parent logger + log4j.logger.com.att.eelf=TRACE, debug + log4j.additivity.com.att.eelf=false + + #Audit logger routing + log4j.logger.com.att.eelf.audit=DEBUG, audit + log4j.additivity.com.att.eelf.audit=false + + #Metric logger routing + log4j.logger.com.att.eelf.metrics=DEBUG, metric + log4j.additivity.com.att.eelf.metrics=false + + #Performance logger routing + log4j.logger.com.att.eelf.perf=DEBUG, metric + log4j.additivity.com.att.eelf.perf=false + + #Server logger routing + log4j.logger.com.att.eelf.server=DEBUG, debug + log4j.additivity.com.att.eelf.server=false + + #Policy logger routing + log4j.logger.com.att.eelf.policy=DEBUG, debug + log4j.additivity.com.att.eelf.policy=false + + #Error logger routing + log4j.logger.com.att.eelf.error=DEBUG, error + log4j.additivity.com.att.eelf.error=false + + #Debug logger routing + log4j.logger.com.att.eelf.debug=DEBUG, debug + log4j.additivity.com.att.eelf.debug=false + diff --git a/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang b/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang new file mode 100644 index 000000000..364707ef5 --- /dev/null +++ b/appc-oam/appc-oam-bundle/src/main/yang/appc-oam.yang @@ -0,0 +1,61 @@ +module appc-oam-impl { + + yang-version 1; + namespace "org:openecomp:appc:oam:impl"; + prefix "appc-oam-impl"; + + import config { prefix config; revision-date 2013-04-05; } + import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; } + + description + "This module contains the base YANG definitions for + appc-oam implementation."; + + revision "2017-03-03" { + description + "Initial revision."; + } + + // This is the definition of the service implementation as a module identity. + identity appc-oam-impl { + base config:module-type; + + // Specifies the prefix for generated java classes. + config:java-name-prefix AppcOam; + } + + // Augments the 'configuration' choice node under modules/module. + // We consume the three main services, RPCs, DataStore, and Notifications + augment "/config:modules/config:module/config:configuration" { + case appc-oam-impl { + when "/config:modules/config:module/config:type = 'appc-oam-impl'"; + + container rpc-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-rpc-registry; + } + } + } + + container notification-service { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsal:binding-notification-service; + } + } + } + + container data-broker { + uses config:service-ref { + refine type { + mandatory false; + config:required-identity mdsal:binding-async-data-broker; + } + } + } + } + } +} diff --git a/appc-oam/appc-oam-features/pom.xml b/appc-oam/appc-oam-features/pom.xml new file mode 100644 index 000000000..a8a9a4478 --- /dev/null +++ b/appc-oam/appc-oam-features/pom.xml @@ -0,0 +1,126 @@ +<?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-oam</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <name>appc-oam-features</name> + <artifactId>appc-oam-features</artifactId> + + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-model</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-bundle</artifactId> + <classifier>config</classifier> + <type>xml</type> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>features-mdsal</artifactId> + <classifier>features</classifier> + <type>xml</type> + + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>features-yangtools</artifactId> + <classifier>features</classifier> + <type>xml</type> + <scope>runtime</scope> + </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. --> + <!-- Skipping ODL feature test --> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <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> + <skipTests>true</skipTests> + </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> + + </plugins> + </build> +</project> diff --git a/appc-oam/appc-oam-features/src/main/resources/features.xml b/appc-oam/appc-oam-features/src/main/resources/features.xml new file mode 100644 index 000000000..cec3bf5fe --- /dev/null +++ b/appc-oam/appc-oam-features/src/main/resources/features.xml @@ -0,0 +1,37 @@ +<?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-${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"> + + <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository> + + <feature name='appc-oam' description="appc oam module" version='${project.version}'> + <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> + <bundle>mvn:org.openecomp.appc/appc-oam-model/${project.version}</bundle> + <bundle>mvn:org.openecomp.appc/appc-oam-bundle/${project.version}</bundle> + <configfile finalname="etc/opendaylight/karaf/201-appc-oam.xml">mvn:org.openecomp.appc/appc-oam-bundle/${project.version}/xml/config</configfile> + </feature> + +</features> diff --git a/appc-oam/appc-oam-installer/.gitignore b/appc-oam/appc-oam-installer/.gitignore new file mode 100644 index 000000000..731eb433c --- /dev/null +++ b/appc-oam/appc-oam-installer/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.settings/ diff --git a/appc-oam/appc-oam-installer/pom.xml b/appc-oam/appc-oam-installer/pom.xml new file mode 100644 index 000000000..02c6ee8a7 --- /dev/null +++ b/appc-oam/appc-oam-installer/pom.xml @@ -0,0 +1,143 @@ +<?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-oam</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + + <artifactId>appc-oam-installer</artifactId> + <name>APPC OAM - Karaf Installer</name> + <packaging>pom</packaging> + + <properties> + <application.name>appc-oam</application.name> + <features.boot>appc-oam</features.boot> + <features.repositories>mvn:org.openecomp.appc/appc-oam-features/${project.version}/xml/features</features.repositories> + <include.transitive.dependencies>false</include.transitive.dependencies> + </properties> + + <dependencies> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-features</artifactId> + <version>${project.version}</version> + <classifier>features</classifier> + <type>xml</type> + <exclusions> + <exclusion> + <groupId>*</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-bundle</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-oam-bundle</artifactId> + <version>${project.version}</version> + <classifier>config</classifier> + <type>xml</type> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>maven-repo-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>false</attach> + <finalName>stage/${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + <execution> + <id>installer-zip</id> + <goals> + <goal>single</goal> + </goals> + <phase>package</phase> + <configuration> + <appendAssemblyId>false</appendAssemblyId> + <attach>true</attach> + <finalName>${application.name}-${project.version}</finalName> + <descriptors> + <descriptor>src/assembly/assemble_installer_zip.xml</descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <transitive>false</transitive> + <outputDirectory>${project.build.directory}/assembly/system</outputDirectory> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <useRepositoryLayout>true</useRepositoryLayout> + <addParentPoms>false</addParentPoms> + <copyPom>false</copyPom> + <excludeGroupIds>org.opendaylight</excludeGroupIds> + <scope>provided</scope> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <executions> + <execution> + <id>copy-version</id> + <goals> + <goal>copy-resources</goal> + </goals> + <!-- here the phase you need --> + <phase>validate</phase> + <configuration> + <outputDirectory>${basedir}/target/stage</outputDirectory> + <resources> + <resource> + <directory>src/main/resources/scripts</directory> + <includes> + <include>install-feature.sh</include> + </includes> + <filtering>true</filtering> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project> diff --git a/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml b/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml new file mode 100644 index 000000000..8948a3302 --- /dev/null +++ b/appc-oam/appc-oam-installer/src/assembly/assemble_installer_zip.xml @@ -0,0 +1,59 @@ +<!-- + ============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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>755</fileMode> + <includes> + <include>*.sh</include> + </includes> + </fileSet> + <fileSet> + <directory>target/stage/</directory> + <outputDirectory>${application.name}</outputDirectory> + <fileMode>644</fileMode> + <excludes> + <exclude>*.sh</exclude> + </excludes> + </fileSet> + </fileSets> + + + +</assembly> diff --git a/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml b/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml new file mode 100644 index 000000000..d88eaaace --- /dev/null +++ b/appc-oam/appc-oam-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -0,0 +1,54 @@ +<!-- + ============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========================================================= + --> + +<!-- Defines how we build the .zip file which is our distribution. --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> + <id>controller</id> + <formats> + <format>zip</format> + </formats> + + <!-- we want "system" and related files right at the root level + as this file is suppose to be unzip on top of a karaf + distro. --> + <includeBaseDirectory>false</includeBaseDirectory> + + <fileSets> + <fileSet> + <directory>target/assembly/</directory> + <outputDirectory>.</outputDirectory> + <excludes> + </excludes> + </fileSet> + </fileSets> + + <files> + <file> + <source>../${feature-name}-bundle/src/main/resources/initial/${feature-name}.xml</source> + <destName>./etc/opendaylight/karaf/201-${feature-name}.xml</destName> + </file> + </files> + +</assembly> diff --git a/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh b/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh new file mode 100644 index 000000000..1d769fada --- /dev/null +++ b/appc-oam/appc-oam-installer/src/main/resources/scripts/install-feature.sh @@ -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========================================================= +### + +#!/bin/bash + +ODL_HOME=${ODL_HOME:-/opt/opendaylight/current} +ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client} +ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-"-u karaf"} +INSTALLERDIR=$(dirname $0) + +REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip + +if [ -f ${REPOZIP} ] +then + unzip -n -d ${ODL_HOME} ${REPOZIP} +else + echo "ERROR : repo zip ($REPOZIP) not found" + exit 1 +fi + +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} +${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:install ${features.boot} diff --git a/appc-oam/appc-oam-model/pom.xml b/appc-oam/appc-oam-model/pom.xml new file mode 100644 index 000000000..e44d9a023 --- /dev/null +++ b/appc-oam/appc-oam-model/pom.xml @@ -0,0 +1,98 @@ +<?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-oam</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-oam-model</artifactId> + <packaging>bundle</packaging> + + <build> + + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Import-Package>*</Import-Package> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.sal.api.gen.plugin.version}</version> + <type>jar</type> + </dependency> + </dependencies> + <executions> + <execution> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir> + <codeGenerators> + <generator> + <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.5.2</version> + <executions> + <execution> + <id>yang</id> + <phase>initialize</phase> + <goals> + <goal>install-file</goal> + </goals> + <configuration> + <file>${project.basedir}/src/main/yang/appc-oam.yang</file> + <groupId>${project.groupId}</groupId> + <artifactId>${project.artifactId}</artifactId> + <version>${project.version}</version> + <packaging>yang</packaging> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + + </build> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>yang-binding</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-common</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + </dependency> + </dependencies> +</project> diff --git a/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang b/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang new file mode 100644 index 000000000..4611a3242 --- /dev/null +++ b/appc-oam/appc-oam-model/src/main/yang/appc-oam.yang @@ -0,0 +1,137 @@ +/* + * Yang model for the OAM component of Application Controller (APP-C) component of ONAP + * + * This model is used to define the data and services of the OAM component of APP-C. + * + * The services exposed by this component are: + * + * get-metrics: + * Used to retrieve current metric data from APP-C. + * + */ + +module appc-oam { + + yang-version 1; + namespace "org:openecomp:appc:oam"; + prefix appc-oam; + organization "Copyright 2017 AT&T Intellectual Property."; + + description + "Defines the services and request/response requirements for the + APP-C OAM component."; + + /* + * Note, the revision changes the package name of the generated java code. Do not + * change the revision unless you also update all references to the bindings. + */ + revision "2017-03-03" { + description + "APP-C OAM interface version 1.5.00"; + } + + grouping common-header { + description "A common header for all APP-C requests"; + container common-header { + description "A common header for all APP-C requests"; + + leaf originator-id { + description "originator-id an identifier of the calling system which can be + used addressing purposes, i.e. returning asynchronous response + to the proper destination over UEB (especially in case of multiple + consumers of APP-C APIs)"; + type string; + mandatory true; + } + + leaf request-id { + description "UUID for the request ID. An OSS/BSS identifier for the request + that caused the current action. Multiple API calls may be made + with the same request-id The request-id shall be recorded throughout + the operations on a single request"; + type string; + mandatory true; + } + + } + } + + grouping status { + description "The specific response codes are to be aligned with ASDC reference + doc (main table removed to avoid duplication and digression from + main table). See ASDC and ECOMP Distribution Consumer Interface + Agreement"; + container status { + description "The specific response codes are to be aligned with ASDC reference + doc (main table removed to avoid duplication and digression from + main table). See ASDC and ECOMP Distribution Consumer Interface + Agreement"; + leaf code { + description "Response code"; + type uint16; + mandatory true; + } + leaf message { + description "Response message"; + type string; + mandatory true; + } + } + } + + rpc get-metrics { + description "An operation to get list of registered Metrics in APP-C"; + output { + list metrics { + key kpi-name; + description "KPI metrics definition"; + leaf kpi-name { + description "metrics name"; + type string; + mandatory true; + } + leaf last-reset-time { + description "Last reset time"; + type string; + mandatory true; + } + list kpi-values { + key name; + description "KPI properties in form of key value pairs"; + leaf name { + description "KPI property name"; + type string; + } + leaf value { + description "KPI property value"; + type string; + } + } + } + } + } + + rpc stop { + description "An operation that disables appc-provider-lcm so that it no longer accepts LCM request. This + operation has no impact on queued and currently executing LCM request. A notification will be + sent out indicating the APP-C is idle once all LCM request have completed execution. "; + input { + uses common-header; + } + output { + uses common-header; + uses status; + } + } + + rpc start { + description "An operation that enables appc-provider-lcm so that it can begin to accepts LCM request. "; + input { + uses common-header; + } + output { + uses common-header; + uses status; + } + } +} diff --git a/appc-oam/pom.xml b/appc-oam/pom.xml new file mode 100644 index 000000000..7378d2357 --- /dev/null +++ b/appc-oam/pom.xml @@ -0,0 +1,26 @@ +<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</artifactId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-oam</artifactId> + <packaging>pom</packaging> + <name>APPC OAM</name> + <description>The app-c OAM api bundle</description> + <properties> + <feature-name>appc-oam</feature-name> + </properties> + + <!-- ================================================================================== --> + <!-- The modules we build --> + <!-- ================================================================================== --> + <modules> + <module>appc-oam-model</module> + <module>appc-oam-features</module> + <module>appc-oam-installer</module> + <module>appc-oam-bundle</module> + </modules> + +</project> diff --git a/appc-provider/appc-provider-bundle/pom.xml b/appc-provider/appc-provider-bundle/pom.xml index 2606a7f60..dc468d8fd 100644 --- a/appc-provider/appc-provider-bundle/pom.xml +++ b/appc-provider/appc-provider-bundle/pom.xml @@ -1,215 +1,226 @@ <?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-provider</artifactId> - <groupId>org.openecomp.appc</groupId> - <version>1.1.0-SNAPSHOT</version> - </parent> - <artifactId>appc-provider-bundle</artifactId> - <packaging>bundle</packaging> - <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Export-Package>org.opendaylight.controller.config.yang.config.sample_provider.impl</Export-Package> - <Export-Package>org.openecomp.appc.provider</Export-Package> - <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*;resolution:=optional</Import-Package> - <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false,domain-model-lib,appc-command-executor-api,appc-request-handler-api</Embed-Dependency> - <Embed-Transitive>true</Embed-Transitive> - </instructions> - </configuration> - </plugin> - <plugin> - <groupId>org.opendaylight.yangtools</groupId> - <artifactId>yang-maven-plugin</artifactId> - <version>${odl.yangtools.version}</version> - <executions> - <execution> - <id>config</id> - <goals> - <goal>generate-sources</goal> - </goals> - <configuration> - <codeGenerators> - <generator> - <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass> - <outputBaseDir>${jmxGeneratorPath}</outputBaseDir> - <additionalConfiguration> - <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1> - </additionalConfiguration> - </generator> - <generator> - <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> - <outputBaseDir>${salGeneratorPath}</outputBaseDir> - </generator> - </codeGenerators> - <inspectDependencies>true</inspectDependencies> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>org.opendaylight.mdsal</groupId> - <artifactId>maven-sal-api-gen-plugin</artifactId> - <version>${odl.sal.api.gen.plugin.version}</version> - <type>jar</type> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>yang-jmx-generator-plugin</artifactId> - <version>${odl.yang.jmx.generator.version}</version> - </dependency> - </dependencies> - </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/initial/appc-provider.xml</file> - <type>xml</type> - <classifier>config</classifier> - </artifact> - </artifacts> - </configuration> - </execution> - </executions> - </plugin> - </plugins> - <pluginManagement> - <plugins> - <!--This plugin's configuration is used to store Eclipse m2e settings - only. It has no influence on the Maven build itself. --> - <plugin> - <groupId>org.eclipse.m2e</groupId> - <artifactId>lifecycle-mapping</artifactId> - <version>1.0.0</version> - <configuration> - <lifecycleMappingMetadata> - <pluginExecutions> - <pluginExecution> - <pluginExecutionFilter> - <groupId>org.codehaus.mojo</groupId> - <artifactId>build-helper-maven-plugin</artifactId> - <versionRange>[1.9.1,)</versionRange> - <goals> - <goal>add-source</goal> - </goals> - </pluginExecutionFilter> - <action> - <ignore /> - </action> - </pluginExecution> - </pluginExecutions> - </lifecycleMappingMetadata> - </configuration> - </plugin> - </plugins> - </pluginManagement> - </build> - <dependencies> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-request-handler-api</artifactId> - <version>1.1.0-SNAPSHOT</version> - <type>bundle</type> - <scope>provided</scope> - <exclusions> - <exclusion> - <groupId>org.openecomp.appc</groupId> - <artifactId>domain-model-lib</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-common</artifactId> - <version>${project.version}</version> - <classifier>jar-with-dependencies</classifier> - </dependency> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>appc-provider-model</artifactId> - <version>${project.version}</version> - </dependency> - - <!-- ADDED THIS ARTIFACT TO BE ABLE TO FIND org.openecomp.appc.domainmodel.lcm --> - <dependency> - <groupId>org.openecomp.appc</groupId> - <artifactId>domain-model-lib</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>config-api</artifactId> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>sal-binding-config</artifactId> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>sal-binding-api</artifactId> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>sal-common-util</artifactId> - </dependency> - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-common</artifactId> - </dependency> - <dependency> - <groupId>org.openecomp.sdnc.core</groupId> - <artifactId>sli-provider</artifactId> - </dependency> - <dependency> - <artifactId>sal-test-model</artifactId> - <groupId>org.opendaylight.controller</groupId> - <scope>test</scope> - </dependency> - <dependency> - <artifactId>sal-rest-connector</artifactId> - <groupId>org.opendaylight.netconf</groupId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>sal-binding-broker-impl</artifactId> - <scope>test</scope> - </dependency> - <dependency> - <groupId>org.opendaylight.controller</groupId> - <artifactId>sal-binding-broker-impl</artifactId> - <classifier>tests</classifier> - <version>${odl.mdsal.version}</version> - <type>test-jar</type> - <scope>test</scope> - </dependency> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - <!-- TEMP CODE --> - <dependency> - <groupId>org.json</groupId> - <artifactId>json</artifactId> - </dependency> - </dependencies> + 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-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-provider-bundle</artifactId> + <packaging>bundle</packaging> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>org.opendaylight.controller.config.yang.config.sample_provider.impl</Export-Package> + <Export-Package>org.openecomp.appc.provider</Export-Package> + <!-- <Import-Package>!groovy.lang,!javax.jms,!org.codehaus.commons.compiler,!org.codehaus.groovy.*,!org.codehaus.janino,!com.ibm.icu.*,!com.sun.faces.*,!org.apache.log,*;resolution:=optional</Import-Package> --> + <!-- <Embed-Dependency>appc-common,eelf-core,logback-core,logback-classic;scope=compile|runtime;inline=false,domain-model-lib,appc-command-executor-api,appc-request-handler-api</Embed-Dependency> --> + <Import-Package> + org.openecomp.appc.i18n, + org.openecomp.appc.logging, + org.openecomp.appc.util, + com.att.eelf.configuration, + com.att.eelf.i18n, + *;resolution:=optional + </Import-Package> + <Embed-Dependency> + appc-common;scope=compile|runtime;inline=false + </Embed-Dependency> + <Embed-Transitive>true</Embed-Transitive> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <executions> + <execution> + <id>config</id> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <codeGenerators> + <generator> + <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass> + <outputBaseDir>${jmxGeneratorPath}</outputBaseDir> + <additionalConfiguration> + <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1> + </additionalConfiguration> + </generator> + <generator> + <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.sal.api.gen.plugin.version}</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>yang-jmx-generator-plugin</artifactId> + <version>${odl.yang.jmx.generator.version}</version> + </dependency> + </dependencies> + </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/initial/appc-provider.xml</file> + <type>xml</type> + <classifier>config</classifier> + </artifact> + </artifacts> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + <pluginManagement> + <plugins> + <!--This plugin's configuration is used to store Eclipse + m2e settings only. It has no influence on the Maven build itself. --> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <versionRange>[1.9.1,)</versionRange> + <goals> + <goal>add-source</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore /> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> + </build> + <dependencies> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-request-handler-api</artifactId> + <version>${project.version}</version> + <type>bundle</type> + <scope>provided</scope> +<!-- <exclusions> --> +<!-- <exclusion> --> +<!-- <groupId>org.openecomp.appc</groupId> --> +<!-- <artifactId>domain-model-lib</artifactId> --> +<!-- </exclusion> --> +<!-- </exclusions> --> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-common</artifactId> + <version>${project.version}</version> +<!-- <classifier>jar-with-dependencies</classifier> --> + </dependency> + <dependency> + <groupId>org.openecomp.appc</groupId> + <artifactId>appc-provider-model</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- ADDED THIS ARTIFACT TO BE ABLE TO FIND org.openecomp.appc.domainmodel.lcm --> +<!-- <dependency> --> +<!-- <groupId>org.openecomp.appc</groupId> --> +<!-- <artifactId>domain-model-lib</artifactId> --> +<!-- <version>${project.version}</version> --> +<!-- </dependency> --> + + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>config-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-config</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-api</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-common-util</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-common</artifactId> + </dependency> + <dependency> + <groupId>org.openecomp.sdnc.core</groupId> + <artifactId>sli-provider</artifactId> + </dependency> + <dependency> + <artifactId>sal-test-model</artifactId> + <groupId>org.opendaylight.controller</groupId> + <scope>test</scope> + </dependency> + <dependency> + <artifactId>sal-rest-connector</artifactId> + <groupId>org.opendaylight.netconf</groupId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.opendaylight.controller</groupId> + <artifactId>sal-binding-broker-impl</artifactId> + <classifier>tests</classifier> + <version>${odl.mdsal.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <!-- TEMP CODE --> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + </dependencies> </project> diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java index c65cc656e..1177504d4 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProvider.java @@ -155,10 +155,7 @@ public class AppcProvider implements AutoCloseable, AppcProviderService { rpcRegistry = rpcProviderRegistry; if (rpcRegistry != null) { - logger.info("rpcRegistry was not null"); rpcRegistration = rpcRegistry.addRpcImplementation(AppcProviderService.class, this); - } else { - logger.error("rpcRegistry WAS NULL"); } logger.info(Msg.COMPONENT_INITIALIZED, appName, "provider"); @@ -263,5 +260,19 @@ public Future<RpcResult<ModifyConfigOutput>> modifyConfig(ModifyConfigInput inpu RpcResult<SnapshotOutput> result = topology.snapshot(hdr, vnf); return Futures.immediateFuture(result); } + + + /** + * Checks status of a VM + */ + @Override + public Future<RpcResult<VmstatuscheckOutput>> vmstatuscheck(VmstatuscheckInput input) { + CommonRequestHeader hdr = input.getCommonRequestHeader(); + VnfResource vnf = input.getVnfResource(); + + TopologyService topology = new TopologyService(this); + RpcResult<VmstatuscheckOutput> result = topology.vmstatuscheck(hdr, vnf); + return Futures.immediateFuture(result); + } } diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java index 0224784d6..4dd026127 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderClient.java @@ -30,10 +30,15 @@ import org.openecomp.sdnc.sli.provider.SvcLogicService; 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.util.Properties; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; public class AppcProviderClient { @@ -44,15 +49,20 @@ public class AppcProviderClient { public AppcProviderClient() { BundleContext bctx = FrameworkUtil.getBundle(SvcLogicService.class).getBundleContext(); - - // Get SvcLogicService reference - ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME); - if (sref != null) { - svcLogic = (SvcLogicService) bctx.getService(sref); - - } else { - LOG.warn("Cannot find service reference for " + SvcLogicService.NAME); - + //Handle BundleContext returning null + if (bctx == null){ + LOG.warn("Cannot find bundle context for " + SvcLogicService.NAME); + } + else{ + // Get SvcLogicService reference + ServiceReference sref = bctx.getServiceReference(SvcLogicService.NAME); + if (sref != null) { + svcLogic = (SvcLogicService) bctx.getService(sref); + + } else { + LOG.warn("Cannot find service reference for " + SvcLogicService.NAME); + + } } } @@ -64,10 +74,40 @@ public class AppcProviderClient { public Properties execute(String module, String rpc, String version, String mode, Properties parms) throws SvcLogicException { + /* + * Set End time for Metrics Logger + */ + long startTime = System.currentTimeMillis(); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + df.setTimeZone(tz); + String startTimeStr = df.format(new Date()); + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + String endTimeStr = String.valueOf(endTime); + String durationStr = String.valueOf(duration); + String endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); + MDC.put("TargetEntity", "sli"); + MDC.put("TargetServiceName", "execute"); + MDC.put("ClassName", "org.openecomp.appc.provider.AppcProviderClient"); + LOG.debug("Parameters passed to SLI: " + StringHelper.propertiesToString(parms)); metricsLogger.info("Parameters passed to SLI: " + StringHelper.propertiesToString(parms)); Properties respProps = svcLogic.execute(module, rpc, version, mode, parms); + + /* + * Set End time for Metrics Logger + */ + endTime = System.currentTimeMillis(); + duration = endTime - startTime; + endTimeStr = String.valueOf(endTime); + durationStr = String.valueOf(duration); + endTimeStrUTC = df.format(new Date()); + MDC.put("EndTimestamp", endTimeStrUTC); + MDC.put("ElapsedTime", durationStr); LOG.debug("Parameters returned by SLI: " + StringHelper.propertiesToString(respProps)); metricsLogger.info("Parameters returned by SLI: " + StringHelper.propertiesToString(respProps)); diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java index 6d186ab5f..a340aa046 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/AppcProviderLcm.java @@ -30,64 +30,10 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AuditOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.CheckLockOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.EvacuateOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.HealthCheckOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LiveUpgradeOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.LockOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.MigrateOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.ModifyConfigOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RebuildOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RestartOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.RollbackOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SnapshotOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SoftwareUploadOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.StopOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.SyncOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TerminateOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.TestOutputBuilder; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockInput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutput; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.UnlockOutputBuilder; -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.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.*; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.status.StatusBuilder; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.openecomp.appc.Constants; @@ -153,13 +99,13 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { * @param rpcProviderRegistry */ @SuppressWarnings({ - "javadoc", "nls" + "javadoc", "nls" }) public AppcProviderLcm(DataBroker dataBroker, NotificationProviderService notificationProviderService, RpcProviderRegistry rpcProviderRegistry) { String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME); - logger.info(Msg.COMPONENT_INITIALIZING, appName, "provider"); + logger.info(Msg.COMPONENT_INITIALIZING, appName, "provider-lcm"); executor = Executors.newFixedThreadPool(1); this.dataBroker = dataBroker; @@ -242,7 +188,14 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); if(null == status) { try { - RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + RequestHandlerInput request = new RequestInputBuilder().requestContext() + .commonHeader(input.getCommonHeader()) + .actionIdentifiers(input.getActionIdentifiers()) + .payload(input.getPayload()) + .action(action) + .rpcName(rpcName) + .build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); } catch (ParseException e) { @@ -405,7 +358,7 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); if(null == status) { try { - RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); status = buildStatusWithDispatcherOutput(executeRequest(request)); logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); } catch (ParseException e) { @@ -447,7 +400,7 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { private RequestHandlerOutput executeRequest(RequestHandlerInput request){ RequestHandler handler = getRequestHandler(); - RequestHandlerOutput requestHandlerOutput=null; + RequestHandlerOutput requestHandlerOutput; try { requestHandlerOutput = handler.handleRequest(request); } catch (Exception e) { @@ -521,14 +474,96 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { return Futures.immediateFuture(result); } + @Override + public Future<RpcResult<ConfigureOutput>> configure(ConfigureInput input) { + logger.debug("Input received : " + input.toString()); + ConfigureOutputBuilder outputBuilder = new ConfigureOutputBuilder(); + String action = Action.Configure.toString() ; + String rpcName = "configure"; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigureOutput> result = RpcResultBuilder.<ConfigureOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<ConfigModifyOutput>> configModify(ConfigModifyInput input) { + logger.debug("Input received : " + input.toString()); + ConfigModifyOutputBuilder outputBuilder = new ConfigModifyOutputBuilder(); + String action = Action.ConfigModify.toString() ; + String rpcName = "config-modify"; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigModifyOutput> result = RpcResultBuilder.<ConfigModifyOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override + public Future<RpcResult<ConfigScaleoutOutput>> configScaleout(ConfigScaleoutInput input) { + logger.debug("Input received : " + input.toString()); + ConfigScaleoutOutputBuilder outputBuilder = new ConfigScaleoutOutputBuilder(); + String action = Action.ConfigScaleOut.toString() ; + String rpcName = "config-scaleout"; + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigScaleoutOutput> result = RpcResultBuilder.<ConfigScaleoutOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } @Override - public Future<RpcResult<ModifyConfigOutput>> modifyConfig(ModifyConfigInput input) { + public Future<RpcResult<ConfigRestoreOutput>> configRestore(ConfigRestoreInput input) { logger.debug("Input received : " + input.toString()); - ModifyConfigOutputBuilder outputBuilder = new ModifyConfigOutputBuilder(); - String action = Action.ModifyConfig.toString() ; - String rpcName = "modify-config"; + ConfigRestoreOutputBuilder outputBuilder = new ConfigRestoreOutputBuilder(); + String action = Action.ConfigRestore.toString() ; + String rpcName = "config-restore"; Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); if(null == status) { try { @@ -547,7 +582,7 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { } outputBuilder.setCommonHeader(input.getCommonHeader()); outputBuilder.setStatus(status); - RpcResult<ModifyConfigOutput> result = RpcResultBuilder.<ModifyConfigOutput> status(true).withResult(outputBuilder.build()).build(); + RpcResult<ConfigRestoreOutput> result = RpcResultBuilder.<ConfigRestoreOutput> status(true).withResult(outputBuilder.build()).build(); return Futures.immediateFuture(result); } @@ -608,6 +643,46 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { return Futures.immediateFuture(result); } + /** + * Starts a specific VNF + * + * @see org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.AppcProviderLcmService#start(StartInput) + */ + @Override + public Future<RpcResult<StartOutput>> start(StartInput input) { + logger.debug("Input received : " + input.toString()); + + StartOutputBuilder outputBuilder = new StartOutputBuilder(); + String action = Action.Start.toString() ; + String rpcName = Action.Start.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext() + .commonHeader(input.getCommonHeader()) + .actionIdentifiers(input.getActionIdentifiers()) + .payload(input.getPayload()) + .action(action) + .rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<StartOutput> result = RpcResultBuilder.<StartOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + @Override public Future<RpcResult<AuditOutput>> audit(AuditInput input) { logger.debug("Input received : " + input.toString()); @@ -617,7 +692,7 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); if(null == status) { try { - RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).payload(input.getPayload()).action(action).rpcName(rpcName).build(); status = buildStatusWithDispatcherOutput(executeRequest(request)); logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); } catch (ParseException e) { @@ -813,6 +888,92 @@ public class AppcProviderLcm implements AutoCloseable, AppcProviderLcmService { return Futures.immediateFuture(result); } + @Override + public Future<RpcResult<ConfigBackupOutput>> configBackup(ConfigBackupInput input) { + logger.debug("Input received : " + input.toString()); + ConfigBackupOutputBuilder outputBuilder = new ConfigBackupOutputBuilder(); + String action = Action.ConfigBackup.toString() ; + String rpcName = Action.ConfigBackup.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigBackupOutput> result = RpcResultBuilder.<ConfigBackupOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + @Override + public Future<RpcResult<ConfigBackupDeleteOutput>> configBackupDelete(ConfigBackupDeleteInput input) { + logger.debug("Input received : " + input.toString()); + ConfigBackupDeleteOutputBuilder outputBuilder = new ConfigBackupDeleteOutputBuilder(); + String action = Action.ConfigBackupDelete.toString() ; + String rpcName = Action.ConfigBackupDelete.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigBackupDeleteOutput> result = RpcResultBuilder.<ConfigBackupDeleteOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + + + @Override + public Future<RpcResult<ConfigExportOutput>> configExport(ConfigExportInput input) { + logger.debug("Input received : " + input.toString()); + ConfigExportOutputBuilder outputBuilder = new ConfigExportOutputBuilder(); + String action = Action.ConfigExport.toString() ; + String rpcName = Action.ConfigExport.name().toLowerCase(); + Status status = ValidationService.getInstance().validateInput(input.getCommonHeader(), input.getAction(), action); + if(null == status) { + try { + RequestHandlerInput request = new RequestInputBuilder().requestContext().commonHeader(input.getCommonHeader()).actionIdentifiers(input.getActionIdentifiers()).action(action).rpcName(rpcName).build(); + status = buildStatusWithDispatcherOutput(executeRequest(request)); + logger.info(String.format("Execute of '%s' finished with status %s. Reason: %s", input.getActionIdentifiers(), status.getCode(), status.getMessage())); + } catch (ParseException e) { + status = buildParsingErrorStatus(e); + + LoggingUtils.logErrorMessage( + LoggingConstants.TargetNames.APPC_PROVIDER, + String.format(COMMON_ERROR_MESSAGE_TEMPLATE, action, e.getMessage()), + this.getClass().getName()); + + } + } + outputBuilder.setCommonHeader(input.getCommonHeader()); + outputBuilder.setStatus(status); + RpcResult<ConfigExportOutput> result = RpcResultBuilder.<ConfigExportOutput> status(true).withResult(outputBuilder.build()).build(); + return Futures.immediateFuture(result); + } + private String convertActionNameToUrl(String action) { String regex = "([a-z])([A-Z]+)"; String replacement = "$1-$2"; diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java index 248492df8..0a535f28a 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/RequestInputBuilder.java @@ -23,11 +23,12 @@ package org.openecomp.appc.provider.lcm.util; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.TimeZone; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Payload; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.action.identifiers.ActionIdentifiers; -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.common.header.Flags; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.Payload; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.action.identifiers.ActionIdentifiers; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.common.header.Flags; import org.openecomp.appc.domainmodel.lcm.Flags.Mode; import org.openecomp.appc.domainmodel.lcm.RequestContext; import org.openecomp.appc.domainmodel.lcm.VNFOperation; @@ -92,6 +93,7 @@ public class RequestInputBuilder { if(null != commonHeader.getTimestamp()) { SimpleDateFormat format = new SimpleDateFormat(FORMAT); format.setLenient(false); + format.setTimeZone(TimeZone.getTimeZone("UTC")); header.setTimestamp(format.parse(commonHeader.getTimestamp().getValue()).toInstant()); }else{ throw new ParseException("Missing mandatory parameter : timestamp " , 0); diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java index fe2fdc142..a16ab0bed 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/lcm/util/ValidationService.java @@ -21,10 +21,10 @@ package org.openecomp.appc.provider.lcm.util; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.Action; -import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160108.common.header.CommonHeader; -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.yang.gen.v1.org.openecomp.appc.lcm.rev160108.Action; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.common.header.CommonHeader; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.status.Status; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.lcm.rev160108.status.StatusBuilder; import org.openecomp.appc.Constants; import org.openecomp.appc.configuration.Configuration; import org.openecomp.appc.configuration.ConfigurationFactory; diff --git a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java index ea88982c1..166fb9612 100644 --- a/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java +++ b/appc-provider/appc-provider-bundle/src/main/java/org/openecomp/appc/provider/topology/TopologyService.java @@ -51,6 +51,8 @@ import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.UUID; import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.common.request.header.CommonRequestHeader; import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.vnf.resource.VnfResource; import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.config.payload.ConfigPayload; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.VmstatuscheckOutput; +import org.opendaylight.yang.gen.v1.org.openecomp.appc.rev160104.VmstatuscheckOutputBuilder; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.openecomp.appc.Constants; @@ -616,6 +618,83 @@ public class TopologyService { RpcResultBuilder.<SnapshotOutput> status(true).withResult(sob.build()).build(); return rpcResult; } + +/**************************************************/ + + public RpcResult<VmstatuscheckOutput> vmstatuscheck(CommonRequestHeader hdr, VnfResource vnf) { + long startTime = System.currentTimeMillis(); + String requestId = hdr.getServiceRequestId(); + + MDC.clear(); + MDC.put(MDC_REMOTE_HOST, ""); + MDC.put(MDC_KEY_REQUEST_ID, requestId); + MDC.put(MDC_SERVICE_NAME, "App-C Provider:vmstatuscheck"); + MDC.put(MDC_SERVICE_INSTANCE_ID, ""); + try { + MDC.put(MDC_SERVER_FQDN, InetAddress.getLocalHost().getHostName()); + MDC.put(MDC_SERVER_IP_ADDRESS, InetAddress.getLocalHost().getHostAddress()); + } catch (Exception e) { + e.printStackTrace(); + } + MDC.put(MDC_INSTANCE_UUID, java.util.UUID.randomUUID().toString()); + MDC.put(MDC_ALERT_SEVERITY, "0"); + logger.info(String.format("Starting VMSTATUSCHECK for request with id [%s]", requestId)); + + performanceLogger.info(String.format("Performance Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime, requestId)); + auditLogger.info(String.format("Audit Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime, requestId)); + metricsLogger.info(String.format("Metrics Logger: App-C vmstatuscheck initiated. Start Time: [%s]. Request ID: [%s]", startTime, requestId)); + + /* + * Copy any needed inputs or other values into the properties to be passed to the DG model + */ + UUID vmId = vnf.getVmId(); + Properties properties = new Properties(); + properties.put(Constants.CONTEXT_ACTION, "vmstatuschecking"); + properties.put(Constants.CONTEXT_REQID, requestId); + properties.put(Constants.CONTEXT_VMID, vmId.getValue()); + properties.put(Constants.STATUS_GETTER, "checking"); + + + + + UUID identityUrl = vnf.getIdentityUrl(); + if (identityUrl != null) { + properties.put(Constants.CONTEXT_IDENTITY_URL, identityUrl.getValue()); + } + /* + * Attempt to call the DG with the appropriate properties + */ + boolean success = callGraph(properties); + + /* + * Generate the appropriate response + */ + String statusStr = success ? "SUCCESS" : "FAILURE"; + String infomsg = + String.format("VMSTATUSCHECK '%s' finished with status %s. Reason: %s", requestId, statusStr, reason); + logger.info(infomsg); + long endTime = System.currentTimeMillis(); + auditLogger.info(String.format("Audit Logger: VMSTATUSCHECK '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Request ID: [%s]. Reason:%s", requestId, statusStr, startTime, endTime, requestId, reason)); + metricsLogger.info(String.format("Metrics Logger: VMSTATUSCHECK '%s' finished with status %s. Start Time: [%s]. End Time: [%s]. Request ID: [%s]. Reason:%s", requestId, statusStr, startTime, endTime, requestId, reason)); + //logger.info(String.format("Step1 [%s]", Constants.STATUS_GETTER)); + String tempstring2 = properties.getProperty(Constants.STATUS_GETTER).trim(); + //logger.info(String.format("Step2 [%s]", tempstring2)); + + + VmstatuscheckOutputBuilder vob = new VmstatuscheckOutputBuilder(); + long duration = System.currentTimeMillis() - startTime; + vob.setCommonResponseHeader(ResponseHeaderBuilder.buildHeader(success, requestId, reason, duration)); + vob.setStatMsg(tempstring2); + + // Status must be set to true to indicate that our return is expected + RpcResult<VmstatuscheckOutput> rpcResult = + RpcResultBuilder.<VmstatuscheckOutput> status(true).withResult(vob.build()).build(); + return rpcResult; + } + + /*************************************************/ + + private boolean callGraph(Properties props) { String moduleName = configuration.getProperty(Constants.PROPERTY_MODULE_NAME); diff --git a/appc-provider/appc-provider-features/src/main/resources/features.xml b/appc-provider/appc-provider-features/src/main/resources/features.xml index f67333648..c9a1bf424 100644 --- a/appc-provider/appc-provider-features/src/main/resources/features.xml +++ b/appc-provider/appc-provider-features/src/main/resources/features.xml @@ -25,13 +25,9 @@ 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"> -<!-- <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.version}/xml/features</repository> --> <repository>mvn:org.opendaylight.mdsal/features-mdsal/${odl.mdsal.features.version}/xml/features</repository> <feature name='appc-provider' description="application controller" version='${project.version}'> - <!--<feature version="${project.version}">appc-aai-adapter</feature>--> - <!-- Most applications will have a dependency on the ODL MD-SAL Broker --> - <!-- <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> --> <feature version="${broker-mdsal.version}">odl-mdsal-broker</feature> <bundle>mvn:org.openecomp.appc/appc-provider-model/${project.version}</bundle> <bundle>mvn:org.openecomp.appc/appc-provider-bundle/${project.version}</bundle> diff --git a/appc-provider/appc-provider-model/pom.xml b/appc-provider/appc-provider-model/pom.xml index 492c30517..23685725e 100644 --- a/appc-provider/appc-provider-model/pom.xml +++ b/appc-provider/appc-provider-model/pom.xml @@ -1,88 +1,118 @@ <?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-provider</artifactId> - <groupId>org.openecomp.appc</groupId> - <version>1.1.0-SNAPSHOT</version> - </parent> - <artifactId>appc-provider-model</artifactId> - <packaging>bundle</packaging> + 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-provider</artifactId> + <groupId>org.openecomp.appc</groupId> + <version>1.1.0-SNAPSHOT</version> + </parent> + <artifactId>appc-provider-model</artifactId> + <packaging>bundle</packaging> - <build> + <build> - <plugins> - <plugin> - <groupId>org.apache.felix</groupId> - <artifactId>maven-bundle-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <instructions> - <Import-Package>*</Import-Package> - </instructions> - </configuration> - </plugin> - <plugin> - <groupId>org.opendaylight.yangtools</groupId> - <artifactId>yang-maven-plugin</artifactId> - <version>${odl.yangtools.version}</version> - <dependencies> - <dependency> - <groupId>org.opendaylight.mdsal</groupId> - <artifactId>maven-sal-api-gen-plugin</artifactId> - <version>${odl.sal.api.gen.plugin.version}</version> - <type>jar</type> - </dependency> - </dependencies> - <executions> - <execution> - <goals> - <goal>generate-sources</goal> - </goals> - <configuration> - <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir> - <codeGenerators> - <generator> - <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> - <outputBaseDir>${salGeneratorPath}</outputBaseDir> - </generator> - </codeGenerators> - <inspectDependencies>true</inspectDependencies> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>build-helper-maven-plugin</artifactId> - <version>1.12</version> - <executions> - <execution> - <id>add-generated-source</id> - <phase>generate-sources</phase> - <goals> - <goal>add-source</goal> - </goals> - <configuration> - <sources> - <!-- project.build.directory defaults to be the "target" folder --> - <source>${project.build.directory}/generated-sources/yang-gen-sal</source> - </sources> - </configuration> - </execution> - </executions> - </plugin> - </plugins> - </build> - <dependencies> - <dependency> - <groupId>org.opendaylight.mdsal</groupId> - <artifactId>yang-binding</artifactId> - </dependency> - <dependency> - <groupId>org.opendaylight.yangtools</groupId> - <artifactId>yang-common</artifactId> - </dependency> - </dependencies> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Import-Package>*</Import-Package> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-maven-plugin</artifactId> + <version>${odl.yangtools.version}</version> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>maven-sal-api-gen-plugin</artifactId> + <version>${odl.sal.api.gen.plugin.version}</version> + <type>jar</type> + </dependency> + </dependencies> + <executions> + <execution> + <goals> + <goal>generate-sources</goal> + </goals> + <configuration> + <yangFilesRootDir>${yang.file.directory}</yangFilesRootDir> + <codeGenerators> + <generator> + <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass> + <outputBaseDir>${salGeneratorPath}</outputBaseDir> + </generator> + </codeGenerators> + <inspectDependencies>true</inspectDependencies> + </configuration> + </execution> + </executions> + </plugin> + <!-- <plugin> --> + <!-- <groupId>org.codehaus.mojo</groupId> --> + <!-- <artifactId>build-helper-maven-plugin</artifactId> --> + <!-- <version>1.12</version> --> + <!-- <executions> --> + <!-- <execution> --> + <!-- <id>add-generated-source</id> --> + <!-- <phase>generate-sources</phase> --> + <!-- <goals> --> + <!-- <goal>add-source</goal> --> + <!-- </goals> --> + <!-- <configuration> --> + <!-- <sources> --> + <!-- project.build.directory defaults to be the "target" folder --> + <!-- <source>${project.build.directory}/generated-sources/yang-gen-sal</source> --> + <!-- </sources> --> + <!-- </configuration> --> + <!-- </execution> --> + <!-- </executions> --> + <!-- </plugin> --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.5.2</version> + <executions> + <execution> + <id>yang</id> + <phase>initialize</phase> + <goals> + <goal>install-file</goal> + </goals> + <configuration> + <file>${project.basedir}/src/main/yang/appc-provider-lcm.yang</file> + <groupId>${project.groupId}</groupId> + <artifactId>${project.artifactId}</artifactId> + <version>${project.version}</version> + <packaging>yang</packaging> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + + </build> + <dependencies> + <dependency> + <groupId>org.opendaylight.mdsal</groupId> + <artifactId>yang-binding</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.yangtools</groupId> + <artifactId>yang-common</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + </dependency> + </dependencies> </project> diff --git a/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang b/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang index 6f2d0b480..422b3197b 100644 --- a/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang +++ b/appc-provider/appc-provider-model/src/main/yang/appc-provider-lcm.yang @@ -19,7 +19,7 @@ module appc-provider-lcm { yang-version 1; - namespace "org:openecomp:appc"; + namespace "org:openecomp:appc:lcm"; prefix appc-provider-lcm; organization "Copyright 2017 AT&T Intellectual Property."; @@ -43,47 +43,11 @@ module appc-provider-lcm { * APP-C controller functions. **********************************************************************************/ - /* - * Define a common definition of a UUID - */ - typedef UUID { - type string { - length "1..255"; - } - description "Universally Unique ID"; - } - - /* - * Define the name of the provider region/LCP to connect to - */ - typedef LCP { - type string { - length "1..255"; - } - description "The local control plane name (OpenStack region name) of the provider"; - } - - /* - * Define a common definition of a time stamp (expressed as a formatted string) as follows - * - * yyyy-MM-dd HH:mm:ss.SSSSSSSS - * - * yyyy ...... exactly 4 digit year, e.g., 2015 - * MM ........ 1 or 2 digit month of year, e.g., 7 - * dd ........ 1 or 2 digit day of month, e.g., 29 - * HH ........ 1 or 2 digit hour of day (24-hour clock) in UTC, e.g., 17 - * mm ........ 1 or 2 digit minute of the hour, e.g. 31 - * ss ........ 1 or 2 digit seconds of the minute, e.g., 28 - * SSSSSS .... 1-6 digit microseconds - */ - typedef TIMESTAMP { - type string { - length "16..28"; - pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}"; - } - } + typedef ZULU { + description "Define a common definition of a time stamp (expressed as a formatted + string) as follows yyyy-MM-ddTHH:mm:ss.SSSSSSSSZ"; type string { length "16..28"; pattern "[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,6}Z"; @@ -96,27 +60,34 @@ module appc-provider-lcm { } typedef action { - type enumeration { - enum "Restart"; - enum "Rebuild"; - enum "Migrate"; - enum "Evacuate"; - enum "Snapshot"; - enum "Rollback"; - enum "Sync"; - enum "Audit"; - enum "Stop"; - enum "Terminate"; - enum "SoftwareUpload"; - enum "HealthCheck"; - enum "LiveUpgrade"; - enum "ModifyConfig"; - enum "Lock"; - enum "Unlock"; - enum "Test"; - enum "CheckLock"; - } - description "The action to be taken by APP-C, e.g. Restart, Rebuild, Migrate"; + type enumeration { + enum "Restart"; + enum "Rebuild"; + enum "Migrate"; + enum "Evacuate"; + enum "Snapshot"; + enum "Rollback"; + enum "Sync"; + enum "Audit"; + enum "Stop"; + enum "Start"; + enum "Terminate"; + enum "SoftwareUpload"; + enum "HealthCheck"; + enum "LiveUpgrade"; + enum "Lock"; + enum "Unlock"; + enum "Test"; + enum "CheckLock"; + enum "Configure"; + enum "ConfigModify"; + enum "ConfigScaleOut"; + enum "ConfigRestore"; + enum "ConfigBackup"; + enum "ConfigBackupDelete"; + enum "ConfigExport"; + } + description "The action to be taken by APP-C, e.g. Restart, Rebuild, Migrate"; } /********************************************************************************** @@ -127,27 +98,7 @@ module appc-provider-lcm { * (called the service-request-id) is meaningful to the caller and is included on * all responses from the services. **********************************************************************************/ - grouping common-request-header { - description "A common header for all requests"; - container common-request-header { - leaf service-request-id { - description "An identifier meaningful to the caller to correlate all responses"; - type string; - mandatory true; - } - - leaf time-to-live { - description "The alloted time to perform the operation, in seconds. If the - operation cannot be completed in this amount of time, the operation is - aborted. If set to zero, no timeout exists and the operation will continue - until it completes or fails. If omitted, the default value of 0 is used."; - type uint32 { - range "0..86400"; - } - mandatory false; - } - } - } + /********************************************************************************** * Basic manipulation of a VNF (or VM) will typically include querying the current @@ -157,27 +108,7 @@ module appc-provider-lcm { * information is used across all of these services, so it has been defined as a * common structure here and is referenced in the appropriate RPC definitions. **********************************************************************************/ - grouping vnf-resource { - description "The data that uniquely identifies a virtual network function (or vm)"; - container vnf-resource { - leaf vm-id { - description "The UUID of the resource. For backwards compatibility, this can be - the self-link URL of the VM."; - type UUID; - mandatory true; - } - leaf identity-url { - description "The identity url used to access the resource"; - type UUID; - mandatory false; - } - leaf tenant-id { - description "The id of the provider tenant that owns the resource"; - type string; - mandatory false; - } - } - } + /********************************************************************************** * All responses will include this standard header @@ -185,32 +116,7 @@ module appc-provider-lcm { * The standard response header includes the time of completion as well as a * success|failure indication **********************************************************************************/ - grouping common-response-header { - description "A common header for all responses defining success or failure - and the time stamp when completed"; - container common-response-header { - leaf service-request-id { - description "An identifier meaningful to the caller to correlate all responses"; - type string; - } - leaf success { - description "True indicates the request was successful"; - type boolean; - } - leaf reason { - description "If success=false, the failure reason. Otherwise, undefined."; - type string; - } - leaf completed { - description "The formatted time stamp when the operation was completed."; - type TIMESTAMP; - } - leaf duration { - description "The amount of time used (in seconds) to process the request"; - type uint32; - } - } - } + /********************************************************************************** @@ -219,43 +125,55 @@ module appc-provider-lcm { * The standard common header is used to define a correlation identification for * the request that is returned on all responses. **********************************************************************************/ - grouping common-header { + + + + grouping common-header { + description "A common header for all APP-C requests"; + container common-header { description "A common header for all APP-C requests"; - container common-header { - description "A common header for all APP-C requests"; - leaf timestamp { - description "timestamp is in ISO 8601 timestamp format ZULU offset"; - type ZULU; - mandatory true; - } + leaf timestamp { + description "timestamp is in ISO 8601 timestamp format ZULU offset"; + type ZULU; + mandatory true; + } - leaf api-ver { - description "api-ver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; - type string { - pattern "[2]\.\d\d"{ - error-message "API Version 2.XX is supported at this end point"; - } + leaf api-ver { + description "api-ver is the API version identifier. A given release of APPC + should support all previous versions of APPC API (correlate with + general requirements)"; + type string { + pattern "[2]\.\d\d" { + error-message "API Version 2.XX is supported at this end point"; } - mandatory true; } + mandatory true; + } - leaf originator-id { - description "originator-id an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; - type string; - mandatory true; - } + leaf originator-id { + description "originator-id an identifier of the calling system which can be + used addressing purposes, i.e. returning asynchronous response + to the proper destination over DMaaP (especially in case of multiple + consumers of APP-C APIs)"; + type string; + mandatory true; + } - leaf request-id { - description "UUID for the request ID. An OSS/BSS identifier for the request that caused the current action. Multiple API calls may be made with the same request-id The request-id shall be recorded throughout the operations on a single request"; - type string; - mandatory true; - } + leaf request-id { + description "UUID for the request ID. An OSS/BSS identifier for the request + that caused the current action. Multiple API calls may be made + with the same request-id The request-id shall be recorded throughout + the operations on a single request"; + type string; + mandatory true; + } - leaf sub-request-id { - description "Uniquely identifies a specific LCM action. It is persistent over the life-cycle of a single request"; - type string; - mandatory false; - } + leaf sub-request-id { + description "Uniquely identifies a specific LCM action. It is persistent over + the life-cycle of a single request"; + type string; + mandatory false; + } /********************************************************************************** @@ -271,61 +189,80 @@ module appc-provider-lcm { * * Optionally resume command acceptance and processing * - NORMAL - Obverse of EXCLUSIVE, the default one. **********************************************************************************/ - container flags { - description "Flags are generic flags that apply to any and all commands, all are optional"; - leaf mode { - type enumeration { - enum "EXCLUSIVE"; - enum "NORMAL"; - } - description "EXCLUSIVE (accept no queued requests on this VNF while processing) or NORMAL (queue other requests until complete)"; - mandatory false; - } - leaf force { - type enumeration { - enum "TRUE"; - enum "FALSE"; - } - description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc.) state"; - mandatory false; - } - leaf ttl { - description "<0....N> - The timeout value (expressed in seconds) for action execution, between action being received by APPC and action initiation"; - type uint16; - mandatory false; + container flags { + description "Flags are generic flags that apply to any and all commands, all + are optional"; + leaf mode { + type enumeration { + enum "EXCLUSIVE"; + enum "NORMAL"; } - } - } - } - - - grouping action-identifiers { - description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; - container action-identifiers { - description "A block containing the action arguments. These are used to specify the object upon which APP-C LCM command is to operate"; - leaf service-instance-id { - description "identifies a specific service the command refers to. When multiple APP-C instances are used and applied to a subset of services, this will become significant . The field is mandatory when the vnf-id is empty"; - type string; + description "EXCLUSIVE (accept no queued requests on this VNF while processing) + or NORMAL (queue other requests until complete)"; mandatory false; } - leaf vnf-id { - description "identifies the VNF to which this action is to be applied(vnf-id uniquely identifies the service-instance referred to). Note that some actions are applied to multiple VNFs in the same service. When this is the case, vnf-id may be left out, but service-instance-id must appear. The field is mandatory when service-instance-id is empty"; - type string; + leaf force { + type enumeration { + enum "TRUE"; + enum "FALSE"; + } + description "TRUE/FALSE - Execute action even if target is in unstable (i.e. + locked, transiting, etc.) state"; mandatory false; } - leaf vnfc-name { - description "identifies the VNFC to which this action is to be applied. Some actions apply only to a component within a VNF (e.g. RESTART is sometimes applied to on VM only). In such a case, the name of the VNFC is used to search for the component within the VNF"; - type string; + leaf ttl { + description "<0....N> - The timeout value (expressed in seconds) for action + execution, between action being received by APPC and action initiation"; + type uint16; mandatory false; } - leaf vserver-id { - description "identifies a specific VM within the given service/vnf to which this action is to be applied"; - type string; - mandatory false; } } } + + grouping action-identifiers { + description "A block containing the action arguments. These are used to specify + the object upon which APP-C LCM command is to operate"; + container action-identifiers { + description "A block containing the action arguments. These are used to specify + the object upon which APP-C LCM command is to operate"; + leaf service-instance-id { + description "identifies a specific service the command refers to. When multiple + APP-C instances are used and applied to a subset of services, + this will become significant . The field is mandatory when the + vnf-id is empty"; + type string; + mandatory false; + } + leaf vnf-id { + description "identifies the VNF to which this action is to be applied(vnf-id + uniquely identifies the service-instance referred to). Note that + some actions are applied to multiple VNFs in the same service. + When this is the case, vnf-id may be left out, but service-instance-id + must appear. The field is mandatory when service-instance-id is + empty"; + type string; + mandatory false; + } + leaf vnfc-name { + description "identifies the VNFC to which this action is to be applied. Some + actions apply only to a component within a VNF (e.g. RESTART is + sometimes applied to on VM only). In such a case, the name of + the VNFC is used to search for the component within the VNF"; + type string; + mandatory false; + } + leaf vserver-id { + description "identifies a specific VM within the given service/vnf to which + this action is to be applied"; + type string; + mandatory false; + } + } + } + + grouping status { description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; container status { @@ -344,163 +281,6 @@ module appc-provider-lcm { } - /********************************************************************************** - * NEW API :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - * All requests will include this standard header - * - * The standard request header is used to define a correlation identification for - * the request that is returned on all responses. This correlation identifier - * (called the service-request-id) is meaningful to the caller and is included on - * all responses from the services. - **********************************************************************************/ - grouping RequestHeader { - container RequestHeader { - description "A common header for all APP-C requests"; - leaf TimeStamp { - description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; - type TIMESTAMP; - mandatory true; - } - - leaf APIver { - description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; - type string; - mandatory true; - } - - leaf OriginatorID { - description "OriginatorID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; - type string; - mandatory true; - } - - leaf TransactionID { - description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; - type string; - mandatory true; - } - - leaf-list RequestTrack { - description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; - type string; - } - - /********************************************************************************** - * Flags are generic flags that apply to any and all commands, all are optional - * FORCE = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. - * TTL = <0....N> - The timeout value for command execution, expressed in seconds - * MODE = EXCLUSIVE/NORMAL - defines execution mode as follows: - * - EXCLUSIVE � on encountering an exclusive command, the APP-C will: - * * Cease accepting additional command requests - - * Complete execution of outstanding commands - * * Execute the exclusive command to completion - * * Optionally report the result of the command - * * Optionally resume command acceptance and processing - * - NORMAL - Obverse of EXCLUSIVE, the default one. - **********************************************************************************/ - container Flags { - description "Flags are generic flags that apply to any and all commands, all are optional"; - leaf FORCE { - description "TRUE/FALSE - Execute action even if target is in unstable (i.e. locked, transiting, etc) state."; - type string; - mandatory false; - } - leaf TTL { - description "<0....N> - The timeout value for action execution, expressed in seconds"; - type string; - mandatory false; - } - leaf MODE { - description "EXCLUSIVE/NORMAL - defines execution mode"; - type string; - mandatory false; - } - } - } - } - - grouping RequestParameters { - description "The request contains the entry of command-specific and is opaque to the APP-C handler"; - leaf Action { - description "The actual action to be taken"; - type string; - mandatory true; - } - leaf TargetID { - description "The specific VF a component of which is to be affected"; - type string; - mandatory true; - } - leaf ObjectID { - description "The specific VFC within a VF to be affected"; - type string; - mandatory true; - } - leaf Payload { - description "An action-specific value opaque to the APPC handler. - The value can be any valid JSON type (primitive, object, collection of those two). - APPC will pass the value as raw JSON string to the executing LCM action."; - type string; - mandatory true; - } - } - - grouping ResponseHeader { - description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; - container ResponseHeader { - description "The response to an APP-C command or control is, likewise, encoded in a JSON object. "; - leaf TimeStamp { - description "TimeStamp is in ISO 8601 timestamp format ZULU offset"; - type TIMESTAMP; - mandatory true; - } - - leaf APIver { - description "APIver is the API version identifier. A given release of APPC should support all previous versions of APPC API (correlate with general requirements)"; - type string; - mandatory true; - } - - leaf ResponseID { - description "ResponseID an identifier of the calling system which can be used addressing purposes, i.e. returning asynchronous response to the proper destination over DMaaP (especially in case of multiple consumers of APP-C APIs)"; - type string; - mandatory true; - } - - leaf-list SubResponseID { - description "Identifiers that may be generated when multiple responses or handling passes are needed for a given request, allowing the request itself to be tracked"; - type string; - } - } - } - - grouping ResponseAttributes { - description "The response contains the status of executed functionality"; - container Status { - description "The specific response codes are to be aligned with ASDC reference doc (main table removed to avoid duplication and digression from main table). See ASDC and ECOMP Distribution Consumer Interface Agreement"; - leaf Code { - description "Response code value"; - type uint32; - mandatory true; - } - leaf Value { - description "Response code description"; - type string; - mandatory true; - } - } - leaf Payload { - description "Payload - the entry is command-specific and is opaque to the APP-C handler. - The value can be any valid JSON type (primitive, object, collection of those two). - APP-C will pass the value as raw JSON string to appropriate addressee"; - type string; - mandatory false; - } - } - - - @@ -677,10 +457,18 @@ module appc-provider-lcm { mandatory true; } uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } } output { uses common-header; uses status; + leaf payload { + type payload; + mandatory false; + } } } @@ -707,26 +495,103 @@ module appc-provider-lcm { } } - /********************************************************************************** - * Define the modify-config service - **********************************************************************************/ - rpc modify-config { - description "An operation to modify-config the configurations of a virtual network function (or VM)"; + + rpc configure { + description "An operation to configure the configurations of a virtual network + function (or VM)"; input { uses common-header; leaf action { - type action; - mandatory true; + type action; + mandatory true; } uses action-identifiers; leaf payload { - type payload; - mandatory false; + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + + rpc config-modify { + description "Use the ModifyConfig command when a full configuration cycle is either not required or is considered too costly. The ModifyConfig LCM action affects only a subset of the total configuration data of a VNF. The set of configuration parameters to be affected is a subset of the total configuration data of the target VNF type. The payload block must contain the configuration parameters to be modified and their values. A successful modify returns a success response. A failed modify returns a failure response and the specific failure messages in the response payload block"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; } } output { uses common-header; uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + + rpc config-scaleout { + description "An operation to scaleout the configurations of a virtual network + function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + + rpc config-restore { + description "An operation to restore the configurations of a virtual network + function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } } } @@ -776,6 +641,26 @@ module appc-provider-lcm { } } + rpc start { + description "An operation to start a virtual network function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } + } + output { + uses common-header; + uses status; + } + } + /********************************************************************************** * Define the audit service **********************************************************************************/ @@ -788,10 +673,18 @@ module appc-provider-lcm { mandatory true; } uses action-identifiers; + leaf payload { + type payload; + mandatory false; + } } output { uses common-header; uses status; + leaf payload { + type payload; + mandatory false; + } } } @@ -893,8 +786,8 @@ module appc-provider-lcm { } /********************************************************************************** - * Define the VNF unlock service - **********************************************************************************/ + * Define the VNF unlock service + **********************************************************************************/ rpc unlock { description "An operation to perform VNF unlock operation"; input { @@ -943,6 +836,65 @@ module appc-provider-lcm { } + rpc config-backup { + description "An operation to Backup configurations of a virtual network function + (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + + rpc config-backup-delete { + description "An operation to Delete backup configurations of a virtual network + function (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + leaf payload { + type payload; + mandatory false; + } + } + } + + rpc config-export { + description "An operation to Export configurations of a virtual network function + (or VM)"; + input { + uses common-header; + leaf action { + type action; + mandatory true; + } + uses action-identifiers; + } + output { + uses common-header; + uses status; + } + } + /********************************************************************************** * Additional RPCs added here... **********************************************************************************/ diff --git a/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang b/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang index 6bdccf483..5430c9624 100644 --- a/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang +++ b/appc-provider/appc-provider-model/src/main/yang/appc-provider.yang @@ -392,7 +392,7 @@ module appc-provider { * FORCE = TRUE/FALSE - Execute command even if target is in unstable (i.e. locked, transiting, etc) state. Specific behaviour of forced commands varies, but implies cancellation of previous command and an override by the new command. The FALSE value is used by default. * TTL = <0....N> - The timeout value for command execution, expressed in seconds * MODE = EXCLUSIVE/NORMAL - defines execution mode as follows: - * - EXCLUSIVE � on encountering an exclusive command, the APP-C will: + * - EXCLUSIVE � on encountering an exclusive command, the APP-C will: * * Cease accepting additional command requests * Complete execution of outstanding commands @@ -616,5 +616,19 @@ module appc-provider { } } + rpc vmstatuscheck { + description "An operation to check status of a VM"; + input { + uses common-request-header; + uses vnf-resource; + } + output { + uses common-response-header; + leaf stat-msg { + description "The status of the VM requested"; + type string; + } + } + } } diff --git a/jenkins-settings.xml b/jenkins-settings.xml deleted file mode 100644 index 7f8f637a9..000000000 --- a/jenkins-settings.xml +++ /dev/null @@ -1,171 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- vi: set et smarttab sw=2 tabstop=2: --> -<!-- - Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. - - This program and the accompanying materials are made available under the - terms of the Eclipse Public License v1.0 which accompanies this distribution, - and is available at http://www.eclipse.org/legal/epl-v10.html ---> -<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> - <profiles> - <!-- NOTE: The ecomp.nexus.url and port will need to be replaced or - defined as properties in your build enviornment. --> - <profile> - <id>openecomp-release</id> - <repositories> - <repository> - <id>openecomp-release</id> - <name>openecomp-release</name> - <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-releases/</url> - <releases> - <enabled>true</enabled> - <updatePolicy>never</updatePolicy> - </releases> - <snapshots> - <enabled>false</enabled> - </snapshots> - </repository> - </repositories> - <pluginRepositories> - <pluginRepository> - <id>openecomp-release</id> - <name>openecomp-release</name> - <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-releases/</url> - <releases> - <enabled>true</enabled> - <updatePolicy>never</updatePolicy> - </releases> - <snapshots> - <enabled>false</enabled> - </snapshots> - </pluginRepository> - </pluginRepositories> - </profile> - <profile> - <id>openecomp-snapshots</id> - <repositories> - <repository> - <id>openecomp-snapshot</id> - <name>openecomp-snapshot</name> - <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-snapshots/</url> - <releases> - <enabled>false</enabled> - </releases> - <snapshots> - <enabled>true</enabled> - </snapshots> - </repository> - </repositories> - <pluginRepositories> - <pluginRepository> - <id>openecomp-snapshot</id> - <name>openecomp-snapshot</name> - <url>https://${ecomp.nexus.url}:${ecomp.nexus.port}/repository/maven-snapshots/</url> - <releases> - <enabled>false</enabled> - </releases> - <snapshots> - <enabled>true</enabled> - </snapshots> - </pluginRepository> - </pluginRepositories> - </profile> - <profile> - <id>opendaylight-release</id> - <repositories> - <repository> - <id>opendaylight-mirror</id> - <name>opendaylight-mirror</name> - <url>https://nexus.opendaylight.org/content/repositories/public/</url> - <releases> - <enabled>true</enabled> - <updatePolicy>never</updatePolicy> - </releases> - <snapshots> - <enabled>false</enabled> - </snapshots> - </repository> - </repositories> - <pluginRepositories> - <pluginRepository> - <id>opendaylight-mirror</id> - <name>opendaylight-mirror</name> - <url>https://nexus.opendaylight.org/content/repositories/public/</url> - <releases> - <enabled>true</enabled> - <updatePolicy>never</updatePolicy> - </releases> - <snapshots> - <enabled>false</enabled> - </snapshots> - </pluginRepository> - </pluginRepositories> - </profile> - <profile> - <id>opendaylight-snapshots</id> - <repositories> - <repository> - <id>opendaylight-snapshot</id> - <name>opendaylight-snapshot</name> - <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> - <releases> - <enabled>false</enabled> - </releases> - <snapshots> - <enabled>true</enabled> - </snapshots> - </repository> - </repositories> - <pluginRepositories> - <pluginRepository> - <id>opendaylight-snapshot</id> - <name>opendaylight-snapshot</name> - <url>https://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url> - <releases> - <enabled>false</enabled> - </releases> - <snapshots> - <enabled>true</enabled> - </snapshots> - </pluginRepository> - </pluginRepositories> - </profile> - </profiles> - <activeProfiles> - <activeProfile>openecomp-release</activeProfile> - <activeProfile>openecomp-snapshots</activeProfile> - <activeProfile>opendaylight-release</activeProfile> - <activeProfile>opendaylight-snapshots</activeProfile> - </activeProfiles> - <servers> - <!-- NOTE: The ecomp.nexus.user and password will need to be replaced or - defined as properties in your build enviornment. --> - <server> - <id>nexus</id> - <username>${ecomp.nexus.user}</username> - <password>${ecomp.nexus.password}</password> - </server> - <server> - <id>openecomp-release</id> - <username>${ecomp.nexus.user}</username> - <password>${ecomp.nexus.password}</password> - </server> - <server> - <id>openecomp-snapshot</id> - <username>${ecomp.nexus.user}</username> - <password>${ecomp.nexus.password}</password> - </server> - <server> - <id>openecomp-public</id> - <username>${ecomp.nexus.user}</username> - <password>${ecomp.nexus.password}</password> - </server> - <!-- Javadocs Server --> - <server> - <id>app-c-javadoc</id> - <username>${ecomp.nexus.user}</username> - <password>${ecomp.nexus.password}</password> - </server> - </servers> -</settings>
\ No newline at end of file @@ -28,32 +28,33 @@ <properties> <!-- VERSIONS --> <!-- OpenDaylight Versions --> - <odl.version>1.7.1-Boron-SR1</odl.version> - <odl.dlux.version>0.4.1-Boron-SR1</odl.dlux.version> - <odl.yangtools.version>1.0.1-Boron-SR1</odl.yangtools.version> - <odl.mdsal.version>1.4.1-Boron-SR1</odl.mdsal.version> - <odl.mdsal.features.version>2.1.1-Boron-SR1</odl.mdsal.features.version> + <odl.version>1.7.1-Boron-SR1</odl.version> + <odl.dlux.version>0.4.1-Boron-SR1</odl.dlux.version> + <odl.yangtools.version>1.0.1-Boron-SR1</odl.yangtools.version> + <odl.mdsal.version>1.4.1-Boron-SR1</odl.mdsal.version> + <odl.mdsal.features.version>2.1.1-Boron-SR1</odl.mdsal.features.version> <odl.controller.mdsal.features.version>1.4.1-Boron-SR1</odl.controller.mdsal.features.version> - <odl.mdsal.model.version>0.9.1-Boron-SR1</odl.mdsal.model.version> - <odl.mdsal.yang.binding.version>0.9.1-Boron-SR1</odl.mdsal.yang.binding.version> - <odl.restconf.version>1.4.1-Boron-SR1</odl.restconf.version> - <odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version> - <odl.controller.config.api.version>0.5.1-Boron-SR1</odl.controller.config.api.version> - <odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version> - <odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version> - <odl.ietf-inet-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-inet-types.version> - <odl.ietf-yang-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-yang-types.version> - <odl.yang.jmx.generator.version>0.5.1-Boron-SR1</odl.yang.jmx.generator.version> - <odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version> - <odl.sal.api.gen.plugin.version>0.9.1-Boron-SR1</odl.sal.api.gen.plugin.version> + <odl.mdsal.model.version>0.9.1-Boron-SR1</odl.mdsal.model.version> + <odl.mdsal.yang.binding.version>0.9.1-Boron-SR1</odl.mdsal.yang.binding.version> + <odl.restconf.version>1.4.1-Boron-SR1</odl.restconf.version> + <odl.controller.model.version>${odl.mdsal.model.version}</odl.controller.model.version> + <odl.controller.config.api.version>0.5.1-Boron-SR1</odl.controller.config.api.version> + <odl.karaf.empty.distro.version>${odl.version}</odl.karaf.empty.distro.version> + <odl.commons.opendaylight.version>${odl.version}</odl.commons.opendaylight.version> + <odl.ietf-inet-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-inet-types.version> + <odl.ietf-yang-types.version>2010.09.24.9.1-Boron-SR1</odl.ietf-yang-types.version> + <odl.yang.jmx.generator.version>0.5.1-Boron-SR1</odl.yang.jmx.generator.version> + <odl.yangtools.yang.maven.plugin.version>${odl.yangtools.version}</odl.yangtools.yang.maven.plugin.version> + <odl.sal.api.gen.plugin.version>0.9.1-Boron-SR1</odl.sal.api.gen.plugin.version> <broker-mdsal.version>1.4.1-Boron-SR1</broker-mdsal.version> <!-- OPENECOMP SDNC versions --> - <sdnctl.sli.version>1.1.0-SNAPSHOT</sdnctl.sli.version> - <sdnctl.dblib.version>1.1.0-SNAPSHOT</sdnctl.dblib.version> - <sdnctl.aai.service.version>1.1.0-SNAPSHOT</sdnctl.aai.service.version> + <sdnctl.sli.version>1.1.1-SNAPSHOT</sdnctl.sli.version> + <sdnctl.dblib.version>1.1.1-SNAPSHOT</sdnctl.dblib.version> + <sdnctl.aai.service.version>1.1.1-SNAPSHOT</sdnctl.aai.service.version> - <cdp.pal.version>0.0.1</cdp.pal.version> + <cdp.pal.version>1.1.7-oss</cdp.pal.version> + <dmaap.client.version>0.2.12</dmaap.client.version> <eelf.version>0.0.1</eelf.version> <eelf.maven.plugin.version>0.0.1</eelf.maven.plugin.version> <cadi-version>1.3.0</cadi-version> @@ -66,6 +67,8 @@ <commons.lang3.version>3.4</commons.lang3.version> <antlr.version>4.5.1</antlr.version> <mysql.connector.version>5.1.39</mysql.connector.version> + <logback.version>1.1.1</logback.version> + <toscalib.version>1.0.0-SNAPSHOT</toscalib.version> <!-- SONAR --> <sonar.language>java</sonar.language> @@ -80,10 +83,10 @@ <!-- ADDING TO SUPPORT APPC-PROVIDER-MODEL yang-gen-sal FOLDER GENERATION --> <yang.file.directory>src/main/yang</yang.file.directory> <features.file>features.xml</features.file> - <jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath> - <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath> + <jmxGeneratorPath>target/generated-sources/yang-gen-config</jmxGeneratorPath> + <!-- <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath> --> <checkstyle.skip>true</checkstyle.skip> - + <!-- NEXUS URLS --> <openecomp.nexus.host>nexus.onap.org</openecomp.nexus.host> <openecomp.nexus.url>https://${openecomp.nexus.host}/content</openecomp.nexus.url> @@ -253,6 +256,16 @@ <version>${odl.karaf.empty.distro.version}</version> <type>zip</type> </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-inet-types</artifactId> + <version>${odl.ietf-inet-types.version}</version> + </dependency> + <dependency> + <groupId>org.opendaylight.mdsal.model</groupId> + <artifactId>ietf-yang-types</artifactId> + <version>${odl.ietf-yang-types.version}</version> + </dependency> <!-- CURRENTLY DOES NOT EXIST IN 3.0. Replacement? --> <!-- Required for launching the feature tests --> <!-- <dependency> --> @@ -287,8 +300,8 @@ <artifactId>dblib-provider</artifactId> <version>${sdnctl.dblib.version}</version> </dependency> - <!-- A&AI service provider dependency override in order to use - a stable version --> + <!-- A&AI service provider dependency override in order to use a stable + version --> <dependency> <groupId>org.openecomp.sdnc.adaptors</groupId> <artifactId>aai-service-provider</artifactId> @@ -348,11 +361,11 @@ <version>1.1.1</version> <scope>compile</scope> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - <version>1.7.12</version> - </dependency> + <!-- <dependency> --> + <!-- <groupId>org.slf4j</groupId> --> + <!-- <artifactId>slf4j-api</artifactId> --> + <!-- <version>1.7.12</version> --> + <!-- </dependency> --> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> @@ -495,7 +508,7 @@ </plugins> </pluginManagement> <plugins> - <!--maven staging plugin--> + <!--maven staging plugin --> <plugin> <groupId>org.sonatype.plugins</groupId> <artifactId>nexus-staging-maven-plugin</artifactId> @@ -572,29 +585,34 @@ </configuration> </execution> </executions> + </plugin> + <!-- blackduck maven plugin --> - <!-- + <!-- <plugin> <groupId>com.blackducksoftware.integration</groupId> <artifactId>hub-maven-plugin</artifactId> + <version>2.0.0</version> <inherited>false</inherited> <configuration> <hubProjectName>${project.name}</hubProjectName> + <outputDirectory>${project.basedir}</outputDirectory> <deployHubBdio>false</deployHubBdio> + </configuration> <executions> <execution> <id>create-bdio-file</id> <phase>package</phase> + <goals> <goal>build-bom</goal> </goals> </execution> </executions> </plugin> --> + + <!-- force Eclipse to skip the additional-install step specified in the + org.opendaylight.odlparent:odlparent-lite:1.7.1-Boron-SR1.pom profile --> <plugin> - <groupId>com.blackducksoftware.integration</groupId> - <artifactId>hub-maven-plugin</artifactId> - <version>1.4.0</version> - <inherited>false</inherited> - <configuration> - <hubProjectName>${project.name}</hubProjectName> - <outputDirectory>${project.basedir}</outputDirectory> - </configuration> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> <executions> <execution> - <id>create-bdio-file</id> - <phase>package</phase> + <id>additional-install</id> + <phase></phase> <goals> - <goal>createHubOutput</goal> + <goal>install-file</goal> </goals> + <configuration> + <skip>true</skip> + </configuration> </execution> </executions> </plugin> - --> </plugins> </build> @@ -629,6 +647,7 @@ <module>appc-provider</module> <module>appc-event-listener</module> <module>appc-asdc-listener</module> + <module>appc-oam</module> </modules> </profile> <profile> |