f7db52b1c0cb024d96c7bb2c85ec5bf940263eb3
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / openecomp / mso / client / appc / ApplicationControllerSupport.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.mso.client.appc;
22
23
24 import java.beans.BeanInfo;
25 import java.beans.IntrospectionException;
26 import java.beans.Introspector;
27 import java.beans.PropertyDescriptor;
28 import java.io.IOException;
29 import java.lang.reflect.InvocationTargetException;
30 import java.lang.reflect.Method;
31 import java.util.Properties;
32
33 import org.springframework.beans.factory.annotation.Value;
34 import org.springframework.core.io.ClassPathResource;
35 import org.springframework.core.io.Resource;
36 import org.springframework.core.io.support.PropertiesLoaderUtils;
37 import org.springframework.stereotype.Component;
38
39 import org.openecomp.appc.client.lcm.api.AppcClientServiceFactoryProvider;
40 import org.openecomp.appc.client.lcm.api.AppcLifeCycleManagerServiceFactory;
41 import org.openecomp.appc.client.lcm.api.ApplicationContext;
42 import org.openecomp.appc.client.lcm.api.LifeCycleManagerStateful;
43 import org.openecomp.appc.client.lcm.api.ResponseHandler;
44 import org.openecomp.appc.client.lcm.exceptions.AppcClientException;
45 import org.openecomp.appc.client.lcm.model.Status;
46 import com.fasterxml.jackson.annotation.JsonInclude.Include;
47 import com.fasterxml.jackson.core.JsonProcessingException;
48 import com.fasterxml.jackson.databind.ObjectMapper;
49 import com.fasterxml.jackson.databind.ObjectWriter;
50
51
52 @Component
53 public class ApplicationControllerSupport {
54
55         private static final int ACCEPT_SERIES = 100;
56         private static final int ERROR_SERIES = 200;
57         private static final int REJECT_SERIES = 300;
58         private static final int SUCCESS_SERIES = 400;
59         private static final int SUCCESS_STATUS = SUCCESS_SERIES;
60         private static final int PARTIAL_SERIES = 500;
61         private static final int PARTIAL_SUCCESS_STATUS = PARTIAL_SERIES;
62         private static final int PARTIAL_FAILURE_STATUS = PARTIAL_SERIES + 1;
63
64         @Value("${lcm.model.package:org.openecomp.appc.client.lcm.model}")
65         private String lcmModelPackage;
66
67         public LifeCycleManagerStateful createService() throws AppcClientException, IOException {
68                 AppcLifeCycleManagerServiceFactory factory = AppcClientServiceFactoryProvider
69                                 .getFactory(AppcLifeCycleManagerServiceFactory.class);
70                 return factory.createLifeCycleManagerStateful(new ApplicationContext(), getLCMProperties());
71         }
72
73         /**
74          * @param action
75          * @return
76          * @throws ClassNotFoundException
77          * @throws InstantiationException
78          * @throws IllegalAccessException
79          */
80         public Object getInput(String action) {
81                 try {
82                         return getInputClass(action).newInstance();
83                 } catch (IllegalAccessException | InstantiationException e) {
84                         throw new RuntimeException(
85                                         String.format("%s : %s", "Unable to instantiate viable LCM Kit input class for action", action), e);
86                 }
87         }
88
89         /**
90          * @param action
91          * @return
92          * @throws ClassNotFoundException
93          */
94         public Method getAPIMethod(String action, LifeCycleManagerStateful lcmStateful, boolean async) {
95                 Method[] methods = lcmStateful.getClass().getMethods();
96                 for (Method method : methods) {
97                         if (method.getName().equalsIgnoreCase(action)) {
98                                 Class<?>[] methodParameterTypes = method.getParameterTypes();
99                                 if (methodParameterTypes.length > 0) {
100                                         if (getInputClass(action).equals(methodParameterTypes[0])) {
101                                                 if (async) {
102                                                         if (methodParameterTypes.length == 2
103                                                                         && ResponseHandler.class.isAssignableFrom(methodParameterTypes[1])) {
104                                                                 return method;
105                                                         }
106                                                 } else if (methodParameterTypes.length == 1) {
107                                                         return method;
108                                                 }
109                                         }
110                                 }
111                         }
112                 }
113                 throw new RuntimeException(String.format("%s : %s, async=%b",
114                                 "Unable to derive viable LCM Kit API method for action", action, async));
115         }
116
117         public Method getCommonHeaderSetterMethod(String action) {
118                 return getBeanPropertyMethodFor(getInputClass(action), "commonHeader", true);
119         }
120
121         public Method getPayloadSetterMethod(String action) {
122                 return getBeanPropertyMethodFor(getInputClass(action), "payload", true);
123         }
124
125         public Status getStatusFromGenericResponse(Object response) {
126                 Method statusReader = getBeanPropertyMethodFor(response.getClass(), "status", false);
127                 if (statusReader != null) {
128                         try {
129                                 return (Status) statusReader.invoke(response);
130                         } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
131                                 throw new RuntimeException("Unable to obtain status from LCM Kit response", e);
132                         }
133                 }
134                 return new Status();
135         }
136         
137         public static StatusCategory getCategoryOf(Status status) {
138                 int codeSeries = status.getCode() - (status.getCode() % 100);
139                 switch (codeSeries) {
140                 case ACCEPT_SERIES:
141                         return StatusCategory.NORMAL;
142                 case ERROR_SERIES:
143                 case REJECT_SERIES:
144                         return StatusCategory.ERROR;
145                 case SUCCESS_SERIES:
146                         return status.getCode() == SUCCESS_STATUS ? StatusCategory.NORMAL : StatusCategory.ERROR;
147                 case PARTIAL_SERIES:
148                         switch (status.getCode()) {
149                         case PARTIAL_SUCCESS_STATUS:
150                                 return StatusCategory.NORMAL;
151                         case PARTIAL_FAILURE_STATUS:
152                                 return StatusCategory.ERROR;
153                         default:
154                                 return StatusCategory.WARNING;
155                         }
156                 default:
157                         return StatusCategory.WARNING;
158                 }
159         }
160         
161         public static boolean getFinalityOf(Status status) {
162                 int codeSeries = status.getCode() - (status.getCode() % 100);
163                 switch (codeSeries) {
164                 case ACCEPT_SERIES:
165                 case PARTIAL_SERIES:
166                         return false;
167                 case ERROR_SERIES:
168                 case REJECT_SERIES:
169                 case SUCCESS_SERIES:
170                         return true;
171                 default:
172                         return true;
173                 }
174         }
175
176         /**
177          * @return
178          * @throws IOException
179          */
180         private Properties getLCMProperties() throws IOException {
181                 Resource resource = new ClassPathResource("/lcm.properties");
182                 Properties properties = PropertiesLoaderUtils.loadProperties(resource);
183                 return properties;
184         }
185
186         private Method getBeanPropertyMethodFor(Class<?> clazz, String propertyName, boolean isWriter) {
187                 BeanInfo beanInfo;
188                 try {
189                         beanInfo = Introspector.getBeanInfo(clazz, Object.class);
190                 } catch (IntrospectionException e) {
191                         throw new RuntimeException(
192                                         String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
193                                                         clazz.getName(), propertyName, isWriter),
194                                         e);
195                 }
196                 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
197                 for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
198                         if (propertyDescriptor.getName().equals(propertyName)) {
199                                 return isWriter ? propertyDescriptor.getWriteMethod() : propertyDescriptor.getReadMethod();
200                         }
201                 }
202                 throw new RuntimeException(
203                                 String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
204                                                 clazz.getName(), propertyName, isWriter));
205         }
206
207         /**
208          * @param action
209          * @return
210          * @throws ClassNotFoundException
211          */
212         private Class<?> getInputClass(String action) {
213                 try {
214                         return Class.forName(lcmModelPackage + '.' + action + "Input");
215                 } catch (ClassNotFoundException e) {
216                         throw new RuntimeException(String.format("%s : %s using package : ",
217                                         "Unable to identify viable LCM Kit input class for action", action, lcmModelPackage), e);
218                 }
219         }
220         
221         public static enum StatusCategory { 
222             NORMAL("normal"),
223             WARNING("warning"),
224             ERROR("error");
225
226             private final String category;
227
228             private StatusCategory(final String category) {
229                 this.category = category;
230             } 
231
232             @Override 
233             public String toString() {
234                 return category;
235             } 
236         }
237         
238         public void logLCMMessage(Object message) throws JsonProcessingException {
239                 ObjectMapper objectMapper = new ObjectMapper();
240                 objectMapper.setSerializationInclusion(Include.NON_NULL);
241                 ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
242                 String inputAsJSON = writer.writeValueAsString(message);
243                 System.out.println("LCM Kit input message follows.");
244                 System.out.println(inputAsJSON);
245         }
246 }