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