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