From e433e0aa67cc6d144cd3d8d6117de864eb7ebf97 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 5 May 2015 18:47:37 +0200 Subject: [PATCH] BUG-3095 Add EventTime attribute to DOMNotification from netconf Introduced new interface DOMEvent and DOMNotifications from sal-netconf-connector implement this interaface. The eventTime is parsed from the the notification xml. Change-Id: I833d86d91f752be55fef3e641a6c8654d2f65a28 Signed-off-by: Maros Marsalek --- .../controller/md/sal/dom/api/DOMEvent.java | 24 +++++ .../md-sal/sal-netconf-connector/pom.xml | 4 + .../sal/connect/api/MessageTransformer.java | 4 +- .../sal/connect/api/RemoteDeviceHandler.java | 4 +- .../sal/connect/netconf/NetconfDevice.java | 10 +-- .../connect/netconf/NotificationHandler.java | 11 ++- .../sal/NetconfDeviceNotificationService.java | 22 +---- .../netconf/sal/NetconfDeviceSalFacade.java | 4 +- .../netconf/sal/NetconfDeviceSalProvider.java | 4 +- .../mapping/NetconfMessageTransformer.java | 89 +++++++++++++++---- .../util/NetconfMessageTransformUtil.java | 1 + .../connect/netconf/NetconfDeviceTest.java | 9 +- .../netconf/NetconfToNotificationTest.java | 9 +- .../test/resources/notification-payload.xml | 2 +- .../cli/NetconfDeviceConnectionHandler.java | 4 +- 15 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMEvent.java diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMEvent.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMEvent.java new file mode 100644 index 0000000000..1b8ec9bbb0 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMEvent.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html. + */ + +package org.opendaylight.controller.md.sal.dom.api; + +import java.util.Date; + +/** + * Generic event interface + */ +public interface DOMEvent { + + /** + * Get the time of the event occurrence + * + * @return the event time + */ + Date getEventTime(); +} diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index fd4d38a111..f407a4431c 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -36,6 +36,10 @@ org.opendaylight.controller netconf-client + + org.opendaylight.controller + netconf-notifications-api + org.opendaylight.controller netty-config-api diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java index dc27cd6572..861aaa43db 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/MessageTransformer.java @@ -7,14 +7,14 @@ */ package org.opendaylight.controller.sal.connect.api; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; public interface MessageTransformer { - ContainerNode toNotification(M message); + DOMNotification toNotification(M message); M toRpcRequest(SchemaPath rpc, NormalizedNode node); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java index 02f45e5bc3..07c5fcb620 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/api/RemoteDeviceHandler.java @@ -7,8 +7,8 @@ */ package org.opendaylight.controller.sal.connect.api; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; public interface RemoteDeviceHandler extends AutoCloseable { @@ -20,7 +20,7 @@ public interface RemoteDeviceHandler extends AutoCloseable { void onDeviceFailed(Throwable throwable); - void onNotification(ContainerNode domNotification); + void onNotification(DOMNotification domNotification); void close(); } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java index c0b57de9a0..a7ae9cb177 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcException; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; @@ -47,7 +48,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.not import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability; import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException; import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory; @@ -182,18 +182,18 @@ public final class NetconfDevice implements RemoteDevice> filterNotification(final NormalizedNode notification) { + public Optional filterNotification(final DOMNotification notification) { if (isCapabilityChanged(notification)) { logger.info("{}: Schemas change detected, reconnecting", id); // Only disconnect is enough, the reconnecting nature of the connector will take care of reconnecting listener.disconnect(); return Optional.absent(); } - return Optional.>of(notification); + return Optional.of(notification); } - private boolean isCapabilityChanged(final NormalizedNode notification) { - return notification.getNodeType().equals(NetconfCapabilityChange.QNAME); + private boolean isCapabilityChanged(final DOMNotification notification) { + return notification.getBody().getNodeType().equals(NetconfCapabilityChange.QNAME); } }; diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java index 481afa5c83..2d47c6ae1b 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NotificationHandler.java @@ -11,13 +11,12 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import java.util.LinkedList; import java.util.List; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.connect.api.MessageTransformer; import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler; import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,8 +64,8 @@ final class NotificationHandler { queue.clear(); } - private ContainerNode transformNotification(final NetconfMessage cachedNotification) { - final ContainerNode parsedNotification = messageTransformer.toNotification(cachedNotification); + private DOMNotification transformNotification(final NetconfMessage cachedNotification) { + final DOMNotification parsedNotification = messageTransformer.toNotification(cachedNotification); Preconditions.checkNotNull(parsedNotification, "%s: Unable to parse received notification: %s", id, cachedNotification); return parsedNotification; } @@ -82,7 +81,7 @@ final class NotificationHandler { queue.add(notification); } - private synchronized void passNotification(final ContainerNode parsedNotification) { + private synchronized void passNotification(final DOMNotification parsedNotification) { logger.debug("{}: Forwarding notification {}", id, parsedNotification); if(filter == null || filter.filterNotification(parsedNotification).isPresent()) { @@ -102,6 +101,6 @@ final class NotificationHandler { static interface NotificationFilter { - Optional> filterNotification(NormalizedNode notification); + Optional filterNotification(DOMNotification notification); } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java index bfcb4caddb..b27430f5e3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceNotificationService.java @@ -8,8 +8,6 @@ package org.opendaylight.controller.sal.connect.netconf.sal; -import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath; - import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; @@ -19,7 +17,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; class NetconfDeviceNotificationService implements DOMNotificationService { @@ -28,22 +25,9 @@ class NetconfDeviceNotificationService implements DOMNotificationService { // Notification publish is very simple and hijacks the thread of the caller // TODO shouldnt we reuse the implementation for notification router from sal-broker-impl ? - public synchronized void publishNotification(final ContainerNode notification) { - final SchemaPath schemaPath = toPath(notification.getNodeType()); - for (final DOMNotificationListener domNotificationListener : listeners.get(schemaPath)) { - domNotificationListener.onNotification(new DOMNotification() { - @Nonnull - @Override - public SchemaPath getType() { - return schemaPath; - } - - @Nonnull - @Override - public ContainerNode getBody() { - return notification; - } - }); + public synchronized void publishNotification(final DOMNotification notification) { + for (final DOMNotificationListener domNotificationListener : listeners.get(notification.getType())) { + domNotificationListener.onNotification(notification); } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java index 11f82c02bf..7ffeec3096 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalFacade.java @@ -11,6 +11,7 @@ import com.google.common.collect.Lists; import java.util.Collections; import java.util.List; import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler; @@ -19,7 +20,6 @@ import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPr import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; import org.opendaylight.controller.sal.core.api.Broker; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.osgi.framework.BundleContext; import org.slf4j.Logger; @@ -46,7 +46,7 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice } @Override - public synchronized void onNotification(final ContainerNode domNotification) { + public synchronized void onNotification(final DOMNotification domNotification) { salProvider.getMountInstance().publish(domNotification); } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java index 2931468501..bf870bf36a 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceSalProvider.java @@ -14,6 +14,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; @@ -22,7 +23,6 @@ import org.opendaylight.controller.sal.connect.util.RemoteDeviceId; import org.opendaylight.controller.sal.core.api.Broker; import org.opendaylight.controller.sal.core.api.Provider; import org.opendaylight.yangtools.concepts.ObjectRegistration; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -187,7 +187,7 @@ final class NetconfDeviceSalProvider implements AutoCloseable, Provider, Binding mountService = null; } - public synchronized void publish(final ContainerNode domNotification) { + public synchronized void publish(final DOMNotification domNotification) { Preconditions.checkNotNull(notificationService, "Device not set up yet, cannot handle notification {}", domNotification); notificationService.publishNotification(domNotification); } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java index 819edce320..5b579a0a8a 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java @@ -7,30 +7,38 @@ */ package org.opendaylight.controller.sal.connect.netconf.schema.mapping; +import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.EVENT_TIME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RPC_QNAME; import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_URI; +import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath; import com.google.common.base.Function; import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.AbstractMap; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Set; +import javax.annotation.Nonnull; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.dom.DOMResult; +import org.opendaylight.controller.md.sal.dom.api.DOMEvent; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult; import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.notifications.NetconfNotification; import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter; import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -111,12 +119,12 @@ public class NetconfMessageTransformer implements MessageTransformer stripped = stripNotification(message); final QName notificationNoRev; try { // How to construct QName with no revision ? - notificationNoRev = QName.cachedReference(QName.create(stripped.getNamespace(), "0000-00-00", stripped.getName()).withoutRevision()); + notificationNoRev = QName.cachedReference(QName.create(stripped.getValue().getNamespace(), "0000-00-00", stripped.getValue().getName()).withoutRevision()); } catch (final MissingNameSpaceException e) { throw new IllegalArgumentException("Unable to parse notification " + message + ", cannot find namespace", e); } @@ -131,23 +139,43 @@ public class NetconfMessageTransformer implements MessageTransformer stripNotification(final NetconfMessage message) { final XmlElement xmlElement = XmlElement.fromDomDocument(message.getDocument()); final List childElements = xmlElement.getChildElements(); Preconditions.checkArgument(childElements.size() == 2, "Unable to parse notification %s, unexpected format", message); + + final XmlElement eventTimeElement; + final XmlElement notificationElement; + + if (childElements.get(0).getName().equals(EVENT_TIME)) { + eventTimeElement = childElements.get(0); + notificationElement = childElements.get(1); + } + else if(childElements.get(1).getName().equals(EVENT_TIME)) { + eventTimeElement = childElements.get(1); + notificationElement = childElements.get(0); + } else { + throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message); + } + try { - return Iterables.find(childElements, new Predicate() { - @Override - public boolean apply(final XmlElement xmlElement) { - return !xmlElement.getName().equals("eventTime"); - } - }); - } catch (final NoSuchElementException e) { - throw new IllegalArgumentException("Unable to parse notification " + message + ", cannot strip notification metadata", e); + return new AbstractMap.SimpleEntry<>(parseEventTime(eventTimeElement.getTextContent()), notificationElement); + } catch (NetconfDocumentedException e) { + throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message); + } + } + + private static Date parseEventTime(final String eventTime) { + try { + return new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT).parse(eventTime); + } catch (ParseException e) { + throw new IllegalArgumentException("Unable to parse event time from " + eventTime, e); } } @@ -268,4 +296,33 @@ public class NetconfMessageTransformer implements MessageTransformer remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class); doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class)); doNothing().when(remoteDeviceHandler).onDeviceDisconnected(); - doNothing().when(remoteDeviceHandler).onNotification(any(ContainerNode.class)); + doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class)); return remoteDeviceHandler; } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java index 294efadc6f..96c478f097 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connect/netconf/NetconfToNotificationTest.java @@ -6,13 +6,17 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.Iterables; import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.Collections; import java.util.List; import java.util.Set; import javax.xml.parsers.DocumentBuilderFactory; import org.junit.Before; import org.junit.Test; +import org.opendaylight.controller.md.sal.dom.api.DOMEvent; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.notifications.NetconfNotification; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -60,9 +64,12 @@ public class NetconfToNotificationTest { @Test public void test() throws Exception { - final ContainerNode root = messageTransformer.toNotification(userNotification); + final DOMNotification domNotification = messageTransformer.toNotification(userNotification); + final ContainerNode root = domNotification.getBody(); assertNotNull(root); assertEquals(6, Iterables.size(root.getValue())); assertEquals("user-visited-page", root.getNodeType().getLocalName()); + assertEquals(new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT).parse("2007-07-08T00:01:00Z"), + ((DOMEvent) domNotification).getEventTime()); } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml index 837fcc1a70..431787d34c 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml +++ b/opendaylight/md-sal/sal-netconf-connector/src/test/resources/notification-payload.xml @@ -1,5 +1,5 @@ -2014-07-08T11:20:48UTC +2007-07-08T00:01:00Z ui:public-user 172.23.29.104 diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java index 50c3243135..aa9f4e8811 100644 --- a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java +++ b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/NetconfDeviceConnectionHandler.java @@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.cli; import com.google.common.base.Optional; import jline.console.completer.Completer; import jline.console.completer.NullCompleter; +import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher; import org.opendaylight.controller.netconf.cli.io.ConsoleContext; import org.opendaylight.controller.netconf.cli.io.ConsoleIO; import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler; import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; /** @@ -87,7 +87,7 @@ public class NetconfDeviceConnectionHandler implements RemoteDeviceHandler