commit etree topology
[unimgr.git] / legato-api / src / main / java / org / opendaylight / unimgr / mef / legato / LegatoServiceController.java
1 /*
2  * Copyright (c) 2018 Xoriant Corporation and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.unimgr.mef.legato;
10
11 import com.google.common.base.Optional;
12
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.concurrent.Future;
17
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
23 import org.opendaylight.unimgr.mef.legato.dao.EVCDao;
24 import org.opendaylight.unimgr.mef.legato.util.LegatoConstants;
25 import org.opendaylight.unimgr.mef.legato.util.LegatoUtils;
26 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.legato.services.rev171215.MefServices;
27 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.legato.services.rev171215.mef.services.CarrierEthernet;
28 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.legato.services.rev171215.mef.services.carrier.ethernet.SubscriberServices;
29 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.legato.services.rev171215.mef.services.carrier.ethernet.subscriber.services.Evc;
30 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.legato.services.rev171215.mef.services.carrier.ethernet.subscriber.services.EvcKey;
31 import org.opendaylight.yang.gen.v1.urn.mef.yang.mef.types.rev171215.EvcIdType;
32 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.CreateConnectivityServiceInput;
33 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.CreateConnectivityServiceOutput;
34 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.DeleteConnectivityServiceInput;
35 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.DeleteConnectivityServiceInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.TapiConnectivityService;
37 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.UpdateConnectivityServiceInput;
38 import org.opendaylight.yang.gen.v1.urn.onf.otcc.yang.tapi.connectivity.rev180307.UpdateConnectivityServiceOutput;
39 import org.opendaylight.yangtools.concepts.ListenerRegistration;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 /**
46  * @author santanu.de@xoriant.com
47  */
48
49 public class LegatoServiceController extends UnimgrDataTreeChangeListener<Evc> {
50
51     public LegatoServiceController(DataBroker dataBroker) {
52         super(dataBroker);
53         registerListener();
54     }
55
56     private static final Logger LOG = LoggerFactory
57             .getLogger(LegatoServiceController.class);
58
59     private static final InstanceIdentifier<Evc> EVC_IID = InstanceIdentifier
60             .builder(MefServices.class).child(CarrierEthernet.class)
61             .child(SubscriberServices.class).child(Evc.class).build();
62
63     private static final InstanceIdentifier<SubscriberServices> EVC_IID_OPERATIONAL = InstanceIdentifier
64             .builder(MefServices.class).child(CarrierEthernet.class)
65             .child(SubscriberServices.class).build();
66
67     private ListenerRegistration<LegatoServiceController> dataTreeChangeListenerRegistration;
68
69     private static final Map<String, String> EVC_UUIDMAP = new HashMap<String, String>();
70
71     private TapiConnectivityService prestoConnectivityService;
72
73     public void setPrestoConnectivityService(
74             TapiConnectivityService prestoConnectivityService) {
75         this.prestoConnectivityService = prestoConnectivityService;
76     }
77
78     public void registerListener() {
79         LOG.info("Initializing LegatoServiceController:int() ");
80
81         assert prestoConnectivityService != null;
82
83         dataTreeChangeListenerRegistration = dataBroker
84                 .registerDataTreeChangeListener(new DataTreeIdentifier<Evc>(
85                         LogicalDatastoreType.CONFIGURATION, EVC_IID), this);
86     }
87
88     public void close() throws Exception {
89         if (dataTreeChangeListenerRegistration != null) {
90             dataTreeChangeListenerRegistration.close();
91         }
92     }
93
94     @Override
95     public void add(DataTreeModification<Evc> newDataObject) {
96         LOG.info("  Node Added  " + newDataObject.getRootNode().getIdentifier());
97
98         Optional<Evc> optionalEvc =
99                 LegatoUtils.readEvc(dataBroker, LogicalDatastoreType.CONFIGURATION, newDataObject
100                         .getRootPath().getRootIdentifier());
101
102         if (optionalEvc.isPresent()) {
103             addNode(optionalEvc.get());
104         }
105     }
106
107     @Override
108     public void remove(DataTreeModification<Evc> removedDataObject) {
109         LOG.info("  Node removed  "
110                 + removedDataObject.getRootNode().getIdentifier());
111
112         deleteNode(removedDataObject.getRootNode().getDataBefore());
113     }
114
115     @Override
116     public void update(DataTreeModification<Evc> modifiedDataObject) {
117         LOG.info("  Node modified  "
118                 + modifiedDataObject.getRootNode().getIdentifier());
119         Optional<Evc> optionalEvc = LegatoUtils.readEvc(dataBroker,
120                 LogicalDatastoreType.CONFIGURATION, modifiedDataObject
121                         .getRootPath().getRootIdentifier());
122
123         if (optionalEvc.isPresent()) {
124             updateNode(optionalEvc.get());
125         }
126
127     }
128
129     private void addNode(Evc evc) {
130         LOG.info(" inside addNode()");
131
132         try {
133             assert evc != null;
134             createConnection(evc);
135
136         } catch (Exception ex) {
137             LOG.error("error: ", ex);
138         }
139
140         LOG.info(" ********** END addNode() ****************** ");
141
142     }
143
144     private void updateNode(Evc evc) {
145         LOG.info(" inside updateNode()");
146
147         try {
148             assert evc != null;
149             updateConnection(evc);
150
151         } catch (Exception ex) {
152             LOG.error("error: ", ex);
153         }
154
155         LOG.info(" ********** END updateNode() ****************** ");
156
157     }
158
159     private void deleteNode(Evc evc) {
160         LOG.info(" inside deleteNode()");
161
162         try {
163             assert evc != null;
164             deleteConnection(evc.getEvcId().getValue());
165         } catch (Exception ex) {
166             LOG.error("error: ", ex);
167         }
168
169         LOG.info(" ********** END deleteNode() ****************** ");
170     }
171
172     private void createConnection(Evc evc) {
173         LOG.info("inside createConnection()");
174
175         try {
176             EVCDao evcDao =  LegatoUtils.parseNodes(evc);
177             assert evcDao != null
178                     && evcDao.getUniList() != null && evcDao.getConnectionType() != null;
179             LOG.info(" connection-type :{}, svc-type :{}", evcDao.getConnectionType(), evcDao.getSvcType());
180
181             if (!evcDao.getSvcType().equalsIgnoreCase("other")) {
182                 if ((evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EPL)
183                         || evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EVPL))
184                         && (!evcDao.getConnectionType().replace("-", "")
185                                 .equalsIgnoreCase(LegatoConstants.POINTTOPOINT))) {
186                     LOG.info(
187                             "connection-type in payload should be point-to-point when svc-type is epl/evpl");
188                 } else if ((evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EPLAN)
189                         || evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EVPLAN))
190                         && (!evcDao.getConnectionType().replace("-", "")
191                                 .equalsIgnoreCase(LegatoConstants.MULTIPOINTTOMULTIPOINT))) {
192                     LOG.info(
193                             "connection-type in payload should be multipoint-to-multipoint when svc-type is eplan/evplan");
194                 } else {
195                     callCreateConnectionService(
196                             LegatoUtils.buildCreateConnectivityServiceInput(evcDao),
197                             evcDao.getEvcId());
198                 }
199             } else {
200                 LOG.info("svc-type in payload should be epl, evpl, eplan, evplan");
201             }
202
203         } catch (Exception ex) {
204             LOG.error("Error in createConnection(). Err: ", ex);
205         }
206
207     }
208
209     private void updateConnection(Evc evc) {
210         LOG.info("inside updateConnection()");
211
212         try {
213             EVCDao evcDao = LegatoUtils.parseNodes(evc);
214             assert evcDao != null && evcDao.getUniList() != null
215                     && evcDao.getConnectionType() != null;
216             LOG.info(" connection-type :{}, svc-type :{} ", evcDao.getConnectionType(), evcDao.getSvcType());
217
218             if (!evcDao.getSvcType().equalsIgnoreCase("other")) {
219                 if ((evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EPL)
220                         || evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EVPL))
221                         && (!evcDao.getConnectionType().replace("-", "")
222                                 .equalsIgnoreCase(LegatoConstants.POINTTOPOINT))) {
223                     LOG.info(
224                             "connection-type in payload should be point-to-point when svc-type is epl/evpl");
225                 } else if ((evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EPLAN)
226                         || evcDao.getSvcType().equalsIgnoreCase(LegatoConstants.EVPLAN))
227                         && (!evcDao.getConnectionType().replace("-", "")
228                                 .equalsIgnoreCase(LegatoConstants.MULTIPOINTTOMULTIPOINT))) {
229                     LOG.info(
230                             "connection-type in payload should be multipoint-to-multipoint when svc-type is eplan/evplan");
231                 } else {
232                     if (EVC_UUIDMAP.containsKey(evcDao.getEvcId())) {
233                         LOG.info("Update UUID: {} of EVC Id: {} ",
234                                 EVC_UUIDMAP.get(evcDao.getEvcId()), evcDao.getEvcId());
235
236                         List<String> uniList = evcDao.getUniList();
237                         assert uniList != null && uniList.size() > 0;
238
239                         for (String uniStr : uniList) {
240                             callUpdateConnectionService(
241                                     LegatoUtils.buildUpdateConnectivityServiceInput(evcDao, uniStr,
242                                             EVC_UUIDMAP.get(evcDao.getEvcId())),
243                                     evcDao.getEvcId());
244                         }
245                     } else {
246                         LOG.info("UUID does not exists for EVC Id : {}", evcDao.getEvcId());
247                     }
248                 }
249             } else {
250                 LOG.info("svc-type in payload should be epl, evpl, eplan, evplan");
251             }
252         } catch (Exception ex) {
253
254             LOG.error("Error in updateConnection(). Err: ", ex);
255         }
256
257     }
258
259     private void deleteConnection(String evcId) {
260         LOG.info(" inside deleteConnection()");
261         try {
262
263             assert EVC_UUIDMAP != null;
264
265             if (EVC_UUIDMAP.containsKey(evcId)) {
266                 LOG.info("Deleting UUID: {} of EVC Id: {} ",
267                         EVC_UUIDMAP.get(evcId), evcId);
268                 // on successful deletion of service, remove respective element from evc_UUIDMap
269                 if (callDeleteConnectionService(new DeleteConnectivityServiceInputBuilder()
270                         .setServiceIdOrName(EVC_UUIDMAP.get(evcId)).build())) {
271                     EVC_UUIDMAP.remove(evcId);
272                 }
273
274                 // delete EVC node from OPERATIONAL DB
275                 LegatoUtils.deleteFromOperationalDB(InstanceIdentifier
276                         .create(MefServices.class).child(CarrierEthernet.class)
277                         .child(SubscriberServices.class)
278                         .child(Evc.class, new EvcKey(new EvcIdType(evcId))), dataBroker);
279
280             } else {
281                 LOG.info("UUID does not exists for EVC Id : {}", evcId);
282             }
283
284         } catch (Exception ex) {
285             LOG.error("error: ", ex);
286         }
287
288         LOG.info(" ********** END deleteConnection() ****************** ");
289     }
290
291     private void callCreateConnectionService(
292             CreateConnectivityServiceInput createConnServiceInput, String evcId) {
293         try {
294             Future<RpcResult<CreateConnectivityServiceOutput>> response = this.prestoConnectivityService
295                     .createConnectivityService(createConnServiceInput);
296
297             if (response.get().isSuccessful()) {
298                 LOG.info("call Success = {}, response = {} ", response.get()
299                         .isSuccessful(), response.get().getResult());
300                 LOG.info("evcId = {}, UUID = {} ", evcId, response.get()
301                         .getResult().getService().getUuid().getValue());
302
303                 EVC_UUIDMAP.put(evcId, response.get().getResult().getService()
304                         .getUuid().getValue());
305
306                 LOG.info("======== {} ", EVC_UUIDMAP.toString());
307
308                 Optional<Evc> optionalEvc = LegatoUtils.readEvc(
309                         dataBroker,
310                         LogicalDatastoreType.CONFIGURATION,
311                         InstanceIdentifier
312                                 .create(MefServices.class)
313                                 .child(CarrierEthernet.class)
314                                 .child(SubscriberServices.class)
315                                 .child(Evc.class,
316                                         new EvcKey(new EvcIdType(evcId))));
317
318                 // Add Node in OPERATIONAL DB
319                 if (optionalEvc.isPresent()) {
320                     LegatoUtils.updateEvcInOperationalDB(optionalEvc.get(), EVC_IID_OPERATIONAL,
321                             dataBroker);
322                 }
323
324             } else {
325                 LOG.info("call Failure = {} >> {} ", response.get()
326                         .isSuccessful(), response.get().getErrors());
327             }
328         } catch (Exception ex) {
329             LOG.error("Error in callCreateConnectionService(). Err: ", ex);
330         }
331     }
332
333     private void callUpdateConnectionService(
334             UpdateConnectivityServiceInput updateConnectivityServiceInput,
335             String evcId) {
336         try {
337             Future<RpcResult<UpdateConnectivityServiceOutput>> response = this.prestoConnectivityService
338                     .updateConnectivityService(updateConnectivityServiceInput);
339
340             if (response.get().isSuccessful()) {
341                 LOG.info("call Success = {}, response = {} ", response.get()
342                         .isSuccessful(), response.get().getResult());
343
344                 Optional<Evc> optionalEvc = LegatoUtils.readEvc(
345                         dataBroker,
346                         LogicalDatastoreType.CONFIGURATION,
347                         InstanceIdentifier
348                                 .create(MefServices.class)
349                                 .child(CarrierEthernet.class)
350                                 .child(SubscriberServices.class)
351                                 .child(Evc.class,
352                                         new EvcKey(new EvcIdType(evcId))));
353
354                 // update EVC Node in OPERATIONAL DB
355                 if (optionalEvc.isPresent()) {
356                     LegatoUtils.deleteFromOperationalDB(InstanceIdentifier
357                             .create(MefServices.class)
358                             .child(CarrierEthernet.class)
359                             .child(SubscriberServices.class)
360                             .child(Evc.class, new EvcKey(new EvcIdType(evcId))), dataBroker);
361
362                     LegatoUtils.updateEvcInOperationalDB(optionalEvc.get(), EVC_IID_OPERATIONAL,  dataBroker);
363                 }
364
365             } else {
366                 LOG.info("call Failure = {} >> {} ", response.get()
367                         .isSuccessful(), response.get().getErrors());
368             }
369         } catch (Exception ex) {
370
371             LOG.error("Error in UpdateConnectivityServiceInput(). Err: ", ex);
372         }
373     }
374
375     private boolean callDeleteConnectionService(
376             DeleteConnectivityServiceInput deleteConnectivityServiceInput) {
377         try {
378             this.prestoConnectivityService
379                     .deleteConnectivityService(deleteConnectivityServiceInput);
380             return true;
381
382         } catch (Exception ex) {
383             LOG.error("Fail to call callDeleteConnectionService(). Err: ", ex);
384             return false;
385         }
386     }
387 }