clean OTN renderer code
[transportpce.git] / renderer / src / main / java / org / opendaylight / transportpce / renderer / provisiondevice / DeviceRendererServiceImpl.java
1 /*
2  * Copyright © 2017 AT&T 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 package org.opendaylight.transportpce.renderer.provisiondevice;
9
10 import com.google.common.collect.Sets;
11 import com.google.common.util.concurrent.FluentFuture;
12 import java.util.ArrayList;
13 import java.util.LinkedList;
14 import java.util.List;
15 import java.util.Optional;
16 import java.util.Set;
17 import java.util.concurrent.ConcurrentLinkedQueue;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.ForkJoinPool;
20 import java.util.concurrent.ForkJoinTask;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.ReadTransaction;
28 import org.opendaylight.mdsal.binding.api.WriteTransaction;
29 import org.opendaylight.mdsal.common.api.CommitInfo;
30 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
31 import org.opendaylight.transportpce.common.StringConstants;
32 import org.opendaylight.transportpce.common.Timeouts;
33 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
34 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
35 import org.opendaylight.transportpce.common.mapping.PortMapping;
36 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaceException;
37 import org.opendaylight.transportpce.common.openroadminterfaces.OpenRoadmInterfaces;
38 import org.opendaylight.transportpce.renderer.openroadminterface.OpenRoadmInterfaceFactory;
39 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServiceListTopology;
40 import org.opendaylight.transportpce.renderer.provisiondevice.servicepath.ServicePathDirection;
41 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.ServiceNodelist;
42 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.service.nodelist.NodelistBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.service.nodelist.NodelistKey;
44 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev200128.network.nodes.Mapping;
45 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsInput;
46 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsOutput;
47 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.CreateOtsOmsOutputBuilder;
48 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.RendererRollbackInput;
49 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.RendererRollbackOutput;
50 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.RendererRollbackOutputBuilder;
51 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.ServicePathInput;
52 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.ServicePathOutput;
53 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.ServicePathOutputBuilder;
54 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.renderer.rollback.output.FailedToRollback;
55 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.renderer.rollback.output.FailedToRollbackBuilder;
56 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.renderer.device.rev200128.renderer.rollback.output.FailedToRollbackKey;
57 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.Topology;
58 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev161014.OchAttributes.ModulationFormat;
59 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.ServiceList;
60 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services;
61 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesBuilder;
62 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesKey;
63 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterface;
64 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceBuilder;
65 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.node.interfaces.NodeInterfaceKey;
66 import org.opendaylight.yang.gen.v1.http.org.transportpce.common.types.rev200128.olm.renderer.input.Nodes;
67 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
70
71 public class DeviceRendererServiceImpl implements DeviceRendererService {
72     private static final Logger LOG = LoggerFactory.getLogger(DeviceRendererServiceImpl.class);
73     private final DataBroker dataBroker;
74     private final DeviceTransactionManager deviceTransactionManager;
75     private final OpenRoadmInterfaceFactory openRoadmInterfaceFactory;
76     private final OpenRoadmInterfaces openRoadmInterfaces;
77     private final CrossConnect crossConnect;
78     private final PortMapping portMapping;
79
80     public DeviceRendererServiceImpl(DataBroker dataBroker, DeviceTransactionManager deviceTransactionManager,
81             OpenRoadmInterfaceFactory openRoadmInterfaceFactory, OpenRoadmInterfaces openRoadmInterfaces,
82             CrossConnect crossConnect, PortMapping portMapping) {
83         this.dataBroker = dataBroker;
84         this.deviceTransactionManager = deviceTransactionManager;
85         this.openRoadmInterfaceFactory = openRoadmInterfaceFactory;
86         this.openRoadmInterfaces = openRoadmInterfaces;
87         this.crossConnect = crossConnect;
88         this.portMapping = portMapping;
89     }
90
91     @Override
92     public ServicePathOutput setupServicePath(ServicePathInput input, ServicePathDirection direction) {
93         List<Nodes> nodes = input.getNodes();
94         // Register node for suppressing alarms
95         if (!alarmSuppressionNodeRegistration(input)) {
96             LOG.warn("Alarm suppresion node registration failed!!!!");
97         }
98         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
99         Set<NodeInterface> nodeInterfaces = Sets.newConcurrentHashSet();
100         Set<String> nodesProvisioned = Sets.newConcurrentHashSet();
101         ServiceListTopology topology = new ServiceListTopology();
102         AtomicBoolean success = new AtomicBoolean(true);
103         ForkJoinPool forkJoinPool = new ForkJoinPool();
104         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
105             String nodeId = node.getNodeId();
106             LOG.info("Starting provisioning for node : {}", nodeId);
107             List<String> createdEthInterfaces = new ArrayList<>();
108             List<String> createdOtuInterfaces = new ArrayList<>();
109             List<String> createdOduInterfaces = new ArrayList<>();
110             List<String> createdOchInterfaces = new ArrayList<>();
111             List<String> createdConnections = new ArrayList<>();
112             int crossConnectFlag = 0;
113             try {
114                 // if the node is currently mounted then proceed
115                 if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
116                     String srcTp = node.getSrcTp();
117                     String destTp = node.getDestTp();
118                     Long waveNumber = input.getWaveNumber();
119                     if ((destTp != null) && destTp.contains(StringConstants.NETWORK_TOKEN)) {
120                         crossConnectFlag++;
121                         Mapping mapping = this.portMapping.getMapping(nodeId,destTp);
122                         String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
123                                 nodeId, destTp, waveNumber, ModulationFormat.DpQpsk);
124                         createdOchInterfaces.add(supportingOchInterface);
125                         String supportingOtuInterface = this.openRoadmInterfaceFactory
126                                 .createOpenRoadmOtu4Interface(nodeId, destTp, supportingOchInterface);
127                         createdOtuInterfaces.add(supportingOtuInterface);
128                         if (mapping != null && mapping.getXponderType() != null
129                             && (mapping.getXponderType().getIntValue() == 3
130                             || mapping.getXponderType().getIntValue() == 2)) {
131                             createdOduInterfaces.add(this.openRoadmInterfaceFactory
132                                 .createOpenRoadmOtnOdu4Interface(nodeId,destTp, supportingOtuInterface));
133                         } else {
134                             createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(nodeId,
135                                     destTp, supportingOtuInterface));
136                         }
137                     }
138                     if ((srcTp != null) && srcTp.contains(StringConstants.CLIENT_TOKEN)) {
139                         crossConnectFlag++;
140                         // create OpenRoadm Xponder Client Interfaces
141                         createdEthInterfaces.add(
142                             this.openRoadmInterfaceFactory.createOpenRoadmEthInterface(nodeId, srcTp));
143                     }
144                     if ((srcTp != null) && srcTp.contains(StringConstants.NETWORK_TOKEN)) {
145                         crossConnectFlag++;
146                         // create OpenRoadm Xponder Line Interfaces
147                         String supportingOchInterface = this.openRoadmInterfaceFactory.createOpenRoadmOchInterface(
148                                 nodeId, srcTp, waveNumber, ModulationFormat.DpQpsk);
149                         createdOchInterfaces.add(supportingOchInterface);
150                         String supportingOtuInterface = this.openRoadmInterfaceFactory
151                                 .createOpenRoadmOtu4Interface(nodeId, srcTp, supportingOchInterface);
152                         createdOtuInterfaces.add(supportingOtuInterface);
153                         createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(nodeId,
154                                 srcTp, supportingOtuInterface));
155                         Mapping mapping = this.portMapping.getMapping(nodeId,srcTp);
156                         if (mapping != null && mapping.getXponderType() != null
157                             && (mapping.getXponderType().getIntValue() == 3
158                             || mapping.getXponderType().getIntValue() == 2)) {
159                             createdOduInterfaces.add(this.openRoadmInterfaceFactory
160                                 .createOpenRoadmOtnOdu4Interface(nodeId, destTp, supportingOtuInterface));
161                         } else {
162                             createdOduInterfaces.add(this.openRoadmInterfaceFactory.createOpenRoadmOdu4Interface(nodeId,
163                                     destTp, supportingOtuInterface));
164                         }
165                     }
166                     if ((destTp != null) && destTp.contains(StringConstants.CLIENT_TOKEN)) {
167                         crossConnectFlag++;
168                         // create OpenRoadm Xponder Client Interfaces
169                         createdEthInterfaces.add(
170                             this.openRoadmInterfaceFactory.createOpenRoadmEthInterface(nodeId, destTp));
171                     }
172                     if ((srcTp != null) && (srcTp.contains(StringConstants.TTP_TOKEN)
173                             || srcTp.contains(StringConstants.PP_TOKEN))) {
174                         createdOchInterfaces.addAll(
175                             this.openRoadmInterfaceFactory
176                                 .createOpenRoadmOchInterface(nodeId, srcTp, waveNumber));
177                     }
178                     if ((destTp != null) && (destTp.contains(StringConstants.TTP_TOKEN)
179                             || destTp.contains(StringConstants.PP_TOKEN))) {
180                         createdOchInterfaces.addAll(
181                             this.openRoadmInterfaceFactory
182                                 .createOpenRoadmOchInterface(nodeId, destTp, waveNumber));
183                     }
184                     if (crossConnectFlag < 1) {
185                         LOG.info("Creating cross connect between source {} and destination {} for node {}", srcTp,
186                                 destTp, nodeId);
187                         Optional<String> connectionNameOpt =
188                                 this.crossConnect.postCrossConnect(nodeId, waveNumber, srcTp, destTp);
189                         if (connectionNameOpt.isPresent()) {
190                             nodesProvisioned.add(nodeId);
191                             createdConnections.add(connectionNameOpt.get());
192                         } else {
193                             processErrorMessage("Unable to post Roadm-connection for node " + nodeId, forkJoinPool,
194                                     results);
195                             success.set(false);
196                         }
197                     }
198                 } else {
199                     processErrorMessage(nodeId + " is not mounted on the controller", forkJoinPool, results);
200                     success.set(false);
201                 }
202             } catch (OpenRoadmInterfaceException ex) {
203                 processErrorMessage("Setup service path failed! Exception:" + ex.toString(), forkJoinPool, results);
204                 success.set(false);
205             }
206             NodeInterfaceBuilder nodeInterfaceBuilder = new NodeInterfaceBuilder()
207                 .withKey(new NodeInterfaceKey(nodeId))
208                 .setNodeId(nodeId)
209                 .setConnectionId(createdConnections)
210                 .setEthInterfaceId(createdEthInterfaces)
211                 .setOtuInterfaceId(createdOtuInterfaces)
212                 .setOduInterfaceId(createdOduInterfaces)
213                 .setOchInterfaceId(createdOchInterfaces);
214             nodeInterfaces.add(nodeInterfaceBuilder.build());
215         }));
216         try {
217             forkJoinTask.get();
218         } catch (InterruptedException | ExecutionException e) {
219             LOG.error("Error while setting up service paths!", e);
220         }
221         forkJoinPool.shutdown();
222
223         if (success.get()) {
224             results.add("Roadm-connection successfully created for nodes: " + String.join(", ", nodesProvisioned));
225         }
226         ServicePathOutputBuilder setServBldr = new ServicePathOutputBuilder()
227             .setNodeInterface(new ArrayList<>(nodeInterfaces))
228             .setSuccess(success.get())
229             .setResult(String.join("\n", results));
230         // setting topology in the service list data store
231         try {
232             setTopologyForService(input.getServiceName(), topology.getTopology());
233         } catch (InterruptedException | TimeoutException | ExecutionException e) {
234             LOG.warn("Failed to write topologies for service {}.", input.getServiceName(), e);
235         }
236         if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
237             LOG.error("Alarm suppresion node removal failed!!!!");
238         }
239         return setServBldr.build();
240     }
241
242     private ConcurrentLinkedQueue<String> processErrorMessage(String message, ForkJoinPool forkJoinPool,
243             ConcurrentLinkedQueue<String> messages) {
244         LOG.warn(message);
245         messages.add(message);
246         forkJoinPool.shutdown();
247         return messages;
248     }
249
250     @Override
251     public ServicePathOutput deleteServicePath(ServicePathInput input) {
252         List<Nodes> nodes = input.getNodes();
253         AtomicBoolean success = new AtomicBoolean(true);
254         ConcurrentLinkedQueue<String> results = new ConcurrentLinkedQueue<>();
255         if (!alarmSuppressionNodeRegistration(input)) {
256             LOG.warn("Alarm suppresion node registraion failed!!!!");
257         }
258         ForkJoinPool forkJoinPool = new ForkJoinPool();
259         ForkJoinTask forkJoinTask = forkJoinPool.submit(() -> nodes.parallelStream().forEach(node -> {
260             List<String> interfacesToDelete = new LinkedList<>();
261             String nodeId = node.getNodeId();
262             LOG.info("Deleting service setup on node {}", nodeId);
263             String srcTp;
264             String destTp;
265             Long waveNumber = input.getWaveNumber();
266             if (node.getDestTp() == null) {
267                 LOG.error("Destination termination point must not be null.");
268                 return;
269             } else {
270                 destTp = node.getDestTp();
271             }
272             if (node.getSrcTp() != null) {
273                 srcTp = node.getSrcTp();
274             } else {
275                 srcTp = "";
276             }
277             // if the node is currently mounted then proceed.
278             if (this.deviceTransactionManager.isDeviceMounted(nodeId)) {
279                 if (destTp.contains(StringConstants.NETWORK_TOKEN)
280                         || srcTp.contains(StringConstants.CLIENT_TOKEN)
281                         || srcTp.contains(StringConstants.NETWORK_TOKEN)
282                         || destTp.contains(StringConstants.CLIENT_TOKEN)) {
283                     if (destTp.contains(StringConstants.NETWORK_TOKEN)) {
284                         try {
285                             if (this.openRoadmInterfaces.getInterface(nodeId, destTp + "-ODU").isPresent()) {
286                                 interfacesToDelete.add(destTp + "-ODU");
287                             }
288                             if (this.openRoadmInterfaces.getInterface(nodeId, destTp + "-ODU4").isPresent()) {
289                                 interfacesToDelete.add(destTp + "-ODU4");
290                             }
291                         }
292                         catch (OpenRoadmInterfaceException e) {
293                             LOG.error("impossible to get interface {} or {}", destTp + "-ODU", destTp + "-ODU4", e);
294                         }
295                         interfacesToDelete.add(destTp + "-OTU");
296                         interfacesToDelete.add(
297                                 this.openRoadmInterfaceFactory.createOpenRoadmOchInterfaceName(destTp, waveNumber));
298                     }
299                     if (srcTp.contains(StringConstants.NETWORK_TOKEN)) {
300                         interfacesToDelete.add(srcTp + "-ODU");
301                         interfacesToDelete.add(srcTp + "-OTU");
302                         interfacesToDelete
303                                 .add(this.openRoadmInterfaceFactory.createOpenRoadmOchInterfaceName(srcTp, waveNumber));
304                     }
305                     if (srcTp.contains(StringConstants.CLIENT_TOKEN)) {
306                         interfacesToDelete.add(srcTp + "-ETHERNET");
307                     }
308                     if (destTp.contains(StringConstants.CLIENT_TOKEN)) {
309                         interfacesToDelete.add(destTp + "-ETHERNET");
310                     }
311                 } else {
312                     String connectionNumber = srcTp + "-" + destTp + "-" + waveNumber;
313                     List<String> intToDelete = this.crossConnect.deleteCrossConnect(nodeId, connectionNumber, false);
314                     connectionNumber = destTp + "-" + srcTp + "-" + waveNumber;
315                     if (intToDelete != null) {
316                         for (String interf : intToDelete) {
317                             if (!this.openRoadmInterfaceFactory.isUsedbyXc(nodeId, interf, connectionNumber,
318                                 this.deviceTransactionManager)) {
319                                 interfacesToDelete.add(interf);
320                             }
321                         }
322                     }
323                 }
324             } else {
325                 String result = nodeId + " is not mounted on the controller";
326                 results.add(result);
327                 success.set(false);
328                 LOG.warn(result);
329                 forkJoinPool.shutdown();
330                 return;
331                 //TODO should deletion end here?
332             }
333             for (String interfaceId : interfacesToDelete) {
334                 try {
335                     this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
336                 } catch (OpenRoadmInterfaceException e) {
337                     String result = String.format("Failed to delete interface %s on node %s!", interfaceId, nodeId);
338                     success.set(false);
339                     LOG.error(result, e);
340                     results.add(result);
341                 }
342             }
343         }));
344         try {
345             forkJoinTask.get();
346         } catch (InterruptedException | ExecutionException e) {
347             LOG.error("Error while deleting service paths!", e);
348         }
349         forkJoinPool.shutdown();
350         if (!alarmSuppressionNodeRemoval(input.getServiceName())) {
351             LOG.error("Alarm suppresion node removal failed!!!!");
352         }
353         ServicePathOutputBuilder delServBldr = new ServicePathOutputBuilder();
354         delServBldr.setSuccess(success.get());
355         if (results.isEmpty()) {
356             return delServBldr.setResult("Request processed").build();
357         } else {
358             return delServBldr.setResult(String.join("\n", results)).build();
359         }
360     }
361
362     @Override
363     public RendererRollbackOutput rendererRollback(RendererRollbackInput input) {
364         boolean success = true;
365         List<FailedToRollback> failedToRollbackList = new ArrayList<>();
366         for (NodeInterface nodeInterfaces : input.getNodeInterface()) {
367             List<String> failedInterfaces = new ArrayList<>();
368             String nodeId = nodeInterfaces.getNodeId();
369             for (String connectionId : nodeInterfaces.getConnectionId()) {
370                 List<String> listInter = this.crossConnect.deleteCrossConnect(nodeId, connectionId, false);
371                 if (listInter != null) {
372                     LOG.info("Cross connect {} on node {} successfully deleted.", connectionId, nodeId);
373                 } else {
374                     LOG.error("Failed to delete cross connect {} on node {}!", connectionId, nodeId);
375                     success = false;
376                     failedInterfaces.add(connectionId);
377                 }
378             }
379             // Interfaces needs to be in specific order to delete. Order is:
380             // 1. ODU interfaces
381             // 2. OTU interfaces
382             // 3. OCH interfaces
383             // 4. ETH interfaces
384             LinkedList<String> interfacesToDelete = new LinkedList<>();
385             if (nodeInterfaces.getOduInterfaceId() != null) {
386                 interfacesToDelete.addAll(nodeInterfaces.getOduInterfaceId());
387             }
388             if (nodeInterfaces.getOtuInterfaceId() != null) {
389                 interfacesToDelete.addAll(nodeInterfaces.getOtuInterfaceId());
390             }
391             if (nodeInterfaces.getOchInterfaceId() != null) {
392                 interfacesToDelete.addAll(nodeInterfaces.getOchInterfaceId());
393             }
394             if (nodeInterfaces.getEthInterfaceId() != null) {
395                 interfacesToDelete.addAll(nodeInterfaces.getEthInterfaceId());
396             }
397             LOG.info("Going to execute rollback on node {}. Interfaces to rollback: {}", nodeId,
398                     String.join(", ", interfacesToDelete));
399             for (String interfaceId : interfacesToDelete) {
400                 try {
401                     this.openRoadmInterfaces.deleteInterface(nodeId, interfaceId);
402                     LOG.info("Interface {} on node {} successfully deleted.", interfaceId, nodeId);
403                 } catch (OpenRoadmInterfaceException e) {
404                     LOG.error("Failed to delete interface {} on node {}!", interfaceId, nodeId);
405                     success = false;
406                     failedInterfaces.add(interfaceId);
407                 }
408             }
409             failedToRollbackList.add(new FailedToRollbackBuilder().withKey(new FailedToRollbackKey(nodeId))
410                     .setNodeId(nodeId).setInterface(failedInterfaces).build());
411         }
412         return new RendererRollbackOutputBuilder().setSuccess(success).setFailedToRollback(failedToRollbackList)
413                 .build();
414     }
415
416     private boolean alarmSuppressionNodeRegistration(ServicePathInput input) {
417         NodelistBuilder nodeListBuilder = new NodelistBuilder()
418             .withKey(new NodelistKey(input.getServiceName()))
419             .setServiceName(input.getServiceName());
420         List<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102.service
421             .nodelist.nodelist.Nodes> nodeList =
422                 new ArrayList<>();
423         for (Nodes node : input.getNodes()) {
424             nodeList.add(
425                     new org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102
426                     .service.nodelist.nodelist.NodesBuilder()
427                             .setNodeId(node.getNodeId()).build());
428         }
429         nodeListBuilder.setNodes(nodeList);
430         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102
431             .service.nodelist.Nodelist> nodeListIID =
432                         InstanceIdentifier.create(ServiceNodelist.class).child(
433                                 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression
434                                     .rev171102.service.nodelist.Nodelist.class,
435                                 new NodelistKey(input.getServiceName()));
436         final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
437         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, nodeListIID, nodeListBuilder.build());
438         FluentFuture<? extends @NonNull CommitInfo> commit = writeTransaction.commit();
439         try {
440             commit.get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
441             LOG.info("Nodes are register for alarm suppression for service: {}", input.getServiceName());
442             return true;
443         } catch (ExecutionException | InterruptedException | TimeoutException e) {
444             LOG.warn("Failed to alarm suppresslist for service: {}", input.getServiceName(), e);
445             return false;
446         }
447     }
448
449     private boolean alarmSuppressionNodeRemoval(String serviceName) {
450         InstanceIdentifier<org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression.rev171102
451             .service.nodelist.Nodelist> nodeListIID =
452                         InstanceIdentifier.create(ServiceNodelist.class).child(
453                                 org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.alarmsuppression
454                                     .rev171102.service.nodelist.Nodelist.class,
455                                 new NodelistKey(serviceName));
456         final WriteTransaction writeTransaction = this.dataBroker.newWriteOnlyTransaction();
457         writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, nodeListIID);
458         FluentFuture<? extends @NonNull CommitInfo> commit = writeTransaction.commit();
459         try {
460             commit.get(Timeouts.DATASTORE_DELETE, TimeUnit.MILLISECONDS);
461             LOG.info("Nodes are unregister for alarm suppression for service: {}", serviceName);
462             return true;
463         } catch (InterruptedException | TimeoutException | ExecutionException e) {
464             LOG.warn("Failed to alarm suppresslist for service: {}", serviceName, e);
465             return false;
466         }
467     }
468
469     private void setTopologyForService(String name, Topology topo)
470             throws InterruptedException, ExecutionException, TimeoutException {
471         ServicesBuilder servicesBuilder;
472         // Get the service from the service list inventory
473         ServicesKey serviceKey = new ServicesKey(name);
474         InstanceIdentifier<Services> iid =
475                 InstanceIdentifier.create(ServiceList.class).child(Services.class, serviceKey);
476         Optional<Services> services;
477         try (ReadTransaction readTx = this.dataBroker.newReadOnlyTransaction()) {
478             Future<java.util.Optional<Services>> future =
479                     readTx.read(LogicalDatastoreType.OPERATIONAL, iid);
480             services = future.get(Timeouts.DATASTORE_READ, TimeUnit.MILLISECONDS);
481         } catch (InterruptedException | ExecutionException | TimeoutException e) {
482             throw e;
483         }
484         if (services.isPresent()) {
485             LOG.info("service {} already exists", name);
486             servicesBuilder = new ServicesBuilder(services.get()).setTopology(topo);
487             WriteTransaction writeTx = this.dataBroker.newWriteOnlyTransaction();
488             writeTx.merge(LogicalDatastoreType.OPERATIONAL, iid, servicesBuilder.build());
489             writeTx.commit().get(Timeouts.DATASTORE_WRITE, TimeUnit.MILLISECONDS);
490         } else {
491             LOG.warn("Service {} does not exist - topology can not be updated", name);
492         }
493     }
494
495     @Override
496     public CreateOtsOmsOutput createOtsOms(CreateOtsOmsInput input) throws OpenRoadmInterfaceException {
497         CreateOtsOmsOutputBuilder output = new CreateOtsOmsOutputBuilder();
498         String result = "";
499         Boolean success = false;
500         // if the node is currently mounted then proceed.
501         if (this.deviceTransactionManager.isDeviceMounted(input.getNodeId())) {
502             Mapping oldMapping = null;
503             Mapping newMapping = null;
504             oldMapping = this.portMapping.getMapping(input.getNodeId(), input.getLogicalConnectionPoint());
505             if (oldMapping != null) {
506                 String otsInterface =
507                         this.openRoadmInterfaceFactory.createOpenRoadmOtsInterface(input.getNodeId(), oldMapping);
508                 newMapping = this.portMapping.getMapping(input.getNodeId(), input.getLogicalConnectionPoint());
509                 int count = 0;
510                 Boolean isSupportingOtsPresent = isSupportingOtsPresent(newMapping);
511                 while (!isSupportingOtsPresent && (count < 6)) {
512                     LOG.info("waiting for post interface operation on node '{}'...", input.getNodeId());
513                     try {
514                         Thread.sleep(10000);
515                         this.portMapping.updateMapping(input.getNodeId(), oldMapping);
516                     } catch (InterruptedException e) {
517                         LOG.error("Failed to wait for post interface operation ");
518                     }
519                     newMapping = this.portMapping.getMapping(input.getNodeId(), input.getLogicalConnectionPoint());
520                     isSupportingOtsPresent = isSupportingOtsPresent(newMapping);
521                     count++;
522                 }
523                 if (count < 6) {
524                     String omsInterface =
525                             this.openRoadmInterfaceFactory.createOpenRoadmOmsInterface(input.getNodeId(), newMapping);
526                     if (omsInterface != null) {
527                         result = "Interfaces " + otsInterface + " - " + omsInterface + " successfully created on node "
528                                 + input.getNodeId();
529                         success = true;
530                     } else {
531                         LOG.error("Fail to create OpenRoadmOms Interface for node '{}'", input.getNodeId());
532                         result = "Fail to create OpenRoadmOms Interface for node : " + input.getNodeId();
533                     }
534                 } else {
535                     LOG.error("Unable to get ots interface from mapping {} for node {}",
536                             oldMapping.getLogicalConnectionPoint(), input.getNodeId());
537                     result = String.format("Unable to get ots interface from mapping %s - %s",
538                             oldMapping.getLogicalConnectionPoint(), input.getNodeId());
539                 }
540             } else {
541                 result = "Logical Connection point " + input.getLogicalConnectionPoint() + " does not exist for "
542                         + input.getNodeId();
543             }
544         } else {
545             result = input.getNodeId() + " is not mounted on the controller";
546             LOG.warn(result);
547         }
548         return output.setResult(result).setSuccess(success).build();
549     }
550
551     private Boolean isSupportingOtsPresent(Mapping mapping) {
552         Boolean result = false;
553         if (mapping != null) {
554             if (mapping.getSupportingOts() != null) {
555                 LOG.info("SupportingOts info is present in mapping {}", mapping);
556                 result = true;
557             } else {
558                 LOG.warn("SupportingOts info not present in mapping {}", mapping);
559             }
560         }
561         return result;
562     }
563 }