add junit coverage for SvnfmService
[so.git] / vnfm-simulator / vnfm-service / src / main / java / org / onap / svnfm / simulator / services / OperationProgressor.java
1 package org.onap.svnfm.simulator.services;
2
3 import com.google.gson.JsonObject;
4 import com.google.gson.JsonParser;
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.net.URL;
10 import java.nio.charset.StandardCharsets;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.UUID;
14 import javax.net.ssl.HttpsURLConnection;
15 import javax.ws.rs.core.MediaType;
16 import org.apache.commons.codec.binary.Base64;
17 import org.modelmapper.ModelMapper;
18 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiResponse;
19 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest;
20 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsAddResources;
21 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinks;
22 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinksVnfLcmOpOcc;
23 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201;
24 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiClient;
25 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiException;
26 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.api.DefaultApi;
27 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs;
28 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum;
29 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks;
30 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationStatusEnum;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationTypeEnum;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationEnum;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo;
38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
39 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
40 import org.onap.svnfm.simulator.config.ApplicationConfig;
41 import org.onap.svnfm.simulator.model.VnfOperation;
42 import org.onap.svnfm.simulator.model.Vnfds;
43 import org.onap.svnfm.simulator.repository.VnfOperationRepository;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.springframework.core.io.ClassPathResource;
47
48 public abstract class OperationProgressor implements Runnable {
49
50     private static final Logger LOGGER = LoggerFactory.getLogger(OperationProgressor.class);
51     private static final String CERTIFICATE_TO_TRUST = "so-vnfm-adapter.crt.pem";
52
53     protected final VnfOperation operation;
54     protected final SvnfmService svnfmService;
55     private final VnfOperationRepository vnfOperationRepository;
56     private final ApplicationConfig applicationConfig;
57     protected final Vnfds vnfds;
58     private final SubscriptionService subscriptionService;
59     private final DefaultApi notificationClient;
60     private final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi grantClient;
61
62     public OperationProgressor(final VnfOperation operation, final SvnfmService svnfmService,
63             final VnfOperationRepository vnfOperationRepository, final ApplicationConfig applicationConfig,
64             final Vnfds vnfds, final SubscriptionService subscriptionService) {
65         this.operation = operation;
66         this.svnfmService = svnfmService;
67         this.vnfOperationRepository = vnfOperationRepository;
68         this.applicationConfig = applicationConfig;
69         this.vnfds = vnfds;
70         this.subscriptionService = subscriptionService;
71
72         final ApiClient apiClient = new ApiClient();
73         String callBackUrl = subscriptionService.getSubscriptions().iterator().next().getCallbackUri();
74         callBackUrl = callBackUrl.substring(0, callBackUrl.indexOf("/lcn/"));
75         apiClient.setBasePath(callBackUrl);
76         apiClient.setSslCaCert(getCertificateToTrust());
77         notificationClient = new DefaultApi(apiClient);
78
79         final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient grantApiClient =
80                 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient();
81         grantApiClient.setBasePath(callBackUrl);
82         grantApiClient.setSslCaCert(getCertificateToTrust());
83         grantClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi(grantApiClient);
84     }
85
86     private InputStream getCertificateToTrust() {
87         try {
88             return new ClassPathResource(CERTIFICATE_TO_TRUST).getInputStream();
89         } catch (final IOException exception) {
90             LOGGER.error("Error reading certificate to trust, https calls to VNFM adapter will fail", exception);
91             return null;
92         }
93     }
94
95     @Override
96     public void run() {
97         try {
98             final VnfLcmOperationOccurrenceNotification notificationOfStarting =
99                     buildNotification(NotificationStatusEnum.START, OperationStateEnum.STARTING);
100             sendNotification(notificationOfStarting);
101
102             sleep(2000);
103             setState(InlineResponse200.OperationStateEnum.PROCESSING);
104             final VnfLcmOperationOccurrenceNotification notificationOfProcessing =
105                     buildNotification(NotificationStatusEnum.START, OperationStateEnum.PROCESSING);
106             sendNotification(notificationOfProcessing);
107
108
109             final GrantRequest grantRequest = buildGrantRequest();
110             final InlineResponse201 grantResponse = sendGrantRequest(grantRequest);
111             final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> vnfcs = handleGrantResponse(grantResponse);
112
113             svnfmService.getVnf(operation.getVnfInstanceId()).getInstantiatedVnfInfo();
114
115             sleep(10000);
116             setState(InlineResponse200.OperationStateEnum.COMPLETED);
117             final VnfLcmOperationOccurrenceNotification notificationOfCompleted =
118                     buildNotification(NotificationStatusEnum.RESULT, OperationStateEnum.COMPLETED);
119             notificationOfCompleted.setAffectedVnfcs(getVnfcs(vnfcs));
120
121             sendNotification(notificationOfCompleted);
122         } catch (final Exception exception) {
123             LOGGER.error("Error in OperationProgressor ", exception);
124         }
125
126     }
127
128     private void sleep(final long milliSeconds) {
129         try {
130             Thread.sleep(milliSeconds);
131         } catch (final InterruptedException e) {
132             operation.setOperationState(InlineResponse200.OperationStateEnum.FAILED);
133             // Restore interrupted state
134             Thread.currentThread().interrupt();
135         }
136     }
137
138     private void setState(final InlineResponse200.OperationStateEnum state) {
139         LOGGER.info("Setting state to {} for operation {}", state, operation.getId());
140         operation.setOperationState(state);
141         vnfOperationRepository.save(operation);
142     }
143
144     private VnfLcmOperationOccurrenceNotification buildNotification(final NotificationStatusEnum status,
145             final OperationStateEnum operationState) {
146         final VnfLcmOperationOccurrenceNotification notification = new VnfLcmOperationOccurrenceNotification();
147         notification.setId(UUID.randomUUID().toString());
148         notification.setNotificationType(NotificationTypeEnum.VNFLCMOPERATIONOCCURRENCENOTIFICATION);
149         notification.setNotificationStatus(status);
150         notification.setOperationState(operationState);
151         notification.setOperation(OperationEnum.fromValue(operation.getOperation().toString()));
152         notification.setVnfInstanceId(operation.getVnfInstanceId());
153         notification.setVnfLcmOpOccId(operation.getId());
154
155         final LcnVnfLcmOperationOccurrenceNotificationLinks links = new LcnVnfLcmOperationOccurrenceNotificationLinks();
156         final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance vnfInstanceLink =
157                 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
158         vnfInstanceLink.setHref(getVnfLink());
159         links.setVnfInstance(vnfInstanceLink);
160
161
162         final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance operationLink =
163                 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
164         operationLink.setHref(getOperationLink());
165         links.setVnfLcmOpOcc(operationLink);
166
167         notification.setLinks(links);
168
169         return notification;
170     }
171
172     private List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> getVnfcs(
173             final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> instantiatedVnfcs) {
174         final List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> vnfcs = new ArrayList<>();
175         if (instantiatedVnfcs != null) {
176             for (final InlineResponse201InstantiatedVnfInfoVnfcResourceInfo instantiatedVnfc : instantiatedVnfcs) {
177                 LOGGER.info("VNFC TO BE CONVERTED: {}", instantiatedVnfc);
178                 final ModelMapper mapper = new ModelMapper();
179                 final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc =
180                         mapper.map(instantiatedVnfc, LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.class);
181                 LOGGER.info("VNFC FROM CONVERSION: {}", vnfc);
182                 vnfc.setChangeType(getVnfcChangeType());
183                 vnfcs.add(vnfc);
184             }
185         }
186         return vnfcs;
187     }
188
189     private void sendNotification(final VnfLcmOperationOccurrenceNotification notification) {
190         LOGGER.info("Sending notification: {}", notification);
191         try {
192             final SubscriptionsAuthenticationParamsBasic subscriptionAuthentication =
193                     subscriptionService.getSubscriptions().iterator().next().getAuthentication().getParamsBasic();
194             final String auth =
195                     subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword();
196             final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
197             String authHeader = "Basic " + new String(encodedAuth);
198
199             notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification,
200                     MediaType.APPLICATION_JSON, authHeader);
201         } catch (final ApiException exception) {
202             LOGGER.error("Error sending notification: " + notification, exception);
203             LOGGER.error("Response code: {}, body: {}, basePath: {}", exception.getCode(), exception.getResponseBody(),
204                     notificationClient.getApiClient().getBasePath());
205
206         }
207     }
208
209
210     public GrantRequest buildGrantRequest() {
211         final GrantRequest grantRequest = new GrantRequest();
212         grantRequest.setVnfInstanceId(operation.getVnfInstanceId());
213         final String vnfdId = svnfmService.getVnf(operation.getVnfInstanceId()).getVnfdId();
214         grantRequest.setVnfdId(vnfdId);
215         grantRequest.setAddResources(getAddResources(vnfdId));
216         grantRequest.setRemoveResources(getRemoveResources(vnfdId));
217         grantRequest.setVnfLcmOpOccId(operation.getId());
218         grantRequest
219                 .setOperation(org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest.OperationEnum
220                         .fromValue(operation.getOperation().getValue()));
221         grantRequest.setIsAutomaticInvocation(false);
222
223         final GrantsLinksVnfLcmOpOcc vnfInstanceLink = new GrantsLinksVnfLcmOpOcc();
224         vnfInstanceLink.setHref(getVnfLink());
225         final GrantsLinksVnfLcmOpOcc operationInstanceLink = new GrantsLinksVnfLcmOpOcc();
226         operationInstanceLink.setHref(getOperationLink());
227         final GrantsLinks links = new GrantsLinks();
228         links.setVnfInstance(vnfInstanceLink);
229         links.setVnfLcmOpOcc(operationInstanceLink);
230         grantRequest.setLinks(links);
231         return grantRequest;
232     }
233
234     protected abstract List<GrantsAddResources> getAddResources(final String vnfdId);
235
236     protected abstract List<GrantsAddResources> getRemoveResources(final String vnfdId);
237
238     protected abstract List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> handleGrantResponse(
239             InlineResponse201 grantResponse);
240
241     protected abstract ChangeTypeEnum getVnfcChangeType();
242
243     private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) {
244         LOGGER.info("Sending grant request: {}", grantRequest);
245         try {
246
247             final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication =
248                     subscriptionService.getSubscriptions().iterator().next().getAuthentication()
249                             .getParamsOauth2ClientCredentials();
250             final String authHeader =
251                     "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication);
252
253             final ApiResponse<InlineResponse201> response = grantClient.grantsPostWithHttpInfo(grantRequest,
254                     MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader);
255             LOGGER.info("Grant Response: {}", response);
256             return response.getData();
257         } catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) {
258             LOGGER.error("Error sending notification: " + grantRequest, exception);
259             return null;
260         }
261     }
262
263     private String getVnfLink() {
264         return getLinkBaseUrl() + "/vnf_instances/" + operation.getVnfInstanceId();
265     }
266
267     private String getOperationLink() {
268         return getLinkBaseUrl() + "/vnf_lcm_op_occs/" + operation.getId();
269     }
270
271     private String getLinkBaseUrl() {
272         return applicationConfig.getBaseUrl() + "/vnflcm/v1";
273     }
274
275     private String getToken(final ApiClient apiClient,
276             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
277         final String basePath = apiClient.getBasePath().substring(0, apiClient.getBasePath().indexOf("/so/"));
278         final String tokenUrl = basePath + "/oauth/token?grant_type=client_credentials";
279
280         try {
281             URL url = new URL(tokenUrl);
282             HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
283             connection.setRequestMethod("POST");
284             final String authorizationHeader = getAuthorizationHeader(oauthClientCredentials);
285             connection.addRequestProperty("Authorization", authorizationHeader);
286
287             connection.connect();
288
289             return getResponse(connection).get("access_token").getAsString();
290
291         } catch (IOException exception) {
292             LOGGER.error("Error getting token", exception);
293             return null;
294         }
295     }
296
297     private String getAuthorizationHeader(
298             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
299         final String auth = oauthClientCredentials.getClientId() + ":" + oauthClientCredentials.getClientPassword();
300         final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
301         return "Basic " + new String(encodedAuth);
302     }
303
304     private JsonObject getResponse(HttpsURLConnection connection) throws IOException {
305         BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
306         String line, data = "";
307         while ((line = in.readLine()) != null) {
308             data += line;
309         }
310         in.close();
311         connection.getInputStream().close();
312
313         JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
314         return jsonObject;
315     }
316
317 }