2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.openecomp.appc.simulator.client.impl;
27 import org.openecomp.appc.client.lcm.api.AppcClientServiceFactoryProvider;
28 import org.openecomp.appc.client.lcm.api.AppcLifeCycleManagerServiceFactory;
29 import org.openecomp.appc.client.lcm.api.ApplicationContext;
30 import org.openecomp.appc.client.lcm.api.LifeCycleManagerStateful;
31 import org.openecomp.appc.client.lcm.api.ResponseHandler;
33 import org.openecomp.appc.client.lcm.exceptions.AppcClientException;
34 import org.openecomp.appc.simulator.client.RequestHandler;
36 import com.att.eelf.configuration.EELFLogger;
37 import com.att.eelf.configuration.EELFManager;
38 import com.fasterxml.jackson.databind.JsonNode;
39 import com.fasterxml.jackson.databind.ObjectMapper;
40 import com.fasterxml.jackson.databind.node.ObjectNode;
42 import java.io.BufferedReader;
44 import java.io.FileNotFoundException;
45 import java.io.FileReader;
46 import java.io.IOException;
47 import java.lang.reflect.Method;
48 import java.util.HashMap;
49 import java.util.Properties;
51 public class JsonRequestHandler implements RequestHandler {
58 public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
59 private String rpcName = null;
60 private String inputClassName = null;
61 private String actionName = null;
62 private String methodName = null;
63 String packageName = null;
64 private LifeCycleManagerStateful service = null;
65 private Properties properties;
66 HashMap<String, String> exceptRpcMap = null;
67 private final EELFLogger LOG = EELFManager.getInstance().getLogger(JsonRequestHandler.class);
68 private AppcLifeCycleManagerServiceFactory appcLifeCycleManagerServiceFactory = null;
71 public JsonRequestHandler(Properties prop) throws AppcClientException {
73 packageName = properties.getProperty("ctx.model.package") + ".";
75 service = createService();
76 } catch (AppcClientException e) {
79 exceptRpcMap = prepareExceptionsMap();
82 private HashMap<String,String> prepareExceptionsMap() {
83 exceptRpcMap = new HashMap<>();
85 try (BufferedReader reader = new BufferedReader(
86 new FileReader(properties.getProperty(
87 "client.rpc.exceptions.map.file")))) {
89 while ((line = reader.readLine()) != null) {
90 String[] parts = line.split(":", 2);
91 if (parts.length >= 2) {
92 String key = parts[0];
93 String value = parts[1];
94 exceptRpcMap.put(key, value);
96 System.out.println("ignoring line: " + line);
99 } catch (FileNotFoundException e) {
101 } catch (IOException e) {
109 public void proceedFile(File source, File log) throws IOException {
110 final JsonNode inputNode = OBJECT_MAPPER.readTree(source);
113 // proceed with inputNode and get some xxxInput object, depends on action
114 prepareNames(inputNode);
116 Object input = prepareObject(inputNode);
118 JsonResponseHandler response = new JsonResponseHandler();
119 response.setFile(source.getPath().toString());
120 switch (isSyncMode(inputNode)) {
122 LOG.debug("Received input request will be processed in synchronously mode");
123 Method rpc = LifeCycleManagerStateful.class.getDeclaredMethod(methodName, input.getClass());
124 response.onResponse(rpc.invoke(service, input));
128 LOG.debug("Received input request will be processed in asynchronously mode");
129 Method rpc = LifeCycleManagerStateful.class.getDeclaredMethod(methodName, input.getClass(), ResponseHandler.class);
130 rpc.invoke(service, input, response);
134 throw new RuntimeException("Unrecognized request mode");
139 //ex.printStackTrace();
142 LOG.debug("Action <" + actionName + "> from input file <" + source.getPath().toString() + "> processed");
145 private modeT isSyncMode(JsonNode inputNode) {
146 // The following solution is for testing purposes only
147 // the sync/async decision logic may change upon request
149 int mode = Integer.parseInt(inputNode.findValue("input").findValue("common-header").findValue("sub-request-id").asText());
150 if ((mode % 2) == 0) {
153 }catch (Exception ex) {
154 //use ASYNC as default, if value is not integer.
159 private LifeCycleManagerStateful createService() throws AppcClientException {
160 appcLifeCycleManagerServiceFactory = AppcClientServiceFactoryProvider.getFactory(AppcLifeCycleManagerServiceFactory.class);
161 return appcLifeCycleManagerServiceFactory.createLifeCycleManagerStateful(new ApplicationContext(), properties);
164 public void shutdown(boolean isForceShutdown){
165 appcLifeCycleManagerServiceFactory.shutdownLifeCycleManager(isForceShutdown);
168 public Object prepareObject(JsonNode input) {
170 Class cls = Class.forName(inputClassName);
172 // since payload is not mandatory field and not all actions contains payload
173 // so we have to check that during input parsing
175 } catch (NoSuchFieldException e) {
176 LOG.debug("In " + actionName + " no payload defined");
179 return OBJECT_MAPPER.treeToValue(input.get("input"), cls);
182 //ex.printStackTrace();
187 private void prepareNames(JsonNode input) throws NoSuchFieldException {
188 JsonNode inputNode = input.findValue("input");
189 actionName = inputNode.findValue("action").asText();
190 if (actionName.isEmpty()) {
191 throw new NoSuchFieldException("Input doesn't contains field <action>");
194 rpcName = prepareRpcFromAction(actionName);
195 inputClassName = packageName + actionName + "Input";
196 methodName = prepareMethodName(rpcName);
199 private void alignPayload(JsonNode input) throws NoSuchFieldException {
200 JsonNode inputNode = input.findValue("input");
201 JsonNode payload = inputNode.findValue("payload");
202 if (payload == null || payload.asText().isEmpty() || payload.toString().isEmpty())
203 throw new NoSuchFieldException("Input doesn't contains field <payload>");
205 String payloadData = payload.asText();
206 if (payloadData.isEmpty())
207 payloadData = payload.toString();
208 ((ObjectNode)inputNode).put("payload", payloadData);
211 private String prepareRpcFromAction(String action) {
212 String rpc = checkExceptionalRpcList(action);
213 if (rpc!= null && !rpc.isEmpty()) {
214 return rpc; // we found exceptional rpc, so no need to format it
218 boolean makeItLowerCase = true;
219 for(int i = 0; i < action.length(); i++)
221 if(makeItLowerCase) // first character will make lower case
223 rpc+=Character.toLowerCase(action.charAt(i));
224 makeItLowerCase = false;
226 else if((i+1 < action.length()) && Character.isUpperCase(action.charAt(i+1)))
228 rpc+=action.charAt(i) + "-";
229 makeItLowerCase = true;
233 rpc+=action.charAt(i);
234 makeItLowerCase = false;
240 private String checkExceptionalRpcList(String action) {
241 if (exceptRpcMap.isEmpty()) {
244 return exceptRpcMap.get(action);
247 private String prepareMethodName(String inputRpcName) {
248 boolean makeItUpperCase = false;
251 for(int i = 0; i < inputRpcName.length(); i++) //to check the characters of string..
253 if(Character.isLowerCase(inputRpcName.charAt(i)) && makeItUpperCase) // skip first character if it lower case
255 method+=Character.toUpperCase(inputRpcName.charAt(i));
256 makeItUpperCase = false;
258 else if(inputRpcName.charAt(i) == '-')
260 makeItUpperCase = true;
264 method+=inputRpcName.charAt(i);
265 makeItUpperCase = false;