X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fimpl%2FNetconfServerSessionNegotiatorFactory.java;h=996bb275877dd74f336db4a410e765fb12f25424;hp=9ffb8da1dd975fc6592e2b789e49e7f5492e0069;hb=b5e3b3f436f8534ddb6c7f326ccbef995b96ddc3;hpb=72a2f458d328d443e2a5479ac147c1242a41a70f diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index 9ffb8da1dd..996bb27587 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -8,67 +8,80 @@ package org.opendaylight.controller.netconf.impl; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import io.netty.channel.Channel; import io.netty.util.Timer; import io.netty.util.concurrent.Promise; - -import java.io.InputStream; - -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; - +import java.util.Set; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences; -import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; -import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; -import org.opendaylight.controller.netconf.util.NetconfUtil; +import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; +import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage; -import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil; -import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; -import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.protocol.framework.SessionListenerFactory; import org.opendaylight.protocol.framework.SessionNegotiator; import org.opendaylight.protocol.framework.SessionNegotiatorFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - -import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory { - public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml"; + public static final Set DEFAULT_BASE_CAPABILITIES = ImmutableSet.of( + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 + ); private final Timer timer; - private static final Document helloMessageTemplate = loadHelloMessageTemplate(); private final SessionIdProvider idProvider; - private final NetconfOperationProvider netconfOperationProvider; + private final NetconfOperationServiceFactory aggregatedOpService; private final long connectionTimeoutMillis; - private final DefaultCommitNotificationProducer commitNotificationProducer; - private final SessionMonitoringService monitoringService; + private final CommitNotifier commitNotificationProducer; + private final NetconfMonitoringService monitoringService; + private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class); + private final Set baseCapabilities; + + // TODO too many params, refactor + public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider, + final SessionIdProvider idProvider, final long connectionTimeoutMillis, + final CommitNotifier commitNot, + final NetconfMonitoringService monitoringService) { + this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, commitNot, monitoringService, DEFAULT_BASE_CAPABILITIES); + } - public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider, - SessionIdProvider idProvider, long connectionTimeoutMillis, - DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) { + // TODO too many params, refactor + public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider, + final SessionIdProvider idProvider, final long connectionTimeoutMillis, + final CommitNotifier commitNot, + final NetconfMonitoringService monitoringService, final Set baseCapabilities) { this.timer = timer; - this.netconfOperationProvider = netconfOperationProvider; + this.aggregatedOpService = netconfOperationProvider; this.idProvider = idProvider; this.connectionTimeoutMillis = connectionTimeoutMillis; this.commitNotificationProducer = commitNot; this.monitoringService = monitoringService; + this.baseCapabilities = validateBaseCapabilities(baseCapabilities); } - private static Document loadHelloMessageTemplate() { - InputStream resourceAsStream = NetconfServerSessionNegotiatorFactory.class - .getResourceAsStream(SERVER_HELLO_XML_LOCATION); - Preconditions.checkNotNull(resourceAsStream, "Unable to load server hello message blueprint from %s", - SERVER_HELLO_XML_LOCATION); - return NetconfUtil.createMessage(resourceAsStream).getDocument(); + private ImmutableSet validateBaseCapabilities(final Set baseCapabilities) { + // Check base capabilities to be supported by the server + final Sets.SetView unknownBaseCaps = Sets.difference(baseCapabilities, DEFAULT_BASE_CAPABILITIES); + Preconditions.checkArgument(unknownBaseCaps.isEmpty(), + "Base capabilities that will be supported by netconf server have to be subset of %s, unknown base capabilities: %s", + DEFAULT_BASE_CAPABILITIES, unknownBaseCaps); + + final ImmutableSet.Builder b = ImmutableSet.builder(); + b.addAll(baseCapabilities); + // Base 1.0 capability is supported by default + b.add(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0); + return b.build(); } /** @@ -81,50 +94,33 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF * @return session negotiator */ @Override - public SessionNegotiator getSessionNegotiator(SessionListenerFactory defunctSessionListenerFactory, - Channel channel, Promise promise) { - long sessionId = idProvider.getNextSessionId(); - NetconfOperationServiceSnapshot netconfOperationServiceSnapshot = netconfOperationProvider.openSnapshot( - getNetconfSessionIdForReporting(sessionId)); - CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot); - - NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences( - createHelloMessage(sessionId, capabilityProvider), sessionId); - - NetconfServerSessionListenerFactory sessionListenerFactory = new NetconfServerSessionListenerFactory( - commitNotificationProducer, monitoringService, - netconfOperationServiceSnapshot, capabilityProvider); + public SessionNegotiator getSessionNegotiator(final SessionListenerFactory defunctSessionListenerFactory, + final Channel channel, final Promise promise) { + final long sessionId = idProvider.getNextSessionId(); + + NetconfServerSessionPreferences proposal; + try { + proposal = new NetconfServerSessionPreferences(createHelloMessage(sessionId, monitoringService), sessionId); + } catch (final NetconfDocumentedException e) { + LOG.error("Unable to create hello message for session {} with {}", sessionId, monitoringService); + throw new IllegalStateException(e); + } return new NetconfServerSessionNegotiator(proposal, promise, channel, timer, - sessionListenerFactory.getSessionListener(), connectionTimeoutMillis); + getListener(Long.toString(sessionId)), connectionTimeoutMillis); } - private static final XPathExpression sessionIdXPath = XMLNetconfUtil - .compileXPath("/netconf:hello/netconf:session-id"); - private static final XPathExpression capabilitiesXPath = XMLNetconfUtil - .compileXPath("/netconf:hello/netconf:capabilities"); - - private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) { - Document helloMessageTemplate = getHelloTemplateClone(); + private NetconfServerSessionListener getListener(final String netconfSessionIdForReporting) { + final NetconfOperationService service = + this.aggregatedOpService.createService(netconfSessionIdForReporting); + final NetconfOperationRouter operationRouter = + new NetconfOperationRouterImpl(service, commitNotificationProducer, monitoringService, netconfSessionIdForReporting); + return new NetconfServerSessionListener(operationRouter, monitoringService, service); - // change session ID - final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, helloMessageTemplate, - XPathConstants.NODE); - sessionIdNode.setTextContent(String.valueOf(sessionId)); - - // add capabilities from yang store - final Element capabilitiesElement = (Element) XmlUtil.evaluateXPath(capabilitiesXPath, helloMessageTemplate, - XPathConstants.NODE); - - for (String capability : capabilityProvider.getCapabilities()) { - final Element capabilityElement = XmlUtil.createElement(helloMessageTemplate, XmlNetconfConstants.CAPABILITY, Optional.absent()); - capabilityElement.setTextContent(capability); - capabilitiesElement.appendChild(capabilityElement); - } - return new NetconfHelloMessage(helloMessageTemplate); } - private synchronized Document getHelloTemplateClone() { - return (Document) helloMessageTemplate.cloneNode(true); + private NetconfHelloMessage createHelloMessage(final long sessionId, final NetconfMonitoringService capabilityProvider) throws NetconfDocumentedException { + return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), baseCapabilities), sessionId); } + }