Add Honeynode emulator for device221
[transportpce.git] / tests / honeynode / 2.2.1 / honeynode-plugin-impl / src / main / java / io / fd / honeycomb / transportpce / device / notifications / DeviceNotificationProducer.java
1 /*
2  * Copyright (c) 2018 Orange and/or its affiliates.
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 package io.fd.honeycomb.transportpce.device.notifications;
17
18 import com.google.common.base.Preconditions;
19 import com.google.common.collect.Lists;
20 import com.google.inject.Inject;
21 import com.google.inject.name.Named;
22
23 import io.fd.honeycomb.notification.ManagedNotificationProducer;
24 import io.fd.honeycomb.notification.NotificationCollector;
25
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Date;
30 import java.util.Iterator;
31 import java.util.List;
32
33 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
34 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
35 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
36 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
37 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
38 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotification;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotification.Datastore;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.ChangeNotificationBuilder;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.change.notification.Edit;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.change.notification.EditBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.ChangedBy;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.ChangedByBuilder;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.changed.by.parms.changed.by.server.or.user.ServerBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.Ports;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.pack.PortsKey;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacks;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.circuit.packs.CircuitPacksKey;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.interfaces.grp.Interface;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019.org.openroadm.device.container.OrgOpenroadmDevice;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditOperationType;
54 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
55 import org.opendaylight.yangtools.yang.binding.DataObject;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.binding.Notification;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 /**
62  * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
63  */
64 public class DeviceNotificationProducer implements ManagedNotificationProducer {
65     private static final Logger LOG = LoggerFactory.getLogger(DeviceNotificationProducer.class);
66     private static final InstanceIdentifier<OrgOpenroadmDevice> DEVICE_CONTAINER_ID = InstanceIdentifier
67             .create(OrgOpenroadmDevice.class);
68     private static final String INTERFACE_CLASS = Interface.class.getName();
69
70     @Inject
71     @Named("device-databroker")
72     private DataBroker dataBroker;
73
74     @Override
75     public Collection<Class<? extends Notification>> getNotificationTypes() {
76         final ArrayList<Class<? extends Notification>> classes = Lists.newArrayList();
77         classes.add(ChangeNotification.class);
78         return classes;
79     }
80
81     @Override
82     public void close() throws Exception {
83         stop();
84     }
85
86     @Override
87     public void start(NotificationCollector collector) {
88         LOG.info("Starting notification stream for OrgOpenroadmDevice");
89         Preconditions.checkArgument(this.dataBroker != null, "Device datastore is null");
90         this.dataBroker.registerDataTreeChangeListener(
91                 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, DEVICE_CONTAINER_ID),
92                 new DataTreeChangeListener<OrgOpenroadmDevice>() {
93                     @Override
94                     public void onDataTreeChanged(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
95                         LOG.info("onDataTreeChanged");
96                         ChangeNotification changeNotification = null;
97                         try {
98                             changeNotification = transformToNotification(changes);
99                             LOG.info("Emitting notification : {}", changeNotification);
100                             collector.onNotification(changeNotification);
101                         } catch (NullPointerException e) {
102                             LOG.warn("Failed to emit notification");
103                         }
104                     }
105                 });
106     }
107
108     @Override
109     public void stop() {
110         LOG.info("Stopping OrgOpenroadmDevice change notification");
111     }
112
113     /**
114      * Transform {@link Collection} of {@link DataTreeModification } to {@link ChangeNotification}
115      *
116      * @return changeNotification {@link ChangeNotification}
117      */
118     private ChangeNotification transformToNotification(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
119         LOG.info("transforming changes to notification...");
120         ChangeNotification result = null;
121         List<Edit> editList = new ArrayList<Edit>();
122         for (DataTreeModification<OrgOpenroadmDevice> change : changes) {
123             LOG.info("Received Device change :\n{}", change.getRootNode().getModificationType());
124             final DataObjectModification<OrgOpenroadmDevice> rootNode = change.getRootNode();
125             final DataTreeIdentifier<OrgOpenroadmDevice> rootPath = change.getRootPath();
126             if (rootNode != null) {
127                 Collection<DataObjectModification<? extends DataObject>> modifiedChildren = rootNode.getModifiedChildren();
128                 switch (rootNode.getModificationType()) {
129                 case SUBTREE_MODIFIED: // OrgOpenroadmDevice
130                     if (!modifiedChildren.isEmpty()) {
131                         Iterator<DataObjectModification<? extends DataObject>> iterator = modifiedChildren.iterator();
132                         while (iterator.hasNext()) {
133                             DataObjectModification<? extends DataObject> modified = iterator.next();
134                             LOG.info(
135                                     "modified = \ndataType : {}\nid : {}\nmodifiedType : {}\noldData : {}\nnewData : {} \n",
136                                     modified.getDataType(), modified.getIdentifier(), modified.getModificationType(),
137                                     modified.getDataBefore(), modified.getDataAfter());
138                             String dataType = modified.getDataType().getName();
139                             if (dataType.equals(INTERFACE_CLASS)) {
140                                 Interface data = null;
141                                 LOG.info("Interface type update !");
142                                 switch (modified.getModificationType()) {
143                                 case SUBTREE_MODIFIED:
144                                     data = (Interface) modified.getDataAfter();
145                                     break;
146                                 case WRITE:
147                                     data = (Interface) modified.getDataAfter();
148                                     break;
149                                 case DELETE:
150                                     data = (Interface) modified.getDataBefore();
151                                     break;
152                                 default:
153                                     break;
154                                 }
155                                 if (data!= null) {
156                                     String circuitPackName = data.getSupportingCircuitPackName();
157                                     String port = data.getSupportingPort().toString();
158                                     String interfaceName = data.getName();
159                                     if (circuitPackName != null && port != null && interfaceName != null) {
160                                         InstanceIdentifier<Ports> portIId = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
161                                                 CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class,
162                                                     new PortsKey(port));
163                                         Edit edit = new EditBuilder()
164                                                 .setOperation(EditOperationType.Merge)
165                                                 .setTarget(portIId)
166                                                 .build();
167                                         editList.add(edit);
168                                     }
169                                 } else {
170                                     LOG.warn("Interface data is null !");
171                                 }
172                             } else {
173                                 LOG.warn("modifiedChild is not an interface !");
174                             }
175                         }
176                     }
177                     break;
178                 case WRITE:
179                     LOG.info("device operational datastore is created !");
180                     break;
181                 case DELETE:
182                     LOG.info("device operational datastore is deleted !");
183                     break;
184                 default:
185                     break;
186                 }
187             } else {
188                 LOG.error("rootNode is null !");
189             }
190         }
191         if (!editList.isEmpty()) {
192             ChangedBy changedBy = new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build())
193                     .build();
194             String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX").format(new Date());
195             result = new ChangeNotificationBuilder().setChangedBy(changedBy).setChangeTime(new DateAndTime(time))
196                     .setDatastore(Datastore.Running).setEdit(editList).build();
197         } else {
198             LOG.warn("edit List is empty !");
199         }
200         return result;
201     }
202 }