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