20093be6a446220e84e8f18891ff05f022f7823a
[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.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.time.Instant;
26 import java.util.Optional;
27 import java.util.Properties;
28 import java.util.UUID;
29 import java.util.concurrent.ConcurrentHashMap;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.factory.annotation.Autowired;
33 import org.springframework.core.env.Environment;
34 import org.springframework.stereotype.Component;
35 import org.onap.appc.client.lcm.api.AppcClientServiceFactoryProvider;
36 import org.onap.appc.client.lcm.api.AppcLifeCycleManagerServiceFactory;
37 import org.onap.appc.client.lcm.api.ApplicationContext;
38 import org.onap.appc.client.lcm.api.LifeCycleManagerStateful;
39 import org.onap.appc.client.lcm.exceptions.AppcClientException;
40 import org.onap.appc.client.lcm.model.Action;
41 import org.onap.appc.client.lcm.model.ActionIdentifiers;
42 import org.onap.appc.client.lcm.model.CommonHeader;
43 import org.onap.appc.client.lcm.model.Flags;
44 import org.onap.appc.client.lcm.model.Flags.Force;
45 import org.onap.appc.client.lcm.model.Flags.Mode;
46 import org.onap.so.adapters.appc.orchestrator.client.ApplicationControllerOrchestratorException;
47 import org.onap.so.adapters.appc.orchestrator.client.ApplicationControllerSupport;
48 import org.onap.so.adapters.appc.orchestrator.client.StatusCategory;
49 import org.onap.appc.client.lcm.model.Payload;
50 import org.onap.appc.client.lcm.model.Status;
51 import org.onap.appc.client.lcm.model.ZULU;
52
53 @Component
54 public class ApplicationControllerClient {
55
56     @Autowired
57     public Environment env;
58
59     public static final String DEFAULT_CONTROLLER_TYPE = "APPC";
60
61     private static final String CLIENT_NAME = "MSO";
62
63     private static final String API_VER = "2.00";
64     private static final String ORIGINATOR_ID = "MSO";
65     private static final int FLAGS_TTL = 65000;
66     private static Logger logger = LoggerFactory.getLogger(ApplicationControllerClient.class);
67
68     @Autowired
69     private ApplicationControllerSupport appCSupport;
70
71     // APPC gave us an API where the controllerType is configured in the
72     // client object, which is not what we asked for. We asked for an API
73     // in which the client would have additional methods that could take
74     // the controllerType as a parameter, so that we would not need to
75     // maintain multiple client objects. This map should be removed when
76     // the (hopefully short-term) controllerType becomes obsolete.
77
78     private String controllerType = DEFAULT_CONTROLLER_TYPE;
79
80     private static ConcurrentHashMap<String, LifeCycleManagerStateful> appCClients = new ConcurrentHashMap<>();
81
82     /**
83      * Creates an ApplicationControllerClient for the specified controller type.
84      *
85      * @param controllerType the controller type: "appc" or "sdnc".
86      */
87     public void setControllerType(String controllerType) {
88         if (controllerType == null) {
89             controllerType = DEFAULT_CONTROLLER_TYPE;
90         }
91         this.controllerType = controllerType.toUpperCase();
92     }
93
94     /**
95      * Gets the controller type.
96      *
97      * @return the controllertype
98      */
99     public String getControllerType() {
100         return controllerType;
101     }
102
103     /**
104      * Returns the AppC client object associated with this ApplicationControllerClient. AppC client objects are shared
105      * objects. One is created if it does not exist.
106      *
107      * @return the client object, or null if creation failed
108      */
109     public LifeCycleManagerStateful getAppCClient() {
110         return appCClients.computeIfAbsent(controllerType, k -> createAppCClient(k));
111     }
112
113     protected LifeCycleManagerStateful createAppCClient(String controllerType) {
114
115         try {
116             if (controllerType == null) {
117                 controllerType = DEFAULT_CONTROLLER_TYPE;
118             }
119             controllerType = controllerType.toUpperCase();
120             return AppcClientServiceFactoryProvider.getFactory(AppcLifeCycleManagerServiceFactory.class)
121                     .createLifeCycleManagerStateful(new ApplicationContext(), getLCMProperties(controllerType));
122         } catch (AppcClientException e) {
123             logger.error("Error in getting LifeCycleManagerStateful: {}", e.getMessage(), e);
124             // This null value will cause NullPointerException when used later.
125             // Error handling could certainly be improved here.
126             return null;
127         }
128     }
129
130     public Status vnfCommand(Action action, String requestId, String vnfId, Optional<String> vserverId,
131             Optional<String> request, String controllerType, ApplicationControllerCallback listener)
132             throws ApplicationControllerOrchestratorException {
133         this.setControllerType(controllerType);
134         Status status;
135         ActionIdentifiers actionIdentifiers = new ActionIdentifiers();
136         actionIdentifiers.setVnfId(vnfId);
137         if (vserverId.isPresent()) {
138             actionIdentifiers.setVserverId(vserverId.get());
139         }
140         Payload payload = null;
141         if (request.isPresent()) {
142             payload = new Payload(request.get());
143
144         }
145         status = runCommand(action, actionIdentifiers, payload, requestId, listener);
146         if (appCSupport.getCategoryOf(status).equals(StatusCategory.ERROR)) {
147             throw new ApplicationControllerOrchestratorException(status.getMessage(), status.getCode());
148         } else {
149             return status;
150         }
151     }
152
153
154     public Status runCommand(Action action, org.onap.appc.client.lcm.model.ActionIdentifiers actionIdentifiers,
155             org.onap.appc.client.lcm.model.Payload payload, String requestID, ApplicationControllerCallback listener)
156             throws ApplicationControllerOrchestratorException {
157         Status status;
158         Object requestObject;
159         requestObject = createRequest(action, actionIdentifiers, payload, requestID);
160         appCSupport.logLCMMessage(requestObject);
161         LifeCycleManagerStateful client = getAppCClient();
162         Method lcmMethod = appCSupport.getAPIMethod(action.name(), client, true);
163         try {
164             Object response = lcmMethod.invoke(client, requestObject, listener);
165             if (response != null) {
166                 return appCSupport.getStatusFromGenericResponse(response);
167             } else {
168                 return new Status();
169             }
170         } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
171             throw new RuntimeException(String.format("%s : %s", "Unable to invoke action", action.toString()), e);
172         }
173     }
174
175     protected Properties getLCMProperties() {
176         return getLCMProperties("appc");
177     }
178
179     protected Properties getLCMProperties(String controllerType) {
180         Properties properties = new Properties();
181
182         properties.put("topic.read", this.env.getProperty("appc.client.topic.read.name"));
183         properties.put("topic.write", this.env.getProperty("appc.client.topic.write"));
184         properties.put("SDNC-topic.read", this.env.getProperty("appc.client.topic.sdnc.read"));
185         properties.put("SDNC-topic.write", this.env.getProperty("appc.client.topic.sdnc.write"));
186         properties.put("topic.read.timeout", this.env.getProperty("appc.client.topic.read.timeout"));
187         properties.put("client.response.timeout", this.env.getProperty("appc.client.response.timeout"));
188         properties.put("poolMembers", this.env.getProperty("appc.client.poolMembers"));
189         properties.put("controllerType", controllerType);
190         properties.put("client.key", this.env.getProperty("appc.client.key"));
191         properties.put("client.secret", this.env.getProperty("appc.client.secret"));
192         properties.put("client.name", CLIENT_NAME);
193         properties.put("service", this.env.getProperty("appc.client.service"));
194         return properties;
195     }
196
197     public Object createRequest(Action action, ActionIdentifiers identifier, Payload payload, String requestId) {
198         Object requestObject = appCSupport.getInput(action.name());
199
200
201         try {
202             CommonHeader commonHeader = buildCommonHeader(requestId);
203             requestObject.getClass().getDeclaredMethod("setCommonHeader", CommonHeader.class).invoke(requestObject,
204                     commonHeader);
205             requestObject.getClass().getDeclaredMethod("setAction", Action.class).invoke(requestObject, action);
206             requestObject.getClass().getDeclaredMethod("setActionIdentifiers", ActionIdentifiers.class)
207                     .invoke(requestObject, identifier);
208             if (payload != null) {
209                 logger.info("payload in RunCommand: " + payload.getValue());
210                 requestObject.getClass().getDeclaredMethod("setPayload", Payload.class).invoke(requestObject, payload);
211             }
212         } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
213             logger.error("Error building Appc request", e);
214         }
215         return requestObject;
216     }
217
218     private CommonHeader buildCommonHeader(String requestId) {
219         CommonHeader commonHeader = new CommonHeader();
220         commonHeader.setApiVer(API_VER);
221         commonHeader.setOriginatorId(ORIGINATOR_ID);
222         commonHeader.setRequestId(requestId == null ? UUID.randomUUID().toString() : requestId);
223         commonHeader.setSubRequestId(UUID.randomUUID().toString());
224         Flags flags = new Flags();
225         String flagsMode = "NORMAL";
226         Mode mode = Mode.valueOf(flagsMode);
227         flags.setMode(mode);
228         String flagsForce = "FALSE";
229         Force force = Force.valueOf(flagsForce);
230         flags.setForce(force);
231         flags.setTtl(FLAGS_TTL);
232         commonHeader.setFlags(flags);
233         Instant timestamp = Instant.now();
234         ZULU zulu = new ZULU(timestamp.toString());
235         commonHeader.setTimestamp(zulu);
236         return commonHeader;
237     }
238
239     public Flags createRequestFlags() {
240         Flags flags = new Flags();
241         flags.setTtl(6000);
242         return flags;
243     }
244 }