X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=netconf-server%2Fsrc%2Fmain%2Fjava%2Forg%2Fcommscope%2Ftr069adapter%2Fnetconf%2Frpc%2FCreateSubscription.java;h=70350f89c0f92dc55221b03ae1177f305b27e117;hb=76744e810f35c84ecbd1d9998e361052466e9483;hp=a5ac333b4cb6ffba1f484f3b2d34b3006ed0030c;hpb=ce4e2d38e3d42725f61c39dd172325d2def4bc44;p=oam%2Ftr069-adapter.git diff --git a/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/rpc/CreateSubscription.java b/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/rpc/CreateSubscription.java index a5ac333..70350f8 100644 --- a/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/rpc/CreateSubscription.java +++ b/netconf-server/src/main/java/org/commscope/tr069adapter/netconf/rpc/CreateSubscription.java @@ -1,238 +1,240 @@ -/* - * ============LICENSE_START======================================================================== - * ONAP : tr-069-adapter - * ================================================================================================= - * Copyright (C) 2020 CommScope Inc Intellectual Property. - * ================================================================================================= - * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License, - * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You - * may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific language governing permissions and - * limitations under the License. - * ===============LICENSE_END======================================================================= - */ - -package org.commscope.tr069adapter.netconf.rpc; - -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; -import javax.xml.bind.annotation.XmlRootElement; -import org.commscope.tr069adapter.netconf.error.NetconfNotificationException; -import org.opendaylight.netconf.api.NetconfMessage; -import org.opendaylight.netconf.api.xml.XmlElement; -import org.opendaylight.netconf.api.xml.XmlNetconfConstants; -import org.opendaylight.netconf.api.xml.XmlUtil; -import org.opendaylight.netconf.impl.NetconfServerSession; -import org.opendaylight.netconf.impl.mapping.operations.DefaultNetconfOperation; -import org.opendaylight.netconf.util.mapping.AbstractLastNetconfOperation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.SAXException; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; - -public class CreateSubscription extends AbstractLastNetconfOperation - implements DefaultNetconfOperation { - - private static final Logger logger = LoggerFactory.getLogger(CreateSubscription.class); - private final Map notifications; - private NetconfServerSession session; - private ScheduledExecutorService scheduledExecutorService; - private static Map netconfServerSessionMap = new HashMap<>(); - private String deviceID; - private String swVersion; - private String hwVersion; - - public CreateSubscription(final String id, final Optional notificationsFile, - String deviceID, String swVersion, String hwVersion) { - - super(id); - - logger.debug("CreateSubscription RPC is created with macID {}", deviceID); - this.deviceID = deviceID; - this.swVersion = swVersion; - this.hwVersion = hwVersion; - - final Optional notifs; - - if (notificationsFile.isPresent()) { - notifs = Optional.of(loadNotifications(notificationsFile.get())); - scheduledExecutorService = Executors.newScheduledThreadPool(1); - } else { - notifs = Optional.empty(); - } - - if (notifs.isPresent()) { - final Collection toCopy = notifs.get().getNotificationList(); - final Map preparedMessages = - Maps.newHashMapWithExpectedSize(toCopy.size()); - for (final Notification notification : toCopy) { - final NetconfMessage parsedNotification = - parseNetconfNotification(notification.getContent()); - preparedMessages.put(notification, parsedNotification); - } - this.notifications = preparedMessages; - } else { - this.notifications = Collections.emptyMap(); - } - } - - private static Notifications loadNotifications(final File file) { - try { - final JAXBContext jaxbContext = JAXBContext.newInstance(Notifications.class); - final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); - return (Notifications) jaxbUnmarshaller.unmarshal(file); - } catch (final JAXBException e) { - throw new IllegalArgumentException("can not parse file " + file + " as a notifications file", - e); - } - } - - @Override - protected String getOperationName() { - return "create-subscription"; - } - - @Override - protected String getOperationNamespace() { - return "urn:ietf:params:xml:ns:netconf:notification:1.0"; - } - - @Override - protected Element handleWithNoSubsequentOperations(final Document document, - final XmlElement operationElement) { - long delayAggregator = 0; - for (final Map.Entry notification : notifications.entrySet()) { - for (int i = 0; i <= notification.getKey().getTimes(); i++) { - - delayAggregator += notification.getKey().getDelayInSeconds(); - - scheduledExecutorService.schedule(() -> { - Preconditions.checkState(session != null, - "Session is not set, cannot process notifications"); - session.sendMessage(notification.getValue()); - }, delayAggregator, TimeUnit.SECONDS); - } - } - return document.createElement(XmlNetconfConstants.OK); - } - - private static NetconfMessage parseNetconfNotification(String content) { - final int startEventTime = content.indexOf("") + "".length(); - final int endEventTime = content.indexOf(""); - final String eventTime = content.substring(startEventTime, endEventTime); - if (eventTime.equals("XXXX")) { - content = content.replace(eventTime, - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date())); - } - - try { - return new NetconfMessage(XmlUtil.readXmlToDocument(content)); - } catch (SAXException | IOException e) { - throw new IllegalArgumentException("Cannot parse notifications", e); - } - } - - @Override - public void setNetconfSession(final NetconfServerSession newSession) { - logger.debug("Adding netconf session to notification server sessions map : {}", newSession); - logger.debug("This CreateSubscription is setup to support macID= {}", deviceID); - this.session = newSession; - netconfServerSessionMap.put(deviceID, newSession); - } - - public static void sendNotification(NetconfMessage netconfMessage, String deviceID) - throws NetconfNotificationException { - logger.debug("Request to send notification. NetConfMessage : {}", netconfMessage); - NetconfServerSession session = netconfServerSessionMap.get(deviceID); - if (session != null && session.isUp()) { - try { - session.sendMessage(netconfMessage); - logger.debug("Successfully send notification for deviceID: {}", deviceID); - } catch (Exception e) { - logger.error("Failed to send notification. while posting got error. {}", e.toString()); - throw new NetconfNotificationException("Exception while posting the netconf message", e); - } - - } else { - logger.debug( - "Failed to send notification. None of valid netconf session is available for {}.", - deviceID); - logger.debug("Available netconf sessions : {}", netconfServerSessionMap); - throw new NetconfNotificationException("NetConf active session deosn't not exist"); - } - } - - @XmlRootElement(name = "notifications") - public static final class Notifications { - - @javax.xml.bind.annotation.XmlElement(nillable = false, name = "notification", required = true) - private List notificationList; - - public List getNotificationList() { - return notificationList; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Notifications{"); - sb.append("notificationList=").append(notificationList); - sb.append('}'); - return sb.toString(); - } - } - - public static final class Notification { - - @javax.xml.bind.annotation.XmlElement(nillable = false, name = "delay") - private long delayInSeconds; - - @javax.xml.bind.annotation.XmlElement(nillable = false, name = "times") - private long times; - - @javax.xml.bind.annotation.XmlElement(nillable = false, name = "content", required = true) - private String content; - - public long getDelayInSeconds() { - return delayInSeconds; - } - - public long getTimes() { - return times; - } - - public String getContent() { - return content; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Notification{"); - sb.append("delayInSeconds=").append(delayInSeconds); - sb.append(", times=").append(times); - sb.append(", content='").append(content).append('\''); - sb.append('}'); - return sb.toString(); - } - } -} +/* + * ============LICENSE_START======================================================================== + * ONAP : tr-069-adapter + * ================================================================================================= + * Copyright (C) 2020 CommScope Inc Intellectual Property. + * ================================================================================================= + * This tr-069-adapter software file is distributed by CommScope Inc under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language governing permissions and + * limitations under the License. + * ===============LICENSE_END======================================================================= + */ + +package org.commscope.tr069adapter.netconf.rpc; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.annotation.XmlRootElement; +import org.commscope.tr069adapter.netconf.error.NetconfNotificationException; +import org.opendaylight.netconf.api.NetconfMessage; +import org.opendaylight.netconf.api.xml.XmlElement; +import org.opendaylight.netconf.api.xml.XmlNetconfConstants; +import org.opendaylight.netconf.api.xml.XmlUtil; +import org.opendaylight.netconf.impl.NetconfServerSession; +import org.opendaylight.netconf.impl.mapping.operations.DefaultNetconfOperation; +import org.opendaylight.netconf.util.mapping.AbstractLastNetconfOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +public class CreateSubscription extends AbstractLastNetconfOperation + implements DefaultNetconfOperation { + + private static final Logger logger = LoggerFactory.getLogger(CreateSubscription.class); + private final Map notifications; + private NetconfServerSession session; + private ScheduledExecutorService scheduledExecutorService; + private static Map netconfServerSessionMap = new HashMap<>(); + private String deviceID; + private String swVersion; + private String hwVersion; + + public CreateSubscription(final String id, final Optional notificationsFile, + String deviceID, String swVersion, String hwVersion) { + + super(id); + + logger.debug("CreateSubscription RPC is created with macID {}", deviceID); + this.deviceID = deviceID; + this.swVersion = swVersion; + this.hwVersion = hwVersion; + + final Optional notifs; + + if (notificationsFile.isPresent()) { + notifs = Optional.of(loadNotifications(notificationsFile.get())); + scheduledExecutorService = Executors.newScheduledThreadPool(1); + } else { + notifs = Optional.empty(); + } + + if (notifs.isPresent()) { + final Collection toCopy = notifs.get().getNotificationList(); + final Map preparedMessages = + Maps.newHashMapWithExpectedSize(toCopy.size()); + for (final Notification notification : toCopy) { + final NetconfMessage parsedNotification = + parseNetconfNotification(notification.getContent()); + preparedMessages.put(notification, parsedNotification); + } + this.notifications = preparedMessages; + } else { + this.notifications = Collections.emptyMap(); + } + } + + private static Notifications loadNotifications(final File file) { + try { + final JAXBContext jaxbContext = JAXBContext.newInstance(Notifications.class); + final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + return (Notifications) jaxbUnmarshaller.unmarshal(file); + } catch (final JAXBException e) { + throw new IllegalArgumentException("can not parse file " + file + " as a notifications file", + e); + } + } + + @Override + protected String getOperationName() { + return "create-subscription"; + } + + @Override + protected String getOperationNamespace() { + return "urn:ietf:params:xml:ns:netconf:notification:1.0"; + } + + @Override + protected Element handleWithNoSubsequentOperations(final Document document, + final XmlElement operationElement) { + long delayAggregator = 0; + for (final Map.Entry notification : notifications.entrySet()) { + for (int i = 0; i <= notification.getKey().getTimes(); i++) { + + delayAggregator += notification.getKey().getDelayInSeconds(); + + scheduledExecutorService.schedule(() -> { + Preconditions.checkState(session != null, + "Session is not set, cannot process notifications"); + session.sendMessage(notification.getValue()); + }, delayAggregator, TimeUnit.SECONDS); + } + } + return document.createElement(XmlNetconfConstants.OK); + } + + private static NetconfMessage parseNetconfNotification(String content) { + final int startEventTime = content.indexOf("") + "".length(); + final int endEventTime = content.indexOf(""); + final String eventTime = content.substring(startEventTime, endEventTime); + if (eventTime.equals("XXXX")) { + content = content.replace(eventTime, + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date())); + } + + try { + return new NetconfMessage(XmlUtil.readXmlToDocument(content)); + } catch (SAXException | IOException e) { + throw new IllegalArgumentException("Cannot parse notifications", e); + } + } + + @Override + public void setNetconfSession(final NetconfServerSession newSession) { + logger.debug("Adding netconf session to notification server sessions map : {}", newSession); + logger.debug("This CreateSubscription is setup to support macID= {}", deviceID); + this.session = newSession; + netconfServerSessionMap.put(deviceID, newSession); + } + + public static void sendNotification(NetconfMessage netconfMessage, String deviceID) + throws NetconfNotificationException { + logger.debug("Request to send notification. NetConfMessage : {}", netconfMessage); + NetconfServerSession session = netconfServerSessionMap.get(deviceID); + if (session != null && session.isUp()) { + try { + session.sendMessage(netconfMessage); + logger.debug("Successfully send notification for deviceID: {}", deviceID); + } catch (Exception e) { + logger.error("Failed to send notification. while posting got error. {}", e.toString()); + throw new NetconfNotificationException("Exception while posting the netconf message", e); + } + + } else { + logger.debug( + "Failed to send notification. None of valid netconf session is available for {}.", + deviceID); + logger.debug("Available netconf sessions : {}", netconfServerSessionMap); + throw new NetconfNotificationException("NetConf active session deosn't not exist"); + } + } + + @XmlRootElement(name = "notifications") + public static final class Notifications { + + @javax.xml.bind.annotation.XmlElement(nillable = false, name = "notification", required = true) + private List notificationList; + + public List getNotificationList() { + return notificationList; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Notifications{"); + sb.append("notificationList=").append(notificationList); + sb.append('}'); + return sb.toString(); + } + } + + public static final class Notification { + + @javax.xml.bind.annotation.XmlElement(nillable = false, name = "delay") + private long delayInSeconds; + + @javax.xml.bind.annotation.XmlElement(nillable = false, name = "times") + private long times; + + @javax.xml.bind.annotation.XmlElement(nillable = false, name = "content", required = true) + private String content; + + public long getDelayInSeconds() { + return delayInSeconds; + } + + public long getTimes() { + return times; + } + + public String getContent() { + return content; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Notification{"); + sb.append("delayInSeconds=").append(delayInSeconds); + sb.append(", times=").append(times); + sb.append(", content='").append(content).append('\''); + sb.append('}'); + return sb.toString(); + } + } +}