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