Replaced all tabs with spaces in java and pom.xml
[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.springframework.stereotype.Component;
30 import org.onap.appc.client.lcm.api.LifeCycleManagerStateful;
31 import org.onap.appc.client.lcm.api.ResponseHandler;
32 import org.onap.appc.client.lcm.model.Status;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import com.fasterxml.jackson.annotation.JsonInclude.Include;
36 import com.fasterxml.jackson.core.JsonProcessingException;
37 import com.fasterxml.jackson.databind.ObjectMapper;
38 import com.fasterxml.jackson.databind.ObjectWriter;
39 import org.springframework.stereotype.Service;
40
41 public class ApplicationControllerSupport {
42
43     private static final int ACCEPT_SERIES = 100;
44     private static final int ERROR_SERIES = 200;
45     private static final int REJECT_SERIES = 300;
46     private static final int SUCCESS_SERIES = 400;
47     private static final int SUCCESS_STATUS = SUCCESS_SERIES;
48     private static final int PARTIAL_SERIES = 500;
49     private static final int PARTIAL_SUCCESS_STATUS = PARTIAL_SERIES;
50     private static final int PARTIAL_FAILURE_STATUS = PARTIAL_SERIES + 1;
51
52     private static Logger logger = LoggerFactory.getLogger(ApplicationControllerSupport.class);
53     private String lcmModelPackage = "org.onap.appc.client.lcm.model";
54
55     /**
56      * @param action
57      * @return
58      * @throws ClassNotFoundException
59      * @throws InstantiationException
60      * @throws IllegalAccessException
61      */
62     public Object getInput(String action) {
63         try {
64             return getInputClass(action).newInstance();
65         } catch (IllegalAccessException | InstantiationException e) {
66             throw new RuntimeException(
67                     String.format("%s : %s", "Unable to instantiate viable LCM Kit input class for action", action), e);
68         }
69     }
70
71     /**
72      * @param action
73      * @return
74      * @throws ClassNotFoundException
75      */
76     public Method getAPIMethod(String action, LifeCycleManagerStateful lcmStateful, boolean async) {
77         Method[] methods = lcmStateful.getClass().getMethods();
78         for (Method method : methods) {
79             if (method.getName().equalsIgnoreCase(action)) {
80                 Class<?>[] methodParameterTypes = method.getParameterTypes();
81                 if (methodParameterTypes.length > 0) {
82                     if (getInputClass(action).equals(methodParameterTypes[0])) {
83                         if (async) {
84                             if (methodParameterTypes.length == 2
85                                     && ResponseHandler.class.isAssignableFrom(methodParameterTypes[1])) {
86                                 return method;
87                             }
88                         } else if (methodParameterTypes.length == 1) {
89                             return method;
90                         }
91                     }
92                 }
93             }
94         }
95         throw new RuntimeException(String.format("%s : %s, async=%b",
96                 "Unable to derive viable LCM Kit API method for action", action, async));
97     }
98
99     public Status getStatusFromGenericResponse(Object response) {
100         Method statusReader = getBeanPropertyMethodFor(response.getClass(), "status", false);
101         if (statusReader != null) {
102             try {
103                 return (Status) statusReader.invoke(response);
104             } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
105                 logger.error("Unable to obtain status from LCM Kit response", e);
106             }
107         }
108         return new Status();
109     }
110
111     public static StatusCategory getCategoryOf(Status status) {
112         int codeSeries = status.getCode() - (status.getCode() % 100);
113         switch (codeSeries) {
114             case ACCEPT_SERIES:
115                 return StatusCategory.NORMAL;
116             case ERROR_SERIES:
117             case REJECT_SERIES:
118                 return StatusCategory.ERROR;
119             case SUCCESS_SERIES:
120                 return status.getCode() == SUCCESS_STATUS ? StatusCategory.NORMAL : StatusCategory.ERROR;
121             case PARTIAL_SERIES:
122                 switch (status.getCode()) {
123                     case PARTIAL_SUCCESS_STATUS:
124                         return StatusCategory.NORMAL;
125                     case PARTIAL_FAILURE_STATUS:
126                         return StatusCategory.ERROR;
127                     default:
128                         return StatusCategory.WARNING;
129                 }
130             default:
131                 return StatusCategory.WARNING;
132         }
133     }
134
135     public static boolean getFinalityOf(Status status) {
136         int codeSeries = status.getCode() - (status.getCode() % 100);
137         switch (codeSeries) {
138             case ACCEPT_SERIES:
139             case PARTIAL_SERIES:
140                 return false;
141             case ERROR_SERIES:
142             case REJECT_SERIES:
143             case SUCCESS_SERIES:
144                 return true;
145             default:
146                 return true;
147         }
148     }
149
150     private Method getBeanPropertyMethodFor(Class<?> clazz, String propertyName, boolean isWriter) {
151         BeanInfo beanInfo;
152         try {
153             beanInfo = Introspector.getBeanInfo(clazz, Object.class);
154         } catch (IntrospectionException e) {
155             throw new RuntimeException(
156                     String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
157                             clazz.getName(), propertyName, isWriter),
158                     e);
159         }
160         PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
161         for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
162             if (propertyDescriptor.getName().equals(propertyName)) {
163                 return isWriter ? propertyDescriptor.getWriteMethod() : propertyDescriptor.getReadMethod();
164             }
165         }
166         throw new RuntimeException(
167                 String.format("Unable to produce bean property method for class : %s, property : %s, writer=%b",
168                         clazz.getName(), propertyName, isWriter));
169     }
170
171     /**
172      * @param action
173      * @return
174      * @throws ClassNotFoundException
175      */
176     private Class<?> getInputClass(String action) {
177         try {
178             return Class.forName(lcmModelPackage + '.' + action + "Input");
179         } catch (ClassNotFoundException e) {
180             throw new RuntimeException(String.format("%s : %s using package : %s",
181                     "Unable to identify viable LCM Kit input class for action", action, lcmModelPackage), e);
182         }
183     }
184
185     public enum StatusCategory {
186         NORMAL("normal"), WARNING("warning"), ERROR("error");
187
188         private final String category;
189
190         private StatusCategory(final String category) {
191             this.category = category;
192         }
193
194         @Override
195         public String toString() {
196             return category;
197         }
198     }
199
200     public void logLCMMessage(Object message) {
201         ObjectMapper objectMapper = new ObjectMapper();
202         objectMapper.setSerializationInclusion(Include.NON_NULL);
203         ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
204         String inputAsJSON;
205         try {
206             inputAsJSON = writer.writeValueAsString(message);
207             logger.info("LCM Kit input message follows: {}", inputAsJSON);
208         } catch (JsonProcessingException e) {
209             logger.error("Error in logging LCM Message", e);
210         }
211     }
212 }