2 * Copyright (c) 2018 Orange and/or its affiliates.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package io.fd.honeycomb.transportpce.device.notifications;
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;
24 import io.fd.honeycomb.notification.ManagedNotificationProducer;
25 import io.fd.honeycomb.notification.NotificationCollector;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Date;
31 import java.util.Iterator;
32 import java.util.List;
36 import org.opendaylight.mdsal.binding.api.DataBroker;
37 import org.opendaylight.mdsal.binding.api.DataObjectModification;
38 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
39 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
40 import org.opendaylight.mdsal.binding.api.DataTreeModification;
41 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotification;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotification.Datastore;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.ChangeNotificationBuilder;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.change.notification.Edit;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.change.notification.EditBuilder;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.changed.by.parms.ChangedBy;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.changed.by.parms.ChangedByBuilder;
49 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
50 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.Ports;
51 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.pack.PortsKey;
52 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacks;
53 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.circuit.packs.CircuitPacksKey;
54 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.interfaces.grp.Interface;
55 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev170206.org.openroadm.device.container.OrgOpenroadmDevice;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditOperationType;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
58 import org.opendaylight.yangtools.yang.binding.DataObject;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.binding.Notification;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
65 * @author Martial COULIBALY ( mcoulibaly.ext@orange.com ) on behalf of Orange
67 public class DeviceNotificationProducer implements ManagedNotificationProducer {
68 private static final Logger LOG = LoggerFactory.getLogger(DeviceNotificationProducer.class);
69 private static final InstanceIdentifier<OrgOpenroadmDevice> DEVICE_CONTAINER_ID = InstanceIdentifier
70 .create(OrgOpenroadmDevice.class);
71 private static final String INTERFACE_CLASS = Interface.class.getName();
74 @Named("device-databroker")
75 private DataBroker dataBroker;
78 public Collection<Class<? extends Notification>> getNotificationTypes() {
79 final ArrayList<Class<? extends Notification>> classes = Lists.newArrayList();
80 classes.add(ChangeNotification.class);
85 public void close() throws Exception {
90 public void start(NotificationCollector collector) {
91 LOG.info("Starting notification stream for OrgOpenroadmDevice");
92 Preconditions.checkArgument(this.dataBroker != null, "Device datastore is null");
93 this.dataBroker.registerDataTreeChangeListener(DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL, DEVICE_CONTAINER_ID),
94 new DataTreeChangeListener<OrgOpenroadmDevice>() {
96 public void onDataTreeChanged(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
97 LOG.info("onDataTreeChanged");
98 ChangeNotification changeNotification = null;
100 changeNotification = transformToNotification(changes);
101 LOG.info("Emitting notification : {}", changeNotification);
102 collector.onNotification(changeNotification);
103 } catch (NullPointerException e) {
104 LOG.warn("Failed to emit notification");
112 LOG.info("Stopping OrgOpenroadmDevice change notification");
116 * Transform {@link Collection} of {@link DataTreeModification } to {@link ChangeNotification}
118 * @return changeNotification {@link ChangeNotification}
120 private ChangeNotification transformToNotification(Collection<DataTreeModification<OrgOpenroadmDevice>> changes) {
121 LOG.info("transforming changes to notification...");
122 ChangeNotification result = null;
123 List<Edit> editList = new ArrayList<Edit>();
124 for (DataTreeModification<OrgOpenroadmDevice> change : changes) {
125 LOG.info("Received Device change :\n{}", change.getRootNode().getModificationType());
126 final DataObjectModification<OrgOpenroadmDevice> rootNode = change.getRootNode();
127 final DataTreeIdentifier<OrgOpenroadmDevice> rootPath = change.getRootPath();
128 if (rootNode != null) {
129 Collection<? extends DataObjectModification<? extends DataObject>> modifiedChildren = rootNode.getModifiedChildren();
130 switch (rootNode.getModificationType()) {
131 case SUBTREE_MODIFIED: // OrgOpenroadmDevice
132 if (!modifiedChildren.isEmpty()) {
133 Iterator<? extends DataObjectModification<? extends DataObject>> iterator = modifiedChildren.iterator();
134 while (iterator.hasNext()) {
135 DataObjectModification<? extends DataObject> modified = iterator.next();
137 "modified = \ndataType : {}\nid : {}\nmodifiedType : {}\noldData : {}\nnewData : {} \n",
138 modified.getDataType(), modified.getIdentifier(), modified.getModificationType(),
139 modified.getDataBefore(), modified.getDataAfter());
140 String dataType = modified.getDataType().getName();
141 if (dataType.equals(INTERFACE_CLASS)) {
142 Interface data = null;
143 LOG.info("Interface type update !");
144 switch (modified.getModificationType()) {
145 case SUBTREE_MODIFIED:
146 data = (Interface) modified.getDataAfter();
149 data = (Interface) modified.getDataAfter();
152 data = (Interface) modified.getDataBefore();
158 String circuitPackName = data.getSupportingCircuitPackName();
159 String port = data.getSupportingPort().toString();
160 String interfaceName = data.getName();
161 if (circuitPackName != null && port != null && interfaceName != null) {
162 InstanceIdentifier<Ports> portIId = InstanceIdentifier.create(OrgOpenroadmDevice.class).child(
163 CircuitPacks.class, new CircuitPacksKey(circuitPackName)).child(Ports.class,
165 Edit edit = new EditBuilder()
166 .setOperation(EditOperationType.Merge)
172 LOG.warn("Interface data is null !");
175 LOG.warn("modifiedChild is not an interface !");
181 LOG.info("device operational datastore is created !");
184 LOG.info("device operational datastore is deleted !");
190 LOG.error("rootNode is null !");
193 if (!editList.isEmpty()) {
194 ChangedBy changedBy = new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build())
196 String time = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX").format(new Date());
197 result = new ChangeNotificationBuilder().setChangedBy(changedBy).setChangeTime(new DateAndTime(time))
198 .setDatastore(Datastore.Running).setEdit(editList).build();
200 LOG.warn("edit List is empty !");