X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=restconf%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fsal%2Fstreams%2Flisteners%2FNotificationListenerAdapter.java;h=1d32b39e23bb077c59120d7bcd5a78c09db0fe35;hb=ddc71443d58ac78f8a593be88e181310f1e4b9c8;hp=093f529acf8c3eb6880c4e9870f96a9dd4df8a7c;hpb=a6e09d92809dd70180afc9abb85e7ac083233b62;p=netconf.git diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java index 093f529acf..1d32b39e23 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java @@ -18,11 +18,14 @@ import io.netty.util.internal.ConcurrentSet; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; +import java.io.StringReader; import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.Date; import java.util.Set; import java.util.concurrent.Executors; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -33,11 +36,15 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import org.json.JSONObject; import org.json.XML; import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener; import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; +import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; @@ -55,6 +62,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.xml.sax.InputSource; /** * {@link NotificationListenerAdapter} is responsible to track events on @@ -74,6 +82,9 @@ public class NotificationListenerAdapter implements DOMNotificationListener { private final SchemaPath path; private final String outputType; + private Date start = null; + private Date stop = null; + private String filter; /** * Set path of listener and stream name, register event bus. @@ -98,7 +109,72 @@ public class NotificationListenerAdapter implements DOMNotificationListener { @Override public void onNotification(final DOMNotification notification) { + final Date now = new Date(); + if (this.stop != null) { + if ((this.start.compareTo(now) < 0) && (this.stop.compareTo(now) > 0)) { + checkFilter(notification); + } + if (this.stop.compareTo(now) < 0) { + try { + this.close(); + } catch (final Exception e) { + throw new RestconfDocumentedException("Problem with unregister listener." + e); + } + } + } else if (this.start != null) { + if (this.start.compareTo(now) < 0) { + this.start = null; + checkFilter(notification); + } + } else { + checkFilter(notification); + } + } + + /** + * Check if is filter used and then prepare and post data do client + * + * @param notification + * - data of notification + */ + private void checkFilter(final DOMNotification notification) { final String xml = prepareXmlFrom(notification); + if (this.filter == null) { + prepareAndPostData(xml); + } else { + try { + if (parseFilterParam(xml)) { + prepareAndPostData(xml); + } + } catch (final Exception e) { + throw new RestconfDocumentedException("Problem while parsing filter.", e); + } + } + } + + /** + * Parse and evaluate filter value by xml + * + * @param xml + * - notification data in xml + * @return true or false - depends on filter expression and data of + * notifiaction + * @throws Exception + */ + private boolean parseFilterParam(final String xml) throws Exception { + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + final DocumentBuilder builder = factory.newDocumentBuilder(); + final Document docOfXml = builder.parse(new InputSource(new StringReader(xml))); + final XPath xPath = XPathFactory.newInstance().newXPath(); + return (boolean) xPath.compile(this.filter).evaluate(docOfXml, XPathConstants.BOOLEAN); + } + + /** + * Prepare data of notification and data to client + * + * @param xml + */ + private void prepareAndPostData(final String xml) { final Event event = new Event(EventType.NOTIFY); if (this.outputType.equals("JSON")) { final JSONObject jsonObject = XML.toJSONObject(xml); @@ -386,4 +462,20 @@ public class NotificationListenerAdapter implements DOMNotificationListener { private enum EventType { REGISTER, DEREGISTER, NOTIFY } + + /** + * Set query parameters for listener + * + * @param start + * - start-time of getting notification + * @param stop + * - stop-time of getting notification + * @param filter + * - indicate which subset of all possible events are of interest + */ + public void setQueryParams(final Date start, final Date stop, final String filter) { + this.start = start; + this.stop = stop; + this.filter = filter; + } }