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%2Fosgi%2FNetconfOperationRouterImpl.java;h=9d58bd911c828bfcba3b185b3db20dc9c0d87985;hp=80ba8388efe6671275bdfadc67d7b07979d1f6f2;hb=3927509ec3ecfa32a51b725d2b7155d425f5b877;hpb=3ab0ebe1df3e7606cce0a61572f79bf12deb17c0 diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index 80ba8388ef..9d58bd911c 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -8,123 +8,83 @@ package org.opendaylight.controller.netconf.impl.osgi; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.NavigableMap; +import java.util.Set; +import java.util.TreeMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfOperationRouter; -import org.opendaylight.controller.netconf.api.NetconfSession; -import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; -import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; +import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; +import org.opendaylight.controller.netconf.impl.CommitNotifier; +import org.opendaylight.controller.netconf.impl.NetconfServerSession; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit; -import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultGetSchema; +import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStartExi; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopExi; -import org.opendaylight.controller.netconf.mapping.api.DefaultNetconfOperation; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.mapping.api.SessionAwareNetconfOperation; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - public class NetconfOperationRouterImpl implements NetconfOperationRouter { - private static final Logger logger = LoggerFactory.getLogger(NetconfOperationRouterImpl.class); - - private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; - private Set allNetconfOperations; - - private NetconfOperationRouterImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { - this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; - } - - private void initNetconfOperations(Set allOperations) { - allNetconfOperations = allOperations; - } - - /** - * Factory method to produce instance of NetconfOperationRouter - */ - public static NetconfOperationRouter createOperationRouter(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot, - CapabilityProvider capabilityProvider, DefaultCommitNotificationProducer commitNotifier) { - NetconfOperationRouterImpl router = new NetconfOperationRouterImpl(netconfOperationServiceSnapshot); - - Preconditions.checkNotNull(netconfOperationServiceSnapshot); - Preconditions.checkNotNull(capabilityProvider); - - final String sessionId = netconfOperationServiceSnapshot.getNetconfSessionIdForReporting(); + private static final Logger LOG = LoggerFactory.getLogger(NetconfOperationRouterImpl.class); + private final NetconfOperationService netconfOperationServiceSnapshot; + private final Collection allNetconfOperations; - final Set defaultNetconfOperations = Sets.newHashSet(); - defaultNetconfOperations.add(new DefaultGetSchema(capabilityProvider, sessionId)); - defaultNetconfOperations.add(new DefaultCloseSession(sessionId, router)); - defaultNetconfOperations.add(new DefaultStartExi(sessionId)); - defaultNetconfOperations.add(new DefaultStopExi(sessionId)); - defaultNetconfOperations.add(new DefaultCommit(commitNotifier, capabilityProvider, sessionId, router)); + public NetconfOperationRouterImpl(final NetconfOperationService netconfOperationServiceSnapshot, + final CommitNotifier commitNotifier, final NetconfMonitoringService netconfMonitoringService, final String sessionId) { + this.netconfOperationServiceSnapshot = Preconditions.checkNotNull(netconfOperationServiceSnapshot); - router.initNetconfOperations(getAllNetconfOperations(defaultNetconfOperations, netconfOperationServiceSnapshot)); + final Set ops = new HashSet<>(); + ops.add(new DefaultCloseSession(sessionId, this)); + ops.add(new DefaultStartExi(sessionId)); + ops.add(new DefaultStopExi(sessionId)); + ops.add(new DefaultCommit(commitNotifier, netconfMonitoringService, sessionId, this)); - return router; - } + ops.addAll(netconfOperationServiceSnapshot.getNetconfOperations()); - private static Set getAllNetconfOperations(Set defaultNetconfOperations, - NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) { - Set result = new HashSet<>(); - result.addAll(defaultNetconfOperations); - - for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) { - final Set netOpsFromService = netconfOperationService.getNetconfOperations(); - for (NetconfOperation netconfOperation : netOpsFromService) { - Preconditions.checkState(result.contains(netconfOperation) == false, - "Netconf operation %s already present", netconfOperation); - result.add(netconfOperation); - } - } - return Collections.unmodifiableSet(result); + allNetconfOperations = ImmutableSet.copyOf(ops); } @Override - public synchronized Document onNetconfMessage(Document message, - NetconfSession session) throws NetconfDocumentedException { + public Document onNetconfMessage(final Document message, final NetconfServerSession session) throws NetconfDocumentedException { Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly"); - NetconfOperationExecution netconfOperationExecution; - String messageAsString = XmlUtil.toString(message); - + final NetconfOperationExecution netconfOperationExecution; try { netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session); } catch (IllegalArgumentException | IllegalStateException e) { - logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e); - - String errorMessage = String.format("Unable to handle rpc %s on session %s", messageAsString, session); - Map errorInfo = Maps.newHashMap(); + final String messageAsString = XmlUtil.toString(message); + LOG.warn("Unable to handle rpc {} on session {}", messageAsString, session, e); - NetconfDocumentedException.ErrorTag tag; + final NetconfDocumentedException.ErrorTag tag; if (e instanceof IllegalArgumentException) { - errorInfo.put(NetconfDocumentedException.ErrorTag.operation_not_supported.toString(), e.getMessage()); tag = NetconfDocumentedException.ErrorTag.operation_not_supported; } else { - errorInfo.put(NetconfDocumentedException.ErrorTag.operation_failed.toString(), e.getMessage()); tag = NetconfDocumentedException.ErrorTag.operation_failed; } - throw new NetconfDocumentedException(errorMessage, e, NetconfDocumentedException.ErrorType.application, - tag, NetconfDocumentedException.ErrorSeverity.error, errorInfo); + throw new NetconfDocumentedException( + String.format("Unable to handle rpc %s on session %s", messageAsString, session), + e, NetconfDocumentedException.ErrorType.application, + tag, NetconfDocumentedException.ErrorSeverity.error, + Collections.singletonMap(tag.toString(), e.getMessage())); } catch (RuntimeException e) { throw handleUnexpectedEx("Unexpected exception during netconf operation sort", e); } try { - return executeOperationWithHighestPriority(message, netconfOperationExecution, messageAsString); + return executeOperationWithHighestPriority(message, netconfOperationExecution); } catch (RuntimeException e) { throw handleUnexpectedEx("Unexpected exception during netconf operation execution", e); } @@ -135,39 +95,41 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { netconfOperationServiceSnapshot.close(); } - private NetconfDocumentedException handleUnexpectedEx(String s, Exception e) throws NetconfDocumentedException { - logger.error(s, e); - - Map info = Maps.newHashMap(); - info.put(NetconfDocumentedException.ErrorSeverity.error.toString(), e.toString()); + private static NetconfDocumentedException handleUnexpectedEx(final String s, final Exception e) throws NetconfDocumentedException { + LOG.error("{}", s, e); return new NetconfDocumentedException("Unexpected error", NetconfDocumentedException.ErrorType.application, NetconfDocumentedException.ErrorTag.operation_failed, - NetconfDocumentedException.ErrorSeverity.error, info); + NetconfDocumentedException.ErrorSeverity.error, + Collections.singletonMap(NetconfDocumentedException.ErrorSeverity.error.toString(), e.toString())); } - private Document executeOperationWithHighestPriority(Document message, - NetconfOperationExecution netconfOperationExecution, String messageAsString) + private Document executeOperationWithHighestPriority(final Document message, + final NetconfOperationExecution netconfOperationExecution) throws NetconfDocumentedException { - logger.debug("Forwarding netconf message {} to {}", messageAsString, netconfOperationExecution.netconfOperation); + if (LOG.isDebugEnabled()) { + LOG.debug("Forwarding netconf message {} to {}", XmlUtil.toString(message), netconfOperationExecution.netconfOperation); + } + return netconfOperationExecution.execute(message); } private NetconfOperationExecution getNetconfOperationWithHighestPriority( - Document message, NetconfSession session) { + final Document message, final NetconfServerSession session) throws NetconfDocumentedException { - TreeMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( + NavigableMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( message, session); - Preconditions.checkArgument(sortedByPriority.isEmpty() == false, - "No %s available to handleWithNoSubsequentOperations message %s", NetconfOperation.class.getName(), - XmlUtil.toString(message)); + if (sortedByPriority.isEmpty()) { + throw new IllegalArgumentException(String.format("No %s available to handle message %s", + NetconfOperation.class.getName(), XmlUtil.toString(message))); + } return NetconfOperationExecution.createExecutionChain(sortedByPriority, sortedByPriority.lastKey()); } - private TreeMap getSortedNetconfOperationsWithCanHandle(Document message, - NetconfSession session) { + private TreeMap getSortedNetconfOperationsWithCanHandle(final Document message, + final NetconfServerSession session) throws NetconfDocumentedException { TreeMap sortedPriority = Maps.newTreeMap(); for (NetconfOperation netconfOperation : allNetconfOperations) { @@ -175,22 +137,40 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { if (netconfOperation instanceof DefaultNetconfOperation) { ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session); } - if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) { + if(netconfOperation instanceof SessionAwareNetconfOperation) { + ((SessionAwareNetconfOperation) netconfOperation).setSession(session); + } + if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) { - Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false, - "Multiple %s available to handle message %s with priority %s", - NetconfOperation.class.getName(), message, handlingPriority); + Preconditions.checkState(!sortedPriority.containsKey(handlingPriority), + "Multiple %s available to handle message %s with priority %s, %s and %s", + NetconfOperation.class.getName(), message, handlingPriority, netconfOperation, sortedPriority.get(handlingPriority)); sortedPriority.put(handlingPriority, netconfOperation); } } return sortedPriority; } + public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() { + @Override + public boolean isExecutionTermination() { + return true; + } + + @Override + public Document execute(final Document requestMessage) throws NetconfDocumentedException { + throw new NetconfDocumentedException("This execution represents the termination point in operation execution and cannot be executed itself", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } + }; + private static class NetconfOperationExecution implements NetconfOperationChainedExecution { private final NetconfOperation netconfOperation; - private NetconfOperationChainedExecution subsequentExecution; + private final NetconfOperationChainedExecution subsequentExecution; - private NetconfOperationExecution(NetconfOperation netconfOperation, NetconfOperationChainedExecution subsequentExecution) { + private NetconfOperationExecution(final NetconfOperation netconfOperation, final NetconfOperationChainedExecution subsequentExecution) { this.netconfOperation = netconfOperation; this.subsequentExecution = subsequentExecution; } @@ -201,12 +181,12 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } @Override - public Document execute(Document message) throws NetconfDocumentedException { + public Document execute(final Document message) throws NetconfDocumentedException { return netconfOperation.handle(message, subsequentExecution); } public static NetconfOperationExecution createExecutionChain( - TreeMap sortedByPriority, HandlingPriority handlingPriority) { + final NavigableMap sortedByPriority, final HandlingPriority handlingPriority) { NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority); HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);