Add Tests for VNF Package Mgmt - Subscribe and Notify
[integration/csit.git] / plans / so / integration-etsi-testing / so-simulators / vnfm-simulator / vnfm-service / src / main / java / org / onap / so / svnfm / simulator / controller / SubscriptionNotificationController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so.svnfm.simulator.controller;
22
23 import javax.ws.rs.core.MediaType;
24 import com.google.gson.Gson;
25 import com.google.gson.GsonBuilder;
26 import com.google.gson.JsonObject;
27 import com.google.gson.JsonParser;
28 import com.google.gson.TypeAdapter;
29 import com.google.gson.stream.JsonReader;
30 import com.google.gson.stream.JsonWriter;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.InlineResponse201;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.PkgmSubscriptionRequest;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication.AuthTypeEnum;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthenticationParamsBasic;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageChangeNotification;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
38 import org.onap.so.svnfm.simulator.constants.Constant;
39 import org.onap.so.svnfm.simulator.services.SubscriptionManager;
40 import org.onap.so.svnfm.simulator.services.providers.VnfPkgOnboardingNotificationCacheServiceProviderImpl;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.beans.factory.annotation.Value;
45 import org.springframework.http.HttpStatus;
46 import org.springframework.http.ResponseEntity;
47 import org.springframework.web.bind.annotation.GetMapping;
48 import org.springframework.web.bind.annotation.PathVariable;
49 import org.springframework.web.bind.annotation.PostMapping;
50 import org.springframework.web.bind.annotation.RequestBody;
51 import org.springframework.web.bind.annotation.RequestMapping;
52 import org.springframework.web.bind.annotation.RestController;
53 import java.io.IOException;
54 import java.time.LocalDateTime;
55 import java.time.format.DateTimeFormatter;
56 import java.util.Optional;
57
58 /**
59  * @author Eoin Hanan (eoin.hanan@est.tech)
60  * @author Andrew Lamb (andrew.a.lamb@est.tech)
61  *
62  */
63 @RestController
64 @RequestMapping(path = Constant.PACKAGE_MANAGEMENT_BASE_URL, produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
65 public class SubscriptionNotificationController {
66
67     private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotificationController.class);
68     private final Gson gson;
69     @Autowired
70     private SubscriptionManager subscriptionManager;
71     @Autowired
72     private VnfPkgOnboardingNotificationCacheServiceProviderImpl vnfPkgOnboardingNotificationCacheServiceProvider;
73
74     @Autowired
75     public SubscriptionNotificationController() {
76         this.gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
77     }
78
79     @Value("${spring.security.usercredentials[0].username}")
80     private String username;
81     @Value("${spring.security.usercredentials[0].password}")
82     private String password;
83
84     @GetMapping(produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
85     public ResponseEntity<Void> testEndpoint() {
86         logger.info("Testing SubscriptionNotification Endpoint");
87         return ResponseEntity.noContent().build();
88     }
89
90     /**
91      * Send subscription request
92      *
93      * @param pkgmSubscriptionRequest The subscription request
94      * @return
95      */
96     @PostMapping(value = Constant.SUBSCRIPTION_ENDPOINT, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
97     public ResponseEntity<?> subscribeForNotifications(@RequestBody final PkgmSubscriptionRequest pkgmSubscriptionRequest){
98         logger.info("Vnf Package Subscription Request received:\n{}", pkgmSubscriptionRequest);
99
100         if(pkgmSubscriptionRequest.getCallbackUri()==null){
101             logger.info("Subscription Request does not include call back URI ");
102             pkgmSubscriptionRequest.setCallbackUri(Constant.PACKAGE_MANAGEMENT_BASE_URL + Constant.NOTIFICATION_ENDPOINT);
103         }
104
105         if(pkgmSubscriptionRequest.getAuthentication()==null) {
106             pkgmSubscriptionRequest.setAuthentication(new SubscriptionsAuthentication()
107                 .addAuthTypeItem(AuthTypeEnum.BASIC)
108                 .paramsBasic(new SubscriptionsAuthenticationParamsBasic().userName(username).password(password)));
109
110         }
111         logger.info("Final Request being sent:\n{}", pkgmSubscriptionRequest);
112
113         final InlineResponse201 response = subscriptionManager.createSubscription(pkgmSubscriptionRequest);
114         logger.info("Response is:\n{}", response);
115
116         return ResponseEntity.ok().body(response);
117     }
118
119     /**
120      * Endpoint to receive VNF package notifications
121      *
122      * @param notification The notification received
123      * @return
124      */
125     @PostMapping(value = Constant.NOTIFICATION_ENDPOINT, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
126     public ResponseEntity<?> postVnfPackageNotification(@RequestBody final Object notification){
127         logger.info("Vnf Notification received:\n{}", notification);
128         final String notificationString = gson.toJson(notification);
129         addNotificationObjectToCache(notificationString);
130         return ResponseEntity.noContent().build();
131     }
132
133     /**
134      * Testing endpoint for checking that notifications have been received
135      *
136      * @param vnfPkgId
137      * @return
138      */
139     @GetMapping(value = Constant.NOTIFICATION_CACHE_TEST_ENDPOINT)
140     public ResponseEntity<?> getVnfPackageNotification(@PathVariable("vnfPkgId") final String vnfPkgId) {
141         logger.info("Getting notification with vnfPkgId: {}", vnfPkgId);
142         final Optional<VnfPackageOnboardingNotification> optionalVnfPackageOnboardingNotification =
143                 vnfPkgOnboardingNotificationCacheServiceProvider.getVnfPkgOnboardingNotification(vnfPkgId);
144         if(optionalVnfPackageOnboardingNotification.isPresent()) {
145             VnfPackageOnboardingNotification vnfPackageOnboardingNotification =
146                     optionalVnfPackageOnboardingNotification.get();
147             logger.info("Return notification with vnfPkgId: {} and body {}", vnfPkgId, vnfPackageOnboardingNotification);
148             return ResponseEntity.ok().body(vnfPackageOnboardingNotification);
149         }
150         final String errorMessage = "No notification found with vnfPkgId: " + vnfPkgId;
151         logger.error(errorMessage);
152         return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorMessage);
153     }
154
155     private void addNotificationObjectToCache(final String notification) {
156         logger.info("addNotificationObjectToCache(): {}", notification);
157         final String notificationType = getNotificationType(notification);
158         if (VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION.getValue()
159                 .equals(notificationType)) {
160             final VnfPackageOnboardingNotification pkgOnboardingNotification =
161                     gson.fromJson(notification, VnfPackageOnboardingNotification.class);
162             logger.info("Onboarding notification received:\n{}", pkgOnboardingNotification);
163             final String vnfPkgId = pkgOnboardingNotification.getVnfPkgId();
164             vnfPkgOnboardingNotificationCacheServiceProvider.addVnfPkgOnboardingNotification(vnfPkgId, pkgOnboardingNotification);
165         } else if (VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue()
166                 .equals(notificationType)) {
167             final VnfPackageChangeNotification pkgChangeNotification =
168                     gson.fromJson(notification, VnfPackageChangeNotification.class);
169             logger.info("Change notification received:\n{}", pkgChangeNotification);
170         } else {
171             final String errorMessage = "An error occurred.  Notification type not supported for: " + notificationType;
172             logger.error(errorMessage);
173             throw new RuntimeException(errorMessage);
174         }
175     }
176
177     private String getNotificationType(final String notification) {
178         try {
179             logger.info("getNotificationType() notification: {}", notification);
180             final JsonParser parser = new JsonParser();
181             final JsonObject element = (JsonObject) parser.parse(notification);
182             return element.get("notificationType").getAsString();
183         } catch (final Exception e) {
184             logger.error("An error occurred processing notificiation: {}", e.getMessage());
185         }
186         throw new RuntimeException(
187                 "Unable to parse notification type in object \n" + notification);
188     }
189
190     public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
191
192         private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
193
194         @Override
195         public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException {
196             if (localDateTime == null) {
197                 out.nullValue();
198             } else {
199                 out.value(FORMATTER.format(localDateTime));
200             }
201         }
202
203         @Override
204         public LocalDateTime read(final JsonReader in) throws IOException {
205             switch (in.peek()) {
206                 case NULL:
207                     in.nextNull();
208                     return null;
209                 default:
210                     final String dateTime = in.nextString();
211                     return LocalDateTime.parse(dateTime, FORMATTER);
212             }
213         }
214     }
215
216 }