X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fimpl%2FNetconfServerSessionListener.java;h=951d0dd98d7d2b52bb13e6fc21a8f88673c74de6;hb=e5af39cc8b49e7e0169980c9e4b8017f7d481d48;hp=43e55d746a4ee59d1ec9bb35245f74e0edbca018;hpb=0a23c5e6383fe72e6c5f59aa727ae2b27bb966f5;p=controller.git diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index 43e55d746a..951d0dd98d 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -8,65 +8,76 @@ package org.opendaylight.controller.netconf.impl; + import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.api.NetconfSessionListener; import org.opendaylight.controller.netconf.api.NetconfTerminationReason; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl; +import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants; +import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil; import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.opendaylight.protocol.framework.SessionListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import static com.google.common.base.Preconditions.checkState; - -public class NetconfServerSessionListener implements - SessionListener { +public class NetconfServerSessionListener implements NetconfSessionListener { - static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class); - public static final String MESSAGE_ID = "message-id"; + private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionListener.class); private final SessionMonitoringService monitoringService; + private final NetconfOperationRouter operationRouter; + private final AutoCloseable onSessionDownCloseable; - private NetconfOperationRouterImpl operationRouter; - - public NetconfServerSessionListener(NetconfOperationRouterImpl operationRouter, - SessionMonitoringService monitoringService) { + public NetconfServerSessionListener(final NetconfOperationRouter operationRouter, final SessionMonitoringService monitoringService, + final AutoCloseable onSessionDownCloseable) { this.operationRouter = operationRouter; this.monitoringService = monitoringService; + this.onSessionDownCloseable = onSessionDownCloseable; } @Override - public void onSessionUp(NetconfServerSession netconfNetconfServerSession) { + public void onSessionUp(final NetconfServerSession netconfNetconfServerSession) { monitoringService.onSessionUp(netconfNetconfServerSession); } @Override - public void onSessionDown(NetconfServerSession netconfNetconfServerSession, Exception e) { - logger.debug("Session {} down, reason: {}", netconfNetconfServerSession, e.getMessage()); + public void onSessionDown(final NetconfServerSession netconfNetconfServerSession, final Exception cause) { + LOG.debug("Session {} down, reason: {}", netconfNetconfServerSession, cause.getMessage()); + onDown(netconfNetconfServerSession); + } + + public void onDown(final NetconfServerSession netconfNetconfServerSession) { monitoringService.onSessionDown(netconfNetconfServerSession); - operationRouter.close(); + try { + operationRouter.close(); + } catch (Exception closingEx) { + LOG.debug("Ignoring exception while closing operationRouter", closingEx); + } + try { + onSessionDownCloseable.close(); + } catch(Exception ex){ + LOG.debug("Ignoring exception while closing onSessionDownCloseable", ex); + } } @Override - public void onSessionTerminated(NetconfServerSession netconfNetconfServerSession, - NetconfTerminationReason netconfTerminationReason) { - logger.debug("Session {} terminated, reason: {}", netconfNetconfServerSession, + public void onSessionTerminated(final NetconfServerSession netconfNetconfServerSession, + final NetconfTerminationReason netconfTerminationReason) { + LOG.debug("Session {} terminated, reason: {}", netconfNetconfServerSession, netconfTerminationReason.getErrorMessage()); - monitoringService.onSessionDown(netconfNetconfServerSession); - - operationRouter.close(); + onDown(netconfNetconfServerSession); } @Override - public void onMessage(NetconfServerSession session, NetconfMessage netconfMessage) { + public void onMessage(final NetconfServerSession session, final NetconfMessage netconfMessage) { try { Preconditions.checkState(operationRouter != null, "Cannot handle message, session up was not yet received"); @@ -74,7 +85,7 @@ public class NetconfServerSessionListener implements // schemas final NetconfMessage message = processDocument(netconfMessage, session); - logger.debug("Responding with message {}", XmlUtil.toString(message.getDocument())); + LOG.debug("Responding with message {}", message); session.sendMessage(message); if (isCloseSession(netconfMessage)) { @@ -83,34 +94,38 @@ public class NetconfServerSessionListener implements } catch (final RuntimeException e) { // TODO: should send generic error or close session? - logger.error("Unexpected exception", e); + LOG.error("Unexpected exception", e); session.onIncommingRpcFail(); - throw new RuntimeException("Unable to process incoming message " + netconfMessage, e); + throw new IllegalStateException("Unable to process incoming message " + netconfMessage, e); } catch (NetconfDocumentedException e) { + LOG.trace("Error occurred while processing message",e); session.onOutgoingRpcError(); session.onIncommingRpcFail(); SendErrorExceptionUtil.sendErrorMessage(session, e, netconfMessage); } } - private void closeNetconfSession(NetconfServerSession session) { + private void closeNetconfSession(final NetconfServerSession session) { // destroy NetconfOperationService session.close(); - logger.info("Session {} closed successfully", session.getSessionId()); + LOG.info("Session {} closed successfully", session.getSessionId()); } - private NetconfMessage processDocument(final NetconfMessage netconfMessage, - NetconfServerSession session) throws NetconfDocumentedException { - final Document incommingDocument = netconfMessage.getDocument(); - final Node rootNode = incommingDocument.getDocumentElement(); + + private NetconfMessage processDocument(final NetconfMessage netconfMessage, final NetconfServerSession session) + throws NetconfDocumentedException { + + final Document incomingDocument = netconfMessage.getDocument(); + final Node rootNode = incomingDocument.getDocumentElement(); if (rootNode.getLocalName().equals(XmlNetconfConstants.RPC_KEY)) { - final String messageId = rootNode.getAttributes().getNamedItem(MESSAGE_ID).getTextContent(); - checkState(messageId != null); final Document responseDocument = XmlUtil.newDocument(); - Document rpcReply = operationRouter.onNetconfMessage( - incommingDocument, session); + checkMessageId(rootNode); + + Document rpcReply = operationRouter.onNetconfMessage(incomingDocument, session); + + rpcReply = SubtreeFilter.applySubtreeFilter(incomingDocument, rpcReply); session.onIncommingRpcSuccess(); @@ -131,11 +146,31 @@ public class NetconfServerSessionListener implements } } - private static boolean isCloseSession(final NetconfMessage incommingDocument) { - final Document document = incommingDocument.getDocument(); + private void checkMessageId(final Node rootNode) throws NetconfDocumentedException { + + NamedNodeMap attributes = rootNode.getAttributes(); + + if(attributes.getNamedItemNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlNetconfConstants.MESSAGE_ID)!=null) { + return; + } + + if(attributes.getNamedItem(XmlNetconfConstants.MESSAGE_ID)!=null) { + return; + } + + throw new NetconfDocumentedException("Missing attribute" + rootNode.getNodeName(), + NetconfDocumentedException.ErrorType.protocol, NetconfDocumentedException.ErrorTag.missing_attribute, + NetconfDocumentedException.ErrorSeverity.error, + ImmutableMap.of(NetconfDocumentedException.ErrorTag.missing_attribute.toString(), + XmlNetconfConstants.MESSAGE_ID)); + } + + private static boolean isCloseSession(final NetconfMessage incomingDocument) { + final Document document = incomingDocument.getDocument(); XmlElement rpcElement = XmlElement.fromDomDocument(document); - if (rpcElement.getOnlyChildElementOptionally("close-session").isPresent()) + if (rpcElement.getOnlyChildElementOptionally(DefaultCloseSession.CLOSE_SESSION).isPresent()) { return true; + } return false; }