[SO] Release so 1.13.0 image
[so.git] / bpmn / MSOCommonBPMN / src / main / java / org / onap / so / 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.onap.so.client.appc;
22
23 import java.beans.BeanInfo;
24 import java.beans.IntrospectionException;
25 import java.beans.Introspector;
26 import java.beans.PropertyDescriptor;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import org.onap.appc.client.lcm.api.LifeCycleManagerStateful;
30 import org.onap.appc.client.lcm.api.ResponseHandler;
31 import org.onap.appc.client.lcm.model.Status;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import com.fasterxml.jackson.annotation.JsonInclude.Include;
35 import com.fasterxml.jackson.core.JsonProcessingException;
36 import com.fasterxml.jackson.databind.ObjectMapper;
37 import com.fasterxml.jackson.databind.ObjectWriter;
38
39 public class ApplicationControllerSupport {
40
41     private static final int ACCEPT_SERIES = 100;
42     private static final int ERROR_SERIES = 200;
43     private static final int REJECT_SERIES = 300;
44     private static final int SUCCESS_SERIES = 400;
45     private static final int SUCCESS_STATUS = SUCCESS_SERIES;
46     private static final int PARTIAL_SERIES = 500;
47     private static final int PARTIAL_SUCCESS_STATUS = PARTIAL_SERIES;
48     private static final int PARTIAL_FAILURE_STATUS = PARTIAL_SERIES + 1;
49
50     private static Logger logger = LoggerFactory.getLogger(ApplicationControllerSupport.class);
51     private String lcmModelPackage = "org.onap.appc.client.lcm.model";
52
53     /**
54      * @param action
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 Status getStatusFromGenericResponse(Object response) {
98         Method statusReader = getBeanPropertyMethodFor(response.getClass(), "status", false);
99         if (statusReader != null) {
100             try {
101                 return (Status) statusReader.invoke(response);
102             } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
103                 logger.error("Unable to obtain status from LCM Kit response", e);
104             }
105         }
106         return new Status();
107     }
108
109     public static StatusCategory getCategoryOf(Status status) {
110         int codeSeries = status.getCode() - (status.getCode() % 100);
111         switch (codeSeries) {
112             case ACCEPT_SERIES:
113                 return StatusCategory.NORMAL;
114             case ERROR_SERIES:
115             case REJECT_SERIES:
116                 return StatusCategory.ERROR;
117             case SUCCESS_SERIES:
118                 return status.getCode() == SUCCESS_STATUS ? StatusCategory.NORMAL : StatusCategory.ERROR;
119             case PARTIAL_SERIES:
120                 switch (status.getCode()) {
121                     case PARTIAL_SUCCESS_STATUS:
122                         return StatusCategory.NORMAL;
123                     case PARTIAL_FAILURE_STATUS:
124                         return StatusCategory.ERROR;
125                     default:
126                         return StatusCategory.WARNING;
127                 }
128             default:
129                 return StatusCategory.WARNING;
130         }
131     }
132
133     public static boolean getFinalityOf(Status status) {
134         int codeSeries = status.getCode() - (status.getCode() % 100);
135         switch (codeSeries) {
136             case ACCEPT_SERIES:
137             case PARTIAL_SERIES:
138                 return false;
139             case ERROR_SERIES:
140             case REJECT_SERIES:
141             case SUCCESS_SERIES:
142                 return true;
143             default:
144                 return true;
145         }
146     }
147
148     private Method getBeanPropertyMethodFor(Class<?> clazz, String propertyName, boolean isWriter) {
149         BeanInfo beanInfo;
150         try {
151             beanInfo = Introspector.getBeanInfo(clazz, Object.class);
152         } catch (IntrospectionException e) {
153             throw new RuntimeException(
154                     String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
155                             clazz.getName(), propertyName, isWriter),
156                     e);
157         }
158         PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
159         for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
160             if (propertyDescriptor.getName().equals(propertyName)) {
161                 return isWriter ? propertyDescriptor.getWriteMethod() : propertyDescriptor.getReadMethod();
162             }
163         }
164         throw new RuntimeException(
165                 String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
166                         clazz.getName(), propertyName, isWriter));
167     }
168
169     /**
170      * @param action
171      * @return
172      * @throws ClassNotFoundException
173      */
174     private Class<?> getInputClass(String action) {
175         try {
176             return Class.forName(lcmModelPackage + '.' + action + "Input");
177         } catch (ClassNotFoundException e) {
178             throw new RuntimeException(String.format("%s : %s using package : %s",
179                     "Unable to identify viable LCM Kit input class for action", action, lcmModelPackage), e);
180         }
181     }
182
183     public enum StatusCategory {
184         NORMAL("normal"), WARNING("warning"), ERROR("error");
185
186         private final String category;
187
188         private StatusCategory(final String category) {
189             this.category = category;
190         }
191
192         @Override
193         public String toString() {
194             return category;
195         }
196     }
197
198     public void logLCMMessage(Object message) {
199         ObjectMapper objectMapper = new ObjectMapper();
200         objectMapper.setSerializationInclusion(Include.NON_NULL);
201         ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
202         String inputAsJSON;
203         try {
204             inputAsJSON = writer.writeValueAsString(message);
205             logger.info("LCM Kit input message follows: {}", inputAsJSON);
206         } catch (JsonProcessingException e) {
207             logger.error("Error in logging LCM Message", e);
208         }
209     }
210 }