2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.netconf.test.tool.rpc;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
14 import java.io.IOException;
15 import java.text.SimpleDateFormat;
16 import java.util.Date;
17 import java.util.List;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.ScheduledExecutorService;
20 import java.util.concurrent.TimeUnit;
21 import javax.xml.bind.JAXBContext;
22 import javax.xml.bind.JAXBException;
23 import javax.xml.bind.Unmarshaller;
24 import javax.xml.bind.annotation.XmlRootElement;
25 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
26 import org.opendaylight.controller.netconf.api.NetconfMessage;
27 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
28 import org.opendaylight.controller.netconf.impl.NetconfServerSession;
29 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
30 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
31 import org.opendaylight.controller.netconf.util.xml.XmlElement;
32 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
33 import org.w3c.dom.Document;
34 import org.w3c.dom.Element;
35 import org.xml.sax.SAXException;
37 public class SimulatedCreateSubscription extends AbstractLastNetconfOperation implements DefaultNetconfOperation {
39 private NetconfServerSession session;
40 private final Optional<Notifications> notifications;
41 private ScheduledExecutorService scheduledExecutorService;
43 public SimulatedCreateSubscription(final String id, final Optional<File> notificationsFile) {
45 if(notificationsFile.isPresent()) {
46 notifications = Optional.of(loadNotifications(notificationsFile.get()));
47 scheduledExecutorService = Executors.newScheduledThreadPool(1);
49 notifications = Optional.absent();
53 private Notifications loadNotifications(final File file) {
55 final JAXBContext jaxbContext = JAXBContext.newInstance(Notifications.class);
56 final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
57 return (Notifications) jaxbUnmarshaller.unmarshal(file);
58 } catch (final JAXBException e) {
59 throw new IllegalArgumentException("Canot parse file " + file + " as a notifications file", e);
64 protected String getOperationName() {
65 return "create-subscription";
69 protected String getOperationNamespace() {
70 return "urn:ietf:params:xml:ns:netconf:notification:1.0";
74 protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws NetconfDocumentedException {
77 if(notifications.isPresent()) {
78 long delayAggregator = 0;
79 System.console().writer().println("Scheduling notifications " + notifications.get());
81 for (final Notification notification : notifications.get().getNotificationList()) {
82 for (int i = 0; i <= notification.getTimes(); i++) {
84 delayAggregator += notification.getDelayInSeconds();
86 System.console().writer().println("Times " + notification.getTimes());
87 scheduledExecutorService.schedule(new Runnable() {
91 System.console().writer().println("Sending actual notification " + notification);
92 Preconditions.checkState(session != null, "Session is not set, cannot process notifications");
93 session.sendMessage(parseNetconfNotification(notification.getContent()));
94 } catch (IOException | SAXException e) {
95 throw new IllegalStateException("Unable to process notification " + notification, e);
98 }, delayAggregator, TimeUnit.SECONDS);
102 return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
105 private static NetconfMessage parseNetconfNotification(String content) throws IOException, SAXException {
106 final int startEventTime = content.indexOf("<eventTime>") + "<eventTime>".length();
107 final int endEventTime = content.indexOf("</eventTime>");
108 final String eventTime = content.substring(startEventTime, endEventTime);
109 if(eventTime.equals("XXXX")) {
110 content = content.replace(eventTime, new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));
113 return new NetconfMessage(XmlUtil.readXmlToDocument(content));
117 public void setNetconfSession(final NetconfServerSession s) {
121 @XmlRootElement(name = "notifications")
122 public static final class Notifications {
124 @javax.xml.bind.annotation.XmlElement(nillable = false, name = "notification", required = true)
125 private List<Notification> notificationList;
127 public List<Notification> getNotificationList() {
128 return notificationList;
132 public String toString() {
133 final StringBuffer sb = new StringBuffer("Notifications{");
134 sb.append("notificationList=").append(notificationList);
136 return sb.toString();
140 public static final class Notification {
142 @javax.xml.bind.annotation.XmlElement(nillable = false, name = "delay")
143 private long delayInSeconds;
145 @javax.xml.bind.annotation.XmlElement(nillable = false, name = "times")
148 @javax.xml.bind.annotation.XmlElement(nillable = false, name = "content", required = true)
149 private String content;
151 public long getDelayInSeconds() {
152 return delayInSeconds;
155 public long getTimes() {
159 public String getContent() {
164 public String toString() {
165 final StringBuffer sb = new StringBuffer("Notification{");
166 sb.append("delayInSeconds=").append(delayInSeconds);
167 sb.append(", times=").append(times);
168 sb.append(", content='").append(content).append('\'');
170 return sb.toString();