summaryrefslogtreecommitdiffstats
path: root/appc-client/client-simulator/src/main/java
diff options
context:
space:
mode:
authorSkip Wonnell <kw5258@att.com>2017-08-29 22:39:17 -0500
committerMarcus Williams <marcus.williams@intel.com>2017-08-30 15:36:41 +0000
commitabe9420ac5220879d4790f9020c583cb037dd577 (patch)
tree178e8b7b0cdaa6317064add7e5e29299459188c5 /appc-client/client-simulator/src/main/java
parent8c9631e438b9491424df0f43d43445f098436834 (diff)
Initial add of APPC client libraries
Issue-ID: APPC-180 Change-Id: Ie0be2b518b90bb7f9996e9260c43fef75d1a5821 Signed-off-by: Skip Wonnell <kw5258@att.com>
Diffstat (limited to 'appc-client/client-simulator/src/main/java')
-rw-r--r--appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/RequestHandler.java33
-rw-r--r--appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/ResponseHandler.java31
-rw-r--r--appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonRequestHandler.java272
-rw-r--r--appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonResponseHandler.java147
-rw-r--r--appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/main/ClientRunner.java99
5 files changed, 582 insertions, 0 deletions
diff --git a/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/RequestHandler.java b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/RequestHandler.java
new file mode 100644
index 000000000..225f6bba9
--- /dev/null
+++ b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/RequestHandler.java
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.simulator.client;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface RequestHandler {
+ void proceedFile(File source, File log) throws IOException, ClassNotFoundException, NoSuchMethodException;
+ void shutdown(boolean isForceShutdown);
+}
diff --git a/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/ResponseHandler.java b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/ResponseHandler.java
new file mode 100644
index 000000000..459804aaa
--- /dev/null
+++ b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/ResponseHandler.java
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.simulator.client;
+
+import java.io.File;
+
+public interface ResponseHandler {
+ void validateResponse(File output);
+}
diff --git a/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonRequestHandler.java b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonRequestHandler.java
new file mode 100644
index 000000000..de1a2055b
--- /dev/null
+++ b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonRequestHandler.java
@@ -0,0 +1,272 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.simulator.client.impl;
+
+import org.openecomp.appc.client.lcm.api.*;
+import org.openecomp.appc.client.lcm.exceptions.*;
+import org.openecomp.appc.simulator.client.RequestHandler;
+
+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 java.io.*;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Properties;
+
+public class JsonRequestHandler implements RequestHandler {
+
+ private enum modeT {
+ SYNCH,
+ ASYNCH
+ }
+
+ public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+ private String rpcName = null;
+ private String inputClassName = null;
+ private String actionName = null;
+ private String methodName = null;
+ String packageName = null;
+ private LifeCycleManagerStateful service = null;
+ private Properties properties;
+ HashMap<String, String> exceptRpcMap = null;
+ private final EELFLogger LOG = EELFManager.getInstance().getLogger(JsonRequestHandler.class);
+ private AppcLifeCycleManagerServiceFactory appcLifeCycleManagerServiceFactory = null;
+
+
+ public JsonRequestHandler(Properties prop) throws AppcClientException {
+ properties = prop;
+ packageName = properties.getProperty("ctx.model.package") + ".";
+ try {
+ service = createService();
+ } catch (AppcClientException e) {
+ e.printStackTrace();
+ }
+ exceptRpcMap = prepareExceptionsMap();
+ }
+
+ private HashMap<String,String> prepareExceptionsMap() {
+ exceptRpcMap = new HashMap<String, String>();
+
+ String line;
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(properties.getProperty("client.rpc.exceptions.map.file")));
+ } catch (FileNotFoundException e) {
+ return exceptRpcMap;
+ }
+
+ try {
+ while ((line = reader.readLine()) != null)
+ {
+ String[] parts = line.split(":", 2);
+ if (parts.length >= 2)
+ {
+ String key = parts[0];
+ String value = parts[1];
+ exceptRpcMap.put(key, value);
+ } else {
+ System.out.println("ignoring line: " + line);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return exceptRpcMap;
+ }
+
+ @Override
+ public void proceedFile(File source, File log) throws IOException {
+ final JsonNode inputNode = OBJECT_MAPPER.readTree(source);
+
+ try {
+ // proceed with inputNode and get some xxxInput object, depends on action
+ prepareNames(inputNode);
+
+ Object input = prepareObject(inputNode);
+
+ JsonResponseHandler response = new JsonResponseHandler();
+ response.setFile(source.getPath().toString());
+ switch (isSyncMode(inputNode)) {
+ case SYNCH: {
+ LOG.debug("Received input request will be processed in synchronously mode");
+ Method rpc = LifeCycleManagerStateful.class.getDeclaredMethod(methodName, input.getClass());
+ response.onResponse(rpc.invoke(service, input));
+ break;
+ }
+ case ASYNCH: {
+ LOG.debug("Received input request will be processed in asynchronously mode");
+ Method rpc = LifeCycleManagerStateful.class.getDeclaredMethod(methodName, input.getClass(), ResponseHandler.class);
+ rpc.invoke(service, input, response);
+ break;
+ }
+ default: {
+ throw new RuntimeException("Unrecognized request mode");
+ }
+ }
+ }
+ catch(Exception ex){
+ //ex.printStackTrace();
+ }
+
+ LOG.debug("Action <" + actionName + "> from input file <" + source.getPath().toString() + "> processed");
+ }
+
+ private modeT isSyncMode(JsonNode inputNode) {
+ // The following solution is for testing purposes only
+ // the sync/async decision logic may change upon request
+ try {
+ int mode = Integer.parseInt(inputNode.findValue("input").findValue("common-header").findValue("sub-request-id").asText());
+ if ((mode % 2) == 0) {
+ return modeT.SYNCH;
+ }
+ }catch (Throwable ex) {
+ //use ASYNC as default, if value is not integer.
+ }
+ return modeT.ASYNCH;
+ }
+
+ private LifeCycleManagerStateful createService() throws AppcClientException {
+ appcLifeCycleManagerServiceFactory = AppcClientServiceFactoryProvider.getFactory(AppcLifeCycleManagerServiceFactory.class);
+ return appcLifeCycleManagerServiceFactory.createLifeCycleManagerStateful(new ApplicationContext(), properties);
+ }
+
+ public void shutdown(boolean isForceShutdown){
+ appcLifeCycleManagerServiceFactory.shutdownLifeCycleManager(isForceShutdown);
+ }
+
+ public Object prepareObject(JsonNode input) {
+ try {
+ Class cls = Class.forName(inputClassName);
+ try {
+ // since payload is not mandatory field and not all actions contains payload
+ // so we have to check that during input parsing
+ alignPayload(input);
+ } catch (NoSuchFieldException e) {
+ LOG.debug("In " + actionName + " no payload defined");
+ }
+
+ return OBJECT_MAPPER.treeToValue(input.get("input"), cls);
+ }
+ catch(Exception ex){
+ //ex.printStackTrace();
+ }
+ return null;
+ }
+
+ private void prepareNames(JsonNode input) throws NoSuchFieldException {
+ JsonNode inputNode = input.findValue("input");
+ actionName = inputNode.findValue("action").asText();
+ if (actionName.isEmpty()) {
+ throw new NoSuchFieldException("Input doesn't contains field <action>");
+ }
+
+ rpcName = prepareRpcFromAction(actionName);
+ inputClassName = packageName + actionName + "Input";
+ methodName = prepareMethodName(rpcName);
+ }
+
+ private void alignPayload(JsonNode input) throws NoSuchFieldException {
+ JsonNode inputNode = input.findValue("input");
+ JsonNode payload = inputNode.findValue("payload");
+ if (payload == null || payload.asText().isEmpty() || payload.toString().isEmpty())
+ throw new NoSuchFieldException("Input doesn't contains field <payload>");
+
+ String payloadData = payload.asText();
+ if (payloadData.isEmpty())
+ payloadData = payload.toString();
+ ((ObjectNode)inputNode).put("payload", payloadData);
+ }
+
+ private String prepareRpcFromAction(String action) {
+ String rpc = checkExceptionalRpcList(action);
+ if (rpc!= null && !rpc.isEmpty()) {
+ return rpc; // we found exceptional rpc, so no need to format it
+ }
+
+ rpc = "";
+ boolean makeItLowerCase = true;
+ for(int i = 0; i < action.length(); i++)
+ {
+ if(makeItLowerCase) // first character will make lower case
+ {
+ rpc+=Character.toLowerCase(action.charAt(i));
+ makeItLowerCase = false;
+ }
+ else if((i+1 < action.length()) && Character.isUpperCase(action.charAt(i+1)))
+ {
+ rpc+=action.charAt(i) + "-";
+ makeItLowerCase = true;
+ }
+ else
+ {
+ rpc+=action.charAt(i);
+ makeItLowerCase = false;
+ }
+ }
+ return rpc;
+ }
+
+ private String checkExceptionalRpcList(String action) {
+ if (exceptRpcMap.isEmpty()) {
+ return null;
+ }
+ return exceptRpcMap.get(action);
+ }
+
+ private String prepareMethodName(String inputRpcName) {
+ boolean makeItUpperCase = false;
+ String method = "";
+
+ for(int i = 0; i < inputRpcName.length(); i++) //to check the characters of string..
+ {
+ if(Character.isLowerCase(inputRpcName.charAt(i)) && makeItUpperCase) // skip first character if it lower case
+ {
+ method+=Character.toUpperCase(inputRpcName.charAt(i));
+ makeItUpperCase = false;
+ }
+ else if(inputRpcName.charAt(i) == '-')
+ {
+ makeItUpperCase = true;
+ }
+ else
+ {
+ method+=inputRpcName.charAt(i);
+ makeItUpperCase = false;
+ }
+ }
+ return method;
+ }
+
+}
diff --git a/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonResponseHandler.java b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonResponseHandler.java
new file mode 100644
index 000000000..aef034f53
--- /dev/null
+++ b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/impl/JsonResponseHandler.java
@@ -0,0 +1,147 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.simulator.client.impl;
+
+import org.openecomp.appc.client.lcm.api.ResponseHandler;
+import org.openecomp.appc.client.lcm.exceptions.AppcClientException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.FileWriter;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class JsonResponseHandler implements ResponseHandler<Object> {
+
+ public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+ private final EELFLogger LOG = EELFManager.getInstance().getLogger(JsonResponseHandler.class);
+
+ private String fileName = "default";
+ private static final int ACCEPT_FAMILY = 1;
+ private static final int SUCCESS_FAMILY = 4;
+ private static final int INTERMEDIATE_MESSAGES =5;
+
+ private AtomicInteger messageCount =new AtomicInteger(1);
+
+ public void setFile(String name) {
+ fileName = name;
+ }
+
+ @Override
+ public void onResponse(Object response) {
+
+ String output = null;
+ try {
+ output = OBJECT_MAPPER.writeValueAsString(response);
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ LOG.debug("Received response : " + output);
+
+ int errorCode = 0;
+ boolean isFinal = true;
+ try {
+ JsonNode code = OBJECT_MAPPER.readTree(output).findValue("status").findValue("code");
+ if (code == null)
+ {
+ LOG.error("Status code doesn't exist. Malformed response : " + output);
+ flushToErrorFile(output, isFinal);
+ return;
+ }
+ errorCode = code.asInt();
+ errorCode = errorCode / 100;
+ switch (errorCode) {
+ case ACCEPT_FAMILY:
+ isFinal = false; // for ACCEPT that it is not a final response
+ break;
+ case INTERMEDIATE_MESSAGES:
+ isFinal = false; // for 5xx series messages are not a final response
+ break;
+ default:
+ break;
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+
+ switch (errorCode) {
+ case ACCEPT_FAMILY: {
+ try {
+ System.out.println("== THR#" + Thread.currentThread().getId() + " Got ACCEPT on ReqID <" +
+ OBJECT_MAPPER.readTree(output).findValue("common-header").findValue("request-id").asText() + ">");
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ // no need to report ACCEPT into output file
+ break;
+ }
+ case SUCCESS_FAMILY:
+ flushToOutputFile(output, isFinal);
+ break;
+ case INTERMEDIATE_MESSAGES:
+ flushToMessageFile(output, isFinal);
+ break;
+ default:
+ flushToErrorFile(output, isFinal);
+ }
+ }
+
+ @Override
+ public void onException(AppcClientException exception) {
+ flushToErrorFile("exception: " + exception, true);
+ }
+
+ private void flushToOutputFile(String output, boolean isFinal) {
+ this.flushToFile(output, ".output", isFinal);
+ }
+ private void flushToMessageFile(String output, boolean isFinal) {
+ this.flushToFile(output, ".message" + messageCount.getAndIncrement(), isFinal);
+
+ }
+
+ private void flushToErrorFile(String output, boolean isFinal) {
+ this.flushToFile(output, ".error", isFinal);
+ }
+
+ private void flushToFile(String output, String suffix, boolean isFinal) {
+ try (FileWriter fileWriter = new FileWriter(fileName + suffix);){
+ LOG.info("Output file : " + fileName + suffix);
+
+ fileWriter.write(output);
+ fileWriter.flush();
+ if (isFinal){
+ fileWriter.close();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ System.out.println("== THR#" +Thread.currentThread().getId()+ " Output file : " + fileName + suffix);
+ }
+}
diff --git a/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/main/ClientRunner.java b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/main/ClientRunner.java
new file mode 100644
index 000000000..d28927302
--- /dev/null
+++ b/appc-client/client-simulator/src/main/java/org/openecomp/appc/simulator/client/main/ClientRunner.java
@@ -0,0 +1,99 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.simulator.client.main;
+
+import org.apache.commons.io.filefilter.WildcardFileFilter;
+import org.openecomp.appc.simulator.client.RequestHandler;
+import org.openecomp.appc.simulator.client.impl.JsonRequestHandler;
+
+import java.io.*;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+public class ClientRunner {
+ public static void main(String ... args) throws Exception {
+ String folder = args[0];
+ if (folder == null) {
+ folder = System.getProperty("user.dir");
+ }
+ System.out.println("== THR#" +Thread.currentThread().getId()+ " Reading files under the folder : " + folder);
+
+ String inputType = args[1];
+ if (inputType != null && !inputType.matches("JSON")) {
+ throw new RuntimeException("### ERROR ### - Unsupported file type <" + inputType + "> was provided");
+ }
+
+ Properties properties = getProperties(folder);
+ RequestHandler reqHandler = new JsonRequestHandler(properties);
+ List<File> sources = getJsonFiles(folder);
+ File log = new File(folder + "/output.txt");
+ int filesNum = 0;
+ for (File source: sources) {
+ reqHandler.proceedFile(source, log);
+ System.out.println("== THR#" +Thread.currentThread().getId()+ " File <" + source.getName() + "> processed.");
+ ++filesNum;
+ }
+ System.out.println("DONE with " + filesNum + " files under the folder : " + folder);
+ Thread.sleep(30);
+ System.out.println("Shutdown ...");
+ reqHandler.shutdown(Boolean.parseBoolean(properties.getProperty("client.force.shutdown")));
+// System.exit(0);
+ }
+
+ private static Properties getProperties(String folder) {
+ Properties prop = new Properties();
+
+ InputStream conf = null;
+ try {
+ conf = new FileInputStream(folder + "client-simulator.properties");
+ } catch (FileNotFoundException e) {
+
+ }
+ if (conf != null) {
+ try {
+ prop.load(conf);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ try {
+ prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("client-simulator.properties"));
+ } catch (Exception e) {
+ throw new RuntimeException("### ERROR ### - Could not load properties to test");
+ }
+ }
+ return prop;
+ }
+
+ private static List<File> getJsonFiles(String folder) throws FileNotFoundException {
+ Path dir = Paths.get(folder);
+ FileFilter fileFilter = new WildcardFileFilter("*.json");
+ return new ArrayList<File>(Arrays.asList(dir.toFile().listFiles(fileFilter)));
+ }
+}