2  * ============LICENSE_START=======================================================
 
   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
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  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=========================================================
 
  21 package org.onap.so.adapters.appc.orchestrator.client;
 
  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;
 
  43 public class ApplicationControllerSupport {
 
  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;
 
  54     private static Logger logger = LoggerFactory.getLogger(ApplicationControllerSupport.class);
 
  55     private String lcmModelPackage = "org.onap.appc.client.lcm.model";
 
  60      * @throws ClassNotFoundException
 
  61      * @throws InstantiationException
 
  62      * @throws IllegalAccessException
 
  64     public Object getInput(String action) {
 
  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);
 
  76      * @throws ClassNotFoundException
 
  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])) {
 
  86                             if (methodParameterTypes.length == 2
 
  87                                     && ResponseHandler.class.isAssignableFrom(methodParameterTypes[1])) {
 
  90                         } else if (methodParameterTypes.length == 1) {
 
  97         throw new RuntimeException(String.format("%s : %s, async=%b",
 
  98                 "Unable to derive viable LCM Kit API method for action", action, async));
 
 101     public Status getStatusFromGenericResponse(Object response) {
 
 102         Method statusReader = getBeanPropertyMethodFor(response.getClass(), "status", false);
 
 103         if (statusReader != null) {
 
 105                 return (Status) statusReader.invoke(response);
 
 106             } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
 
 107                 logger.error("Unable to obtain status from LCM Kit response", e);
 
 113     public StatusCategory getCategoryOf(Status status) {
 
 114         int codeSeries = status.getCode() - (status.getCode() % 100);
 
 115         switch (codeSeries) {
 
 117                 return StatusCategory.NORMAL;
 
 120                 return StatusCategory.ERROR;
 
 122                 return status.getCode() == SUCCESS_STATUS ? StatusCategory.NORMAL : StatusCategory.ERROR;
 
 124                 switch (status.getCode()) {
 
 125                     case PARTIAL_SUCCESS_STATUS:
 
 126                         return StatusCategory.NORMAL;
 
 127                     case PARTIAL_FAILURE_STATUS:
 
 128                         return StatusCategory.ERROR;
 
 130                         return StatusCategory.WARNING;
 
 133                 return StatusCategory.WARNING;
 
 137     public boolean getFinalityOf(Status status) {
 
 138         int codeSeries = status.getCode() - (status.getCode() % 100);
 
 139         switch (codeSeries) {
 
 152     private Method getBeanPropertyMethodFor(Class<?> clazz, String propertyName, boolean isWriter) {
 
 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),
 
 162         PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
 
 163         for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
 
 164             if (propertyDescriptor.getName().equals(propertyName)) {
 
 165                 return isWriter ? propertyDescriptor.getWriteMethod() : propertyDescriptor.getReadMethod();
 
 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));
 
 176      * @throws ClassNotFoundException
 
 178     private Class<?> getInputClass(String action) {
 
 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);
 
 188     public void logLCMMessage(Object message) {
 
 189         ObjectMapper objectMapper = new ObjectMapper();
 
 190         objectMapper.setSerializationInclusion(Include.NON_NULL);
 
 191         ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
 
 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);
 
 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;