Add SO APIs to Nokia VNFM adapter
[vfc/nfvo/driver/vnfm/svnfm.git] / nokiav2 / driver / src / main / java / org / onap / vfc / nfvo / driver / vnfm / svnfm / nokia / onap / core / SelfRegistrationManager.java
1 /*
2  * Copyright 2016-2017, Nokia Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core;
18
19 import com.google.common.annotations.VisibleForTesting;
20 import com.google.common.collect.BiMap;
21 import com.google.common.collect.HashBiMap;
22 import com.nokia.cbam.lcn.v32.api.SubscriptionsApi;
23 import com.nokia.cbam.lcn.v32.model.*;
24 import java.util.ArrayList;
25 import java.util.HashSet;
26 import java.util.Set;
27 import org.onap.msb.model.MicroServiceFullInfo;
28 import org.onap.msb.model.MicroServiceInfo;
29 import org.onap.msb.model.Node;
30 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.VnfmInfoProvider;
31 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.MultiException;
32 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider;
33 import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.Constants;
34 import org.onap.vnfmdriver.model.VnfmInfo;
35 import org.slf4j.Logger;
36 import org.springframework.beans.factory.annotation.Value;
37
38 import static com.nokia.cbam.lcn.v32.model.SubscriptionAuthentication.TypeEnum.NONE;
39 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.buildFatalFailure;
40 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions;
41 import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCN_API_VERSION;
42 import static org.slf4j.LoggerFactory.getLogger;
43
44 /**
45  * Responsible for registering the driver in the core systems.
46  */
47 public class SelfRegistrationManager {
48     public static final String DRIVER_VERSION = "v1";
49     public static final String SERVICE_NAME = "NokiaSVNFM";
50     public static final String SWAGGER_API_DEFINITION = "self.swagger.json";
51     private static Logger logger = getLogger(SelfRegistrationManager.class);
52     private final MsbApiProvider msbApiProvider;
53     private final CbamRestApiProvider cbamRestApiProvider;
54     private final VnfmInfoProvider vnfmInfoProvider;
55     private final BiMap<String, String> vnfmIdToSubscriptionId = HashBiMap.create();
56     @Value("${driverMsbExternalIp}")
57     private String driverMsbExternalIp;
58     @Value("${driverVnfmExternalIp}")
59     private String driverVnfmExternalIp;
60     @Value("${server.port}")
61     private String driverPort;
62     @Value("${skipLcnSubscription}")
63     private boolean skipLcnSubscription;
64     @Value("${skipSelfRegistration}")
65     private boolean skipSelfRegistration;
66     private volatile boolean ready = false;
67
68     SelfRegistrationManager(VnfmInfoProvider vnfmInfoProvider, MsbApiProvider msbApiProvider, CbamRestApiProvider cbamRestApiProvider) {
69         this.cbamRestApiProvider = cbamRestApiProvider;
70         this.msbApiProvider = msbApiProvider;
71         this.vnfmInfoProvider = vnfmInfoProvider;
72     }
73
74     /**
75      * Register the driver in micro-service bus and subscribe to LCNs from CBAM
76      */
77     public void register() {
78         //the order is important (only publish it's existence after the subscription has been created)
79         if(!skipLcnSubscription) {
80             subscribeToLcns();
81         }
82         try {
83             if(!skipSelfRegistration) {
84                 registerMicroService();
85             }
86         } catch (RuntimeException e) {
87             if(!skipLcnSubscription) {
88                 deleteSubscriptions();
89             }
90             throw e;
91         }
92         ready = true;
93     }
94
95     /**
96      * De-register the VNFM driver from the micro-service bus
97      */
98     public void deRegister() {
99         if(!skipSelfRegistration) {
100             try {
101                 logger.info("Cancelling micro service registration");
102                 msbApiProvider.getMsbApi().deleteMicroService(SERVICE_NAME, DRIVER_VERSION, null, null).blockingFirst();
103             } catch (Exception e) {
104                 //ONAP throws 500 internal server error, but deletes the micro service
105                 boolean serviceFoundAfterDelete = false;
106                 try {
107                     msbApiProvider.getMsbApi().getMicroService_0(SERVICE_NAME, DRIVER_VERSION, null, null, null, null, null);
108                     serviceFoundAfterDelete = true;
109                 } catch (Exception e1) {
110                     logger.info("Unable to query " + SERVICE_NAME + " from MSB (so the service was successfully deleted)", e1);
111                     // the micro service was deleted (even though 500 HTTP code was reported)
112                 }
113                 if (serviceFoundAfterDelete) {
114                     throw buildFatalFailure(logger, "Unable to deRegister Nokia VNFM driver", e);
115                 }
116             }
117         }
118         if(!skipLcnSubscription) {
119             deleteSubscriptions();
120         }
121     }
122
123     /**
124      * Subscribes to LCN if not yet subscribed
125      *
126      * @param vnfmId the identifier of the VNFM
127      */
128     @VisibleForTesting
129     public void assureSubscription(String vnfmId) {
130         if (!vnfmIdToSubscriptionId.containsKey(vnfmId) && !skipLcnSubscription) {
131             subscribeToLcn(vnfmId);
132         }
133     }
134
135     /**
136      * @return the swagger API definition
137      */
138     public byte[] getSwaggerApiDefinition() {
139         return systemFunctions().loadFile(SWAGGER_API_DEFINITION);
140     }
141
142     /**
143      * @param subscriptionId the identifier of the subscription
144      * @return the identifier of the VNFM for the subscription
145      */
146     public String getVnfmId(String subscriptionId) {
147         return vnfmIdToSubscriptionId.inverse().get(subscriptionId);
148     }
149
150     private String getDriverVnfmUrl() {
151         return "http://" + driverVnfmExternalIp + ":" + driverPort + Constants.BASE_URL;
152     }
153
154     private void deleteSubscriptions() {
155         Set<Exception> exceptions = new HashSet<>();
156         for (String vnfmId : vnfmIdToSubscriptionId.keySet()) {
157             try {
158                 deleteSubscription(vnfmId);
159             } catch (Exception e) {
160                 exceptions.add(e);
161                 logger.warn("Unable to delete subscription for the " + vnfmId);
162             }
163         }
164         if (!exceptions.isEmpty()) {
165             throw new MultiException("Unable to delete some of the subscriptions", exceptions);
166         }
167     }
168
169     private void deleteSubscription(String vnfmId) {
170         logger.info("Deleting CBAM LCN subscription");
171         SubscriptionsApi lcnApi = cbamRestApiProvider.getCbamLcnApi(vnfmId);
172         try {
173             String callbackUrl = getDriverVnfmUrl() + Constants.LCN_URL;
174             for (Subscription subscription : lcnApi.subscriptionsGet(NOKIA_LCN_API_VERSION).blockingFirst()) {
175                 if (subscription.getCallbackUrl().equals(callbackUrl)) {
176                     logger.info("Deleting subscription with {} identifier", subscription.getId());
177                     lcnApi.subscriptionsSubscriptionIdDelete(subscription.getId(), NOKIA_LCN_API_VERSION).blockingFirst();
178                 }
179             }
180         } catch (Exception e) {
181             throw buildFatalFailure(logger, "Unable to delete CBAM LCN subscription", e);
182         }
183     }
184
185     private MicroServiceFullInfo registerMicroService() {
186         logger.info("Registering micro service");
187         MicroServiceInfo microServiceInfo = new MicroServiceInfo();
188         microServiceInfo.setUrl(Constants.BASE_URL);
189         //the PATH should not be set
190         microServiceInfo.setProtocol(MicroServiceInfo.ProtocolEnum.REST);
191         microServiceInfo.setVisualRange(MicroServiceInfo.VisualRangeEnum._1);
192         microServiceInfo.setServiceName(SERVICE_NAME);
193         microServiceInfo.setVersion(DRIVER_VERSION);
194         microServiceInfo.setEnableSsl(false);
195         Node node = new Node();
196         microServiceInfo.setNodes(new ArrayList<>());
197         microServiceInfo.getNodes().add(node);
198         node.setIp(driverMsbExternalIp);
199         node.setPort(driverPort);
200         node.setTtl("0");
201         try {
202             return msbApiProvider.getMsbApi().addMicroService(microServiceInfo, true, false).blockingFirst();
203         } catch (Exception e) {
204             throw buildFatalFailure(logger, "Unable to register Nokia VNFM driver", e);
205         }
206     }
207
208     private void subscribeToLcns() {
209         for (String vnfmId : vnfmInfoProvider.getVnfms()) {
210             subscribeToLcn(vnfmId);
211         }
212     }
213
214     private void subscribeToLcn(String vnfmId) {
215         String callbackUrl = getDriverVnfmUrl() + Constants.LCN_URL;
216         VnfmInfo vnfmInfo = vnfmInfoProvider.getVnfmInfo(vnfmId);
217         VnfmUrls vnfmUrls = GenericExternalSystemInfoProvider.convert(vnfmInfo);
218         logger.info("Subscribing to CBAM LCN {} with callback to {}", vnfmUrls.getLcnUrl(), callbackUrl);
219         SubscriptionsApi lcnApi = cbamRestApiProvider.getCbamLcnApi(vnfmId);
220         try {
221             for (Subscription subscription : lcnApi.subscriptionsGet(NOKIA_LCN_API_VERSION).blockingFirst()) {
222                 if (subscription.getCallbackUrl().equals(callbackUrl)) {
223                     logger.warn("The subscription with {} identifier has the same callback URL", subscription.getId());
224                     vnfmIdToSubscriptionId.put(vnfmId, subscription.getId());
225                     return;
226                 }
227             }
228             CreateSubscriptionRequest request = new CreateSubscriptionRequest();
229             request.setFilter(new SubscriptionFilter());
230             request.getFilter().setNotificationTypes(new ArrayList<>());
231             request.getFilter().getNotificationTypes().add(VnfNotificationType.VNFLIFECYCLECHANGENOTIFICATION);
232             request.setCallbackUrl(callbackUrl);
233             request.getFilter().addOperationTypesItem(OperationType.HEAL);
234             request.getFilter().addOperationTypesItem(OperationType.INSTANTIATE);
235             request.getFilter().addOperationTypesItem(OperationType.SCALE);
236             request.getFilter().addOperationTypesItem(OperationType.TERMINATE);
237             SubscriptionAuthentication subscriptionAuthentication = new SubscriptionAuthentication();
238             subscriptionAuthentication.setType(NONE);
239             request.setAuthentication(subscriptionAuthentication);
240             Subscription createdSubscription = lcnApi.subscriptionsPost(request, NOKIA_LCN_API_VERSION).blockingFirst();
241             logger.info("Subscribed to LCN with {} identifier", createdSubscription.getId());
242             vnfmIdToSubscriptionId.put(vnfmId, createdSubscription.getId());
243         } catch (Exception e) {
244             throw buildFatalFailure(logger, "Unable to subscribe to CBAM LCN", e);
245         }
246     }
247
248     /**
249      * @return is the component ready to serve requests
250      */
251     public boolean isReady() {
252         return ready;
253     }
254 }