+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>config-netconf-connector</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-jmx-generator</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.logback_settings</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-generator-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.confignetconfconnector.osgi.Activator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-
-public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation {
-
- private final ConfigSubsystemFacade configSubsystemFacade;
-
- protected AbstractConfigNetconfOperation(ConfigSubsystemFacade configSubsystemFacade,
- String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- this.configSubsystemFacade = configSubsystemFacade;
- }
-
- public ConfigSubsystemFacade getConfigSubsystemFacade() {
- return configSubsystemFacade;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Commit extends AbstractConfigNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Commit.class);
-
- public Commit(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- private static void checkXml(XmlElement xml) throws DocumentedException {
- xml.checkName(XmlNetconfConstants.COMMIT);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.COMMIT;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
-
- checkXml(xml);
- CommitStatus status;
- try {
- status = getConfigSubsystemFacade().commitTransaction();
- LOG.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
- } catch (ConflictingVersionException | ValidationException e) {
- throw DocumentedException.wrap(e);
- }
- LOG.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import com.google.common.base.Optional;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-
-public class DiscardChanges extends AbstractConfigNetconfOperation {
-
- public static final String DISCARD = "discard-changes";
-
- private static final Logger LOG = LoggerFactory.getLogger(DiscardChanges.class);
-
- public DiscardChanges(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- private static void fromXml(XmlElement xml) throws DocumentedException {
- xml.checkName(DISCARD);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- }
-
- @Override
- protected String getOperationName() {
- return DISCARD;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- fromXml(xml);
- try {
- getConfigSubsystemFacade().abortConfiguration();
- } catch (final RuntimeException e) {
- LOG.warn("Abort failed: ", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo
- .put(ErrorTag.operation_failed.name(),
- "Abort failed.");
- throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
- ErrorSeverity.error, errorInfo);
- }
- LOG.trace("Changes discarded successfully from datastore {}", Datastore.candidate);
-
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Simple Lock implementation that pretends to lock candidate datastore.
- * Candidate datastore is allocated per session and is private so no real locking is needed (JMX is the only possible interference)
- */
-public class Lock extends AbstractLastNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Lock.class);
-
- private static final String LOCK = "lock";
- private static final String TARGET_KEY = "target";
-
- public Lock(final String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Datastore targetDatastore = extractTargetParameter(operationElement);
- if(targetDatastore == Datastore.candidate) {
- // Since candidate datastore instances are allocated per session and not accessible anywhere else, no need to lock
- LOG.debug("Locking {} datastore on session: {}", targetDatastore, getNetconfSessionIdForReporting());
- // TODO should this fail if we are already locked ?
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- // Not supported running lock
- throw new DocumentedException("Unable to lock " + Datastore.running + " datastore", DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
- }
-
- static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
- final XmlElement targetElement = operationElement.getOnlyChildElementWithSameNamespace(TARGET_KEY);
- final XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
-
- return Datastore.valueOf(targetChildNode.getName());
- }
-
- @Override
- protected String getOperationName() {
- return LOCK;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Simple unlock implementation that pretends to unlock candidate datastore.
- * Candidate datastore is allocated per session and is private so no real locking is needed (JMX is the only possible interference)
- */
-public class UnLock extends AbstractLastNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(UnLock.class);
-
- private static final String UNLOCK = "unlock";
-
- public UnLock(final String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Datastore targetDatastore = Lock.extractTargetParameter(operationElement);
- if(targetDatastore == Datastore.candidate) {
- // Since candidate datastore instances are allocated per session and not accessible anywhere else, no need to lock
- LOG.debug("Unlocking {} datastore on session: {}", targetDatastore, getNetconfSessionIdForReporting());
- // TODO this should fail if we are not locked
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- // Not supported running lock
- throw new DocumentedException("Unable to unlock " + Datastore.running + " datastore", DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
- }
-
- @Override
- protected String getOperationName() {
- return UNLOCK;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import com.google.common.base.Optional;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Validate extends AbstractConfigNetconfOperation {
-
- public static final String VALIDATE = "validate";
-
- private static final Logger LOG = LoggerFactory.getLogger(Validate.class);
-
- public Validate(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- private void checkXml(XmlElement xml) throws DocumentedException {
- xml.checkName(VALIDATE);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
- XmlElement sourceElement = xml.getOnlyChildElement(XmlNetconfConstants.SOURCE_KEY,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- XmlElement sourceChildNode = sourceElement.getOnlyChildElement();
-
- sourceChildNode.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- String datastoreValue = sourceChildNode.getName();
- Datastore sourceDatastore = Datastore.valueOf(datastoreValue);
-
- if (sourceDatastore != Datastore.candidate){
- throw new DocumentedException( "Only " + Datastore.candidate
- + " is supported as source for " + VALIDATE + " but was " + datastoreValue, ErrorType.application, ErrorTag.data_missing, ErrorSeverity.error);
- }
- }
-
- @Override
- protected String getOperationName() {
- return VALIDATE;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- checkXml(xml);
- try {
- getConfigSubsystemFacade().validateConfiguration();
- } catch (ValidationException e) {
- LOG.warn("Validation failed", e);
- throw DocumentedException.wrap(e);
- } catch (IllegalStateException e) {
- LOG.warn("Validation failed", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo
- .put(ErrorTag.operation_failed.name(),
- "Datastore is not present. Use 'get-config' or 'edit-config' before triggering 'operations' operation");
- throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
- ErrorSeverity.error, errorInfo);
-
- }
-
- LOG.trace("Datastore {} validated successfully", Datastore.candidate);
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.facade.xml.ConfigExecution;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.mapping.config.Config;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class EditConfig extends AbstractConfigNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(EditConfig.class);
-
- private EditConfigXmlParser editConfigXmlParser;
-
- public EditConfig(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- this.editConfigXmlParser = new EditConfigXmlParser();
- }
-
- @VisibleForTesting
- Element getResponseInternal(final Document document,
- final ConfigExecution configExecution) throws DocumentedException {
-
- try {
- getConfigSubsystemFacade().executeConfigExecution(configExecution);
- } catch (ValidationException e) {
- LOG.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
- throw new DocumentedException("Test phase: " + e.getMessage(), e, ErrorType.application,
- ErrorTag.operation_failed, ErrorSeverity.error, errorInfo);
- }
-
- LOG.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return EditConfigXmlParser.EDIT_CONFIG;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- ConfigExecution configExecution;
- // FIXME config mapping getter works on dynamic yang store service and so does later executeConfigExecution method
- // They might have different view of current yangs in ODL and might cause race conditions
- Config cfg = getConfigSubsystemFacade().getConfigMapping();
- configExecution = editConfigXmlParser.fromXml(xml, cfg);
-
- return getResponseInternal(document, configExecution);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.facade.xml.ConfigExecution;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.facade.xml.TestOption;
-import org.opendaylight.controller.config.facade.xml.mapping.config.Config;
-import org.opendaylight.controller.config.facade.xml.strategy.EditStrategyType;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EditConfigXmlParser {
-
- private static final Logger LOG = LoggerFactory.getLogger(EditConfigXmlParser.class);
-
- public static final String EDIT_CONFIG = "edit-config";
- public static final String DEFAULT_OPERATION_KEY = "default-operation";
- static final String ERROR_OPTION_KEY = "error-option";
- static final String DEFAULT_ERROR_OPTION = "stop-on-error";
- static final String TARGET_KEY = "target";
- static final String TEST_OPTION_KEY = "test-option";
-
- public EditConfigXmlParser() {
- }
-
- ConfigExecution fromXml(final XmlElement xml, final Config cfgMapping)
- throws DocumentedException {
-
- //TODO remove transactionProvider and CfgRegistry from parameters, accept only service ref store
-
- EditStrategyType editStrategyType = EditStrategyType.getDefaultStrategy();
-
- xml.checkName(EditConfigXmlParser.EDIT_CONFIG);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
-
- XmlElement targetElement = null;
- XmlElement targetChildNode = null;
- targetElement = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY);
- targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
-
- String datastoreValue = targetChildNode.getName();
- Datastore targetDatastore = Datastore.valueOf(datastoreValue);
- LOG.debug("Setting {} to '{}'", EditConfigXmlParser.TARGET_KEY, targetDatastore);
-
- // check target
- if (targetDatastore != Datastore.candidate){
- throw new DocumentedException(String.format(
- "Only %s datastore supported for edit config but was: %s",
- Datastore.candidate,
- targetDatastore),
- DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.invalid_value,
- DocumentedException.ErrorSeverity.error);
- }
-
- // Test option
- TestOption testOption;
- Optional<XmlElement> testOptionElementOpt = xml
- .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.TEST_OPTION_KEY);
- if (testOptionElementOpt.isPresent()) {
- String testOptionValue = testOptionElementOpt.get().getTextContent();
- testOption = TestOption.getFromXmlName(testOptionValue);
- } else {
- testOption = TestOption.getDefault();
- }
- LOG.debug("Setting {} to '{}'", EditConfigXmlParser.TEST_OPTION_KEY, testOption);
-
- // Error option
- Optional<XmlElement> errorOptionElement = xml
- .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.ERROR_OPTION_KEY);
- if (errorOptionElement.isPresent()) {
- String errorOptionParsed = errorOptionElement.get().getTextContent();
- if (!errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)){
- throw new UnsupportedOperationException("Only " + EditConfigXmlParser.DEFAULT_ERROR_OPTION
- + " supported for " + EditConfigXmlParser.ERROR_OPTION_KEY + ", was " + errorOptionParsed);
- }
- }
-
- // Default op
- Optional<XmlElement> defaultContent = xml
- .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.DEFAULT_OPERATION_KEY);
- if (defaultContent.isPresent()) {
- String mergeStrategyString = defaultContent.get().getTextContent();
- LOG.trace("Setting merge strategy to {}", mergeStrategyString);
- editStrategyType = EditStrategyType.valueOf(mergeStrategyString);
- }
-
- XmlElement configElement = null;
- configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
-
- return new ConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.get;
-
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Get extends AbstractConfigNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Get.class);
-
- public Get(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- private static void checkXml(XmlElement xml) throws DocumentedException {
- xml.checkName(XmlNetconfConstants.GET);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
- // Filter option: ignore for now, TODO only load modules specified by the filter
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.GET;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- checkXml(xml);
- final Element element = getConfigSubsystemFacade().get(document);
- LOG.trace("{} operation successful", XmlNetconfConstants.GET);
- return element;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.Datastore;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class GetConfig extends AbstractConfigNetconfOperation {
-
- public static final String GET_CONFIG = "get-config";
-
- private final Optional<String> maybeNamespace;
-
- private static final Logger LOG = LoggerFactory.getLogger(GetConfig.class);
-
- public GetConfig(final ConfigSubsystemFacade configSubsystemFacade, final Optional<String> maybeNamespace, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- this.maybeNamespace = maybeNamespace;
- }
-
- public static Datastore fromXml(XmlElement xml) throws DocumentedException {
-
- xml.checkName(GET_CONFIG);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
- XmlElement sourceElement = xml.getOnlyChildElement(XmlNetconfConstants.SOURCE_KEY,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- XmlElement sourceNode = sourceElement.getOnlyChildElement();
- String sourceParsed = sourceNode.getName();
- LOG.debug("Setting source datastore to '{}'", sourceParsed);
- Datastore sourceDatastore = Datastore.valueOf(sourceParsed);
-
- // Filter option: ignore for now, TODO only load modules specified by the filter
-
- return sourceDatastore;
-
- }
-
- @Override
- protected String getOperationName() {
- return GET_CONFIG;
- }
-
- @Override
- public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- return getConfigSubsystemFacade().getConfiguration(document, fromXml(xml), maybeNamespace);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.RpcFacade;
-import org.opendaylight.controller.config.facade.xml.rpc.InstanceRuntimeRpc;
-import org.opendaylight.controller.config.facade.xml.rpc.ModuleRpcs;
-import org.opendaylight.controller.config.facade.xml.rpc.Rpcs;
-import org.opendaylight.controller.config.facade.xml.rpc.RuntimeRpcElementResolved;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class RuntimeRpc extends AbstractConfigNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpc.class);
-
- public RuntimeRpc(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
- super(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
-
- @Override
- public HandlingPriority canHandle(Document message) throws DocumentedException {
- XmlElement requestElement = null;
- requestElement = getRequestElementWithCheck(message);
-
- XmlElement operationElement = requestElement.getOnlyChildElement();
- final String netconfOperationName = operationElement.getName();
- final String netconfOperationNamespace;
- try {
- netconfOperationNamespace = operationElement.getNamespace();
- } catch (DocumentedException e) {
- LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
- return HandlingPriority.CANNOT_HANDLE;
- }
-
- final Optional<XmlElement> contextInstanceElement = operationElement
- .getOnlyChildElementOptionally(RpcFacade.CONTEXT_INSTANCE);
-
- if (!contextInstanceElement.isPresent()){
- return HandlingPriority.CANNOT_HANDLE;
- }
-
- final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
- .getTextContent(), netconfOperationName, netconfOperationNamespace);
-
- // TODO reuse rpcs instance in fromXml method
- final Rpcs rpcs = getConfigSubsystemFacade().getRpcFacade().mapRpcs();
-
- try {
- final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
- final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(),
- netconfOperationName);
- Preconditions.checkState(instanceRuntimeRpc != null, "No rpc found for %s:%s", netconfOperationNamespace,
- netconfOperationName);
- } catch (IllegalStateException e) {
- LOG.debug("Cannot handle runtime operation {}:{}", netconfOperationNamespace, netconfOperationName, e);
- return HandlingPriority.CANNOT_HANDLE;
- }
-
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
- }
-
- @Override
- protected HandlingPriority canHandle(String netconfOperationName, String namespace) {
- throw new UnsupportedOperationException(
- "This should not be used since it is not possible to provide check with these attributes");
- }
-
- @Override
- protected String getOperationName() {
- throw new UnsupportedOperationException("Runtime rpc does not have a stable name");
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
- // TODO check for namespaces and unknown elements
- final RpcFacade.OperationExecution execution = getConfigSubsystemFacade().getRpcFacade().fromXml(xml);
-
- LOG.debug("Invoking operation {} on {} with arguments {}", execution.getOperationName(), execution.getOn(),
- execution.getAttributes());
- final Object result = getConfigSubsystemFacade().getRpcFacade().executeOperation(execution);
-
- LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.getOperationName(),
- execution.getOn(), execution.getAttributes(), result);
-
- if (execution.isVoid()) {
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- } else {
- return getConfigSubsystemFacade().getRpcFacade().toXml(document, result, execution);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
-import org.opendaylight.controller.netconf.api.util.NetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Activator implements BundleActivator {
-
- private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
-
- private ServiceRegistration<?> osgiRegistration;
-
- @Override
- public void start(final BundleContext context) throws Exception {
- ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaServiceTrackerCustomizer = new ServiceTrackerCustomizer<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory>() {
-
- @Override
- public ConfigSubsystemFacadeFactory addingService(ServiceReference<ConfigSubsystemFacadeFactory> reference) {
- LOG.debug("Got addingService(SchemaContextProvider) event");
- // Yang store service should not be registered multiple times
- ConfigSubsystemFacadeFactory configSubsystemFacade = reference.getBundle().getBundleContext().getService(reference);
- osgiRegistration = startNetconfServiceFactory(configSubsystemFacade, context);
- return configSubsystemFacade;
- }
-
- @Override
- public void modifiedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
- LOG.warn("Config manager facade was modified unexpectedly");
- }
-
- @Override
- public void removedService(ServiceReference<ConfigSubsystemFacadeFactory> reference, ConfigSubsystemFacadeFactory service) {
- LOG.warn("Config manager facade was removed unexpectedly");
- }
- };
-
- ServiceTracker<ConfigSubsystemFacadeFactory, ConfigSubsystemFacadeFactory> schemaContextProviderServiceTracker =
- new ServiceTracker<>(context, ConfigSubsystemFacadeFactory.class, schemaServiceTrackerCustomizer);
- schemaContextProviderServiceTracker.open();
- }
-
- @Override
- public void stop(final BundleContext bundleContext) throws Exception {
- if (osgiRegistration != null) {
- osgiRegistration.unregister();
- }
- }
-
- private ServiceRegistration<NetconfOperationServiceFactory> startNetconfServiceFactory(final ConfigSubsystemFacadeFactory configSubsystemFacade, final BundleContext context) {
- final NetconfOperationServiceFactoryImpl netconfOperationServiceFactory = new NetconfOperationServiceFactoryImpl(configSubsystemFacade);
- // Add properties to autowire with netconf-impl instance for cfg subsystem
- final Dictionary<String, String> properties = new Hashtable<>();
- properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.CONFIG_NETCONF_CONNECTOR);
- return context.registerService(NetconfOperationServiceFactory.class, netconfOperationServiceFactory, properties);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Lock;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.UnLock;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Validate;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-
-final class NetconfOperationProvider {
- private final Set<NetconfOperation> operations;
-
- NetconfOperationProvider(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
-
- operations = setUpOperations(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- Set<NetconfOperation> getOperations() {
- return operations;
- }
-
- private static Set<NetconfOperation> setUpOperations(final ConfigSubsystemFacade configSubsystemFacade,
- String netconfSessionIdForReporting) {
- Set<NetconfOperation> ops = Sets.newHashSet();
-
- GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), netconfSessionIdForReporting);
-
- ops.add(getConfigOp);
- ops.add(new EditConfig(configSubsystemFacade, netconfSessionIdForReporting));
- ops.add(new Commit(configSubsystemFacade, netconfSessionIdForReporting));
- ops.add(new Lock(netconfSessionIdForReporting));
- ops.add(new UnLock(netconfSessionIdForReporting));
- ops.add(new Get(configSubsystemFacade, netconfSessionIdForReporting));
- ops.add(new DiscardChanges(configSubsystemFacade, netconfSessionIdForReporting));
- ops.add(new Validate(configSubsystemFacade, netconfSessionIdForReporting));
- ops.add(new RuntimeRpc(configSubsystemFacade, netconfSessionIdForReporting));
-
- return ops;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.capability.ModuleListener;
-import org.opendaylight.controller.config.util.capability.YangModuleCapability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.yangtools.yang.model.api.Module;
-
-public class NetconfOperationServiceFactoryImpl implements NetconfOperationServiceFactory {
-
- private final ConfigSubsystemFacadeFactory configFacadeFactory;
-
- public NetconfOperationServiceFactoryImpl(ConfigSubsystemFacadeFactory configFacadeFactory) {
- this.configFacadeFactory = configFacadeFactory;
- }
-
- @Override
- public NetconfOperationServiceImpl createService(String netconfSessionIdForReporting) {
- return new NetconfOperationServiceImpl(configFacadeFactory.createFacade(netconfSessionIdForReporting), netconfSessionIdForReporting);
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- return configFacadeFactory.getCurrentCapabilities();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return configFacadeFactory.getYangStoreService().registerModuleListener(new ModuleListener() {
- @Override
- public void onCapabilitiesChanged(Set<Module> added, Set<Module> removed) {
- listener.onCapabilitiesChanged(
- transformModulesToCapabilities(added), transformModulesToCapabilities(removed));
- }
- });
- }
-
- private static final Function<Module, Capability> MODULE_TO_CAPABILITY = new Function<Module, Capability>() {
- @Override
- public Capability apply(final Module module) {
- return new YangModuleCapability(module, module.getSource());
- }
- };
-
- public static Set<Capability> transformModulesToCapabilities(Set<Module> modules) {
- return Sets.newHashSet(Collections2.transform(modules, MODULE_TO_CAPABILITY));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-
-import java.util.Set;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-
-public class NetconfOperationServiceImpl implements NetconfOperationService {
-
- private final NetconfOperationProvider operationProvider;
- private ConfigSubsystemFacade configSubsystemFacade;
-
- public NetconfOperationServiceImpl(final ConfigSubsystemFacade configSubsystemFacade,
- final String netconfSessionIdForReporting) {
- this.configSubsystemFacade = configSubsystemFacade;
- operationProvider = new NetconfOperationProvider(configSubsystemFacade, netconfSessionIdForReporting);
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return operationProvider.getOperations();
- }
-
- @Override
- public void close() {
- configSubsystemFacade.close();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector;
-
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.opendaylight.controller.config.util.xml.XmlUtil.readXmlToElement;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import io.netty.channel.Channel;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import org.custommonkey.xmlunit.AbstractNodeTester;
-import org.custommonkey.xmlunit.NodeTest;
-import org.custommonkey.xmlunit.NodeTestException;
-import org.custommonkey.xmlunit.NodeTester;
-import org.custommonkey.xmlunit.XMLAssert;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
-import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.osgi.EnumResolver;
-import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
-import org.opendaylight.controller.config.facade.xml.transactions.TransactionProvider;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
-import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.config.yang.test.impl.ComplexDtoBInner;
-import org.opendaylight.controller.config.yang.test.impl.ComplexList;
-import org.opendaylight.controller.config.yang.test.impl.Deep;
-import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.DtoAInner;
-import org.opendaylight.controller.config.yang.test.impl.DtoAInnerInner;
-import org.opendaylight.controller.config.yang.test.impl.DtoC;
-import org.opendaylight.controller.config.yang.test.impl.DtoD;
-import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
-import org.opendaylight.controller.config.yang.test.impl.Peers;
-import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.Lock;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.UnLock;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListener;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
-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.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
-import org.w3c.dom.traversal.DocumentTraversal;
-import org.xml.sax.SAXException;
-
-
-public class NetconfMappingTest extends AbstractConfigTest {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMappingTest.class);
-
- private static final String INSTANCE_NAME = "instance-from-code";
- private static final String NETCONF_SESSION_ID = "foo";
- private static final String TEST_NAMESPACE= "urn:opendaylight:params:xml:ns:yang:controller:test:impl";
- private NetconfTestImplModuleFactory factory;
- private DepTestImplModuleFactory factory2;
- private IdentityTestModuleFactory factory3;
- private TestImplModuleFactory factory4;
-
- @Mock
- YangStoreService yangStoreSnapshot;
- @Mock
- NetconfOperationRouter netconfOperationRouter;
- @Mock
- AggregatedNetconfOperationServiceFactory netconfOperationServiceSnapshot;
- @Mock
- private AutoCloseable sessionCloseable;
-
- private TransactionProvider transactionProvider;
-
- private ConfigSubsystemFacade configSubsystemFacade;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
-
- final Filter filter = mock(Filter.class);
- doReturn(filter).when(mockedContext).createFilter(anyString());
- doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
- doReturn(new ServiceReference<?>[]{}).when(mockedContext).getServiceReferences(anyString(), anyString());
-
- doReturn(yangStoreSnapshot).when(yangStoreSnapshot).getCurrentSnapshot();
- doReturn(getMbes()).when(this.yangStoreSnapshot).getModuleMXBeanEntryMap();
- doReturn(getModules()).when(this.yangStoreSnapshot).getModules();
- doReturn(new EnumResolver() {
- @Override
- public String fromYang(final String enumType, final String enumYangValue) {
- return Preconditions.checkNotNull(getEnumMapping().get(enumYangValue),
- "Unable to resolve enum value %s, for enum %s with mappings %s", enumYangValue, enumType, getEnumMapping());
- }
-
- @Override
- public String toYang(final String enumType, final String enumYangValue) {
- return Preconditions.checkNotNull(getEnumMapping().inverse().get(enumYangValue),
- "Unable to resolve enum value %s, for enum %s with mappings %s", enumYangValue, enumType, getEnumMapping().inverse());
- }
- }).when(this.yangStoreSnapshot).getEnumResolver();
-
- this.factory = new NetconfTestImplModuleFactory();
- this.factory2 = new DepTestImplModuleFactory();
- this.factory3 = new IdentityTestModuleFactory();
- factory4 = new TestImplModuleFactory();
- doNothing().when(sessionCloseable).close();
-
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2,
- this.factory3, factory4));
-
- transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
-
- configSubsystemFacade = new ConfigSubsystemFacade(configRegistryClient, configRegistryClient, yangStoreSnapshot, "mapping-test");
- }
-
- private ObjectName createModule(final String instanceName) throws InstanceAlreadyExistsException, InstanceNotFoundException, URISyntaxException, ValidationException, ConflictingVersionException {
- final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
-
- final ObjectName on = transaction.createModule(this.factory.getImplementationName(), instanceName);
- final NetconfTestImplModuleMXBean mxBean = transaction.newMXBeanProxy(on, NetconfTestImplModuleMXBean.class);
- setModule(mxBean, transaction, instanceName + "_dep");
-
- int i = 1;
- for (Class<? extends AbstractServiceInterface> sInterface : factory.getImplementedServiceIntefaces()) {
- ServiceInterfaceAnnotation annotation = sInterface.getAnnotation(ServiceInterfaceAnnotation.class);
- transaction.saveServiceReference(
- transaction.getServiceInterfaceName(annotation.namespace(), annotation.localName()), "ref_from_code_to_" + instanceName + "_" + i++,
- on);
-
- }
- transaction.commit();
- return on;
- }
-
- @Test
- public void testIdentityRefs() throws Exception {
- edit("netconfMessages/editConfig_identities.xml");
-
- commit();
- Document configRunning = getConfigRunning();
- String asString = XmlUtil.toString(configRunning);
- assertThat(asString, containsString("test-identity2"));
- assertThat(asString, containsString("test-identity1"));
- assertEquals(2, countSubstringOccurence(asString, "</identities>"));
-
- edit("netconfMessages/editConfig_identities_inner_replace.xml");
- commit();
- configRunning = getConfigRunning();
- asString = XmlUtil.toString(configRunning);
- // test-identity1 was removed by replace
- assertThat(asString, not(containsString("test-identity2")));
- // now only 1 identities entry is present
- assertEquals(1, countSubstringOccurence(asString, "</identities>"));
- }
-
- private int countSubstringOccurence(final String string, final String substring) {
- final Matcher matches = Pattern.compile(substring).matcher(string);
- int count = 0;
- while (matches.find()) {
- count++;
- }
- return count;
- }
-
- @Override
- protected BindingRuntimeContext getBindingRuntimeContext() {
- final BindingRuntimeContext ret = super.getBindingRuntimeContext();
- doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
- doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
- return ret;
- }
-
- @Test
- public void testServicePersistance() throws Exception {
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- Document config = getConfigCandidate();
- assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user",
- "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
- "ref_from_code_to_instance-from-code_1"));
-
-
- edit("netconfMessages/editConfig_addServiceName.xml");
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user",
- "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
- "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"));
-
- edit("netconfMessages/editConfig_addServiceNameOnTest.xml");
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user",
- "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
- "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"));
-
- commit();
- config = getConfigRunning();
- assertCorrectRefNamesForDependencies(config);
- assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user",
- "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
- "ref_from_code_to_instance-from-code_1", "ref_dep_user_another"));
-
- edit("netconfMessages/editConfig_removeServiceNameOnTest.xml");
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user",
- "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
- "ref_from_code_to_instance-from-code_1"));
-
- try {
- edit("netconfMessages/editConfig_removeServiceNameOnTest.xml");
- fail("Should've failed, non-existing service instance");
- } catch (DocumentedException e) {
- assertEquals(e.getErrorSeverity(), DocumentedException.ErrorSeverity.error);
- assertEquals(e.getErrorTag(), DocumentedException.ErrorTag.operation_failed);
- assertEquals(e.getErrorType(), DocumentedException.ErrorType.application);
- }
-
- edit("netconfMessages/editConfig_replace_default.xml");
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Collections.<String>emptySet());
-
- edit("netconfMessages/editConfig_remove.xml");
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Collections.<String>emptySet());
-
- commit();
- config = getConfigCandidate();
- assertCorrectServiceNames(config, Collections.<String>emptySet());
-
- }
-
- @Test
- public void testUnLock() throws Exception {
- assertTrue(NetconfMessageUtil.isOKMessage(lockCandidate()));
- assertTrue(NetconfMessageUtil.isOKMessage(unlockCandidate()));
- }
-
- private void assertCorrectRefNamesForDependencies(Document config) throws NodeTestException {
- NodeList modulesList = config.getElementsByTagName("modules");
- assertEquals(1, modulesList.getLength());
-
- NodeTest nt = new NodeTest((DocumentTraversal) config, modulesList.item(0));
- NodeTester tester = new AbstractNodeTester() {
- private int defaultRefNameCount = 0;
- private int userRefNameCount = 0;
-
- @Override
- public void testText(Text text) throws NodeTestException {
- if(text.getData().equals("ref_dep2")) {
- defaultRefNameCount++;
- } else if(text.getData().equals("ref_dep_user_two")) {
- userRefNameCount++;
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertEquals(0, defaultRefNameCount);
- assertEquals(2, userRefNameCount);
- }
- };
- nt.performTest(tester, Node.TEXT_NODE);
- }
-
- private void assertCorrectServiceNames(Document configCandidate, Set<String> refNames) throws NodeTestException {
- final Set<String> refNames2 = new HashSet<>(refNames);
- NodeList servicesNodes = configCandidate.getElementsByTagName("services");
- assertEquals(1, servicesNodes.getLength());
-
- NodeTest nt = new NodeTest((DocumentTraversal) configCandidate, servicesNodes.item(0));
- NodeTester tester = new AbstractNodeTester() {
-
- @Override
- public void testElement(Element element) throws NodeTestException {
- if(element.getNodeName() != null) {
- if(element.getNodeName().equals("name")) {
- String elmText = element.getTextContent();
- if(refNames2.contains(elmText)) {
- refNames2.remove(elmText);
- } else {
- throw new NodeTestException("Unexpected services defined: " + elmText);
- }
- }
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertEquals(Collections.<String>emptySet(), refNames2);
- assertTrue(refNames2.toString(), refNames2.isEmpty());
- }
- };
- nt.performTest(tester, Node.ELEMENT_NODE);
- }
-
- @Test
- public void testConfigNetconfUnionTypes() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- commit();
- Document response = getConfigRunning();
- Element ipElement = readXmlToElement("<ip xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">0:0:0:0:0:0:0:1</ip>");
- assertContainsElement(response, readXmlToElement("<ip xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">0:0:0:0:0:0:0:1</ip>"));
-
- assertContainsElement(response, readXmlToElement("<union-test-attr xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">456</union-test-attr>"));
-
-
- edit("netconfMessages/editConfig_setUnions.xml");
- commit();
- response = getConfigRunning();
- assertContainsElement(response, readXmlToElement("<ip xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">127.1.2.3</ip>"));
- assertContainsElement(response, readXmlToElement("<union-test-attr xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">randomStringForUnion</union-test-attr>"));
-
- }
-
- @Test
- public void testConfigNetconf() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- Document configCandidate = getConfigCandidate();
- checkBinaryLeafEdited(configCandidate);
-
-
- // default-operation:none, should not affect binary leaf
- edit("netconfMessages/editConfig_none.xml");
- checkBinaryLeafEdited(getConfigCandidate());
-
- // check after edit
- commit();
- Document response = getConfigRunning();
-
- checkBinaryLeafEdited(response);
- checkTypeConfigAttribute(response);
- checkTypedefs(response);
- checkTestingDeps(response);
- checkEnum(response);
- checkBigDecimal(response);
-
- edit("netconfMessages/editConfig_remove.xml");
-
- commit();
- assertXMLEqual(getConfigCandidate(), getConfigRunning());
-
- final Document expectedResult = XmlFileLoader.xmlFileToDocument("netconfMessages/editConfig_expectedResult.xml");
- XMLUnit.setIgnoreWhitespace(true);
- assertXMLEqual(expectedResult, getConfigRunning());
- assertXMLEqual(expectedResult, getConfigCandidate());
-
- edit("netconfMessages/editConfig_none.xml");
- closeSession();
- verify(sessionCloseable).close();
- verifyNoMoreInteractions(netconfOperationRouter);
- verifyNoMoreInteractions(netconfOperationServiceSnapshot);
- }
-
- private void checkBigDecimal(Document response) throws NodeTestException, SAXException, IOException {
- assertContainsElement(response, readXmlToElement("<sleep-factor xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2.58</sleep-factor>"));
- // Default
- assertContainsElement(response, readXmlToElement("<sleep-factor xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2.00</sleep-factor>"));
-
- }
-
- private void closeSession() throws ParserConfigurationException, SAXException,
- IOException, DocumentedException {
- final Channel channel = mock(Channel.class);
- doReturn("channel").when(channel).toString();
- final NetconfServerSessionListener listener = mock(NetconfServerSessionListener.class);
- final NetconfServerSession session =
- new NetconfServerSession(listener, channel, 1L,
- NetconfHelloMessageAdditionalHeader.fromString("[netconf;10.12.0.102:48528;ssh;;;;;;]"));
- DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID, sessionCloseable);
- closeOp.setNetconfSession(session);
- executeOp(closeOp, "netconfMessages/closeSession.xml");
- }
-
- private void edit(String resource) throws ParserConfigurationException, SAXException, IOException,
- DocumentedException {
- EditConfig editOp = new EditConfig(configSubsystemFacade, NETCONF_SESSION_ID);
- executeOp(editOp, resource);
- }
-
- private void commit() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- Commit commitOp = new Commit(configSubsystemFacade, NETCONF_SESSION_ID);
- executeOp(commitOp, "netconfMessages/commit.xml");
- }
-
- private Document lockCandidate() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- Lock commitOp = new Lock(NETCONF_SESSION_ID);
- return executeOp(commitOp, "netconfMessages/lock.xml");
- }
-
- private Document unlockCandidate() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- UnLock commitOp = new UnLock(NETCONF_SESSION_ID);
- return executeOp(commitOp, "netconfMessages/unlock.xml");
- }
-
- private Document getConfigCandidate() throws ParserConfigurationException, SAXException, IOException,
- DocumentedException {
- GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), NETCONF_SESSION_ID);
- return executeOp(getConfigOp, "netconfMessages/getConfig_candidate.xml");
- }
-
- private Document getConfigRunning() throws ParserConfigurationException, SAXException, IOException,
- DocumentedException {
- GetConfig getConfigOp = new GetConfig(configSubsystemFacade, Optional.<String> absent(), NETCONF_SESSION_ID);
- return executeOp(getConfigOp, "netconfMessages/getConfig.xml");
- }
-
- @Ignore("second edit message corrupted")
- @Test(expected = DocumentedException.class)
- public void testConfigNetconfReplaceDefaultEx() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- edit("netconfMessages/editConfig_replace_default_ex.xml");
- }
-
- @Test
- public void testConfigNetconfReplaceDefault() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- commit();
- Document response = getConfigRunning();
- final int allInstances = response.getElementsByTagName("module").getLength();
-
- edit("netconfMessages/editConfig_replace_default.xml");
-
- commit();
- response = getConfigRunning();
-
- final int afterReplace = response.getElementsByTagName("module").getLength();
- assertEquals(4, allInstances);
- assertEquals(2, afterReplace);
- }
-
- @Test
- public void testSameAttrDifferentNamespaces() throws Exception {
- try {
- edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml");
- fail();
- } catch (DocumentedException e) {
- String message = e.getMessage();
- assertContainsString(message, "Element simpleInt present multiple times with different namespaces");
- assertContainsString(message, TEST_NAMESPACE);
- assertContainsString(message, XmlMappingConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
- }
- }
-
- @Test
- public void testDifferentNamespaceInTO() throws Exception {
- try {
- edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml");
- fail();
- } catch (DocumentedException e) {
- String message = e.getMessage();
- assertContainsString(message, "Unrecognised elements");
- assertContainsString(message, "simple-int2");
- assertContainsString(message, "dto_d");
- }
- }
-
- @Test
- public void testSameAttrDifferentNamespacesList() throws Exception {
- try {
- edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml");
- fail();
- } catch (DocumentedException e) {
- String message = e.getMessage();
- assertContainsString(message, "Element allow-user present multiple times with different namespaces");
- assertContainsString(message, TEST_NAMESPACE);
- assertContainsString(message, XmlMappingConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
- }
- }
-
- @Test
- public void testTypeNameConfigAttributeMatching() throws Exception {
- edit("netconfMessages/editConfig.xml");
- commit();
- edit("netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml");
- commit();
-
- Document response = getConfigRunning();
- checkTypeConfigAttribute(response);
- }
-
- // TODO add <modules operation="replace"> functionality
- @Test(expected = DocumentedException.class)
- public void testConfigNetconfReplaceModuleEx() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- edit("netconfMessages/editConfig_replace_module_ex.xml");
- }
-
- @Test
- public void testUnrecognisedConfigElements() throws Exception {
-
- String format = "netconfMessages/unrecognised/editConfig_unrecognised%d.xml";
- final int TESTS_COUNT = 8;
-
- for (int i = 0; i < TESTS_COUNT; i++) {
- String file = String.format(format, i + 1);
- LOG.info("Reading {}", file);
- try {
- edit(file);
- } catch (DocumentedException e) {
- assertContainsString(e.getMessage(), "Unrecognised elements");
- assertContainsString(e.getMessage(), "unknownAttribute");
- continue;
- }
- fail("Unrecognised test should throw exception " + file);
- }
- }
-
- @Test
- @Ignore
- // FIXME
- public void testConfigNetconfReplaceModule() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- commit();
- Document response = getConfigRunning();
- final int allInstances = response.getElementsByTagName("instance").getLength();
-
- edit("netconfMessages/editConfig_replace_module.xml");
-
- commit();
- response = getConfigRunning();
- final int afterReplace = response.getElementsByTagName("instance").getLength();
-
- assertEquals(4 + 4 /* Instances from services */, allInstances);
- assertEquals(3 + 3, afterReplace);
- }
-
- @Test(expected = DocumentedException.class)
- public void testEx() throws Exception {
-
- commit();
- }
-
- @Test
- public void testEx2() throws Exception {
- //check abort before tx creation
- assertContainsElement(discard(), readXmlToElement("<ok xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
-
- //check abort after tx creation
- edit("netconfMessages/editConfig.xml");
- assertContainsElement(discard(), readXmlToElement("<ok xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
- }
-
- @Test
- public void testFailedDiscardChangesAbort() throws Exception {
- final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
- doThrow(new RuntimeException("Mocked runtime exception, Abort has to fail")).when(facade).abortConfiguration();
-
- DiscardChanges discardOp = new DiscardChanges(facade, NETCONF_SESSION_ID);
-
- try {
- executeOp(discardOp, "netconfMessages/discardChanges.xml");
- fail("Should've failed, abort on mocked is supposed to throw RuntimeException");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorTag() == DocumentedException.ErrorTag.operation_failed);
- assertTrue(e.getErrorSeverity() == DocumentedException.ErrorSeverity.error);
- assertTrue(e.getErrorType() == DocumentedException.ErrorType.application);
- }
- }
-
- private Document discard() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- DiscardChanges discardOp = new DiscardChanges(configSubsystemFacade, NETCONF_SESSION_ID);
- return executeOp(discardOp, "netconfMessages/discardChanges.xml");
- }
-
- private void checkBinaryLeafEdited(final Document response) throws NodeTestException, SAXException, IOException {
- assertContainsElement(response, readXmlToElement("<binaryLeaf xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">YmluYXJ5</binaryLeaf>"));
- assertContainsElement(response, readXmlToElement("<binaryLeaf xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">ZGVmYXVsdEJpbg==</binaryLeaf>"));
- }
-
- private void checkTypedefs(final Document response) throws NodeTestException, SAXException, IOException {
-
- assertContainsElement(response, readXmlToElement("<extended xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">10</extended>"));
- // Default
- assertContainsElement(response, readXmlToElement("<extended xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">1</extended>"));
-
- assertContainsElement(response, readXmlToElement("<extended-twice xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">20</extended-twice>"));
- // Default
- assertContainsElement(response, readXmlToElement("<extended-twice xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">2</extended-twice>"));
-
- assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">two</extended-enum>"));
- // Default
- assertContainsElement(response, readXmlToElement("<extended-enum xmlns=\"urn:opendaylight:params:xml:ns:yang:controller:test:impl\">one</extended-enum>"));
- }
-
- private void assertContainsString(String string, String substring) {
- assertThat(string, containsString(substring));
- }
-
- private void checkEnum(final Document response) throws Exception {
-
- String expectedEnumContent = "two";
-
- XMLAssert.assertXpathEvaluatesTo(expectedEnumContent,
- getXpathForNetconfImplSubnode(INSTANCE_NAME,"extended-enum"),
- response);
- }
-
- private void checkTestingDeps(Document response) {
- int testingDepsSize = response.getElementsByTagName("testing-deps").getLength();
- assertEquals(2, testingDepsSize);
- }
-
- private String getXpathForNetconfImplSubnode(String instanceName, String subnode) {
- return "/urn:ietf:params:xml:ns:netconf:base:1.0:rpc-reply" +
- "/urn:ietf:params:xml:ns:netconf:base:1.0:data" +
- "/urn:opendaylight:params:xml:ns:yang:controller:config:modules" +
- "/module[name='"+instanceName+"']" +
- "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:impl-netconf" +
- "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:"+subnode;
- }
-
- private void checkTypeConfigAttribute(Document response) throws Exception {
-
- Map<String,String> namesToTypeValues = ImmutableMap.of("instance-from-code", "configAttributeType",
- "test2", "default-string");
- for (Entry<String, String> nameToExpectedValue : namesToTypeValues.entrySet()) {
- XMLAssert.assertXpathEvaluatesTo(nameToExpectedValue.getValue(),
- getXpathForNetconfImplSubnode(nameToExpectedValue.getKey(),"type"),
- response);
- }
- }
-
- private Map<String, Map<String, ModuleMXBeanEntry>> getMbes() throws Exception {
- final List<InputStream> yangDependencies = getYangs();
-
- final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries = Maps.newHashMap();
-
- YangParserImpl yangParser = new YangParserImpl();
- final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(yangDependencies).values()));
- YangStoreService yangStoreService = new YangStoreService(new SchemaContextProvider() {
- @Override
- public SchemaContext getSchemaContext() {
- return schemaContext ;
- }
- });
- final BindingRuntimeContext bindingRuntimeContext = mock(BindingRuntimeContext.class);
- doReturn(getEnumMapping()).when(bindingRuntimeContext).getEnumMapping(any(Class.class));
- yangStoreService.refresh(bindingRuntimeContext);
- mBeanEntries.putAll(yangStoreService.getModuleMXBeanEntryMap());
-
- return mBeanEntries;
- }
-
- private BiMap<String, String> getEnumMapping() {
- final HashBiMap<String, String> enumBiMap = HashBiMap.create();
- // Enum constants mapping from yang -> Java and back
- enumBiMap.put("one", "One");
- enumBiMap.put("two", "Two");
- enumBiMap.put("version1", "Version1");
- enumBiMap.put("version2", "Version2");
- return enumBiMap;
- }
-
- private Set<org.opendaylight.yangtools.yang.model.api.Module> getModules() throws Exception {
- SchemaContext resolveSchemaContext = getSchemaContext();
- return resolveSchemaContext.getModules();
- }
-
- private SchemaContext getSchemaContext() throws Exception {
- final List<InputStream> yangDependencies = getYangs();
- YangParserImpl parser = new YangParserImpl();
-
- Set<Module> allYangModules = parser.parseYangModelsFromStreams(yangDependencies);
-
- return parser.resolveSchemaContext(Sets
- .newHashSet(allYangModules));
- }
-
- @Test
- public void testConfigNetconfRuntime() throws Exception {
-
- createModule(INSTANCE_NAME);
-
- edit("netconfMessages/editConfig.xml");
- checkBinaryLeafEdited(getConfigCandidate());
-
- // check after edit
- commit();
- Document response = get();
-
- assertEquals(2/*With runtime beans*/ + 2 /*Without runtime beans*/, getElementsSize(response, "module"));
- // data from state
- assertEquals(2, getElementsSize(response, "asdf"));
- // data from running config
- assertEquals(2, getElementsSize(response, "simple-short"));
-
- assertEquals(8, getElementsSize(response, "inner-running-data"));
- assertEquals(8, getElementsSize(response, "deep2"));
- assertEquals(8 * 4, getElementsSize(response, "inner-inner-running-data"));
- assertEquals(8 * 4, getElementsSize(response, "deep3"));
- assertEquals(8 * 4 * 2, getElementsSize(response, "list-of-strings"));
- assertEquals(8, getElementsSize(response, "inner-running-data-additional", "urn:opendaylight:params:xml:ns:yang:controller:test:impl"));
- assertEquals(8, getElementsSize(response, "deep4"));
- // TODO assert keys
-
- RuntimeRpc netconf = new RuntimeRpc(configSubsystemFacade, NETCONF_SESSION_ID);
-
- response = executeOp(netconf, "netconfMessages/rpc.xml");
- assertContainsElementWithText(response, "testarg1");
-
- response = executeOp(netconf, "netconfMessages/rpcInner.xml");
- Document expectedReplyOk = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc-reply_ok.xml");
- XMLUnit.setIgnoreWhitespace(true);
- XMLAssert.assertXMLEqual(expectedReplyOk, response);
-
- response = executeOp(netconf, "netconfMessages/rpcInnerInner.xml");
- assertContainsElementWithText(response, "true");
-
- response = executeOp(netconf, "netconfMessages/rpcInnerInner_complex_output.xml");
- assertContainsElementWithText(response, "1");
- assertContainsElementWithText(response, "2");
- }
-
- private Document get() throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- Get getOp = new Get(configSubsystemFacade, NETCONF_SESSION_ID);
- return executeOp(getOp, "netconfMessages/get.xml");
- }
-
- private int getElementsSize(Document response, String elementName) {
- return response.getElementsByTagName(elementName).getLength();
- }
-
- private int getElementsSize(Document response, String elementName, String namespace) {
- return response.getElementsByTagNameNS(namespace, elementName).getLength();
- }
-
- private Document executeOp(final NetconfOperation op, final String filename) throws ParserConfigurationException,
- SAXException, IOException, DocumentedException {
-
- final Document request = XmlFileLoader.xmlFileToDocument(filename);
-
- LOG.debug("Executing netconf operation\n{}", XmlUtil.toString(request));
- HandlingPriority priority = op.canHandle(request);
-
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- LOG.debug("Got response\n{}", XmlUtil.toString(response));
- return response;
- }
-
- private List<InputStream> getYangs() throws FileNotFoundException {
- List<String> paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang",
- "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang", "/META-INF/yang/test-types.yang",
- "/META-INF/yang/test-groups.yang", "/META-INF/yang/ietf-inet-types.yang");
- final Collection<InputStream> yangDependencies = new ArrayList<>();
- for (String path : paths) {
- final InputStream is = Preconditions
- .checkNotNull(getClass().getResourceAsStream(path), path + " not found");
- yangDependencies.add(is);
- }
- return Lists.newArrayList(yangDependencies);
- }
-
- private void setModule(final NetconfTestImplModuleMXBean mxBean, final ConfigTransactionJMXClient transaction, String depName)
- throws InstanceAlreadyExistsException, InstanceNotFoundException {
- mxBean.setSimpleInt((long) 44);
- mxBean.setBinaryLeaf(new byte[] { 8, 7, 9 });
- final DtoD dtob = getDtoD();
- mxBean.setDtoD(dtob);
- //
- final DtoC dtoa = getDtoC();
- mxBean.setDtoC(dtoa);
- mxBean.setSimpleBoolean(false);
- //
- final Peers p1 = new Peers();
- p1.setCoreSize(44L);
- p1.setPort("port1");
- p1.setSimpleInt3(456);
- final Peers p2 = new Peers();
- p2.setCoreSize(44L);
- p2.setPort("port23");
- p2.setSimpleInt3(456);
- mxBean.setPeers(Lists.<Peers> newArrayList(p1, p2));
- // //
- mxBean.setSimpleLong(454545L);
- mxBean.setSimpleLong2(44L);
- mxBean.setSimpleBigInteger(BigInteger.valueOf(999L));
- mxBean.setSimpleByte(new Byte((byte) 4));
- mxBean.setSimpleShort(new Short((short) 4));
- mxBean.setSimpleTest(545);
-
- mxBean.setComplexList(Lists.<ComplexList> newArrayList());
- mxBean.setSimpleList(Lists.<Integer> newArrayList());
-
- final ObjectName testingDepOn = transaction.createModule(this.factory2.getImplementationName(), depName);
- int i = 1;
- for (Class<? extends AbstractServiceInterface> sInterface : factory2.getImplementedServiceIntefaces()) {
- ServiceInterfaceAnnotation annotation = sInterface.getAnnotation(ServiceInterfaceAnnotation.class);
- transaction.saveServiceReference(
- transaction.getServiceInterfaceName(annotation.namespace(), annotation.localName()), "ref_from_code_to_" + depName + "_" + i++,
- testingDepOn);
-
- }
- mxBean.setTestingDep(testingDepOn);
- }
-
- private static DtoD getDtoD() {
- final DtoD dtob = new DtoD();
- dtob.setSimpleInt1((long) 444);
- dtob.setSimpleInt2((long) 4444);
- dtob.setSimpleInt3(454);
- final ComplexDtoBInner dtobInner = new ComplexDtoBInner();
- final Deep deep = new Deep();
- deep.setSimpleInt3(4);
- dtobInner.setDeep(deep);
- dtobInner.setSimpleInt3(44);
- dtobInner.setSimpleList(Lists.newArrayList(4));
- dtob.setComplexDtoBInner(Lists.newArrayList(dtobInner));
- dtob.setSimpleList(Lists.newArrayList(4));
- return dtob;
- }
-
- private static DtoC getDtoC() {
- final DtoC dtoa = new DtoC();
- // dtoa.setSimpleArg((long) 55);
- final DtoAInner dtoAInner = new DtoAInner();
- final DtoAInnerInner dtoAInnerInner = new DtoAInnerInner();
- dtoAInnerInner.setSimpleArg(456L);
- dtoAInner.setDtoAInnerInner(dtoAInnerInner);
- dtoAInner.setSimpleArg(44L);
- dtoa.setDtoAInner(dtoAInner);
- return dtoa;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.opendaylight.controller.config.facade.xml.mapping.config.Services;
-import org.opendaylight.controller.config.facade.xml.mapping.config.Services.ServiceInstance;
-
-public class ServiceTrackerTest {
-
- @Test
- public void test() {
- Services.ServiceInstance serviceInstance = new ServiceInstance("module", "serviceInstance");
-
- String string = serviceInstance.toString();
-
- Services.ServiceInstance serviceInstance2 = Services.ServiceInstance.fromString(string);
-
- assertEquals(serviceInstance, serviceInstance2);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.w3c.dom.Element;
-
-public class ValidateTest {
-
- public static final String NETCONF_SESSION_ID_FOR_REPORTING = "foo";
-
- @Test(expected = DocumentedException.class)
- public void test() throws Exception {
- final XmlElement xml = XmlElement.fromString("<abc></abc>");
- final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test(expected = DocumentedException.class)
- public void testNoSource() throws Exception {
- final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
- + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 + "\"/>");
- final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test(expected = DocumentedException.class)
- public void testNoNamespace() throws Exception {
- final XmlElement xml = XmlElement.fromString("<validate/>");
- final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test(expected = DocumentedException.class)
- public void testRunningSource() throws Exception {
-
- final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
- + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
- + "\"><source><running></running></source></validate>");
- final Validate validate = new Validate(null, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test(expected = DocumentedException.class)
- public void testNoTransaction() throws Exception {
- final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
- + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
- + "\"><source><candidate/></source></validate>");
- final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
- doThrow(IllegalStateException.class).when(facade).validateConfiguration();
- final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test(expected = DocumentedException.class)
- public void testValidationException() throws Exception {
- final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
- + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
- + "\">><source><candidate/></source></validate>");
- final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
- doThrow(ValidationException.class).when(facade).validateConfiguration();
- final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
- validate.handleWithNoSubsequentOperations(null, xml);
- }
-
- @Test
- public void testValidation() throws Exception {
- final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
- + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
- + "\"><source><candidate/></source></validate>");
- final Element okElement = XmlUtil.readXmlToElement("<ok/>");
- final ConfigSubsystemFacade facade = mock(ConfigSubsystemFacade.class);
- doNothing().when(facade).validateConfiguration();
- final Validate validate = new Validate(facade, NETCONF_SESSION_ID_FOR_REPORTING);
- Element ok = validate.handleWithNoSubsequentOperations(XmlUtil.newDocument(), xml);
- assertEquals(XmlUtil.toString(okElement), XmlUtil.toString(ok));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyMapOf;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import java.util.Collections;
-import java.util.Map;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
-import org.opendaylight.controller.config.facade.xml.ConfigExecution;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
-import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.config.facade.xml.mapping.config.InstanceConfigElementResolved;
-import org.opendaylight.controller.config.facade.xml.mapping.config.ModuleElementDefinition;
-import org.opendaylight.controller.config.facade.xml.mapping.config.ModuleElementResolved;
-import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.config.facade.xml.mapping.config.Services;
-import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
-import org.opendaylight.controller.config.facade.xml.strategy.EditConfigStrategy;
-import org.opendaylight.controller.config.facade.xml.strategy.EditStrategyType;
-import org.opendaylight.controller.config.facade.xml.transactions.TransactionProvider;
-import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
-
-public class EditConfigTest {
-
- @Mock
- private YangStoreService yangStoreSnapshot;
- @Mock
- private TransactionProvider provider;
- @Mock
- private ConfigRegistryClient configRegistry;
- @Mock
- private ConfigTransactionClient configTransactionClient;
- @Mock
- private ObjectName mockOn;
-
- private ConfigSubsystemFacade cfgFacade;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- doReturn("mockON").when(mockOn).toString();
- doReturn(mockOn).when(provider).getTestTransaction();
- doNothing().when(provider).validateTestTransaction(any(ObjectName.class));
-
- doReturn(mockOn).when(provider).getTestTransaction();
- doNothing().when(provider).abortTestTransaction(any(ObjectName.class));
- doReturn(mockOn).when(provider).getOrCreateTransaction();
-
- doNothing().when(provider).wipeTestTransaction(any(ObjectName.class));
-
- doReturn(configTransactionClient).when(configRegistry).getConfigTransactionClient(any(ObjectName.class));
- doReturn("mockConfigTransactionClient").when(configTransactionClient).toString();
-
- doReturn(mockOn).when(configTransactionClient).lookupConfigBean(anyString(), anyString());
-
- cfgFacade = new ConfigSubsystemFacade(configRegistry, configRegistry, yangStoreSnapshot, provider);
- }
-
- @Test
- public void test() throws Exception {
- EditConfig edit = new EditConfig(cfgFacade, ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
- EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
-
- doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
- any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
-
- ConfigExecution editConfigExecution = mockExecution(editStrat);
-
- edit.getResponseInternal(XmlUtil.newDocument(), editConfigExecution);
-
- verify(provider).getTestTransaction();
- verify(provider).validateTestTransaction(mockOn);
- verify(provider).abortTestTransaction(mockOn);
-
- verify(provider).getOrCreateTransaction();
-
- // For every instance execute strat
- verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(),
- anyString(), anyMapOf(String.class, AttributeConfigElement.class),
- any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
- }
-
- private ConfigExecution mockExecution(EditConfigStrategy editStrat) throws Exception {
- ConfigExecution mock = mock(ConfigExecution.class);
- doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
- doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
- doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
- doReturn(true).when(mock).shouldSet();
- doReturn(true).when(mock).shouldTest();
- doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
- doReturn(new Services()).when(mock).getServices();
- doReturn(XmlElement.fromDomElement(XmlUtil.readXmlToElement("<abc/>"))).when(mock).getConfigElement();
- return mock;
- }
-
- private Object getMappingDefinition(EditConfigStrategy editStrat) {
- Map<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
-
- Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
- Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
-
- ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class);
- doReturn(editStrat).when(mockedDefinition).getEditStrategy();
- doReturn("i1").when(mockedDefinition).getInstanceName();
- innerMultimap.put("m1", mockedDefinition);
-
- ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class);
- doReturn(editStrat).when(mockedDefinition2).getEditStrategy();
- doReturn("i2").when(mockedDefinition2).getInstanceName();
- innerMultimap.put("m1", mockedDefinition2);
-
- result.put("n1", innerMultimap);
-
- return result;
- }
-
- private static ServiceReferenceReadableRegistry mockServiceRegistry() {
- ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class);
- doReturn(
- Collections.emptyMap())
- .when(mock).getServiceMapping();
- doReturn("mockedServiceReg").when(mock).toString();
-
- return mock;
- }
-
- static ServiceRegistryWrapper mockServices() {
- return new ServiceRegistryWrapper(mockServiceRegistry());
- }
-
- private Map<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
- Map<String, Multimap<String, ModuleElementResolved>> result = Maps.newHashMap();
-
- Multimap<String, ModuleElementResolved> innerMultimap = HashMultimap.create();
- Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
-
- InstanceConfigElementResolved ice1 = mock(InstanceConfigElementResolved.class);
- doReturn(attributes).when(ice1).getConfiguration();
- doReturn(editStrat).when(ice1).getEditStrategy();
- innerMultimap.put("m1", new ModuleElementResolved("i1", ice1));
-
- InstanceConfigElementResolved ice2 = mock(InstanceConfigElementResolved.class);
- doReturn(attributes).when(ice2).getConfiguration();
- doReturn(editStrat).when(ice2).getEditStrategy();
- innerMultimap.put("m1", new ModuleElementResolved("i2", ice2));
-
- result.put("n1", innerMultimap);
-
- return result;
- }
-
- static Map<String, AttributeConfigElement> getSimpleAttributes() {
- Map<String, AttributeConfigElement> attributes = Maps.newHashMap();
- AttributeConfigElement ace1 = mock(AttributeConfigElement.class);
- doReturn("abcd").when(ace1).getResolvedDefaultValue();
- doReturn(Optional.<String> of("abc")).when(ace1).getResolvedValue();
- doReturn("mockedAce1").when(ace1).toString();
- doReturn("jmxNameAce1").when(ace1).getJmxName();
- attributes.put("a1", ace1);
- return attributes;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import static java.util.Arrays.asList;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.controller.config.api.jmx.ObjectNameUtil.createReadOnlyModuleON;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import java.util.List;
-import java.util.Map;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.config.facade.xml.mapping.config.ServiceRegistryWrapper;
-import org.opendaylight.controller.config.facade.xml.strategy.MergeEditConfigStrategy;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
-import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModule;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
-
-public class MergeEditConfigStrategyTest extends AbstractConfigTest {
- private static final MultipleDependenciesModuleFactory factory = new MultipleDependenciesModuleFactory();
- public static final String PARENT = "parent";
- public static final String D1 = "d1";
- public static final String D2 = "d2";
- public static final String D3 = "d3";
-
- private static final String factoryName = factory.getImplementationName();
-
- @Before
- public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
-
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
- ObjectName d1 = transaction.createModule(factoryName, D1);
- ObjectName d2 = transaction.createModule(factoryName, D2);
- ObjectName parent = transaction.createModule(factoryName, PARENT);
- MultipleDependenciesModuleMXBean multipleDependenciesModuleMXBean = transaction.newMXBeanProxy(parent,
- MultipleDependenciesModuleMXBean.class);
- multipleDependenciesModuleMXBean.setTestingDeps(asList(d1, d2));
- transaction.createModule(factoryName, D3);
- transaction.commit();
- }
-
- @Test
- public void testMergingOfObjectNames() throws Exception {
- MergeEditConfigStrategy strategy = new MergeEditConfigStrategy();
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-
- // add D3
-
- AttributeConfigElement attributeConfigElement = mock(AttributeConfigElement.class);
- doReturn(Optional.of(new ObjectName[] {createReadOnlyModuleON(factoryName, D3)})).when(attributeConfigElement).getResolvedValue();
- doReturn("mocked").when(attributeConfigElement).toString();
- String attributeName = MultipleDependenciesModule.testingDepsJmxAttribute.getAttributeName();
- doReturn(attributeName).when(attributeConfigElement).getJmxName();
- Map<String, AttributeConfigElement> configuration = ImmutableMap.of(
- attributeName,
- attributeConfigElement);
-
- strategy.executeConfiguration(factoryName, PARENT, configuration, transaction,
- mock(ServiceRegistryWrapper.class));
- transaction.commit();
-
- // parent's attribute should contain d1,d2,d3
- MultipleDependenciesModuleMXBean proxy = configRegistryClient.newMXBeanProxy(
- createReadOnlyModuleON(factoryName, PARENT),
- MultipleDependenciesModuleMXBean.class);
- List<ObjectName> testingDeps = proxy.getTestingDeps();
- List<ObjectName> expected = asList(createReadOnlyModuleON(factoryName, D1),
- createReadOnlyModuleON(factoryName, D2),
- createReadOnlyModuleON(factoryName, D3));
- assertEquals(expected, testingDeps);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.collect.Sets;
-import java.util.Map;
-import javax.management.Attribute;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.facade.xml.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.config.facade.xml.strategy.ReplaceEditConfigStrategy;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
-
-public class ReplaceEditConfigStrategyTest {
-
- @Mock
- private ConfigTransactionClient ta;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doNothing().when(ta).destroyModule(anyString(), anyString());
- doReturn(mockON()).when(ta).lookupConfigBean(anyString(), anyString());
- doNothing().when(ta).setAttribute(any(ObjectName.class), anyString(), any(Attribute.class));
- }
-
- @Test
- public void test() throws Exception {
- ReplaceEditConfigStrategy strat = new ReplaceEditConfigStrategy();
-
- Map<String, AttributeConfigElement> map = EditConfigTest.getSimpleAttributes();
-
- doReturn(Sets.newHashSet(mockON(), mockON())).when(ta).lookupConfigBeans();
-
- strat.executeConfiguration("m1", "i1", map, ta, EditConfigTest.mockServices());
-
- verify(ta).lookupConfigBean(anyString(), anyString());
- verify(ta).setAttribute(any(ObjectName.class), anyString(), any(Attribute.class));
- }
-
- ObjectName mockON() {
- ObjectName mock = mock(ObjectName.class);
- doReturn("mockON").when(mock).toString();
- return mock;
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
---><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../../</relativePath>
- </parent>
- <artifactId>features-netconf-connector</artifactId>
-
- <!-- Preserve mdsal version-->
- <version>${mdsal.version}</version>
- <packaging>jar</packaging>
- <properties>
- <features.file>features.xml</features.file>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>features-yangtools</artifactId>
- <version>${yangtools.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-mdsal</artifactId>
- <version>${mdsal.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-netconf</artifactId>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>features-aaa</artifactId>
- <version>${aaa.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-config-dispatcher</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-tcp</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-ssh</artifactId>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk15on</artifactId>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-connector-config</artifactId>
- <version>${netconf.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>messagebus-netconf</artifactId>
- <version>${netconf.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>messagebus-netconf</artifactId>
- <version>${netconf.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
-
- <!--
- Optional TODO: Remove TODO comments.
- -->
- <!-- test to validate features.xml -->
- <!--FIXME BUG-2195 When running single feature tests for netconf connector, features including ssh proxy server always fail (this behavior does not appear when running karaf distro directly)-->
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>features-test</artifactId>
- <scope>test</scope>
- </dependency>
- <!-- dependency for opendaylight-karaf-empty for use by testing -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>opendaylight-karaf-empty</artifactId>
- <version>${commons.opendaylight.version}</version>
- <type>zip</type>
- </dependency>
- <!-- Uncomment this if you get an error : java.lang.NoSuchMethodError: org.slf4j.helpers.MessageFormatter.format(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Lorg/slf4j/helpers/FormattingTuple;
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>1.7.2</version>
- </dependency>
- -->
-
- </dependencies>
- <build>
- <resources>
- <resource>
- <directory>src/main/resources</directory>
- <filtering>true</filtering>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <executions>
- <execution>
- <id>filter</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>resources</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <phase>package</phase>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/${features.file}</file>
- <type>xml</type>
- <classifier>features</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <systemPropertyVariables>
- <karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>
- <karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>
- <karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>
- </systemPropertyVariables>
- <dependenciesToScan>
- <dependency>org.opendaylight.odlparent:features-test</dependency>
- </dependenciesToScan>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=summary</url>
- </scm>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<features name="odl-controller-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
- <repository>mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-netconf/${netconf.version}/xml/features</repository>
-
- <feature name='odl-netconf-connector-all' version='${project.version}' description='OpenDaylight :: Netconf Connector :: All'>
- <feature version='${project.version}'>odl-netconf-connector</feature>
- <feature version='${project.version}'>odl-netconf-connector-ssh</feature>
- </feature>
-
- <feature name='odl-message-bus' version='${project.version}'>
- <!-- messagebus endpoint for netconf connector-->
- <feature version='${project.version}'>odl-netconf-connector-all</feature>
- <feature version='${mdsal.version}'>odl-message-bus-collector</feature>
- <bundle>mvn:org.opendaylight.controller/messagebus-netconf/${netconf.version}</bundle>
- <configfile finalname="${config.configfile.directory}/06-message-netconf.xml">mvn:org.opendaylight.controller/messagebus-netconf/${netconf.version}/xml/config</configfile>
- </feature>
-
- <feature name='odl-netconf-connector' version='${project.version}' description="OpenDaylight :: Netconf Connector :: Netconf Connector">
- <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <feature version='${netconf.version}'>odl-netconf-client</feature>
- <feature version='${yangtools.version}'>odl-yangtools-models</feature>
- <bundle>mvn:org.opendaylight.controller/sal-netconf-connector/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller.model/model-inventory/${mdsal.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-connector-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: Netconf Connector + Netconf SSH Server + loopback connection configuration">
- <feature version='${netconf.version}'>odl-netconf-ssh</feature>
- <feature version='${project.version}'>odl-netconf-connector</feature>
- <configfile finalname="${config.configfile.directory}/${config.netconf.connector.configfile}">mvn:org.opendaylight.controller/netconf-connector-config/${netconf.version}/xml/config</configfile>
- </feature>
-
-</features>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../../</relativePath>
- </parent>
- <artifactId>features-netconf</artifactId>
-
- <packaging>jar</packaging>
-
- <properties>
- <features.file>features.xml</features.file>
- </properties>
-
- <dependencies>
- <!-- FIXME AAA netconf dependency loop-->
- <dependency>
- <groupId>org.opendaylight.aaa</groupId>
- <artifactId>features-aaa</artifactId>
- <version>${aaa.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-config</artifactId>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-protocol-framework</artifactId>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-config-persister</artifactId>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-auth</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-notifications</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sshd</groupId>
- <artifactId>sshd-core</artifactId>
- </dependency>
- <dependency>
- <groupId>openexi</groupId>
- <artifactId>nagasena</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-common</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-buffer</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-transport</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-config</artifactId>
- <version>${config.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-connector-config</artifactId>
- <version>${netconf.version}</version>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>mdsal-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>mdsal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-mdsal-config</artifactId>
- <classifier>config</classifier>
- <type>xml</type>
- </dependency>
- <!-- test to validate features.xml -->
- <dependency>
- <groupId>org.opendaylight.odlparent</groupId>
- <artifactId>features-test</artifactId>
- <scope>test</scope>
- </dependency>
- <!-- dependency for opendaylight-karaf-empty for use by testing -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>opendaylight-karaf-empty</artifactId>
- <version>${commons.opendaylight.version}</version>
- <type>zip</type>
- </dependency>
- </dependencies>
-
- <build>
- <resources>
- <resource>
- <filtering>true</filtering>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <executions>
- <execution>
- <id>filter</id>
- <goals>
- <goal>resources</goal>
- </goals>
- <phase>generate-resources</phase>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/${features.file}</file>
- <type>xml</type>
- <classifier>features</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <!-- FIXME uncomment after merge -->
- <!--<plugin>-->
- <!--<groupId>org.apache.maven.plugins</groupId>-->
- <!--<artifactId>maven-surefire-plugin</artifactId>-->
- <!--<version>${surefire.version}</version>-->
- <!--<configuration>-->
- <!--<systemPropertyVariables>-->
- <!--<karaf.distro.groupId>org.opendaylight.controller</karaf.distro.groupId>-->
- <!--<karaf.distro.artifactId>opendaylight-karaf-empty</karaf.distro.artifactId>-->
- <!--<karaf.distro.version>${commons.opendaylight.version}</karaf.distro.version>-->
- <!--</systemPropertyVariables>-->
- <!--<dependenciesToScan>-->
- <!--<dependency>org.opendaylight.odlparent:features-test</dependency>-->
- <!--</dependenciesToScan>-->
- <!--</configuration>-->
- <!--</plugin>-->
- </plugins>
- </build>
- <scm>
- <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-
-<features name="odl-netconf-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
- <repository>mvn:org.opendaylight.controller/features-protocol-framework/${protocol-framework.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-config/${config.version}/xml/features</repository>
- <repository>mvn:org.opendaylight.controller/features-config-persister/${config.version}/xml/features</repository>
- <!-- FIXME: This introduces cycle between projects, which makes version updates
- harder. Should be moved to different.
- -->
- <repository>mvn:org.opendaylight.aaa/features-aaa/${aaa.version}/xml/features</repository>
-
- <feature name='odl-netconf-all' version='${project.version}' description="OpenDaylight :: Netconf :: All">
- <feature version='${project.version}'>odl-netconf-api</feature>
- <feature version='${project.version}'>odl-netconf-mapping-api</feature>
- <feature version='${project.version}'>odl-netconf-util</feature>
- <feature version='${project.version}'>odl-netconf-impl</feature>
- <feature version='${project.version}'>odl-config-netconf-connector</feature>
- <feature version='${project.version}'>odl-netconf-netty-util</feature>
- <feature version='${project.version}'>odl-netconf-client</feature>
- <feature version='${project.version}'>odl-netconf-monitoring</feature>
- </feature>
-
- <feature name='odl-netconf-api' version='${project.version}' description="OpenDaylight :: Netconf :: API">
- <feature version='${protocol-framework.version}'>odl-protocol-framework</feature>
- <bundle>mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-util/${config.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-api/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-auth/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/ietf-netconf/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/ietf-netconf-notifications/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/ietf-netconf-monitoring-extension/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools.model/ietf-inet-types/${ietf-inet-types.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types/${ietf-yang-types.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools.model/ietf-yang-types-20130715/2013.07.15.8-SNAPSHOT</bundle>
- </feature>
-
- <feature name='odl-netconf-mapping-api' version='${project.version}' description="OpenDaylight :: Netconf :: Mapping API">
- <feature version='${project.version}'>odl-netconf-api</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-mapping-api/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-util' version='${project.version}'>
- <feature version='${project.version}'>odl-netconf-mapping-api</feature>
- <bundle>mvn:org.opendaylight.yangtools/yang-model-api/${yangtools.version}</bundle>
- <bundle>mvn:org.opendaylight.yangtools/yang-data-api/${yangtools.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-util/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Impl">
- <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
- <feature version='${project.version}'>odl-netconf-api</feature>
- <feature version='${project.version}'>odl-netconf-mapping-api</feature>
- <feature version='${project.version}'>odl-netconf-util</feature>
- <feature version='${project.version}'>odl-netconf-netty-util</feature>
- <!-- Netconf server without config connector is just an empty shell -->
- <feature version='${project.version}'>odl-config-netconf-connector</feature>
- <!-- Netconf will not provide schemas without monitoring -->
- <bundle>mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version}</bundle>
- <feature version='${project.version}'>odl-netconf-monitoring</feature>
- <feature version='${project.version}'>odl-netconf-notifications-impl</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
- </feature>
-
- <feature name='odl-config-netconf-connector' version='${project.version}' description="OpenDaylight :: Netconf :: Connector">
- <bundle>mvn:org.opendaylight.controller/yang-jmx-generator/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-manager-facade-xml/${project.version}</bundle>
- <feature version='${config.version}'>odl-config-manager</feature>
- <feature version='${project.version}'>odl-netconf-netty-util</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-impl/${project.version}</bundle>
- <feature version='${project.version}'>odl-netconf-notifications-api</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/config-netconf-connector/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-netty-util' version='${project.version}' description="OpenDaylight :: Netconf :: Netty Util">
- <feature version='${project.version}'>odl-netconf-api</feature>
- <feature version='${project.version}'>odl-netconf-mapping-api</feature>
- <feature version='${project.version}'>odl-netconf-util</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-netty-util/${project.version}</bundle>
- <bundle>mvn:org.bouncycastle/bcpkix-jdk15on/${bouncycastle.version}</bundle>
- <bundle>mvn:org.bouncycastle/bcprov-jdk15on/${bouncycastle.version}</bundle>
- <bundle>mvn:org.apache.sshd/sshd-core/${sshd-core.version}</bundle>
- <bundle>mvn:openexi/nagasena/${exi.nagasena.version}</bundle>
- <bundle>mvn:io.netty/netty-codec/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-handler/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-common/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-buffer/${netty.version}</bundle>
- <bundle>mvn:io.netty/netty-transport/${netty.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-client' version='${project.version}' description="OpenDaylight :: Netconf :: Client">
- <feature version='${config.version}'>odl-config-all</feature>
- <feature version='${project.version}'>odl-netconf-netty-util</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-client/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/netconf-config-dispatcher/${config.version}</bundle>
- <configfile finalname='${config.configfile.directory}/${config.netconf.client.configfile}'>mvn:org.opendaylight.controller/netconf-config/${project.version}/xml/config</configfile>
- </feature>
-
- <feature name='odl-netconf-monitoring' version='${project.version}' description="OpenDaylight :: Netconf :: Monitoring">
- <feature version='${project.version}'>odl-netconf-util</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-monitoring/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-notifications-api' version='${project.version}' description="OpenDaylight :: Netconf :: Notification :: Api">
- <feature version='${project.version}'>odl-config-manager-facade-xml</feature>
- <feature version='${project.version}'>odl-netconf-api</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-notifications-api/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-notifications-impl' version='${project.version}' description="OpenDaylight :: Netconf :: Monitoring :: Impl">
- <feature version='${project.version}'>odl-netconf-notifications-api</feature>
- <feature version='${project.version}'>odl-netconf-util</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-notifications-impl/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-ssh' version='${project.version}' description="OpenDaylight :: Netconf Connector :: SSH">
- <feature version='${project.version}'>odl-netconf-tcp</feature>
- <!-- FIXME: This introduces cycle between projects, which makes version updates
- harder. Should be moved to different.
- -->
- <feature version='${aaa.version}'>odl-aaa-netconf-plugin</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-ssh/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-tcp' version='${project.version}' description="OpenDaylight :: Netconf Connector :: TCP">
- <feature version='${project.version}'>odl-netconf-impl</feature>
- <feature version='${config.version}'>odl-config-netty</feature>
- <bundle>mvn:org.opendaylight.controller/netconf-tcp/${project.version}</bundle>
- </feature>
-
- <feature name='odl-netconf-mdsal' version='${mdsal.version}' description="OpenDaylight :: Netconf :: Mdsal">
- <feature version='${config.version}'>odl-config-all</feature>
- <feature version='${config.version}'>odl-config-netty</feature>
- <feature version='${project.version}'>odl-netconf-all</feature>
- <feature version='${project.version}'>odl-netconf-tcp</feature>
- <feature version='${project.version}'>odl-netconf-ssh</feature>
- <feature version='${project.version}'>odl-netconf-client</feature>
- <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
- <bundle>mvn:org.opendaylight.controller/mdsal-netconf-connector/${project.version}</bundle>
- <bundle>mvn:org.opendaylight.controller/mdsal-netconf-monitoring/${project.version}</bundle>
- <configfile finalname='${config.configfile.directory}/${config.netconf.mdsal.configfile}'>mvn:org.opendaylight.controller/netconf-mdsal-config/${project.version}/xml/config</configfile>
- </feature>
-</features>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../</relativePath>
- </parent>
- <artifactId>features-netconf-parent</artifactId>
- <packaging>pom</packaging>
-
- <modules>
- <module>netconf</module>
- <module>netconf-connector</module>
- </modules>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>mdsal-netconf-connector</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-tcp</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>object-cache-api</artifactId>
- </exclusion>
- </exclusions>
-
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>object-cache-noop</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-dom-config</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.logback_settings</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-distributed-datastore</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Import-Package>*</Import-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yang.netconf.mdsal.mapper;
-
-import org.opendaylight.controller.netconf.mdsal.connector.MdsalNetconfOperationServiceFactory;
-
-public class NetconfMdsalMapperModule extends org.opendaylight.controller.config.yang.netconf.mdsal.mapper.AbstractNetconfMdsalMapperModule{
- public NetconfMdsalMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfMdsalMapperModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.mdsal.mapper.NetconfMdsalMapperModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final MdsalNetconfOperationServiceFactory mdsalNetconfOperationServiceFactory =
- new MdsalNetconfOperationServiceFactory(getRootSchemaServiceDependency()) {
- @Override
- public void close() throws Exception {
- super.close();
- getMapperAggregatorDependency().onRemoveNetconfOperationServiceFactory(this);
- }
- };
- getDomBrokerDependency().registerConsumer(mdsalNetconfOperationServiceFactory);
- getMapperAggregatorDependency().onAddNetconfOperationServiceFactory(mdsalNetconfOperationServiceFactory);
- return mdsalNetconfOperationServiceFactory;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-mdsal-mapper yang module local name: netconf-mdsal-mapper
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Jan 14 14:58:42 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.netconf.mdsal.mapper;
-public class NetconfMdsalMapperModuleFactory extends org.opendaylight.controller.config.yang.netconf.mdsal.mapper.AbstractNetconfMdsalMapperModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-
-public class CurrentSchemaContext implements SchemaContextListener, AutoCloseable {
- final AtomicReference<SchemaContext> currentContext = new AtomicReference<SchemaContext>();
- private final ListenerRegistration<SchemaContextListener> schemaContextListenerListenerRegistration;
- private final Set<CapabilityListener> listeners1 = Collections.synchronizedSet(Sets.<CapabilityListener>newHashSet());
-
- public SchemaContext getCurrentContext() {
- Preconditions.checkState(currentContext.get() != null, "Current context not received");
- return currentContext.get();
- }
-
- public CurrentSchemaContext(final SchemaService schemaService) {
- schemaContextListenerListenerRegistration = schemaService.registerSchemaContextListener(this);
- }
-
- @Override
- public void onGlobalContextUpdated(final SchemaContext schemaContext) {
- currentContext.set(schemaContext);
- // FIXME is notifying all the listeners from this callback wise ?
- final Set<Capability> addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get());
- for (final CapabilityListener listener : listeners1) {
- listener.onCapabilitiesChanged(addedCaps, Collections.<Capability>emptySet());
- }
- }
-
- @Override
- public void close() throws Exception {
- listeners1.clear();
- schemaContextListenerListenerRegistration.close();
- currentContext.set(null);
- }
-
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- listener.onCapabilitiesChanged(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get()), Collections.<Capability>emptySet());
- listeners1.add(listener);
- return new AutoCloseable() {
- @Override
- public void close() throws Exception {
- listeners1.remove(listener);
- }
- };
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector;
-
-import java.util.Set;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-
-public class MdsalNetconfOperationService implements NetconfOperationService {
-
- private final OperationProvider operationProvider;
-
- public MdsalNetconfOperationService(final CurrentSchemaContext schemaContext, final String netconfSessionIdForReporting,
- final DOMDataBroker dataBroker, final DOMRpcService rpcService) {
- this.operationProvider = new OperationProvider(netconfSessionIdForReporting, schemaContext, dataBroker, rpcService);
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return operationProvider.getOperations();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.capability.YangModuleCapability;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-import org.opendaylight.controller.sal.core.api.Consumer;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MdsalNetconfOperationServiceFactory implements NetconfOperationServiceFactory, Consumer, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(MdsalNetconfOperationServiceFactory.class);
-
- private ConsumerSession session = null;
- private DOMDataBroker dataBroker = null;
- private DOMRpcService rpcService = null;
- private final CurrentSchemaContext currentSchemaContext;
-
- public MdsalNetconfOperationServiceFactory(final SchemaService schemaService) {
- this.currentSchemaContext = new CurrentSchemaContext(Preconditions.checkNotNull(schemaService));
- }
-
- @Override
- public MdsalNetconfOperationService createService(final String netconfSessionIdForReporting) {
- Preconditions.checkState(dataBroker != null, "MD-SAL provider not yet initialized");
- return new MdsalNetconfOperationService(currentSchemaContext, netconfSessionIdForReporting, dataBroker, rpcService);
- }
-
- @Override
- public void close() throws Exception {
- currentSchemaContext.close();
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- return transformCapabilities(currentSchemaContext.getCurrentContext());
- }
-
- static Set<Capability> transformCapabilities(final SchemaContext currentContext) {
- final Set<Capability> capabilities = new HashSet<>();
-
- // Added by netconf-impl by default
-// capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
-
- final Set<Module> modules = currentContext.getModules();
- for (final Module module : modules) {
- Optional<YangModuleCapability> cap = moduleToCapability(module);
- if(cap.isPresent()) {
- capabilities.add(cap.get());
- }
- for (final Module submodule : module.getSubmodules()) {
- cap = moduleToCapability(submodule);
- if(cap.isPresent()) {
- capabilities.add(cap.get());
- }
- }
- }
-
- return capabilities;
- }
-
- private static Optional<YangModuleCapability> moduleToCapability(final Module module) {
- final String source = module.getSource();
- if(source !=null) {
- return Optional.of(new YangModuleCapability(module, source));
- } else {
- LOG.warn("Missing source for module {}. This module will not be available from netconf server",
- module);
- }
- return Optional.absent();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return currentSchemaContext.registerCapabilityListener(listener);
- }
-
- @Override
- public void onSessionInitiated(ConsumerSession session) {
- this.session = Preconditions.checkNotNull(session);
- this.dataBroker = this.session.getService(DOMDataBroker.class);
- this.rpcService = this.session.getService(DOMRpcService.class);
- }
-
- @Override
- public Collection<ConsumerFunctionality> getConsumerFunctionality() {
- return Collections.emptySet();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Commit;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.DiscardChanges;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.EditConfig;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Lock;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.RuntimeRpc;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Unlock;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.get.Get;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.get.GetConfig;
-
-final class OperationProvider {
-
- private final String netconfSessionIdForReporting;
- private final CurrentSchemaContext schemaContext;
- private final DOMDataBroker dataBroker;
- private final DOMRpcService rpcService;
- private final TransactionProvider transactionProvider;
-
- public OperationProvider(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext,
- final DOMDataBroker dataBroker, final DOMRpcService rpcService) {
- this.netconfSessionIdForReporting = netconfSessionIdForReporting;
- this.schemaContext = schemaContext;
- this.dataBroker = dataBroker;
- this.rpcService = rpcService;
- this.transactionProvider = new TransactionProvider(this.dataBroker, netconfSessionIdForReporting);
- }
-
- Set<NetconfOperation> getOperations() {
- return Sets.<NetconfOperation>newHashSet(
- new Commit(netconfSessionIdForReporting, transactionProvider),
- new DiscardChanges(netconfSessionIdForReporting, transactionProvider),
- new EditConfig(netconfSessionIdForReporting, schemaContext, transactionProvider),
- new Get(netconfSessionIdForReporting, schemaContext, transactionProvider),
- new GetConfig(netconfSessionIdForReporting, schemaContext, transactionProvider),
- new Lock(netconfSessionIdForReporting),
- new Unlock(netconfSessionIdForReporting),
- new RuntimeRpc(netconfSessionIdForReporting, schemaContext, rpcService)
- );
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-//TODO make a global TransactionProvider for all Netconf sessions instead of each session having one.
-public class TransactionProvider implements AutoCloseable{
-
- private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class);
-
- private final DOMDataBroker dataBroker;
-
- private DOMDataReadWriteTransaction candidateTransaction = null;
- private DOMDataReadWriteTransaction runningTransaction = null;
- private final List<DOMDataReadWriteTransaction> allOpenReadWriteTransactions = new ArrayList<>();
-
- private final String netconfSessionIdForReporting;
-
- private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No candidateTransaction found for session ";
-
-
- public TransactionProvider(DOMDataBroker dataBroker, String netconfSessionIdForReporting) {
- this.dataBroker = dataBroker;
- this.netconfSessionIdForReporting = netconfSessionIdForReporting;
- }
-
- @Override
- public synchronized void close() throws Exception {
- for (DOMDataReadWriteTransaction rwt : allOpenReadWriteTransactions) {
- rwt.cancel();
- }
-
- allOpenReadWriteTransactions.clear();
- }
-
- public synchronized Optional<DOMDataReadWriteTransaction> getCandidateTransaction() {
- if (candidateTransaction == null) {
- return Optional.absent();
- }
-
- return Optional.of(candidateTransaction);
- }
-
- public synchronized DOMDataReadWriteTransaction getOrCreateTransaction() {
- if (getCandidateTransaction().isPresent()) {
- return getCandidateTransaction().get();
- }
-
- candidateTransaction = dataBroker.newReadWriteTransaction();
- allOpenReadWriteTransactions.add(candidateTransaction);
- return candidateTransaction;
- }
-
- public synchronized boolean commitTransaction() throws DocumentedException {
- if (!getCandidateTransaction().isPresent()) {
- throw new DocumentedException(NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting,
- ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
- }
-
- CheckedFuture<Void, TransactionCommitFailedException> future = candidateTransaction.submit();
- try {
- future.checkedGet();
- } catch (TransactionCommitFailedException e) {
- LOG.debug("Transaction {} failed on", candidateTransaction, e);
- throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
- ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
- }
- allOpenReadWriteTransactions.remove(candidateTransaction);
- candidateTransaction = null;
-
- return true;
- }
-
- public synchronized void abortTransaction() {
- LOG.debug("Aborting current candidateTransaction");
- Optional<DOMDataReadWriteTransaction> otx = getCandidateTransaction();
- Preconditions.checkState(otx.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
- candidateTransaction.cancel();
- allOpenReadWriteTransactions.remove(candidateTransaction);
- candidateTransaction = null;
- }
-
- public synchronized DOMDataReadWriteTransaction createRunningTransaction() {
- runningTransaction = dataBroker.newReadWriteTransaction();
- allOpenReadWriteTransactions.add(runningTransaction);
- return runningTransaction;
- }
-
- public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws DocumentedException {
- allOpenReadWriteTransactions.remove(tx);
-
- CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
- try {
- future.checkedGet();
- } catch (TransactionCommitFailedException e) {
- LOG.debug("Transaction {} failed on", tx, e);
- throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting,
- ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error);
- }
-
- return true;
- }
-
- public synchronized void abortRunningTransaction(DOMDataReadWriteTransaction tx) {
- LOG.debug("Aborting current running Transaction");
- Preconditions.checkState(runningTransaction != null, NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
- tx.cancel();
- allOpenReadWriteTransactions.remove(tx);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Commit extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Commit.class);
-
- private static final String OPERATION_NAME = "commit";
- private final TransactionProvider transactionProvider;
-
- public Commit(final String netconfSessionIdForReporting, final TransactionProvider transactionProvider) {
- super(netconfSessionIdForReporting);
- this.transactionProvider = transactionProvider;
-
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
-
- boolean commitStatus = transactionProvider.commitTransaction();
- LOG.trace("Transaction commited succesfuly {}", commitStatus);
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.collect.Lists;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class DataTreeChangeTracker {
-
- private final ModifyAction defaultAction;
-
- private final Deque<ModifyAction> actions;
- private final Deque<PathArgument> currentPath;
- private final ArrayList<DataTreeChange> dataTreeChanges;
- private int deleteOperationTracker = 0;
- private int removeOperationTracker = 0;
-
- public DataTreeChangeTracker(final ModifyAction defaultAction) {
- this.defaultAction = defaultAction;
- this.currentPath = new ArrayDeque<>();
- this.actions = new ArrayDeque<>();
- this.dataTreeChanges = new ArrayList<>();
- }
-
- public void pushAction(final ModifyAction action) {
- if (ModifyAction.DELETE.equals(action)) {
- deleteOperationTracker++;
- }
-
- if (ModifyAction.REMOVE.equals(action)) {
- removeOperationTracker++;
- }
- this.actions.push(action);
- }
-
- public ModifyAction peekAction() {
- return this.actions.peekFirst();
- }
-
- public ModifyAction popAction() {
- final ModifyAction popResult = actions.pop();
- if (ModifyAction.DELETE.equals(popResult)) {
- deleteOperationTracker--;
- }
-
- if (ModifyAction.REMOVE.equals(popResult)) {
- removeOperationTracker--;
- }
- return popResult;
- }
-
- public int getDeleteOperationTracker() {
- return deleteOperationTracker;
- }
-
- public int getRemoveOperationTracker() {
- return removeOperationTracker;
- }
-
- public void addDataTreeChange(final DataTreeChange change) {
- dataTreeChanges.add(change);
- }
-
- public ArrayList<DataTreeChange> getDataTreeChanges() {
- return dataTreeChanges;
- }
-
- public ModifyAction getDefaultAction() {
- return defaultAction;
- }
-
- public void pushPath(final PathArgument pathArgument) {
- currentPath.push(pathArgument);
- }
-
- public PathArgument popPath() {
- return currentPath.pop();
- }
-
- public Deque<PathArgument> getCurrentPath() {
- return currentPath;
- }
-
-
- public static final class DataTreeChange {
-
- private final NormalizedNode<?, ?> changeRoot;
- private final ModifyAction action;
- private final List<PathArgument> path;
-
- public DataTreeChange(final NormalizedNode<?, ?> changeRoot, final ModifyAction action, final ArrayList<PathArgument> path) {
- this.changeRoot = changeRoot;
- this.action = action;
- this.path = Lists.reverse(path);
- }
-
- public NormalizedNode<?, ?> getChangeRoot() {
- return changeRoot;
- }
-
- public ModifyAction getAction() {
- return action;
- }
-
- public List<PathArgument> getPath() {
- return path;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-public enum Datastore {
- candidate, running
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import java.util.HashMap;
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DiscardChanges extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(DiscardChanges.class);
-
- private static final String OPERATION_NAME = "discard-changes";
-
- private final TransactionProvider transactionProvider;
-
- public DiscardChanges(final String netconfSessionIdForReporting, final TransactionProvider transactionProvider) {
- super(netconfSessionIdForReporting);
- this.transactionProvider = transactionProvider;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
-
- try {
- transactionProvider.abortTransaction();
- } catch (IllegalStateException e) {
- LOG.warn("Abort failed ", e);
- final Map<String, String> errorInfo = new HashMap<>();
- errorInfo
- .put(ErrorTag.operation_failed.name(),
- "Operation failed. Use 'get-config' or 'edit-config' before triggering 'discard-changes' operation");
- throw new DocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
- ErrorSeverity.error, errorInfo);
- }
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.List;
-import java.util.ListIterator;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.DataTreeChangeTracker.DataTreeChange;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public class EditConfig extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(EditConfig.class);
-
- private static final String OPERATION_NAME = "edit-config";
- private static final String CONFIG_KEY = "config";
- private static final String TARGET_KEY = "target";
- private static final String DEFAULT_OPERATION_KEY = "default-operation";
- private final CurrentSchemaContext schemaContext;
- private final TransactionProvider transactionProvider;
-
- public EditConfig(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext, final TransactionProvider transactionProvider) {
- super(netconfSessionIdForReporting);
- this.schemaContext = schemaContext;
- this.transactionProvider = transactionProvider;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Datastore targetDatastore = extractTargetParameter(operationElement);
- if (targetDatastore == Datastore.running) {
- throw new DocumentedException("edit-config on running datastore is not supported",
- ErrorType.protocol,
- ErrorTag.operation_not_supported,
- ErrorSeverity.error);
- }
-
- final ModifyAction defaultAction = getDefaultOperation(operationElement);
-
- final XmlElement configElement = getElement(operationElement, CONFIG_KEY);
-
- for (XmlElement element : configElement.getChildElements()) {
- final String ns = element.getNamespace();
- final DataSchemaNode schemaNode = getSchemaNodeFromNamespace(ns, element).get();
-
- final DataTreeChangeTracker changeTracker = new DataTreeChangeTracker(defaultAction);
- final DomToNormalizedNodeParserFactory.BuildingStrategyProvider editOperationStrategyProvider = new EditOperationStrategyProvider(changeTracker);
-
- parseIntoNormalizedNode(schemaNode, element, editOperationStrategyProvider);
- executeOperations(changeTracker);
- }
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- private void executeOperations(final DataTreeChangeTracker changeTracker) throws DocumentedException {
- final DOMDataReadWriteTransaction rwTx = transactionProvider.getOrCreateTransaction();
- final List<DataTreeChange> aa = changeTracker.getDataTreeChanges();
- final ListIterator<DataTreeChange> iterator = aa.listIterator(aa.size());
-
- while (iterator.hasPrevious()) {
- final DataTreeChange dtc = iterator.previous();
- executeChange(rwTx, dtc);
- }
- }
-
- private void executeChange(final DOMDataReadWriteTransaction rwtx, final DataTreeChange change) throws DocumentedException {
- switch (change.getAction()) {
- case NONE:
- return;
- case MERGE:
- rwtx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
- break;
- case CREATE:
- try {
- final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
- if (readResult.isPresent()) {
- throw new DocumentedException("Data already exists, cannot execute CREATE operation", ErrorType.protocol, ErrorTag.data_exists, ErrorSeverity.error);
- }
- rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
- } catch (ReadFailedException e) {
- LOG.warn("Read from datastore failed when trying to read data for create operation", change, e);
- }
- break;
- case REPLACE:
- rwtx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()), change.getChangeRoot());
- break;
- case DELETE:
- try {
- final Optional<NormalizedNode<?, ?>> readResult = rwtx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath())).checkedGet();
- if (!readResult.isPresent()) {
- throw new DocumentedException("Data is missing, cannot execute DELETE operation", ErrorType.protocol, ErrorTag.data_missing, ErrorSeverity.error);
- }
- rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()));
- } catch (ReadFailedException e) {
- LOG.warn("Read from datastore failed when trying to read data for delete operation", change, e);
- }
- break;
- case REMOVE:
- rwtx.delete(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(change.getPath()));
- break;
- default:
- LOG.warn("Unknown/not implemented operation, not executing");
- }
- }
-
- private NormalizedNode parseIntoNormalizedNode(final DataSchemaNode schemaNode, final XmlElement element,
- final DomToNormalizedNodeParserFactory.BuildingStrategyProvider editOperationStrategyProvider) {
-
-
- if (schemaNode instanceof ContainerSchemaNode) {
- return DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext(), editOperationStrategyProvider)
- .getContainerNodeParser()
- .parse(Collections.singletonList(element.getDomElement()), (ContainerSchemaNode) schemaNode);
- } else if (schemaNode instanceof ListSchemaNode) {
- return DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext(), editOperationStrategyProvider)
- .getMapNodeParser()
- .parse(Collections.singletonList(element.getDomElement()), (ListSchemaNode) schemaNode);
- } else {
- //this should never happen since edit-config on any other node type should not be possible nor makes sense
- LOG.debug("DataNode from module is not ContainerSchemaNode nor ListSchemaNode, aborting..");
- }
- throw new UnsupportedOperationException("implement exception if parse fails");
- }
-
- private Optional<DataSchemaNode> getSchemaNodeFromNamespace(final String namespace, final XmlElement element) throws DocumentedException{
- Optional<DataSchemaNode> dataSchemaNode = Optional.absent();
- try {
- //returns module with newest revision since findModuleByNamespace returns a set of modules and we only need the newest one
- final Module module = schemaContext.getCurrentContext().findModuleByNamespaceAndRevision(new URI(namespace), null);
- DataSchemaNode schemaNode = module.getDataChildByName(element.getName());
- if (schemaNode != null) {
- dataSchemaNode = Optional.of(module.getDataChildByName(element.getName()));
- } else {
- throw new DocumentedException("Unable to find node with namespace: " + namespace + "in module: " + module.toString(),
- ErrorType.application,
- ErrorTag.unknown_namespace,
- ErrorSeverity.error);
- }
- } catch (URISyntaxException e) {
- LOG.debug("Unable to create URI for namespace : {}", namespace);
- }
-
- return dataSchemaNode;
- }
-
- private Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
- final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(TARGET_KEY);
- // Direct lookup instead of using XmlElement class due to performance
- if (elementsByTagName.getLength() == 0) {
- throw new DocumentedException("Missing target element", ErrorType.rpc, ErrorTag.missing_attribute, ErrorSeverity.error);
- } else if (elementsByTagName.getLength() > 1) {
- throw new DocumentedException("Multiple target elements", ErrorType.rpc, ErrorTag.unknown_attribute, ErrorSeverity.error);
- } else {
- final XmlElement targetChildNode = XmlElement.fromDomElement((Element) elementsByTagName.item(0)).getOnlyChildElement();
- return Datastore.valueOf(targetChildNode.getName());
- }
- }
-
- private ModifyAction getDefaultOperation(final XmlElement operationElement) throws DocumentedException {
- final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(DEFAULT_OPERATION_KEY);
- if(elementsByTagName.getLength() == 0) {
- return ModifyAction.MERGE;
- } else if(elementsByTagName.getLength() > 1) {
- throw new DocumentedException("Multiple " + DEFAULT_OPERATION_KEY + " elements",
- ErrorType.rpc, ErrorTag.unknown_attribute, ErrorSeverity.error);
- } else {
- return ModifyAction.fromXmlValue(elementsByTagName.item(0).getTextContent());
- }
-
- }
-
- private XmlElement getElement(final XmlElement operationElement, String elementName) throws DocumentedException {
- final Optional<XmlElement> childNode = operationElement.getOnlyChildElementOptionally(elementName);
- if (!childNode.isPresent()) {
- throw new DocumentedException(elementName + " element is missing",
- ErrorType.protocol,
- ErrorTag.missing_element,
- ErrorSeverity.error);
- }
-
- return childNode.get();
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfigInput;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ExtensibleParser;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-
-class EditOperationStrategyProvider extends DomToNormalizedNodeParserFactory.BuildingStrategyProvider {
-
- private static final QName OPERATION_ATTRIBUTE = QName.create(EditConfigInput.QNAME.getNamespace(), null, XmlNetconfConstants.OPERATION_ATTR_KEY);
-
- private final DataTreeChangeTracker changeTracker;
-
- public EditOperationStrategyProvider(final DataTreeChangeTracker changeTracker) {
- this.changeTracker = changeTracker;
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, LeafNode<?>> forLeaf() {
- return new NetconfOperationLeafStrategy(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ContainerNode> forContainer() {
- return new NetconfOperationContainerStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, MapNode> forMap() {
- return new NetconfOperationCollectionStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> forLeafSetEntry() {
- return new NetconfOperationLeafSetEntryStrategy(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> forMapEntry() {
- return new NetconfOperationContainerStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, OrderedMapNode> forOrderedList() {
- return new NetconfOperationCollectionStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> forUnkeyedListEntry() {
- return new NetconfOperationContainerStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, UnkeyedListNode> forUnkeyedList() {
- return new NetconfOperationCollectionStrategy<>(changeTracker);
- }
-
- @Override
- protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> forChoice() {
- return new NetconfOperationContainerStrategy<>(changeTracker);
- }
-
- @Override
- public ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> forAugmentation() {
- return new NetconfOperationContainerStrategy<>(changeTracker);
- }
-
- private static class NetconfOperationCollectionStrategy<N extends NormalizedNode<YangInstanceIdentifier.NodeIdentifier, ?>> implements ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, N> {
- private final DataTreeChangeTracker changeTracker;
-
- public NetconfOperationCollectionStrategy(final DataTreeChangeTracker changeTracker) {
- this.changeTracker = changeTracker;
- }
-
- @Nullable
- @Override
- public N build(final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, N> builder) {
- changeTracker.popPath();
- return builder.build();
- }
-
- @Override
- public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, N> containerBuilder) {
- changeTracker.pushPath(containerBuilder.build().getIdentifier());
- }
- }
-
- public static final class NetconfOperationLeafStrategy implements ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, LeafNode<?>> {
-
- private final DataTreeChangeTracker dataTreeChangeTracker;
-
- public NetconfOperationLeafStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
- this.dataTreeChangeTracker = dataTreeChangeTracker;
- }
-
- @Nullable
- @Override
- public LeafNode<?> build(final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, LeafNode<?>> builder) {
- LeafNode<?> node = builder.build();
- String operation = (String) node.getAttributeValue(OPERATION_ATTRIBUTE);
- if (operation == null) {
- return node;
- }
-
- if(builder instanceof AttributesBuilder<?>) {
- ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
- }
-
- node = builder.build();
-
- ModifyAction action = ModifyAction.fromXmlValue(operation);
- if (dataTreeChangeTracker.getDeleteOperationTracker() > 0 || dataTreeChangeTracker.getRemoveOperationTracker() > 0) {
- return node;
- } else {
- if (!action.equals(dataTreeChangeTracker.peekAction())) {
- dataTreeChangeTracker.pushPath(node.getIdentifier());
- dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node, action, new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
- dataTreeChangeTracker.popPath();
- return null;
- } else {
- return node;
- }
- }
- }
-
- @Override
- public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, LeafNode<?>> containerBuilder) {
- // Noop
- }
- }
-
- public static final class NetconfOperationLeafSetEntryStrategy implements ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> {
-
- private final DataTreeChangeTracker dataTreeChangeTracker;
-
- public NetconfOperationLeafSetEntryStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
- this.dataTreeChangeTracker = dataTreeChangeTracker;
- }
-
- @Nullable
- @Override
- public LeafSetEntryNode<?> build(final NormalizedNodeBuilder<YangInstanceIdentifier.NodeWithValue, ?, LeafSetEntryNode<?>> builder) {
- LeafSetEntryNode<?> node = builder.build();
- String operation = (String) node.getAttributeValue(OPERATION_ATTRIBUTE);
- if (operation == null) {
- return node;
- }
-
- if (builder instanceof AttributesBuilder<?>) {
- ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
- }
-
- node = builder.build();
-
- ModifyAction action = ModifyAction.fromXmlValue(operation);
- if (dataTreeChangeTracker.getDeleteOperationTracker() > 0 || dataTreeChangeTracker.getRemoveOperationTracker() > 0) {
- return node;
- } else {
- if (!action.equals(dataTreeChangeTracker.peekAction())) {
- dataTreeChangeTracker.pushPath(node.getIdentifier());
- dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node, action, new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
- dataTreeChangeTracker.popPath();
- return null;
- } else {
- return node;
- }
- }
- }
-
- @Override
- public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<YangInstanceIdentifier.NodeWithValue, ?, LeafSetEntryNode<?>> containerBuilder) {
-
- }
- }
-
- public static final class NetconfOperationContainerStrategy<P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>> implements ExtensibleParser.BuildingStrategy<P, N> {
-
- private final DataTreeChangeTracker dataTreeChangeTracker;
-
- public NetconfOperationContainerStrategy(final DataTreeChangeTracker dataTreeChangeTracker) {
- this.dataTreeChangeTracker = dataTreeChangeTracker;
- }
-
- @Nullable
- @Override
- public N build(final NormalizedNodeBuilder<P, ?, N> builder) {
- if (builder instanceof AttributesBuilder<?>) {
- ((AttributesBuilder<?>) builder).withAttributes(Collections.<QName, String>emptyMap());
- }
-
- final N node = builder.build();
- final ModifyAction currentAction = dataTreeChangeTracker.popAction();
-
- //if we know that we are going to delete a parent node just complete the entire subtree
- if (dataTreeChangeTracker.getDeleteOperationTracker() > 0 || dataTreeChangeTracker.getRemoveOperationTracker() > 0) {
- dataTreeChangeTracker.popPath();
- return node;
- } else {
- //if parent and current actions dont match create a DataTreeChange and add it to the change list
- //dont add a new child to the parent node
- if (!currentAction.equals(dataTreeChangeTracker.peekAction())) {
- dataTreeChangeTracker.addDataTreeChange(new DataTreeChangeTracker.DataTreeChange(node, currentAction, new ArrayList<>(dataTreeChangeTracker.getCurrentPath())));
- dataTreeChangeTracker.popPath();
- return null;
- } else {
- dataTreeChangeTracker.popPath();
- return node;
- }
- }
- }
-
- @Override
- public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<P, ?, N> containerBuilder) {
- dataTreeChangeTracker.pushPath(containerBuilder.build().getIdentifier());
- final String operation = attributes.get(OPERATION_ATTRIBUTE);
- if (operation != null) {
- dataTreeChangeTracker.pushAction(ModifyAction.fromXmlValue(operation));
- } else {
- dataTreeChangeTracker.pushAction(dataTreeChangeTracker.peekAction() != null
- ? dataTreeChangeTracker.peekAction() : dataTreeChangeTracker.getDefaultAction());
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Lock extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Lock.class);
-
- private static final String OPERATION_NAME = "lock";
- private static final String TARGET_KEY = "target";
-
- public Lock(final String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Datastore targetDatastore = extractTargetParameter(operationElement);
- if (targetDatastore == Datastore.candidate) {
- LOG.debug("Locking candidate datastore on session: {}", getNetconfSessionIdForReporting());
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- throw new DocumentedException("Unable to lock " + targetDatastore + " datastore", DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
- }
-
- static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
- final XmlElement targetElement = operationElement.getOnlyChildElementWithSameNamespace(TARGET_KEY);
- final XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace();
- return Datastore.valueOf(targetChildNode.getName());
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nullable;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class RuntimeRpc extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpc.class);
-
- private final CurrentSchemaContext schemaContext;
- private static final XMLOutputFactory XML_OUTPUT_FACTORY;
-
- static {
- XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
- XML_OUTPUT_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- private final DOMRpcService rpcService;
-
- public RuntimeRpc(final String netconfSessionIdForReporting, CurrentSchemaContext schemaContext, DOMRpcService rpcService) {
- super(netconfSessionIdForReporting);
- this.schemaContext = schemaContext;
- this.rpcService = rpcService;
- }
-
- @Override
- protected HandlingPriority canHandle(final String netconfOperationName, final String namespace) {
- final URI namespaceURI = createNsUri(namespace);
- final Optional<Module> module = getModule(namespaceURI);
-
- if (!module.isPresent()) {
- LOG.debug("Cannot handle rpc: {}, {}", netconfOperationName, namespace);
- return HandlingPriority.CANNOT_HANDLE;
- }
-
- getRpcDefinitionFromModule(module.get(), namespaceURI, netconfOperationName);
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
-
- }
-
- @Override
- protected String getOperationName() {
- throw new UnsupportedOperationException("Runtime rpc does not have a stable name");
- }
-
- private URI createNsUri(final String namespace) {
- final URI namespaceURI;
- try {
- namespaceURI = new URI(namespace);
- } catch (URISyntaxException e) {
- // Cannot occur, namespace in parsed XML cannot be invalid URI
- throw new IllegalStateException("Unable to parse URI " + namespace, e);
- }
- return namespaceURI;
- }
-
- //this returns module with the newest revision if more then 1 module with same namespace is found
- private Optional<Module> getModule(final URI namespaceURI) {
- return Optional.fromNullable(schemaContext.getCurrentContext().findModuleByNamespaceAndRevision(namespaceURI, null));
- }
-
- private Optional<RpcDefinition> getRpcDefinitionFromModule(Module module, URI namespaceURI, String name) {
- for (RpcDefinition rpcDef : module.getRpcs()) {
- if (rpcDef.getQName().getNamespace().equals(namespaceURI)
- && rpcDef.getQName().getLocalName().equals(name)) {
- return Optional.of(rpcDef);
- }
- }
- return Optional.absent();
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
-
- final String netconfOperationName = operationElement.getName();
- final String netconfOperationNamespace;
- try {
- netconfOperationNamespace = operationElement.getNamespace();
- } catch (DocumentedException e) {
- LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
- throw new DocumentedException("Cannot retrieve netconf operation namespace from message",
- ErrorType.protocol, ErrorTag.unknown_namespace, ErrorSeverity.error);
- }
-
- final URI namespaceURI = createNsUri(netconfOperationNamespace);
- final Optional<Module> moduleOptional = getModule(namespaceURI);
-
- if (!moduleOptional.isPresent()) {
- throw new DocumentedException("Unable to find module in Schema Context with namespace and name : " +
- namespaceURI + " " + netconfOperationName + schemaContext.getCurrentContext(),
- ErrorType.application, ErrorTag.bad_element, ErrorSeverity.error);
- }
-
- final Optional<RpcDefinition> rpcDefinitionOptional = getRpcDefinitionFromModule(moduleOptional.get(), namespaceURI, netconfOperationName);
-
- if (!rpcDefinitionOptional.isPresent()) {
- throw new DocumentedException("Unable to find RpcDefinition with namespace and name : " + namespaceURI + " " + netconfOperationName,
- ErrorType.application, ErrorTag.bad_element, ErrorSeverity.error);
- }
-
- final RpcDefinition rpcDefinition = rpcDefinitionOptional.get();
- final SchemaPath schemaPath = SchemaPath.create(Collections.singletonList(rpcDefinition.getQName()), true);
- final NormalizedNode<?, ?> inputNode = rpcToNNode(operationElement, rpcDefinition.getInput());
-
- final CheckedFuture<DOMRpcResult, DOMRpcException> rpcFuture = rpcService.invokeRpc(schemaPath, inputNode);
- try {
- final DOMRpcResult result = rpcFuture.checkedGet();
- if (result.getResult() == null) {
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
- }
- return (Element) transformNormalizedNode(document, result.getResult(), rpcDefinition.getOutput().getPath());
- } catch (DOMRpcException e) {
- throw DocumentedException.wrap(e);
- }
- }
-
- @Override
- public Document handle(final Document requestMessage,
- final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
-
- final XmlElement requestElement = getRequestElementWithCheck(requestMessage);
-
- final Document document = XmlUtil.newDocument();
-
- final XmlElement operationElement = requestElement.getOnlyChildElement();
- final Map<String, Attr> attributes = requestElement.getAttributes();
-
- final Element response = handle(document, operationElement, subsequentOperation);
- final Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
-
- if(XmlElement.fromDomElement(response).hasNamespace()) {
- rpcReply.appendChild(response);
- } else {
- final NodeList list = response.getChildNodes();
- if (list.getLength() == 0) {
- rpcReply.appendChild(response);
- } else {
- while (list.getLength() != 0) {
- rpcReply.appendChild(list.item(0));
- }
- }
- }
-
- for (Attr attribute : attributes.values()) {
- rpcReply.setAttributeNode((Attr) document.importNode(attribute, true));
- }
- document.appendChild(rpcReply);
- return document;
- }
-
- //TODO move all occurences of this method in mdsal netconf(and xml factories) to a utility class
- private Node transformNormalizedNode(final Document document, final NormalizedNode<?, ?> data, final SchemaPath rpcOutputPath) {
- final DOMResult result = new DOMResult(document.createElement(XmlMappingConstants.RPC_REPLY_KEY));
-
- final XMLStreamWriter xmlWriter = getXmlStreamWriter(result);
-
- final NormalizedNodeStreamWriter nnStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
- schemaContext.getCurrentContext(), rpcOutputPath);
-
- final OrderedNormalizedNodeWriter nnWriter = new OrderedNormalizedNodeWriter(nnStreamWriter, schemaContext.getCurrentContext(), rpcOutputPath);
-
- writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
- try {
- nnStreamWriter.close();
- xmlWriter.close();
- } catch (IOException | XMLStreamException e) {
- LOG.warn("Error while closing streams", e);
- }
-
- return result.getNode();
- }
-
- private XMLStreamWriter getXmlStreamWriter(final DOMResult result) {
- try {
- return XML_OUTPUT_FACTORY.createXMLStreamWriter(result);
- } catch (final XMLStreamException e) {
- throw new RuntimeException(e);
- }
- }
-
- private void writeRootElement(final XMLStreamWriter xmlWriter, final OrderedNormalizedNodeWriter nnWriter, final ContainerNode data) {
- try {
- Collection<DataContainerChild<?, ?>> value = (Collection) data.getValue();
- nnWriter.write(value);
- nnWriter.flush();
- xmlWriter.flush();
- } catch (XMLStreamException | IOException e) {
- Throwables.propagate(e);
- }
- }
-
- /**
- * Parses xml element rpc input into normalized node or null if rpc does not take any input
- * @param oElement rpc xml element
- * @param input input container schema node, or null if rpc does not take any input
- * @return parsed rpc into normalized node, or null if input schema is null
- */
- @Nullable
- private NormalizedNode<?, ?> rpcToNNode(final XmlElement oElement, @Nullable final ContainerSchemaNode input) {
- return input == null ? null : DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext())
- .getContainerNodeParser()
- .parse(Collections.singletonList(oElement.getDomElement()), input);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Unlock extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Unlock.class);
-
- private static final String OPERATION_NAME = "unlock";
-
- public Unlock(final String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Datastore targetDatastore = Lock.extractTargetParameter(operationElement);
- if (targetDatastore == Datastore.candidate) {
- LOG.debug("Unlocking candidate datastore on session: {}", getNetconfSessionIdForReporting());
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- throw new DocumentedException("Unable to unlock " + targetDatastore + " datastore", DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_not_supported, DocumentedException.ErrorSeverity.error);
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-public abstract class AbstractGet extends AbstractSingletonNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractGet.class);
-
- protected static final String FILTER = "filter";
- static final YangInstanceIdentifier ROOT = YangInstanceIdentifier.builder().build();
- protected final CurrentSchemaContext schemaContext;
-
- public AbstractGet(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext) {
- super(netconfSessionIdForReporting);
- this.schemaContext = schemaContext;
- }
-
- private static final XMLOutputFactory XML_OUTPUT_FACTORY;
-
- static {
- XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
- XML_OUTPUT_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
- }
-
- protected Node transformNormalizedNode(final Document document, final NormalizedNode<?, ?> data, final YangInstanceIdentifier dataRoot) {
-
- final DOMResult result = new DOMResult(document.createElement(XmlNetconfConstants.DATA_KEY));
-
- final XMLStreamWriter xmlWriter = getXmlStreamWriter(result);
-
- final NormalizedNodeStreamWriter nnStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter,
- schemaContext.getCurrentContext(), getSchemaPath(dataRoot));
-
- final NormalizedNodeWriter nnWriter = NormalizedNodeWriter.forStreamWriter(nnStreamWriter);
-
- writeRootElement(xmlWriter, nnWriter, (ContainerNode) data);
- return result.getNode();
- }
-
-
- private XMLStreamWriter getXmlStreamWriter(final DOMResult result) {
- try {
- return XML_OUTPUT_FACTORY.createXMLStreamWriter(result);
- } catch (final XMLStreamException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static final Function<PathArgument, QName> PATH_ARG_TO_QNAME = new Function<YangInstanceIdentifier.PathArgument, QName>() {
- @Override
- public QName apply(final YangInstanceIdentifier.PathArgument input) {
- return input.getNodeType();
- }
- };
-
- private SchemaPath getSchemaPath(final YangInstanceIdentifier dataRoot) {
- return SchemaPath.create(Iterables.transform(dataRoot.getPathArguments(), PATH_ARG_TO_QNAME), dataRoot.equals(ROOT));
- }
-
- // TODO this code is located in Restconf already
- private void writeRootElement(final XMLStreamWriter xmlWriter, final NormalizedNodeWriter nnWriter, final ContainerNode data) {
- try {
- if (data.getNodeType().equals(SchemaContext.NAME)) {
- for (final DataContainerChild<? extends PathArgument, ?> child : data.getValue()) {
- nnWriter.write(child);
- }
- } else {
- nnWriter.write(data);
- }
- nnWriter.flush();
- xmlWriter.flush();
- } catch (XMLStreamException | IOException e) {
- Throwables.propagate(e);
- }
- }
-
- private DataSchemaNode getSchemaNodeFromNamespace(final XmlElement element) throws DocumentedException {
-
- try {
- final Module module = schemaContext.getCurrentContext().findModuleByNamespaceAndRevision(new URI(element.getNamespace()), null);
- DataSchemaNode dataSchemaNode = module.getDataChildByName(element.getName());
- if (dataSchemaNode != null) {
- return dataSchemaNode;
- }
- } catch (URISyntaxException e) {
- LOG.debug("Error during parsing of element namespace, this should not happen since namespace of an xml " +
- "element is valid and if the xml was parsed then the URI should be as well");
- throw new IllegalArgumentException("Unable to parse element namespace, this should not happen since " +
- "namespace of an xml element is valid and if the xml was parsed then the URI should be as well");
- }
- throw new DocumentedException("Unable to find node with namespace: " + element.getNamespace() + "in schema context: " + schemaContext.getCurrentContext().toString(),
- ErrorType.application,
- ErrorTag.unknown_namespace,
- ErrorSeverity.error);
- }
-
- protected Element serializeNodeWithParentStructure(Document document, YangInstanceIdentifier dataRoot, NormalizedNode node) {
- if (!dataRoot.equals(ROOT)) {
- return (Element) transformNormalizedNode(document,
- ImmutableNodes.fromInstanceId(schemaContext.getCurrentContext(), dataRoot, node),
- ROOT);
- }
- return (Element) transformNormalizedNode(document, node, ROOT);
- }
-
- /**
- *
- * @param operationElement operation element
- * @return if Filter is present and not empty returns Optional of the InstanceIdentifier to the read location in datastore.
- * empty filter returns Optional.absent() which should equal an empty <data/> container in the response.
- * if filter is not present we want to read the entire datastore - return ROOT.
- * @throws DocumentedException
- */
- protected Optional<YangInstanceIdentifier> getDataRootFromFilter(XmlElement operationElement) throws DocumentedException {
- Optional<XmlElement> filterElement = operationElement.getOnlyChildElementOptionally(FILTER);
- if (filterElement.isPresent()) {
- if (filterElement.get().getChildElements().size() == 0) {
- return Optional.absent();
- }
- return Optional.of(getInstanceIdentifierFromFilter(filterElement.get()));
- } else {
- return Optional.of(ROOT);
- }
- }
-
- @VisibleForTesting
- protected YangInstanceIdentifier getInstanceIdentifierFromFilter(XmlElement filterElement) throws DocumentedException {
-
- if (filterElement.getChildElements().size() != 1) {
- throw new DocumentedException("Multiple filter roots not supported yet",
- ErrorType.application, ErrorTag.operation_not_supported, ErrorSeverity.error);
- }
-
- XmlElement element = filterElement.getOnlyChildElement();
- DataSchemaNode schemaNode = getSchemaNodeFromNamespace(element);
-
- return getReadPointFromNode(YangInstanceIdentifier.builder().build(), filterToNormalizedNode(element, schemaNode));
- }
-
- private YangInstanceIdentifier getReadPointFromNode(final YangInstanceIdentifier pathArg, final NormalizedNode nNode) {
- final YangInstanceIdentifier path = pathArg.node(nNode.getIdentifier());
- if (nNode instanceof DataContainerNode) {
- DataContainerNode node = (DataContainerNode) nNode;
- if (node.getValue().size() == 1) {
- return getReadPointFromNode(path, (NormalizedNode) Lists.newArrayList(node.getValue()).get(0));
- }
- }
- return path;
- }
-
- private NormalizedNode filterToNormalizedNode(XmlElement element, DataSchemaNode schemaNode) throws DocumentedException {
- DomToNormalizedNodeParserFactory parserFactory = DomToNormalizedNodeParserFactory
- .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext());
-
- final NormalizedNode parsedNode;
-
- if (schemaNode instanceof ContainerSchemaNode) {
- parsedNode = parserFactory.getContainerNodeParser().parse(Collections.singletonList(element.getDomElement()), (ContainerSchemaNode) schemaNode);
- } else if (schemaNode instanceof ListSchemaNode) {
- parsedNode = parserFactory.getMapNodeParser().parse(Collections.singletonList(element.getDomElement()), (ListSchemaNode) schemaNode);
- } else {
- throw new DocumentedException("Schema node of the top level element is not an instance of container or list",
- ErrorType.application, ErrorTag.unknown_element, ErrorSeverity.error);
- }
- return parsedNode;
- }
-
- protected static final class GetConfigExecution {
-
- private final Optional<Datastore> datastore;
- public GetConfigExecution(final Optional<Datastore> datastore) {
- this.datastore = datastore;
- }
-
- public Optional<Datastore> getDatastore() {
- return datastore;
- }
-
- static GetConfigExecution fromXml(final XmlElement xml, final String operationName) throws DocumentedException {
- try {
- validateInputRpc(xml, operationName);
- } catch (final DocumentedException e) {
- throw new DocumentedException("Incorrect RPC: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
- }
-
- final Optional<Datastore> sourceDatastore;
- try {
- sourceDatastore = parseSource(xml);
- } catch (final DocumentedException e) {
- throw new DocumentedException("Get-config source attribute error: " + e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
- }
-
- return new GetConfigExecution(sourceDatastore);
- }
-
- private static Optional<Datastore> parseSource(final XmlElement xml) throws DocumentedException {
- final Optional<XmlElement> sourceElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SOURCE_KEY,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
- return sourceElement.isPresent() ?
- Optional.of(Datastore.valueOf(sourceElement.get().getOnlyChildElement().getName())) : Optional.<Datastore>absent();
- }
-
- private static void validateInputRpc(final XmlElement xml, String operationName) throws DocumentedException{
- xml.checkName(operationName);
- xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- }
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Get extends AbstractGet {
-
- private static final Logger LOG = LoggerFactory.getLogger(Get.class);
-
- private static final String OPERATION_NAME = "get";
- private final TransactionProvider transactionProvider;
-
- public Get(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext, final TransactionProvider transactionProvider) {
- super(netconfSessionIdForReporting, schemaContext);
- this.transactionProvider = transactionProvider;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
-
- final Optional<YangInstanceIdentifier> dataRootOptional = getDataRootFromFilter(operationElement);
- if (!dataRootOptional.isPresent()) {
- return XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
- }
-
- final YangInstanceIdentifier dataRoot = dataRootOptional.get();
-
- DOMDataReadWriteTransaction rwTx = getTransaction(Datastore.running);
- try {
- final Optional<NormalizedNode<?, ?>> normalizedNodeOptional = rwTx.read(LogicalDatastoreType.OPERATIONAL, dataRoot).checkedGet();
- transactionProvider.abortRunningTransaction(rwTx);
-
- if (!normalizedNodeOptional.isPresent()) {
- return XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
- }
-
- return serializeNodeWithParentStructure(document, dataRoot, normalizedNodeOptional.get());
- } catch (ReadFailedException e) {
- LOG.warn("Unable to read data: {}", dataRoot, e);
- throw new IllegalStateException("Unable to read data " + dataRoot, e);
- }
- }
-
- private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws DocumentedException{
- if (datastore == Datastore.candidate) {
- return transactionProvider.getOrCreateTransaction();
- } else if (datastore == Datastore.running) {
- return transactionProvider.createRunningTransaction();
- }
- throw new DocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops.get;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.Datastore;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class GetConfig extends AbstractGet {
-
- private static final Logger LOG = LoggerFactory.getLogger(GetConfig.class);
-
- private static final String OPERATION_NAME = "get-config";
- private final TransactionProvider transactionProvider;
-
- public GetConfig(final String netconfSessionIdForReporting, final CurrentSchemaContext schemaContext, final TransactionProvider transactionProvider) {
- super(netconfSessionIdForReporting, schemaContext);
- this.transactionProvider = transactionProvider;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
- GetConfigExecution getConfigExecution = null;
- try {
- getConfigExecution = GetConfigExecution.fromXml(operationElement, OPERATION_NAME);
-
- } catch (final DocumentedException e) {
- LOG.warn("Get request processing failed on session: {}", getNetconfSessionIdForReporting(), e);
- throw e;
- }
-
- final Optional<YangInstanceIdentifier> dataRootOptional = getDataRootFromFilter(operationElement);
- if (!dataRootOptional.isPresent()) {
- return XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
- }
-
- final YangInstanceIdentifier dataRoot = dataRootOptional.get();
-
- // Proper exception should be thrown
- Preconditions.checkState(getConfigExecution.getDatastore().isPresent(), "Source element missing from request");
-
- DOMDataReadWriteTransaction rwTx = getTransaction(getConfigExecution.getDatastore().get());
- try {
- final Optional<NormalizedNode<?, ?>> normalizedNodeOptional = rwTx.read(LogicalDatastoreType.CONFIGURATION, dataRoot).checkedGet();
- if (getConfigExecution.getDatastore().get() == Datastore.running) {
- transactionProvider.abortRunningTransaction(rwTx);
- }
-
- if (!normalizedNodeOptional.isPresent()) {
- return XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
- }
-
- return serializeNodeWithParentStructure(document, dataRoot, normalizedNodeOptional.get());
- } catch (ReadFailedException e) {
- LOG.warn("Unable to read data: {}", dataRoot, e);
- throw new IllegalStateException("Unable to read data " + dataRoot, e);
- }
- }
-
- private DOMDataReadWriteTransaction getTransaction(Datastore datastore) throws DocumentedException{
- if (datastore == Datastore.candidate) {
- return transactionProvider.getOrCreateTransaction();
- } else if (datastore == Datastore.running) {
- return transactionProvider.createRunningTransaction();
- }
- throw new DocumentedException("Incorrect Datastore: ", ErrorType.protocol, ErrorTag.bad_element, ErrorSeverity.error);
- }
-
- @Override
- protected String getOperationName() {
- return OPERATION_NAME;
- }
-
-}
+++ /dev/null
-module netconf-mdsal-mapper {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper";
- prefix "nmm";
-
- import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
- import opendaylight-md-sal-dom { prefix md-sal-dom; revision-date 2013-10-28; }
- import config { prefix config; revision-date 2013-04-05; }
-
- organization "Cisco Systems, Inc.";
-
- description
- "This module contains the base YANG definitions for
- an MD-SAL mapper implementation";
-
- revision "2015-01-14" {
- description
- "Initial revision.";
- }
-
- identity netconf-mdsal-mapper {
- base config:module-type;
- config:provided-service nnm:netconf-northbound-mapper;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-mdsal-mapper {
- when "/config:modules/config:module/config:type = 'netconf-mdsal-mapper'";
-
- container root-schema-service {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity md-sal-dom:schema-service;
- }
- }
- }
-
- container dom-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity md-sal-dom:dom-broker-osgi-registry;
- }
- }
- }
-
- container mapper-aggregator {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity nnm:netconf-mapper-registry;
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.google.common.io.ByteSource;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.custommonkey.xmlunit.DetailedDiff;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.mdsal.connector.TransactionProvider;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.get.Get;
-import org.opendaylight.controller.netconf.mdsal.connector.ops.get.GetConfig;
-import org.opendaylight.controller.netconf.util.test.NetconfXmlUnitRecursiveQualifier;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.spi.data.DOMStore;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
-import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-public class NetconfMDSalMappingTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMDSalMappingTest.class);
-
- private static final String RPC_REPLY_ELEMENT = "rpc-reply";
- private static final String DATA_ELEMENT = "data";
- private static final String FILTER_NODE = "filter";
- private static final String GET_CONFIG = "get-config";
- private static final QName TOP = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "top");
- private static final QName USERS = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "users");
- private static final QName USER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "user");
- private static final QName MODULES = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "modules");
- private static final QName AUGMENTED_CONTAINER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "augmented-container");
- private static final QName AUGMENTED_STRING_IN_CONT = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "identifier");
- private static final QName CHOICE_NODE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "choice-node");
- private static final QName AUGMENTED_CASE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "augmented-case");
- private static final QName CHOICE_WRAPPER = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "choice-wrapper");
- private static final QName INNER_CHOICE = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "inner-choice");
- private static final QName INNER_CHOICE_TEXT = QName.create("urn:opendaylight:mdsal:mapping:test", "2015-02-26", "text");
-
- private static final YangInstanceIdentifier AUGMENTED_CONTAINER_IN_MODULES =
- YangInstanceIdentifier.builder().node(TOP).node(MODULES).build().node(new AugmentationIdentifier(Collections.singleton(AUGMENTED_CONTAINER)));
-
- private static Document RPC_REPLY_OK = null;
-
- static {
- try {
- RPC_REPLY_OK = XmlFileLoader.xmlFileToDocument("messages/mapping/rpc-reply_ok.xml");
- } catch (Exception e) {
- LOG.debug("unable to load rpc reply ok.", e);
- RPC_REPLY_OK = XmlUtil.newDocument();
- }
- }
-
- private CurrentSchemaContext currentSchemaContext = null;
- private SchemaContext schemaContext = null;
- private String sessionIdForReporting = "netconf-test-session1";
-
- private TransactionProvider transactionProvider = null;
-
- @Before
- public void setUp() throws Exception {
-
- XMLUnit.setIgnoreWhitespace(true);
- XMLUnit.setIgnoreAttributeOrder(true);
-
- this.schemaContext = parseSchemas(getYangSchemas());
- schemaContext.getModules();
- final SchemaService schemaService = createSchemaService();
-
- final DOMStore operStore = InMemoryDOMDataStoreFactory.create("DOM-OPER", schemaService);
- final DOMStore configStore = InMemoryDOMDataStoreFactory.create("DOM-CFG", schemaService);
-
- final EnumMap<LogicalDatastoreType, DOMStore> datastores = new EnumMap<>(LogicalDatastoreType.class);
- datastores.put(LogicalDatastoreType.CONFIGURATION, configStore);
- datastores.put(LogicalDatastoreType.OPERATIONAL, operStore);
-
- ExecutorService listenableFutureExecutor = SpecialExecutors.newBlockingBoundedCachedThreadPool(
- 16, 16, "CommitFutures");
-
- final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor);
- this.transactionProvider = new TransactionProvider(cdb, sessionIdForReporting);
- this.currentSchemaContext = new CurrentSchemaContext(schemaService);
-
- }
-
- @Test
- public void testEmptyDatastore() throws Exception {
- assertEmptyDatastore(get());
- assertEmptyDatastore(getConfigCandidate());
- assertEmptyDatastore(getConfigRunning());
- }
-
- @Test
- public void testDiscard() throws Exception {
-
- try {
- discardChanges();
- fail("Should have failed, need to execute an edit before discard");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
- }
-
- @Test
- public void testIncorrectGet() throws Exception {
-
- try {
- executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_getConfig.xml");
- fail("Should have failed, this is an incorrect request");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
-
- try {
- executeOperation(new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider), "messages/mapping/bad_namespace_getConfig.xml");
- fail("Should have failed, this is an incorrect request");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
-
-
- }
-
- @Test
- public void testEditRunning() throws Exception {
-
- try {
- edit("messages/mapping/editConfigs/editConfig_running.xml");
- fail("Should have failed - edit config on running datastore is not supported");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
- assertTrue(e.getErrorType() == ErrorType.protocol);
- }
-
- }
-
- @Test
- public void testCandidateTransaction() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
- assertEmptyDatastore(getConfigRunning());
-
- verifyResponse(discardChanges(), RPC_REPLY_OK);
- assertEmptyDatastore(getConfigCandidate());
-
- }
-
- @Test
- public void testEditWithCommit() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_n1.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
-
- verifyResponse(commit(), RPC_REPLY_OK);
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_n1_control.xml"));
-
- deleteDatastore();
-
- }
-
- @Test
- public void testMultipleEditsWithMerge() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_1.xml"));
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml"));
- assertEmptyDatastore(getConfigRunning());
-
- verifyResponse(commit(), RPC_REPLY_OK);
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_control_2.xml"));
-
- deleteDatastore();
-
- }
-
- @Test
- public void testMoreComplexEditConfigs() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_1.xml"), RPC_REPLY_OK);
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_single_1.xml"), RPC_REPLY_OK);
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_2.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_3.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_more_complex_merge_2.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_4_replace.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml"));
- verifyResponse(commit(), RPC_REPLY_OK);
-
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_after_replace.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_replace_default.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_replace_default_control.xml"));
- verifyResponse(commit(), RPC_REPLY_OK);
-
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_replace_default_control.xml"));
-
- deleteDatastore();
-
- }
-
- @Test
- public void testLock() throws Exception {
-
- verifyResponse(lockCandidate(), RPC_REPLY_OK);
-
- try {
- lock();
- fail("Should have failed - locking of running datastore is not supported");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
-
-
- try {
- lockWithoutTarget();
- fail("Should have failed, target is missing");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.invalid_value);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
- }
-
- @Test
- public void testUnlock() throws Exception {
-
- verifyResponse(unlockCandidate(), RPC_REPLY_OK);
-
- try {
- unlock();
- fail("Should have failed - unlocking of running datastore is not supported");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_not_supported);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
-
- try {
- unlockWithoutTarget();
- fail("Should have failed, target is missing");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.invalid_value);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
- }
-
- @Test
- public void testEditWithCreate() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_create.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfig_create_n1_control.xml"));
-
-
- try {
- edit("messages/mapping/editConfigs/editConfig_create.xml");
- fail("Create should have failed - data already exists");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.data_exists);
- assertTrue(e.getErrorType() == ErrorType.protocol);
- }
-
- verifyResponse(discardChanges(), RPC_REPLY_OK);
-
- }
-
- @Test
- public void testDeleteNonExisting() throws Exception {
-
- assertEmptyDatastore(getConfigCandidate());
- assertEmptyDatastore(getConfigRunning());
-
- try {
- edit("messages/mapping/editConfigs/editConfig_delete-top.xml");
- fail("Delete should have failed - data is missing");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.data_missing);
- assertTrue(e.getErrorType() == ErrorType.protocol);
- }
-
- }
-
- @Test
- public void testEditMissingDefaultOperation() throws Exception {
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_1.xml"), RPC_REPLY_OK);
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_2.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml"));
-
- verifyResponse(commit(), RPC_REPLY_OK);
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_missing_default-operation_control.xml"));
-
- deleteDatastore();
- }
-
- public static void printDocument(Document doc) throws IOException, TransformerException {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
- transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
- transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
-
- StringWriter writer = new StringWriter();
- transformer.transform(new DOMSource(doc),
- new StreamResult(writer));
- LOG.warn(writer.getBuffer().toString());
- }
-
- @Test
- public void testEditConfigWithMultipleOperations() throws Exception {
- deleteDatastore();
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_setup.xml"), RPC_REPLY_OK);
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_1.xml"), RPC_REPLY_OK);
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_2.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_2_control.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_leaf_operations.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_3_control.xml"));
-
- deleteDatastore();
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_setup.xml"), RPC_REPLY_OK);
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_default-replace.xml"), RPC_REPLY_OK);
-
- try {
- edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_create_existing.xml");
- fail();
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.data_exists);
- assertTrue(e.getErrorType() == ErrorType.protocol);
- }
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations_control.xml"));
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_remove-non-existing.xml"), RPC_REPLY_OK);
-
- try {
- edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete-non-existing.xml");
- fail();
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.data_missing);
- assertTrue(e.getErrorType() == ErrorType.protocol);
- }
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup-control.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_setup2-control.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_merge_multiple_operations_5_choice_delete.xml"), RPC_REPLY_OK);
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/editConfigs/editConfig_merge_multiple_operations_4_delete_children_operations_control.xml"));
-
- deleteDatastore();
- }
-
- @Test
- public void testFiltering() throws Exception {
-
- assertEmptyDatastore(getConfigCandidate());
- assertEmptyDatastore(getConfigRunning());
-
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-config-empty-filter.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
- verifyResponse(getWithFilter("messages/mapping/filters/get-empty-filter.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
-
- verifyResponse(getConfigCandidate(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
- verifyResponse(getConfigRunning(), XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-users.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/get-empty-response.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup.xml"), RPC_REPLY_OK);
- verifyResponse(commit(), RPC_REPLY_OK);
-
- //TODO uncomment these tests once we can parse KeyedListNode as a selection node, currently you cannot use a KeyedList as a selection node in filter
-// verifyFilterIdentifier("messages/mapping/filters/get-filter-alluser.xml",
-// YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
- verifyFilterIdentifier("messages/mapping/filters/get-filter-company-info.xml",
- YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
- verifyFilterIdentifier("messages/mapping/filters/get-filter-modules-and-admin.xml",
- YangInstanceIdentifier.builder().node(TOP).build());
- verifyFilterIdentifier("messages/mapping/filters/get-filter-only-names-types.xml",
- YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
-// verifyFilterIdentifier("messages/mapping/filters/get-filter-specific-module-type-and-user.xml",
-// YangInstanceIdentifier.builder().node(TOP).build());
-// verifyFilterIdentifier("messages/mapping/filters/get-filter-superuser.xml",
-// YangInstanceIdentifier.builder().node(TOP).node(USERS).node(USER).build());
- verifyFilterIdentifier("messages/mapping/filters/get-filter-users.xml",
- YangInstanceIdentifier.builder().node(TOP).node(USERS).build());
-
- YangInstanceIdentifier ident = YangInstanceIdentifier.
- builder(AUGMENTED_CONTAINER_IN_MODULES).
- node(AUGMENTED_CONTAINER).
- node(AUGMENTED_STRING_IN_CONT).build();
-
- verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-string.xml", ident);
- verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case.xml",
- YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(AUGMENTED_CASE).build());
-
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case.xml"));
- verifyResponse(edit("messages/mapping/editConfigs/editConfig-filtering-setup2.xml"), RPC_REPLY_OK);
- verifyResponse(commit(), RPC_REPLY_OK);
-
- verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml",
- YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).build());
- verifyFilterIdentifier("messages/mapping/filters/get-filter-augmented-case-inner-case.xml",
- YangInstanceIdentifier.builder().node(TOP).node(CHOICE_NODE).node(CHOICE_WRAPPER).node(INNER_CHOICE).node(INNER_CHOICE_TEXT).build());
-
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-string.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-string.xml"));
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-choice.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml"));
- verifyResponse(getConfigWithFilter("messages/mapping/filters/get-filter-augmented-case-inner-case.xml"),
- XmlFileLoader.xmlFileToDocument("messages/mapping/filters/response-augmented-case-inner-choice.xml"));
-
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-top.xml"), RPC_REPLY_OK);
- verifyResponse(commit(), RPC_REPLY_OK);
-
- }
-
- private void verifyFilterIdentifier(String resource, YangInstanceIdentifier identifier) throws Exception{
- TestingGetConfig getConfig = new TestingGetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
- Document request = XmlFileLoader.xmlFileToDocument(resource);
- YangInstanceIdentifier iid = getConfig.getInstanceIdentifierFromDocument(request);
- assertTrue(iid.equals(identifier));
- }
-
- private class TestingGetConfig extends GetConfig{
- public TestingGetConfig(String sessionId, CurrentSchemaContext schemaContext, TransactionProvider transactionProvider) {
- super(sessionId, schemaContext, transactionProvider);
- }
-
- public YangInstanceIdentifier getInstanceIdentifierFromDocument(Document request) throws DocumentedException {
- XmlElement filterElement = XmlElement.fromDomDocument(request).getOnlyChildElement(GET_CONFIG).getOnlyChildElement(FILTER_NODE);
- return getInstanceIdentifierFromFilter(filterElement);
- }
- }
-
- private void deleteDatastore() throws Exception{
- verifyResponse(edit("messages/mapping/editConfigs/editConfig_delete-root.xml"), RPC_REPLY_OK);
- assertEmptyDatastore(getConfigCandidate());
-
- verifyResponse(commit(), RPC_REPLY_OK);
- assertEmptyDatastore(getConfigRunning());
- }
-
- private void verifyResponse(Document response, Document template) throws IOException, TransformerException {
- DetailedDiff dd = new DetailedDiff(new Diff(response, template));
- dd.overrideElementQualifier(new NetconfXmlUnitRecursiveQualifier());
-
- printDocument(response);
- printDocument(template);
-
- assertTrue(dd.toString(), dd.similar());
- }
-
- private void assertEmptyDatastore(Document response) {
-
- NodeList nodes = response.getChildNodes();
- assertTrue(nodes.getLength() == 1);
-
- assertEquals(nodes.item(0).getLocalName(), RPC_REPLY_ELEMENT);
-
- NodeList replyNodes = nodes.item(0).getChildNodes();
- assertTrue(replyNodes.getLength() == 1);
-
- Node dataNode = replyNodes.item(0);
- assertEquals(dataNode.getLocalName(), DATA_ELEMENT);
- assertFalse(dataNode.hasChildNodes());
-
- }
-
- private Document commit() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Commit commit = new Commit(sessionIdForReporting, transactionProvider);
- return executeOperation(commit, "messages/mapping/commit.xml");
- }
-
- private Document discardChanges() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- DiscardChanges discardOp = new DiscardChanges(sessionIdForReporting, transactionProvider);
- return executeOperation(discardOp, "messages/mapping/discardChanges.xml");
- }
-
- private Document edit(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- EditConfig editConfig = new EditConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(editConfig, resource);
- }
-
- private Document get() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(get, "messages/mapping/get.xml");
- }
-
- private Document getWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Get get = new Get(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(get, resource);
- }
-
- private Document getConfigRunning() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(getConfig, "messages/mapping/getConfig.xml");
- }
-
- private Document getConfigCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(getConfig, "messages/mapping/getConfig_candidate.xml");
- }
-
- private Document getConfigWithFilter(String resource) throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- GetConfig getConfig = new GetConfig(sessionIdForReporting, currentSchemaContext, transactionProvider);
- return executeOperation(getConfig, resource);
- }
-
- private Document lock() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Lock lock = new Lock(sessionIdForReporting);
- return executeOperation(lock, "messages/mapping/lock.xml");
- }
-
- private Document unlock() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Unlock unlock = new Unlock(sessionIdForReporting);
- return executeOperation(unlock, "messages/mapping/unlock.xml");
- }
-
- private Document lockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Lock lock = new Lock(sessionIdForReporting);
- return executeOperation(lock, "messages/mapping/lock_notarget.xml");
- }
-
- private Document unlockWithoutTarget() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Unlock unlock = new Unlock(sessionIdForReporting);
- return executeOperation(unlock, "messages/mapping/unlock_notarget.xml");
- }
-
- private Document lockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Lock lock = new Lock(sessionIdForReporting);
- return executeOperation(lock, "messages/mapping/lock_candidate.xml");
- }
-
- private Document unlockCandidate() throws DocumentedException, ParserConfigurationException, SAXException, IOException {
- Unlock unlock = new Unlock(sessionIdForReporting);
- return executeOperation(unlock, "messages/mapping/unlock_candidate.xml");
- }
-
- private Document executeOperation(NetconfOperation op, String filename) throws ParserConfigurationException, SAXException, IOException, DocumentedException {
- final Document request = XmlFileLoader.xmlFileToDocument(filename);
- final Document response = op.handle(request, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
-
- LOG.debug("Got response {}" , response);
- return response;
- }
-
- private Collection<InputStream> getYangSchemas() {
- final List<String> schemaPaths = Arrays.asList("/META-INF/yang/config.yang", "/yang/mdsal-netconf-mapping-test.yang");
- final List<InputStream> schemas = new ArrayList<>();
-
- for (String schemaPath : schemaPaths) {
- InputStream resourceAsStream = getClass().getResourceAsStream(schemaPath);
- schemas.add(resourceAsStream);
- }
-
- return schemas;
- }
-
- private SchemaContext parseSchemas(Collection<InputStream> schemas) throws IOException, YangSyntaxErrorException {
- final YangParserImpl parser = new YangParserImpl();
- Collection<ByteSource> sources = BuilderUtils.streamsToByteSources(schemas);
- return parser.parseSources(sources);
- }
-
- private SchemaService createSchemaService() {
- return new SchemaService() {
-
- @Override
- public void addModule(Module module) {
- }
-
- @Override
- public void removeModule(Module module) {
-
- }
-
- @Override
- public SchemaContext getSessionContext() {
- return schemaContext;
- }
-
- @Override
- public SchemaContext getGlobalContext() {
- return schemaContext;
- }
-
- @Override
- public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(final SchemaContextListener listener) {
- listener.onGlobalContextUpdated(getGlobalContext());
- return new ListenerRegistration<SchemaContextListener>() {
- @Override
- public void close() {
-
- }
-
- @Override
- public SchemaContextListener getInstance() {
- return listener;
- }
- };
- }
- };
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mdsal.connector.ops;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import com.google.common.base.Preconditions;
-import com.google.common.io.ByteSource;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.xml.transform.TransformerException;
-import org.custommonkey.xmlunit.DetailedDiff;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.mdsal.connector.CurrentSchemaContext;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
-import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-public class RuntimeRpcTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpcTest.class);
-
- private String sessionIdForReporting = "netconf-test-session1";
-
- private static Document RPC_REPLY_OK = null;
-
- static {
- try {
- RPC_REPLY_OK = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/runtimerpc-ok-reply.xml");
- } catch (Exception e) {
- LOG.debug("unable to load rpc reply ok.", e);
- RPC_REPLY_OK = XmlUtil.newDocument();
- }
- }
-
- private DOMRpcService rpcServiceVoidInvoke = new DOMRpcService() {
- @Nonnull
- @Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input) {
- return Futures.immediateCheckedFuture((DOMRpcResult) new DefaultDOMRpcResult(null, Collections.<RpcError>emptyList()));
- }
-
- @Nonnull
- @Override
- public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull T listener) {
- return null;
- }
- };
-
- private DOMRpcService rpcServiceFailedInvocation = new DOMRpcService() {
- @Nonnull
- @Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input) {
- return Futures.immediateFailedCheckedFuture((DOMRpcException) new DOMRpcException("rpc invocation not implemented yet") {
- });
- }
-
- @Nonnull
- @Override
- public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull T listener) {
- return null;
- }
- };
-
- private DOMRpcService rpcServiceSuccesfullInvocation = new DOMRpcService() {
- @Nonnull
- @Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull SchemaPath type, @Nullable NormalizedNode<?, ?> input) {
- Collection<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> children = (Collection) input.getValue();
- Module module = schemaContext.findModuleByNamespaceAndRevision(type.getLastComponent().getNamespace(), null);
- RpcDefinition rpcDefinition = getRpcDefinitionFromModule(module, module.getNamespace(), type.getLastComponent().getLocalName());
- ContainerSchemaNode outputSchemaNode = rpcDefinition.getOutput();
- ContainerNode node = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(outputSchemaNode.getQName()))
- .withValue(children).build();
-
- return Futures.immediateCheckedFuture((DOMRpcResult) new DefaultDOMRpcResult(node));
- }
-
- @Nonnull
- @Override
- public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull T listener) {
- return null;
- }
- };
-
- private SchemaContext schemaContext = null;
- private CurrentSchemaContext currentSchemaContext = null;
- @Mock
- private SchemaService schemaService;
- @Mock
- private SchemaContextListener listener;
- @Mock
- private ListenerRegistration registration;
-
- @Before
- public void setUp() throws Exception {
-
- initMocks(this);
- doNothing().when(registration).close();
- doReturn(listener).when(registration).getInstance();
- doNothing().when(schemaService).addModule(any(Module.class));
- doNothing().when(schemaService).removeModule(any(Module.class));
- doReturn(schemaContext).when(schemaService).getGlobalContext();
- doReturn(schemaContext).when(schemaService).getSessionContext();
- doAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
- ((SchemaContextListener) invocationOnMock.getArguments()[0]).onGlobalContextUpdated(schemaContext);
- return registration;
- }
- }).when(schemaService).registerSchemaContextListener(any(SchemaContextListener.class));
-
- XMLUnit.setIgnoreWhitespace(true);
- XMLUnit.setIgnoreAttributeOrder(true);
-
- this.schemaContext = parseSchemas(getYangSchemas());
- this.currentSchemaContext = new CurrentSchemaContext(schemaService);
- }
-
- @Test
- public void testVoidOutputRpc() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceVoidInvoke);
-
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-void-output.xml");
- HandlingPriority priority = rpc.canHandle(rpcDocument);
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- Document response = rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
-
- verifyResponse(response, RPC_REPLY_OK);
- }
-
- @Test
- public void testSuccesfullNonVoidInvocation() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceSuccesfullInvocation);
-
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-nonvoid.xml");
- HandlingPriority priority = rpc.canHandle(rpcDocument);
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- Document response = rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- verifyResponse(response, XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-nonvoid-control.xml"));
- }
-
- @Test
- public void testSuccesfullContainerInvocation() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceSuccesfullInvocation);
-
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-container.xml");
- HandlingPriority priority = rpc.canHandle(rpcDocument);
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- Document response = rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- verifyResponse(response, XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-container-control.xml"));
- }
-
- @Test
- public void testFailedInvocation() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceFailedInvocation);
-
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-nonvoid.xml");
- HandlingPriority priority = rpc.canHandle(rpcDocument);
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- try {
- rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- fail("should have failed with rpc invocation not implemented yet");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorType() == ErrorType.application);
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.operation_failed);
- }
- }
-
- @Test
- public void testVoidInputOutputRpc() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceVoidInvoke);
-
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-void-input-output.xml");
- HandlingPriority priority = rpc.canHandle(rpcDocument);
- Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
-
- Document response = rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
-
- verifyResponse(response, RPC_REPLY_OK);
- }
-
- @Test
- public void testBadNamespaceInRpc() throws Exception {
- RuntimeRpc rpc = new RuntimeRpc(sessionIdForReporting, currentSchemaContext, rpcServiceVoidInvoke);
- Document rpcDocument = XmlFileLoader.xmlFileToDocument("messages/mapping/rpcs/rpc-bad-namespace.xml");
-
- try {
- rpc.handle(rpcDocument, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- fail("Should have failed, rpc has bad namespace");
- } catch (DocumentedException e) {
- assertTrue(e.getErrorSeverity() == ErrorSeverity.error);
- assertTrue(e.getErrorTag() == ErrorTag.bad_element);
- assertTrue(e.getErrorType() == ErrorType.application);
- }
- }
-
- private void verifyResponse(Document response, Document template) throws IOException, TransformerException {
- DetailedDiff dd = new DetailedDiff(new Diff(response, template));
- dd.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
- //we care about order so response has to be identical
- assertTrue(dd.identical());
- }
-
- private RpcDefinition getRpcDefinitionFromModule(Module module, URI namespaceURI, String name) {
- for (RpcDefinition rpcDef : module.getRpcs()) {
- if (rpcDef.getQName().getNamespace().equals(namespaceURI)
- && rpcDef.getQName().getLocalName().equals(name)) {
- return rpcDef;
- }
- }
-
- return null;
-
- }
-
- private Collection<InputStream> getYangSchemas() {
- final List<String> schemaPaths = Arrays.asList("/yang/mdsal-netconf-rpc-test.yang");
- final List<InputStream> schemas = new ArrayList<>();
-
- for (String schemaPath : schemaPaths) {
- InputStream resourceAsStream = getClass().getResourceAsStream(schemaPath);
- schemas.add(resourceAsStream);
- }
-
- return schemas;
- }
-
- private SchemaContext parseSchemas(Collection<InputStream> schemas) throws IOException, YangSyntaxErrorException {
- final YangParserImpl parser = new YangParserImpl();
- Collection<ByteSource> sources = BuilderUtils.streamsToByteSources(schemas);
- return parser.parseSources(sources);
- }
-}
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <bad-get-config>
- <source>
- <candidate/>
- </source>
- </bad-get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="bad-namespace" message-id="101">
- <get-config>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <commit/>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <discard-changes/>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-put</id>
- <content>put content</content>
- </mapping-node>
- </mapping-nodes>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>rooty root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>admin</name>
- <type>superuser</type>
- <full-name>johny admin</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>regular</name>
- <type>user</type>
- <full-name>burt regular</full-name>
- <company-info>
- <dept>3</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <modules>
- <augmented-container>
- <identifier>augmented container</identifier>
- </augmented-container>
- <module>
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module>
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- <module>
- <id>module3</id>
- <type>unknown</type>
- <desc>module3-desc</desc>
- </module>
- </modules>
- <augmented-case>augmented case</augmented-case>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text>augmented nested choice text1</text>
- </choice-wrapper>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>none</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">
- <mapping-node>
- <id>node1-put</id>
- <content>put content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>none</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="remove">
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="remove">
- </top>
- </config>
-</edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>none</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- </top>
- </config>
-</edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>merged content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>updated merged content</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>new node</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>updated merged content</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>new node</content>
- </mapping-node>
- </mapping-nodes>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>merged content node 1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>merged content node 2</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- <mapping-node>
- <id>new-node4</id>
- <content>new node4 content</content>
- </mapping-node>
- <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>node3-merge</id>
- <content>merged content node 3</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new node5 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content>new node6 content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">
- <mapping-node>
- <id>new-node7</id>
- <content>new node content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- <mapping-node>
- <id>new-node4</id>
- <content>new node4 content</content>
- </mapping-node>
- </mapping-nodes>
-</data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>new-node4</id>
- <content>new node4 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new node5 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content>new node6 content</content>
- </mapping-node>
- </mapping-nodes>
-</data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>new-node7</id>
- <content>new node content</content>
- </mapping-node>
- </mapping-nodes>
-</data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>merged content node 1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>merged content node 2</content>
- </mapping-node>
- </mapping-nodes>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
-<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>merged content node 1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>merged content node 2</content>
- </mapping-node>
- <mapping-node>
- <id>node3-merge</id>
- <content>merged content node 3</content>
- </mapping-node>
- </mapping-nodes>
-</data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <name>root</name>
- <type>superuser</type>
- <full-name>rooty root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>admin</name>
- <type>superuser</type>
- <full-name>johny admin updated</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- </users>
- <modules>
- <module xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- <module>
- <id>new module</id>
- <type>merged module</type>
- <desc>merged module desc</desc>
- </module>
- </modules>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="101" a="64" id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new node5 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content>new node6 content</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>admin</name>
- <full-name>johny admin updated</full-name>
- <type>superuser</type>
- <company-info>
- <id>2</id>
- <dept>2</dept>
- </company-info>
- </user>
- <user>
- <name>regular</name>
- <full-name>burt regular</full-name>
- <type>user</type>
- <company-info>
- <id>3</id>
- <dept>3</dept>
- </company-info>
- </user>
- </users>
- <modules>
- <augmented-container>
- <identifier>augmented container</identifier>
- </augmented-container>
- <module>
- <id>module3</id>
- <type>unknown</type>
- <desc>module3-desc</desc>
- </module>
- <module>
- <id>new module</id>
- <type>merged module</type>
- <desc>merged module desc</desc>
- </module>
- </modules>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">
- <user>
- <name>single user</name>
- <type>superuser</type>
- <full-name>i replaced everything</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- </users>
- <modules>
- <augmented-container xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <identifier>augmented container</identifier>
- </augmented-container>
- <module xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- </modules>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="101" a="64" id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new node5 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content>new node6 content</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <modules>
- <module>
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module>
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- <module>
- <id>module3</id>
- <type>unknown</type>
- <desc>module3-desc</desc>
- </module>
- <module>
- <id>new module</id>
- <type>merged module</type>
- <desc>merged module desc</desc>
- </module>
- </modules>
- <users>
- <user>
- <name>single user</name>
- <type>superuser</type>
- <full-name>i replaced everything</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="101" a="64" id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new-node5 replaced content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- </mapping-node>
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>single user</name>
- <type>superuser</type>
- <full-name>i replaced everything</full-name>
- </user>
- </users>
- <modules>
- <module>
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module>
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- <module>
- <id>module3</id>
- <type>unknown</type>
- <desc>module3-desc</desc>
- </module>
- <module>
- <id>new module</id>
- <type>merged module</type>
- <desc>merged module desc</desc>
- </module>
- </modules>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="replace">new-node5 replaced content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">new node6 content</content>
- </mapping-node>
- <mapping-node xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>single user</name>
- <type>superuser</type>
- <full-name>i replaced everything</full-name>
- <company-info xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- </users>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">
- <low-level/>
- </mid-level>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>replace</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level>
- <low-level>
- <lowest-level>
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- </lowest-level>
- </low-level>
- <low-level2>
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- </low-level2>
- </mid-level>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete"/>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <low-level>
- <lowest-level xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- <note>note5</note>
- </lowest-level>
- </low-level>
- <low-level2 xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- <note>note5</note>
- </low-level2>
- </mid-level>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test"/>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="remove"/>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <mid-level>
- <low-level>
- <lowest-level>
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- <note>note5</note>
- </lowest-level>
- </low-level>
- <low-level2>
- <note>note1</note>
- <note>note2</note>
- <note>note3</note>
- <note>note4</note>
- <note>note5</note>
- </low-level2>
- </mid-level>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete"/>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text>choice created</text>
- </choice-wrapper>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">choice created</text>
- </choice-wrapper>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text>choice updated</text>
- <text2>choice text2 created</text2>
- </choice-wrapper>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text>choice updated</text>
- <text2 xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="create">choice text2 created</text2>
- </choice-wrapper>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-merge</id>
- <content>overwritten old content node1</content>
- </mapping-node>
- <mapping-node>
- <id>node2-merge</id>
- <content>overwritten old content node2</content>
- </mapping-node>
- <mapping-node>
- <id>new-node5</id>
- <content>new node5 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node6</id>
- <content>new node6 content</content>
- </mapping-node>
- </mapping-nodes>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>rooty root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>admin</name>
- <type>superuser</type>
- <full-name>johny admin</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>regular</name>
- <type>user</type>
- <full-name>burt regular</full-name>
- <company-info>
- <dept>3</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <modules>
- <augmented-container>
- <identifier>augmented container</identifier>
- </augmented-container>
- <module>
- <id>module1</id>
- <type>type1</type>
- <desc>module1-desc</desc>
- </module>
- <module>
- <id>module2</id>
- <type>type1</type>
- <desc>module2-desc</desc>
- </module>
- <module>
- <id>module3</id>
- <type>unknown</type>
- <desc>module3-desc</desc>
- </module>
- </modules>
- </top>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-put</id>
- <content>put content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-put</id>
- <content>put content</content>
- </mapping-node>
- </mapping-nodes>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node3-merge</id>
- <content>merged content node 3</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>none</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test" xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="remove">
- </mapping-nodes>
- </config>
-</edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>replace</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>new-node1</id>
- <content>replaced node 1 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node2</id>
- <content>replaced node 2 content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply a="64" id="a" message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlnx="a:b:c:d">
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>new-node1</id>
- <content>replaced node 1 content</content>
- </mapping-node>
- <mapping-node>
- <id>new-node2</id>
- <content>replaced node 2 content</content>
- </mapping-node>
- </mapping-nodes>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <running/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <mapping-nodes xmlns="urn:opendaylight:mdsal:mapping:test">
- <mapping-node>
- <id>node1-put</id>
- <content>put content</content>
- </mapping-node>
- </mapping-nodes>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get>
- <filter type="subtree">
- </filter>
- </get>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user/>
- </users>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text/>
- </choice-wrapper>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
-
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper/>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <augmented-case/>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <modules>
- <augmented-container>
- <identifier/>
- </augmented-container>
- </modules>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>root</name>
- <company-info/>
- </user>
- <user>
- <name>admin</name>
- <company-info>
- <id/>
- </company-info>
- </user>
- <user>
- <name>regular</name>
- <company-info>
- <dept/>
- </company-info>
- </user>
- </users>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name>admin</name>
- </user>
- </users>
- <modules/>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <name/>
- <type/>
- </user>
- </users>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <type>superuser</type>
- </user>
- </users>
- <modules>
- <module>
- <type>type1</type>
- </module>
- </modules>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users>
- <user>
- <type>superuser</type>
- </user>
- </users>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <filter type="subtree">
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <users/>
- </top>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <choice-wrapper>
- <text>augmented nested choice text1</text>
- </choice-wrapper>
- </top>
- </data>
-</rpc-reply>
-
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <augmented-case>augmented case</augmented-case>
- </top>
- </data>
-</rpc-reply>
-
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <top xmlns="urn:opendaylight:mdsal:mapping:test">
- <modules>
- <augmented-container>
- <identifier>augmented container</identifier>
- </augmented-container>
- </modules>
- </top>
- </data>
-</rpc-reply>
-
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data/>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <source>
- <candidate/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <running/>
- </target>
- </lock>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <candidate/>
- </target>
- </lock>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- </lock>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" message-id="a">
- <ok/>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <nonvoid-rpca>
- <test-string>
- test rpc input string 1
- </test-string>
- <test-string2>
- test rpc input string 2
- </test-string2>
- </nonvoid-rpca>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <cont1 xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- <test-string>
- cont1 input string 1
- </test-string>
- <test-string2>
- cont1 input string 2
- </test-string2>
- </cont1>
- <cont2 xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- <test-string>
- cont2 input string 1
- </test-string>
- <test-string2>
- cont2 input string 2
- </test-string2>
- </cont2>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <container-rpc xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- <cont1>
- <test-string>
- cont1 input string 1
- </test-string>
- <test-string2>
- cont1 input string 2
- </test-string2>
- </cont1>
- <cont2>
- <test-string>
- cont2 input string 1
- </test-string>
- <test-string2>
- cont2 input string 2
- </test-string2>
- </cont2>
- </container-rpc>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <test-string xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- test rpc input string 1
- </test-string>
- <test-string2 xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- test rpc input string 2
- </test-string2>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <nonvoid-rpc xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- <test-string>
- test rpc input string 1
- </test-string>
- <test-string2>
- test rpc input string 2
- </test-string2>
- </nonvoid-rpc>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <void-input-output-rpc xmlns="urn:opendaylight:mdsal:mapping:rpc:test"/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <void-output-rpc xmlns="urn:opendaylight:mdsal:mapping:rpc:test">
- <test-string>
- test rpc input string 1
- </test-string>
- <test-string2>
- test rpc input string 2
- </test-string2>
- </void-output-rpc>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="2">
- <ok/>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <running/>
- </target>
- </unlock>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <candidate/>
- </target>
- </unlock>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc a="64" message-id="a" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- </unlock>
-</rpc>
+++ /dev/null
-module config {
- yang-version 1;
- namespace "urn:opendaylight:mdsal:mapping:test";
- prefix "map";
-
- revision "2015-02-26";
-
- container mapping-nodes {
-
- list mapping-node{
- key "id";
- leaf id {
- type string;
- }
-
- leaf content {
- type string;
- }
- }
- }
-
- container top {
-
- container users {
-
- list user {
-
- key "name";
-
- leaf name {
- type string;
- }
-
- leaf type {
- type string;
- }
-
- leaf full-name {
- type string;
- }
-
- container company-info {
-
- leaf dept {
- type string;
- }
-
- leaf id {
- type string;
- }
- }
- }
- }
-
- container modules {
-
- list module {
-
- key "id";
-
- leaf id {
- type string;
- }
-
- leaf type {
- type string;
- }
-
- leaf desc {
- type string;
- }
- }
- }
-
- choice choice-node {
- case a {
- leaf text {
- type string;
- }
- }
-
- case b {
- container text-cont {
- leaf text {
- type string;
- }
- }
- }
- }
-
- } //top
-
- augment "/map:top/map:choice-node" {
- case c {
- leaf augmented-case {
- type string;
- }
- }
-
- case d {
- container choice-wrapper {
- choice inner-choice {
- case ia {
- leaf text {
- type string;
- }
- }
-
- case ib {
- leaf text2 {
- type string;
- }
- }
- }
- }
- }
- }
-
- augment "/map:top/map:modules/" {
- container augmented-container{
- leaf identifier {
- type string;
- }
- }
- }
-
- augment "/map:top" {
- container mid-level {
- container low-level {
- container lowest-level {
- leaf-list note {
- type string;
- }
- }
- }
- container low-level2 {
- leaf-list note {
- type string;
- }
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module rpc-test {
- yang-version 1;
- namespace "urn:opendaylight:mdsal:mapping:rpc:test";
- prefix "rpc";
-
- rpc void-input-output-rpc {
-
- }
-
- rpc void-output-rpc {
- input {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
- }
-
- rpc nonvoid-rpc {
- input {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
-
- output {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
- }
-
- rpc container-rpc {
- input {
- container cont1 {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
-
- container cont2 {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
- }
-
- output {
- container cont1 {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
-
- container cont2 {
- leaf test-string {
- type string;
- }
-
- leaf test-string2 {
- type string;
- }
- }
- }
- }
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>mdsal-netconf-monitoring</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-config</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yang.netconf.mdsal.monitoring;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class MonitoringToMdsalWriter implements AutoCloseable, NetconfMonitoringService.MonitoringListener, BindingAwareProvider {
-
- private static final Logger LOG = LoggerFactory.getLogger(MonitoringToMdsalWriter.class);
-
- private final NetconfMonitoringService serverMonitoringDependency;
- private DataBroker dataBroker;
-
- public MonitoringToMdsalWriter(final NetconfMonitoringService serverMonitoringDependency) {
- this.serverMonitoringDependency = serverMonitoringDependency;
- }
-
- @Override
- public void close() {
- final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- tx.delete(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetconfState.class));
- final CheckedFuture<Void, TransactionCommitFailedException> submit = tx.submit();
-
- Futures.addCallback(submit, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void aVoid) {
- LOG.debug("Netconf state cleared successfully");
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.warn("Unable to clear netconf state", throwable);
- }
- });
- }
-
- @Override
- public void onStateChanged(final NetconfState state) {
- Preconditions.checkState(dataBroker != null);
- final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- tx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(NetconfState.class), state);
- // FIXME first attempt (right after we register to binding broker) always fails
- // Is it due to the fact that we are writing from the onSessionInitiated callback ?
- try {
- tx.submit().checkedGet();
- LOG.debug("Netconf state updated successfully");
- } catch (TransactionCommitFailedException e) {
- LOG.warn("Unable to update netconf state", e);
- }
- }
-
- @Override
- public void onSessionInitiated(final BindingAwareBroker.ProviderContext providerContext) {
- dataBroker = providerContext.getSALService(DataBroker.class);
- serverMonitoringDependency.registerListener(this);
- }
-}
+++ /dev/null
-package org.opendaylight.controller.config.yang.netconf.mdsal.monitoring;
-
-import java.util.Collections;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.monitoring.GetSchema;
-
-public class NetconfMdsalMonitoringMapperModule extends org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.AbstractNetconfMdsalMonitoringMapperModule {
- public NetconfMdsalMonitoringMapperModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfMdsalMonitoringMapperModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.NetconfMdsalMonitoringMapperModule oldModule, final java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final NetconfMonitoringService serverMonitoringDependency = getServerMonitoringDependency();
-
- final MonitoringToMdsalWriter monitoringToMdsalWriter = new MonitoringToMdsalWriter(serverMonitoringDependency);
- getBindingAwareBrokerDependency().registerProvider(monitoringToMdsalWriter);
-
- final MdSalMonitoringMapperFactory mdSalMonitoringMapperFactory = new MdSalMonitoringMapperFactory(new MdsalMonitoringMapper(serverMonitoringDependency)) {
- @Override
- public void close() {
- super.close();
- monitoringToMdsalWriter.close();
- getAggregatorDependency().onRemoveNetconfOperationServiceFactory(this);
- }
- };
-
- getAggregatorDependency().onAddNetconfOperationServiceFactory(mdSalMonitoringMapperFactory);
- return mdSalMonitoringMapperFactory;
-
- }
-
- // FIXME almost exactly same code as in netconf-monitoring, refactor
- private static class MdSalMonitoringMapperFactory implements NetconfOperationServiceFactory, AutoCloseable {
-
- private final NetconfOperationService operationService;
-
- private static final AutoCloseable AUTO_CLOSEABLE = new AutoCloseable() {
- @Override
- public void close() throws Exception {
- // NOOP
- }
- };
-
- public MdSalMonitoringMapperFactory(final NetconfOperationService operationService) {
- this.operationService = operationService;
- }
-
- @Override
- public NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return operationService;
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- // TODO
- // No capabilities exposed to prevent clashes with schemas from mdsal-netconf-connector (it exposes all the schemas)
- // If the schemas exposed by mdsal-netconf-connector are filtered, this class would expose monitoring related models
- return Collections.emptySet();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return AUTO_CLOSEABLE;
- }
-
- @Override
- public void close() {}
- }
-
-
- private static class MdsalMonitoringMapper implements NetconfOperationService {
-
- private final NetconfMonitoringService serverMonitoringDependency;
-
- public MdsalMonitoringMapper(final NetconfMonitoringService serverMonitoringDependency) {
- this.serverMonitoringDependency = serverMonitoringDependency;
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return Collections.<NetconfOperation>singleton(new GetSchema(serverMonitoringDependency));
- }
-
- @Override
- public void close() {
- // NOOP
- }
- }
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-mdsal-monitoring yang module local name: netconf-mdsal-monitoring-mapper
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Feb 18 10:22:17 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.netconf.mdsal.monitoring;
-public class NetconfMdsalMonitoringMapperModuleFactory extends org.opendaylight.controller.config.yang.netconf.mdsal.monitoring.AbstractNetconfMdsalMonitoringMapperModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.monitoring.Get;
-import org.opendaylight.controller.netconf.monitoring.GetSchema;
-
-public class NetconfMonitoringOperationService implements NetconfOperationService {
-
- private final NetconfMonitoringService monitor;
-
- public NetconfMonitoringOperationService(final NetconfMonitoringService monitor) {
- this.monitor = monitor;
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return Sets.<NetconfOperation>newHashSet(new Get(monitor), new GetSchema(monitor));
- }
-
- @Override
- public void close() {
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring;
-
-import java.util.Collections;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-
-public class NetconfMonitoringOperationServiceFactory implements NetconfOperationServiceFactory, AutoCloseable {
-
- private final NetconfMonitoringOperationService operationService;
-
- private static final AutoCloseable AUTO_CLOSEABLE = new AutoCloseable() {
- @Override
- public void close() throws Exception {
- // NOOP
- }
- };
-
- public NetconfMonitoringOperationServiceFactory(final NetconfMonitoringOperationService operationService) {
- this.operationService = operationService;
- }
-
- @Override
- public NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return operationService;
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- // TODO
- // No capabilities exposed to prevent clashes with schemas from config-netconf-connector (it exposes all the schemas)
- // If the schemas exposed by config-netconf-connector are filtered, this class would expose monitoring related models
- return Collections.emptySet();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return AUTO_CLOSEABLE;
- }
-
- @Override
- public void close() {}
-}
+++ /dev/null
-module netconf-mdsal-monitoring {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring";
- prefix "nmmonitor";
-
- import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
- import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
- import netconf-northbound { prefix nn; revision-date 2015-01-14; }
- import config { prefix config; revision-date 2013-04-05; }
-
- organization "Cisco Systems, Inc.";
-
- description
- "This module contains the base YANG definitions for
- an MD-SAL monitoring mapper implementation";
-
- revision "2015-02-18" {
- description
- "Initial revision.";
- }
-
- identity netconf-mdsal-monitoring-mapper {
- base config:module-type;
- config:provided-service nnm:netconf-northbound-mapper;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-mdsal-monitoring-mapper {
- when "/config:modules/config:module/config:type = 'netconf-mdsal-monitoring-mapper'";
-
- container server-monitoring {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity nn:netconf-server-monitoring;
- }
- }
- }
-
- container aggregator {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity nnm:netconf-mapper-registry;
- }
- }
- }
-
- container binding-aware-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity md-sal-binding:binding-broker-osgi-registry;
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
-
-This program and the accompanying materials are made available under the
-terms of the Eclipse Public License v1.0 which accompanies this distribution,
-and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>messagebus-netconf</artifactId>
- <name>${project.artifactId}</name>
-
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-notifications</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>messagebus-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>messagebus-spi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>messagebus-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-config</artifactId>
- </dependency>
-
- <!-- Testing Dependencies -->
- <dependency>
- <groupId>org.glassfish.jersey.test-framework.providers</groupId>
- <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- </sources>
- </configuration>
- </execution>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/initial/06-message-netconf.xml</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-package org.opendaylight.controller.config.yang.messagebus.netconf;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.controller.messagebus.app.util.Providers;
-import org.opendaylight.controller.messagebus.eventsources.netconf.NetconfEventSourceManager;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker;
-
-public class MessageBusNetconfModule extends org.opendaylight.controller.config.yang.messagebus.netconf.AbstractMessageBusNetconfModule {
- public MessageBusNetconfModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public MessageBusNetconfModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.messagebus.netconf.MessageBusNetconfModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {}
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final BindingAwareBroker.ProviderContext bindingCtx = getBindingBrokerDependency().registerProvider(new Providers.BindingAware());
- final Broker.ProviderSession domCtx = getDomBrokerDependency().registerProvider(new Providers.BindingIndependent());
-
- final MountPointService mountPointService = bindingCtx.getSALService(MountPointService.class);
- final DataBroker dataBroker = bindingCtx.getSALService(DataBroker.class);
-
- final DOMNotificationPublishService domPublish = domCtx.getService(DOMNotificationPublishService.class);
- final DOMMountPointService domMount = domCtx.getService(DOMMountPointService.class);
-
- return NetconfEventSourceManager.create(dataBroker, domPublish, domMount,
- mountPointService, getEventSourceRegistryDependency(), getNamespaceToStream());
- }
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: messagebus-netconf yang module local name: messagebus-netconf
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Jul 29 14:15:30 CEST 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.messagebus.netconf;
-public class MessageBusNetconfModuleFactory extends org.opendaylight.controller.config.yang.messagebus.netconf.AbstractMessageBusNetconfModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicId;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.EventSourceStatus;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.EventSourceStatusNotification;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.EventSourceStatusNotificationBuilder;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class ConnectionNotificationTopicRegistration extends NotificationTopicRegistration {
-
- private static final Logger LOG = LoggerFactory.getLogger(ConnectionNotificationTopicRegistration.class);
-
- public static final SchemaPath EVENT_SOURCE_STATUS_PATH = SchemaPath
- .create(true, QName.create(EventSourceStatusNotification.QNAME, "event-source-status"));
- private static final NodeIdentifier EVENT_SOURCE_STATUS_ARG = new NodeIdentifier(
- EventSourceStatusNotification.QNAME);
- private static final String XMLNS_ATTRIBUTE_KEY = "xmlns";
- private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
-
- private final DOMNotificationListener domNotificationListener;
- private ConcurrentHashMap<SchemaPath, ArrayList<TopicId>> notificationTopicMap = new ConcurrentHashMap<>();
-
- public ConnectionNotificationTopicRegistration(String SourceName, DOMNotificationListener domNotificationListener) {
- super(NotificationSourceType.ConnectionStatusChange, SourceName,
- EVENT_SOURCE_STATUS_PATH.getLastComponent().getNamespace().toString());
- this.domNotificationListener = Preconditions.checkNotNull(domNotificationListener);
- LOG.info("Connection notification source has been initialized.");
- setActive(true);
- setReplaySupported(false);
- }
-
- @Override public void close() throws Exception {
- if (isActive()) {
- LOG.debug("Connection notification - publish Deactive");
- publishNotification(EventSourceStatus.Deactive);
- notificationTopicMap.clear();
- setActive(false);
- }
- }
-
- @Override void activateNotificationSource() {
- LOG.debug("Connection notification - publish Active");
- publishNotification(EventSourceStatus.Active);
- }
-
- @Override void deActivateNotificationSource() {
- LOG.debug("Connection notification - publish Inactive");
- publishNotification(EventSourceStatus.Inactive);
- }
-
- @Override void reActivateNotificationSource() {
- LOG.debug("Connection notification - reactivate - publish active");
- publishNotification(EventSourceStatus.Active);
- }
-
- @Override boolean registerNotificationTopic(SchemaPath notificationPath, TopicId topicId) {
- if (checkNotificationPath(notificationPath) == false) {
- LOG.debug("Bad SchemaPath for notification try to register");
- return false;
- }
- ArrayList<TopicId> topicIds = getNotificationTopicIds(notificationPath);
- if (topicIds == null) {
- topicIds = new ArrayList<>();
- topicIds.add(topicId);
- } else {
- if (topicIds.contains(topicId) == false) {
- topicIds.add(topicId);
- }
- }
- notificationTopicMap.put(notificationPath, topicIds);
- return true;
- }
-
- @Override ArrayList<TopicId> getNotificationTopicIds(SchemaPath notificationPath) {
- return notificationTopicMap.get(notificationPath);
- }
-
- @Override synchronized void unRegisterNotificationTopic(TopicId topicId) {
- List<SchemaPath> notificationPathToRemove = new ArrayList<>();
- for (SchemaPath notifKey : notificationTopicMap.keySet()) {
- ArrayList<TopicId> topicList = notificationTopicMap.get(notifKey);
- if (topicList != null) {
- topicList.remove(topicId);
- if (topicList.isEmpty()) {
- notificationPathToRemove.add(notifKey);
- }
- }
- }
- for (SchemaPath notifKey : notificationPathToRemove) {
- notificationTopicMap.remove(notifKey);
- }
- }
-
- private void publishNotification(EventSourceStatus eventSourceStatus) {
-
- final EventSourceStatusNotification notification = new EventSourceStatusNotificationBuilder()
- .setStatus(eventSourceStatus).build();
- domNotificationListener.onNotification(createNotification(notification));
- }
-
- private DOMNotification createNotification(EventSourceStatusNotification notification) {
- final ContainerNode cn = Builders.containerBuilder().withNodeIdentifier(EVENT_SOURCE_STATUS_ARG)
- .withChild(encapsulate(notification)).build();
- DOMNotification dn = new DOMNotification() {
-
- @Override public SchemaPath getType() {
- return EVENT_SOURCE_STATUS_PATH;
- }
-
- @Override public ContainerNode getBody() {
- return cn;
- }
- };
- return dn;
- }
-
- private AnyXmlNode encapsulate(EventSourceStatusNotification notification) {
-
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder docBuilder;
-
- try {
- docBuilder = docFactory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- throw new IllegalStateException("Can not create XML DocumentBuilder");
- }
-
- Document doc = docBuilder.newDocument();
-
- final Optional<String> namespace = Optional.of(EVENT_SOURCE_STATUS_ARG.getNodeType().getNamespace().toString());
- final Element rootElement = createElement(doc, "EventSourceStatusNotification", namespace);
-
- final Element sourceElement = doc.createElement("status");
- sourceElement.appendChild(doc.createTextNode(notification.getStatus().name()));
- rootElement.appendChild(sourceElement);
-
- return Builders.anyXmlBuilder().withNodeIdentifier(EVENT_SOURCE_STATUS_ARG)
- .withValue(new DOMSource(rootElement)).build();
-
- }
-
- // Helper to create root XML element with correct namespace and attribute
- private Element createElement(final Document document, final String qName, final Optional<String> namespaceURI) {
- if (namespaceURI.isPresent()) {
- final Element element = document.createElementNS(namespaceURI.get(), qName);
- String name = XMLNS_ATTRIBUTE_KEY;
- if (element.getPrefix() != null) {
- name += ":" + element.getPrefix();
- }
- element.setAttributeNS(XMLNS_URI, name, namespaceURI.get());
- return element;
- }
- return document.createElement(qName);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import static com.google.common.util.concurrent.Futures.immediateFuture;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Future;
-import java.util.regex.Pattern;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.messagebus.app.util.TopicDOMNotification;
-import org.opendaylight.controller.messagebus.app.util.Util;
-import org.opendaylight.controller.messagebus.spi.EventSource;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.NotificationPattern;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicId;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicNotification;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.DisJoinTopicInput;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.JoinTopicInput;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.JoinTopicOutput;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.JoinTopicOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.JoinTopicStatus;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class NetconfEventSource implements EventSource, DOMNotificationListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfEventSource.class);
-
- private static final NodeIdentifier TOPIC_NOTIFICATION_ARG = new NodeIdentifier(TopicNotification.QNAME);
- private static final NodeIdentifier EVENT_SOURCE_ARG = new NodeIdentifier(
- QName.create(TopicNotification.QNAME, "node-id"));
- private static final NodeIdentifier TOPIC_ID_ARG = new NodeIdentifier(
- QName.create(TopicNotification.QNAME, "topic-id"));
- private static final NodeIdentifier PAYLOAD_ARG = new NodeIdentifier(
- QName.create(TopicNotification.QNAME, "payload"));
- private static final String ConnectionNotificationSourceName = "ConnectionNotificationSource";
-
- private final String nodeId;
- private final Node node;
-
- private final DOMMountPoint netconfMount;
- private final MountPoint mountPoint;
- private final DOMNotificationPublishService domPublish;
-
- private final Map<String, String> urnPrefixToStreamMap; // key = urnPrefix, value = StreamName
- private final List<NotificationTopicRegistration> notificationTopicRegistrationList = new ArrayList<>();
-
- public NetconfEventSource(final Node node, final Map<String, String> streamMap, final DOMMountPoint netconfMount,
- final MountPoint mountPoint, final DOMNotificationPublishService publishService) {
- this.netconfMount = Preconditions.checkNotNull(netconfMount);
- this.mountPoint = Preconditions.checkNotNull(mountPoint);
- this.node = Preconditions.checkNotNull(node);
- this.urnPrefixToStreamMap = Preconditions.checkNotNull(streamMap);
- this.domPublish = Preconditions.checkNotNull(publishService);
- this.nodeId = node.getNodeId().getValue();
- this.initializeNotificationTopicRegistrationList();
-
- LOG.info("NetconfEventSource [{}] created.", this.nodeId);
- }
-
- private void initializeNotificationTopicRegistrationList() {
- notificationTopicRegistrationList
- .add(new ConnectionNotificationTopicRegistration(ConnectionNotificationSourceName, this));
- Optional<Map<String, Stream>> streamMap = getAvailableStreams();
- if (streamMap.isPresent()) {
- LOG.debug("Stream configuration compare...");
- for (String urnPrefix : this.urnPrefixToStreamMap.keySet()) {
- final String streamName = this.urnPrefixToStreamMap.get(urnPrefix);
- LOG.debug("urnPrefix: {} streamName: {}", urnPrefix, streamName);
- if (streamMap.get().containsKey(streamName)) {
- LOG.debug("Stream containig on device");
- notificationTopicRegistrationList
- .add(new StreamNotificationTopicRegistration(streamMap.get().get(streamName), urnPrefix, this));
- }
- }
- }
- }
-
- private Optional<Map<String, Stream>> getAvailableStreams() {
-
- Map<String, Stream> streamMap = null;
- InstanceIdentifier<Streams> pathStream = InstanceIdentifier.builder(Netconf.class).child(Streams.class).build();
- Optional<DataBroker> dataBroker = this.mountPoint.getService(DataBroker.class);
-
- if (dataBroker.isPresent()) {
- LOG.debug("GET Available streams ...");
- ReadOnlyTransaction tx = dataBroker.get().newReadOnlyTransaction();
- CheckedFuture<Optional<Streams>, ReadFailedException> checkFeature = tx
- .read(LogicalDatastoreType.OPERATIONAL, pathStream);
-
- try {
- Optional<Streams> streams = checkFeature.checkedGet();
- if (streams.isPresent()) {
- streamMap = new HashMap<>();
- for (Stream stream : streams.get().getStream()) {
- LOG.debug("*** find stream {}", stream.getName().getValue());
- streamMap.put(stream.getName().getValue(), stream);
- }
- }
- } catch (ReadFailedException e) {
- LOG.warn("Can not read streams for node {}", this.nodeId);
- }
-
- } else {
- LOG.warn("No databroker on node {}", this.nodeId);
- }
-
- return Optional.fromNullable(streamMap);
- }
-
- @Override public Future<RpcResult<JoinTopicOutput>> joinTopic(final JoinTopicInput input) {
- LOG.debug("Join topic {} on {}", input.getTopicId().getValue(), this.nodeId);
- final NotificationPattern notificationPattern = input.getNotificationPattern();
- final List<SchemaPath> matchingNotifications = getMatchingNotifications(notificationPattern);
- return registerTopic(input.getTopicId(), matchingNotifications);
-
- }
-
- @Override public Future<RpcResult<Void>> disJoinTopic(DisJoinTopicInput input) {
- for (NotificationTopicRegistration reg : notificationTopicRegistrationList) {
- reg.unRegisterNotificationTopic(input.getTopicId());
- }
- return Util.resultRpcSuccessFor((Void) null);
- }
-
- private synchronized Future<RpcResult<JoinTopicOutput>> registerTopic(final TopicId topicId,
- final List<SchemaPath> notificationsToSubscribe) {
- LOG.debug("Join topic {} - register", topicId);
- JoinTopicStatus joinTopicStatus = JoinTopicStatus.Down;
- if (notificationsToSubscribe != null && notificationsToSubscribe.isEmpty() == false) {
- LOG.debug("Notifications to subscribe has found - count {}", notificationsToSubscribe.size());
- final Optional<DOMNotificationService> notifyService = getDOMMountPoint()
- .getService(DOMNotificationService.class);
- if (notifyService.isPresent()) {
- int registeredNotificationCount = 0;
- for (SchemaPath schemaNotification : notificationsToSubscribe) {
- for (NotificationTopicRegistration reg : notificationTopicRegistrationList) {
- LOG.debug("Try notification registratio {} on SchemaPathNotification {}", reg.getSourceName(),
- schemaNotification.getLastComponent().getLocalName());
- if (reg.checkNotificationPath(schemaNotification)) {
- LOG.info("Source of notification {} is activating, TopicId {}", reg.getSourceName(),
- topicId.getValue());
- boolean regSuccess = reg.registerNotificationTopic(schemaNotification, topicId);
- if (regSuccess) {
- registeredNotificationCount = registeredNotificationCount + 1;
- }
- }
- }
- }
- if (registeredNotificationCount > 0) {
- joinTopicStatus = JoinTopicStatus.Up;
- }
- } else {
- LOG.warn("NO DOMNotification service on node {}", this.nodeId);
- }
- } else {
- LOG.debug("Notifications to subscribe has NOT found");
- }
-
- final JoinTopicOutput output = new JoinTopicOutputBuilder().setStatus(joinTopicStatus).build();
- return immediateFuture(RpcResultBuilder.success(output).build());
-
- }
-
- public void reActivateStreams() {
- for (NotificationTopicRegistration reg : notificationTopicRegistrationList) {
- LOG.info("Source of notification {} is reactivating on node {}", reg.getSourceName(), this.nodeId);
- reg.reActivateNotificationSource();
- }
- }
-
- public void deActivateStreams() {
- for (NotificationTopicRegistration reg : notificationTopicRegistrationList) {
- LOG.info("Source of notification {} is deactivating on node {}", reg.getSourceName(), this.nodeId);
- reg.deActivateNotificationSource();
- }
- }
-
- @Override public void onNotification(final DOMNotification notification) {
- SchemaPath notificationPath = notification.getType();
- Date notificationEventTime = null;
- if (notification instanceof DOMEvent) {
- notificationEventTime = ((DOMEvent) notification).getEventTime();
- }
- for (NotificationTopicRegistration notifReg : notificationTopicRegistrationList) {
- ArrayList<TopicId> topicIdsForNotification = notifReg.getNotificationTopicIds(notificationPath);
- if (topicIdsForNotification != null && topicIdsForNotification.isEmpty() == false) {
-
- if (notifReg instanceof StreamNotificationTopicRegistration) {
- StreamNotificationTopicRegistration streamReg = (StreamNotificationTopicRegistration) notifReg;
- streamReg.setLastEventTime(notificationEventTime);
- }
-
- for (TopicId topicId : topicIdsForNotification) {
- publishNotification(notification, topicId);
- LOG.debug("Notification {} has been published for TopicId {}", notification.getType(),
- topicId.getValue());
- }
-
- }
- }
- }
-
- private void publishNotification(final DOMNotification notification, TopicId topicId) {
- final ContainerNode topicNotification = Builders.containerBuilder().withNodeIdentifier(TOPIC_NOTIFICATION_ARG)
- .withChild(ImmutableNodes.leafNode(TOPIC_ID_ARG, topicId))
- .withChild(ImmutableNodes.leafNode(EVENT_SOURCE_ARG, this.nodeId)).withChild(encapsulate(notification))
- .build();
- try {
- domPublish.putNotification(new TopicDOMNotification(topicNotification));
- } catch (final InterruptedException e) {
- throw Throwables.propagate(e);
- }
- }
-
- private AnyXmlNode encapsulate(final DOMNotification body) {
- // FIXME: Introduce something like AnyXmlWithNormalizedNodeData in Yangtools
- final Document doc = XmlUtil.newDocument();
- final Optional<String> namespace = Optional.of(PAYLOAD_ARG.getNodeType().getNamespace().toString());
- final Element element = XmlUtil.createElement(doc, "payload", namespace);
-
- final DOMResult result = new DOMResult(element);
-
- final SchemaContext context = getDOMMountPoint().getSchemaContext();
- final SchemaPath schemaPath = body.getType();
- try {
- NetconfMessageTransformUtil.writeNormalizedNode(body.getBody(), result, schemaPath, context);
- return Builders.anyXmlBuilder().withNodeIdentifier(PAYLOAD_ARG).withValue(new DOMSource(element)).build();
- } catch (IOException | XMLStreamException e) {
- LOG.error("Unable to encapsulate notification.", e);
- throw Throwables.propagate(e);
- }
- }
-
- private List<SchemaPath> getMatchingNotifications(NotificationPattern notificationPattern) {
- // FIXME: default language should already be regex
- final String regex = Util.wildcardToRegex(notificationPattern.getValue());
-
- final Pattern pattern = Pattern.compile(regex);
- List<SchemaPath> availableNotifications = getAvailableNotifications();
- if (availableNotifications == null || availableNotifications.isEmpty()) {
- return null;
- }
- return Util.expandQname(availableNotifications, pattern);
- }
-
- @Override public void close() throws Exception {
- for (NotificationTopicRegistration streamReg : notificationTopicRegistrationList) {
- streamReg.close();
- }
- }
-
- @Override public NodeKey getSourceNodeKey() {
- return getNode().getKey();
- }
-
- @Override public List<SchemaPath> getAvailableNotifications() {
-
- final List<SchemaPath> availNotifList = new ArrayList<>();
- // add Event Source Connection status notification
- availNotifList.add(ConnectionNotificationTopicRegistration.EVENT_SOURCE_STATUS_PATH);
-
- // FIXME: use SchemaContextListener to get changes asynchronously
- final Set<NotificationDefinition> availableNotifications = getDOMMountPoint().getSchemaContext()
- .getNotifications();
- // add all known notifications from netconf device
- for (final NotificationDefinition nd : availableNotifications) {
- availNotifList.add(nd.getPath());
- }
- return availNotifList;
- }
-
- public Node getNode() {
- return node;
- }
-
- DOMMountPoint getDOMMountPoint() {
- return netconfMount;
- }
-
- MountPoint getMountPoint() {
- return mountPoint;
- }
-
- NetconfNode getNetconfNode() {
- return node.getAugmentation(NetconfNode.class);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import com.google.common.base.Preconditions;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.controller.config.yang.messagebus.netconf.NamespaceToStream;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.MountPointService;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.controller.messagebus.spi.EventSourceRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfEventSourceManager implements DataChangeListener, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfEventSourceManager.class);
- private static final TopologyKey NETCONF_TOPOLOGY_KEY = new TopologyKey(
- new TopologyId(TopologyNetconf.QNAME.getLocalName()));
- private static final InstanceIdentifier<Node> NETCONF_DEVICE_PATH = InstanceIdentifier.create(NetworkTopology.class)
- .child(Topology.class, NETCONF_TOPOLOGY_KEY).child(Node.class);
-
- private final Map<String, String> streamMap;
- private final ConcurrentHashMap<InstanceIdentifier<?>, NetconfEventSourceRegistration> registrationMap = new ConcurrentHashMap<>();
- private final DOMNotificationPublishService publishService;
- private final DOMMountPointService domMounts;
- private final MountPointService mountPointService;
- private ListenerRegistration<DataChangeListener> listenerRegistration;
- private final EventSourceRegistry eventSourceRegistry;
-
- public static NetconfEventSourceManager create(final DataBroker dataBroker,
- final DOMNotificationPublishService domPublish, final DOMMountPointService domMount,
- final MountPointService bindingMount, final EventSourceRegistry eventSourceRegistry,
- final List<NamespaceToStream> namespaceMapping) {
-
- final NetconfEventSourceManager eventSourceManager = new NetconfEventSourceManager(domPublish, domMount,
- bindingMount, eventSourceRegistry, namespaceMapping);
-
- eventSourceManager.initialize(dataBroker);
-
- return eventSourceManager;
-
- }
-
- private NetconfEventSourceManager(final DOMNotificationPublishService domPublish,
- final DOMMountPointService domMount, final MountPointService bindingMount,
- final EventSourceRegistry eventSourceRegistry, final List<NamespaceToStream> namespaceMapping) {
-
- Preconditions.checkNotNull(domPublish);
- Preconditions.checkNotNull(domMount);
- Preconditions.checkNotNull(bindingMount);
- Preconditions.checkNotNull(eventSourceRegistry);
- Preconditions.checkNotNull(namespaceMapping);
- this.streamMap = namespaceToStreamMapping(namespaceMapping);
- this.domMounts = domMount;
- this.mountPointService = bindingMount;
- this.publishService = domPublish;
- this.eventSourceRegistry = eventSourceRegistry;
- }
-
- private void initialize(final DataBroker dataBroker) {
- Preconditions.checkNotNull(dataBroker);
- listenerRegistration = dataBroker
- .registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, NETCONF_DEVICE_PATH, this,
- DataChangeScope.SUBTREE);
- LOG.info("NetconfEventSourceManager initialized.");
- }
-
- private Map<String, String> namespaceToStreamMapping(final List<NamespaceToStream> namespaceMapping) {
- final Map<String, String> streamMap = new HashMap<>(namespaceMapping.size());
-
- for (final NamespaceToStream nToS : namespaceMapping) {
- streamMap.put(nToS.getUrnPrefix(), nToS.getStreamName());
- }
-
- return streamMap;
- }
-
- @Override public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> event) {
-
- LOG.debug("[DataChangeEvent<InstanceIdentifier<?>, DataObject>: {}]", event);
- for (final Map.Entry<InstanceIdentifier<?>, DataObject> changeEntry : event.getCreatedData().entrySet()) {
- if (changeEntry.getValue() instanceof Node) {
- nodeCreated(changeEntry.getKey(), (Node) changeEntry.getValue());
- }
- }
-
- for (final Map.Entry<InstanceIdentifier<?>, DataObject> changeEntry : event.getUpdatedData().entrySet()) {
- if (changeEntry.getValue() instanceof Node) {
- nodeUpdated(changeEntry.getKey(), (Node) changeEntry.getValue());
- }
- }
-
- for (InstanceIdentifier<?> removePath : event.getRemovedPaths()) {
- DataObject removeObject = event.getOriginalData().get(removePath);
- if (removeObject instanceof Node) {
- nodeRemoved(removePath);
- }
- }
-
- }
-
- private void nodeCreated(final InstanceIdentifier<?> key, final Node node) {
- Preconditions.checkNotNull(key);
- if (validateNode(node) == false) {
- LOG.warn("NodeCreated event : Node [{}] is null or not valid.", key.toString());
- return;
- }
- LOG.info("Netconf event source [{}] is creating...", key.toString());
- NetconfEventSourceRegistration nesr = NetconfEventSourceRegistration.create(key, node, this);
- if (nesr != null) {
- NetconfEventSourceRegistration nesrOld = registrationMap.put(key, nesr);
- if (nesrOld != null) {
- nesrOld.close();
- }
- }
- }
-
- private void nodeUpdated(final InstanceIdentifier<?> key, final Node node) {
- Preconditions.checkNotNull(key);
- if (validateNode(node) == false) {
- LOG.warn("NodeUpdated event : Node [{}] is null or not valid.", key.toString());
- return;
- }
-
- LOG.info("Netconf event source [{}] is updating...", key.toString());
- NetconfEventSourceRegistration nesr = registrationMap.get(key);
- if (nesr != null) {
- nesr.updateStatus();
- } else {
- nodeCreated(key, node);
- }
- }
-
- private void nodeRemoved(final InstanceIdentifier<?> key) {
- Preconditions.checkNotNull(key);
- LOG.info("Netconf event source [{}] is removing...", key.toString());
- NetconfEventSourceRegistration nesr = registrationMap.remove(key);
- if (nesr != null) {
- nesr.close();
- }
- }
-
- private boolean validateNode(final Node node) {
- if (node == null) {
- return false;
- }
- return isNetconfNode(node);
- }
-
- Map<String, String> getStreamMap() {
- return streamMap;
- }
-
- DOMNotificationPublishService getPublishService() {
- return publishService;
- }
-
- DOMMountPointService getDomMounts() {
- return domMounts;
- }
-
- EventSourceRegistry getEventSourceRegistry() {
- return eventSourceRegistry;
- }
-
- MountPointService getMountPointService() {
- return mountPointService;
- }
-
- private boolean isNetconfNode(final Node node) {
- return node.getAugmentation(NetconfNode.class) != null;
- }
-
- @Override public void close() {
- listenerRegistration.close();
- for (final NetconfEventSourceRegistration reg : registrationMap.values()) {
- reg.close();
- }
- registrationMap.clear();
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.List;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.messagebus.spi.EventSourceRegistration;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helper class to keep connection status of netconf node and event source registration object
- */
-public class NetconfEventSourceRegistration implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfEventSourceRegistration.class);
- private static final YangInstanceIdentifier NETCONF_DEVICE_DOM_PATH = YangInstanceIdentifier.builder()
- .node(NetworkTopology.QNAME).node(Topology.QNAME)
- .nodeWithKey(Topology.QNAME, QName.create(Topology.QNAME, "topology-id"), TopologyNetconf.QNAME.getLocalName())
- .node(Node.QNAME).build();
- private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "node-id");
- private static final String NotificationCapabilityPrefix = "(urn:ietf:params:xml:ns:netconf:notification";
-
- private final Node node;
- private final InstanceIdentifier<?> instanceIdent;
- private final NetconfEventSourceManager netconfEventSourceManager;
- private ConnectionStatus currentNetconfConnStatus;
- private EventSourceRegistration<NetconfEventSource> eventSourceRegistration;
-
- public static NetconfEventSourceRegistration create(final InstanceIdentifier<?> instanceIdent, final Node node,
- final NetconfEventSourceManager netconfEventSourceManager) {
- Preconditions.checkNotNull(instanceIdent);
- Preconditions.checkNotNull(node);
- Preconditions.checkNotNull(netconfEventSourceManager);
- if (isEventSource(node) == false) {
- return null;
- }
- NetconfEventSourceRegistration nesr = new NetconfEventSourceRegistration(instanceIdent, node,
- netconfEventSourceManager);
- nesr.updateStatus();
- LOG.debug("NetconfEventSourceRegistration for node {} has been initialized...", node.getNodeId().getValue());
- return nesr;
- }
-
- private static boolean isEventSource(final Node node) {
- final NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
- if (netconfNode == null) {
- return false;
- }
- if (netconfNode.getAvailableCapabilities() == null) {
- return false;
- }
- final List<String> capabilities = netconfNode.getAvailableCapabilities().getAvailableCapability();
- if (capabilities == null || capabilities.isEmpty()) {
- return false;
- }
- for (final String capability : netconfNode.getAvailableCapabilities().getAvailableCapability()) {
- if (capability.startsWith(NotificationCapabilityPrefix)) {
- return true;
- }
- }
-
- return false;
- }
-
- private NetconfEventSourceRegistration(final InstanceIdentifier<?> instanceIdent, final Node node,
- final NetconfEventSourceManager netconfEventSourceManager) {
- this.instanceIdent = instanceIdent;
- this.node = node;
- this.netconfEventSourceManager = netconfEventSourceManager;
- this.eventSourceRegistration = null;
- }
-
- public Node getNode() {
- return node;
- }
-
- Optional<EventSourceRegistration<NetconfEventSource>> getEventSourceRegistration() {
- return Optional.fromNullable(eventSourceRegistration);
- }
-
- NetconfNode getNetconfNode() {
- return node.getAugmentation(NetconfNode.class);
- }
-
- void updateStatus() {
- ConnectionStatus netconfConnStatus = getNetconfNode().getConnectionStatus();
- LOG.info("Change status on node {}, new status is {}", this.node.getNodeId().getValue(), netconfConnStatus);
- if (netconfConnStatus.equals(currentNetconfConnStatus)) {
- return;
- }
- changeStatus(netconfConnStatus);
- }
-
- private boolean checkConnectionStatusType(ConnectionStatus status) {
- if (status == ConnectionStatus.Connected || status == ConnectionStatus.Connecting
- || status == ConnectionStatus.UnableToConnect) {
- return true;
- }
- return false;
- }
-
- private void changeStatus(ConnectionStatus newStatus) {
- Preconditions.checkNotNull(newStatus);
- if (checkConnectionStatusType(newStatus) == false) {
- throw new IllegalStateException("Unknown new Netconf Connection Status");
- }
- if (this.currentNetconfConnStatus == null) {
- if (newStatus == ConnectionStatus.Connected) {
- registrationEventSource();
- }
- } else if (this.currentNetconfConnStatus == ConnectionStatus.Connecting) {
- if (newStatus == ConnectionStatus.Connected) {
- if (this.eventSourceRegistration == null) {
- registrationEventSource();
- } else {
- // reactivate stream on registered event source (invoke publish notification about connection)
- this.eventSourceRegistration.getInstance().reActivateStreams();
- }
- }
- } else if (this.currentNetconfConnStatus == ConnectionStatus.Connected) {
-
- if (newStatus == ConnectionStatus.Connecting || newStatus == ConnectionStatus.UnableToConnect) {
- // deactivate streams on registered event source (invoke publish notification about connection)
- this.eventSourceRegistration.getInstance().deActivateStreams();
- }
- } else if (this.currentNetconfConnStatus == ConnectionStatus.UnableToConnect) {
- if (newStatus == ConnectionStatus.Connected) {
- if (this.eventSourceRegistration == null) {
- registrationEventSource();
- } else {
- // reactivate stream on registered event source (invoke publish notification about connection)
- this.eventSourceRegistration.getInstance().reActivateStreams();
- }
- }
- } else {
- throw new IllegalStateException("Unknown current Netconf Connection Status");
- }
- this.currentNetconfConnStatus = newStatus;
- }
-
- private void registrationEventSource() {
- final Optional<MountPoint> mountPoint = netconfEventSourceManager.getMountPointService()
- .getMountPoint(instanceIdent);
- final Optional<DOMMountPoint> domMountPoint = netconfEventSourceManager.getDomMounts()
- .getMountPoint(domMountPath(node.getNodeId()));
- EventSourceRegistration<NetconfEventSource> registration = null;
- if (domMountPoint.isPresent() && mountPoint.isPresent()) {
- final NetconfEventSource netconfEventSource = new NetconfEventSource(node,
- netconfEventSourceManager.getStreamMap(), domMountPoint.get(), mountPoint.get(),
- netconfEventSourceManager.getPublishService());
- registration = netconfEventSourceManager.getEventSourceRegistry().registerEventSource(netconfEventSource);
- LOG.info("Event source {} has been registered", node.getNodeId().getValue());
- }
- this.eventSourceRegistration = registration;
- }
-
- private YangInstanceIdentifier domMountPath(final NodeId nodeId) {
- return YangInstanceIdentifier.builder(NETCONF_DEVICE_DOM_PATH)
- .nodeWithKey(Node.QNAME, NODE_ID_QNAME, nodeId.getValue()).build();
- }
-
- private void closeEventSourceRegistration() {
- if (getEventSourceRegistration().isPresent()) {
- getEventSourceRegistration().get().close();
- }
- }
-
- @Override public void close() {
- closeEventSourceRegistration();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import java.util.ArrayList;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicId;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class NotificationTopicRegistration implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NotificationTopicRegistration.class);
-
- public enum NotificationSourceType {
- NetconfDeviceStream,
- ConnectionStatusChange;
- }
-
- private boolean active;
- private final NotificationSourceType notificationSourceType;
- private final String sourceName;
- private final String notificationUrnPrefix;
- private boolean replaySupported;
-
- protected NotificationTopicRegistration(NotificationSourceType notificationSourceType, String sourceName,
- String notificationUrnPrefix) {
- this.notificationSourceType = notificationSourceType;
- this.sourceName = sourceName;
- this.notificationUrnPrefix = notificationUrnPrefix;
- this.active = false;
- this.setReplaySupported(false);
- }
-
- public boolean isActive() {
- return active;
- }
-
- protected void setActive(boolean active) {
- this.active = active;
- }
-
- public NotificationSourceType getNotificationSourceType() {
- return notificationSourceType;
- }
-
- public String getSourceName() {
- return sourceName;
- }
-
- public String getNotificationUrnPrefix() {
- return notificationUrnPrefix;
- }
-
- public boolean checkNotificationPath(SchemaPath notificationPath) {
- if (notificationPath == null) {
- return false;
- }
- String nameSpace = notificationPath.getLastComponent().toString();
- LOG.debug("CheckNotification - name space {} - NotificationUrnPrefix {}", nameSpace,
- getNotificationUrnPrefix());
- return nameSpace.startsWith(getNotificationUrnPrefix());
- }
-
- abstract void activateNotificationSource();
-
- abstract void deActivateNotificationSource();
-
- abstract void reActivateNotificationSource();
-
- abstract boolean registerNotificationTopic(SchemaPath notificationPath, TopicId topicId);
-
- abstract void unRegisterNotificationTopic(TopicId topicId);
-
- abstract ArrayList<TopicId> getNotificationTopicIds(SchemaPath notificationPath);
-
- public boolean isReplaySupported() {
- return replaySupported;
- }
-
- protected void setReplaySupported(boolean replaySupported) {
- this.replaySupported = replaySupported;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class StreamNotificationTopicRegistration extends NotificationTopicRegistration {
-
- private static final Logger LOG = LoggerFactory.getLogger(StreamNotificationTopicRegistration.class);
- private static final NodeIdentifier STREAM_QNAME = new NodeIdentifier(
- QName.create(CreateSubscriptionInput.QNAME, "stream"));
- private static final SchemaPath CREATE_SUBSCRIPTION = SchemaPath
- .create(true, QName.create(CreateSubscriptionInput.QNAME, "create-subscription"));
- private static final NodeIdentifier START_TIME_SUBSCRIPTION = new NodeIdentifier(
- QName.create(CreateSubscriptionInput.QNAME, "startTime"));
-
- final private DOMMountPoint domMountPoint;
- final private String nodeId;
- final private NetconfEventSource netconfEventSource;
- final private Stream stream;
- private Date lastEventTime;
-
- private ConcurrentHashMap<SchemaPath, ListenerRegistration<NetconfEventSource>> notificationRegistrationMap = new ConcurrentHashMap<>();
- private ConcurrentHashMap<SchemaPath, ArrayList<TopicId>> notificationTopicMap = new ConcurrentHashMap<>();
-
- public StreamNotificationTopicRegistration(final Stream stream, final String notificationPrefix,
- NetconfEventSource netconfEventSource) {
- super(NotificationSourceType.NetconfDeviceStream, stream.getName().getValue(), notificationPrefix);
- this.domMountPoint = netconfEventSource.getDOMMountPoint();
- this.nodeId = netconfEventSource.getNode().getNodeId().getValue().toString();
- this.netconfEventSource = netconfEventSource;
- this.stream = stream;
- this.lastEventTime = null;
- setReplaySupported(this.stream.isReplaySupport());
- setActive(false);
- LOG.info("StreamNotificationTopicRegistration initialized for {}", getStreamName());
- }
-
- void activateNotificationSource() {
- if (isActive() == false) {
- LOG.info("Stream {} is not active on node {}. Will subscribe.", this.getStreamName(), this.nodeId);
- final ContainerNode input = Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
- .withChild(ImmutableNodes.leafNode(STREAM_QNAME, this.getStreamName())).build();
- CheckedFuture<DOMRpcResult, DOMRpcException> csFuture = domMountPoint.getService(DOMRpcService.class).get()
- .invokeRpc(CREATE_SUBSCRIPTION, input);
- try {
- csFuture.checkedGet();
- setActive(true);
- } catch (DOMRpcException e) {
- LOG.warn("Can not subscribe stream {} on node {}", this.getSourceName(), this.nodeId);
- setActive(false);
- return;
- }
- } else {
- LOG.info("Stream {} is now active on node {}", this.getStreamName(), this.nodeId);
- }
- }
-
- void reActivateNotificationSource() {
- if (isActive()) {
- LOG.info("Stream {} is reactivating on node {}.", this.getStreamName(), this.nodeId);
- DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> inputBuilder = Builders.containerBuilder()
- .withNodeIdentifier(new NodeIdentifier(CreateSubscriptionInput.QNAME))
- .withChild(ImmutableNodes.leafNode(STREAM_QNAME, this.getStreamName()));
- if (isReplaySupported() && this.getLastEventTime() != null) {
- inputBuilder.withChild(ImmutableNodes.leafNode(START_TIME_SUBSCRIPTION, this.getLastEventTime()));
- }
- final ContainerNode input = inputBuilder.build();
- CheckedFuture<DOMRpcResult, DOMRpcException> csFuture = domMountPoint.getService(DOMRpcService.class).get()
- .invokeRpc(CREATE_SUBSCRIPTION, input);
- try {
- csFuture.checkedGet();
- setActive(true);
- } catch (DOMRpcException e) {
- LOG.warn("Can not resubscribe stream {} on node {}", this.getSourceName(), this.nodeId);
- setActive(false);
- return;
- }
- }
- }
-
- @Override void deActivateNotificationSource() {
- // no operations need
- }
-
- private void closeStream() {
- if (isActive()) {
- for (ListenerRegistration<NetconfEventSource> reg : notificationRegistrationMap.values()) {
- reg.close();
- }
- notificationRegistrationMap.clear();
- notificationTopicMap.clear();
- setActive(false);
- }
- }
-
- private String getStreamName() {
- return getSourceName();
- }
-
- @Override ArrayList<TopicId> getNotificationTopicIds(SchemaPath notificationPath) {
- return notificationTopicMap.get(notificationPath);
- }
-
- @Override boolean registerNotificationTopic(SchemaPath notificationPath, TopicId topicId) {
-
- if (checkNotificationPath(notificationPath) == false) {
- LOG.debug("Bad SchemaPath for notification try to register");
- return false;
- }
-
- final Optional<DOMNotificationService> notifyService = domMountPoint.getService(DOMNotificationService.class);
- if (notifyService.isPresent() == false) {
- LOG.debug("DOMNotificationService is not present");
- return false;
- }
-
- activateNotificationSource();
- if (isActive() == false) {
- LOG.warn("Stream {} is not active, listener for notification {} is not registered.", getStreamName(),
- notificationPath.toString());
- return false;
- }
-
- ListenerRegistration<NetconfEventSource> registration = notifyService.get()
- .registerNotificationListener(this.netconfEventSource, notificationPath);
- notificationRegistrationMap.put(notificationPath, registration);
- ArrayList<TopicId> topicIds = getNotificationTopicIds(notificationPath);
- if (topicIds == null) {
- topicIds = new ArrayList<>();
- topicIds.add(topicId);
- } else {
- if (topicIds.contains(topicId) == false) {
- topicIds.add(topicId);
- }
- }
-
- notificationTopicMap.put(notificationPath, topicIds);
- return true;
- }
-
- @Override synchronized void unRegisterNotificationTopic(TopicId topicId) {
- List<SchemaPath> notificationPathToRemove = new ArrayList<>();
- for (SchemaPath notifKey : notificationTopicMap.keySet()) {
- ArrayList<TopicId> topicList = notificationTopicMap.get(notifKey);
- if (topicList != null) {
- topicList.remove(topicId);
- if (topicList.isEmpty()) {
- notificationPathToRemove.add(notifKey);
- }
- }
- }
- for (SchemaPath notifKey : notificationPathToRemove) {
- notificationTopicMap.remove(notifKey);
- ListenerRegistration<NetconfEventSource> reg = notificationRegistrationMap.remove(notifKey);
- if (reg != null) {
- reg.close();
- }
- }
- }
-
- Optional<Date> getLastEventTime() {
- return Optional.fromNullable(lastEventTime);
- }
-
- void setLastEventTime(Date lastEventTime) {
- this.lastEventTime = lastEventTime;
- }
-
- @Override public void close() throws Exception {
- closeStream();
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <name>messagebus-netconf</name>
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">binding-impl:messagebus-netconf</type>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- <binding-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-broker>
- <event-source-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">
- <type xmlns:mb-esr="urn:opendaylight:params:xml:ns:yang:controller:messagebus:spi:eventsourceregistry">mb-esr:event-source-registry</type>
- <name>messagebus-app-impl</name>
- </event-source-registry>
- <namespace-to-stream xmlns="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">
- <urn-prefix>urn:ietf:params:xml:ns:yang:smiv2</urn-prefix>
- <stream-name>SNMP</stream-name>
- </namespace-to-stream>
- <namespace-to-stream xmlns="urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf">
- <urn-prefix>urn:ietf:params:xml:ns:yang:ietf-syslog-notification</urn-prefix>
- <stream-name>SYSLOG</stream-name>
- </namespace-to-stream>
- </module>
- </modules>
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf?module=messagebus-netconf&revision=2015-07-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:messagebus:spi:eventsourceregistry?module=messagebus-event-source-registry&revision=2015-04-02</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-module messagebus-netconf {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:messagebus:netconf";
- prefix "msgb-netconf";
-
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-binding {prefix sal;}
- import opendaylight-md-sal-dom {prefix dom;}
- import messagebus-event-source-registry {prefix esr;}
-
- description
- "Message bus netconf event source";
-
- revision "2015-07-28" {
- description "Message bus netconf event source initial definition";
- }
-
- identity messagebus-netconf {
- base config:module-type;
- config:java-name-prefix MessageBusNetconf;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case messagebus-netconf {
- when "/config:modules/config:module/config:type = 'messagebus-netconf'";
-
- container event-source-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity esr:event-source-registry;
- }
- }
- }
-
- container dom-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dom:dom-broker-osgi-registry;
- }
- }
- }
-
- container binding-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity sal:binding-broker-osgi-registry;
- }
- }
- }
-
- list namespace-to-stream {
- key urn-prefix;
-
- leaf urn-prefix {
- type string;
- }
-
- leaf stream-name {
- type string;
- }
- }
-
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.notNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.config.yang.messagebus.netconf.NamespaceToStream;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
-import org.opendaylight.controller.md.sal.binding.api.MountPointService;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.controller.messagebus.spi.EventSource;
-import org.opendaylight.controller.messagebus.spi.EventSourceRegistration;
-import org.opendaylight.controller.messagebus.spi.EventSourceRegistry;
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public class NetconfEventSourceManagerTest {
-
- NetconfEventSourceManager netconfEventSourceManager;
- ListenerRegistration listenerRegistrationMock;
- DOMMountPointService domMountPointServiceMock;
- MountPointService mountPointServiceMock;
- EventSourceRegistry eventSourceTopologyMock;
- AsyncDataChangeEvent asyncDataChangeEventMock;
- RpcProviderRegistry rpcProviderRegistryMock;
- EventSourceRegistry eventSourceRegistry;
- @BeforeClass
- public static void initTestClass() throws IllegalAccessException, InstantiationException {
- }
-
- @Before
- public void setUp() throws Exception {
- DataBroker dataBrokerMock = mock(DataBroker.class);
- DOMNotificationPublishService domNotificationPublishServiceMock = mock(DOMNotificationPublishService.class);
- domMountPointServiceMock = mock(DOMMountPointService.class);
- mountPointServiceMock = mock(MountPointService.class);
- eventSourceTopologyMock = mock(EventSourceRegistry.class);
- rpcProviderRegistryMock = mock(RpcProviderRegistry.class);
- eventSourceRegistry = mock(EventSourceRegistry.class);
- List<NamespaceToStream> namespaceToStreamList = new ArrayList<>();
-
- listenerRegistrationMock = mock(ListenerRegistration.class);
- doReturn(listenerRegistrationMock).when(dataBrokerMock).registerDataChangeListener(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class), any(NetconfEventSourceManager.class), eq(
- AsyncDataBroker.DataChangeScope.SUBTREE));
-
- Optional<DOMMountPoint> optionalDomMountServiceMock = (Optional<DOMMountPoint>) mock(Optional.class);
- doReturn(true).when(optionalDomMountServiceMock).isPresent();
- doReturn(optionalDomMountServiceMock).when(domMountPointServiceMock).getMountPoint((YangInstanceIdentifier)notNull());
-
- DOMMountPoint domMountPointMock = mock(DOMMountPoint.class);
- doReturn(domMountPointMock).when(optionalDomMountServiceMock).get();
-
-
- Optional optionalBindingMountMock = mock(Optional.class);
- doReturn(true).when(optionalBindingMountMock).isPresent();
-
- MountPoint mountPointMock = mock(MountPoint.class);
- doReturn(optionalBindingMountMock).when(mountPointServiceMock).getMountPoint(any(InstanceIdentifier.class));
- doReturn(mountPointMock).when(optionalBindingMountMock).get();
-
- Optional optionalMpDataBroker = mock(Optional.class);
- DataBroker mpDataBroker = mock(DataBroker.class);
- doReturn(optionalMpDataBroker).when(mountPointMock).getService(DataBroker.class);
- doReturn(true).when(optionalMpDataBroker).isPresent();
- doReturn(mpDataBroker).when(optionalMpDataBroker).get();
-
- ReadOnlyTransaction rtx = mock(ReadOnlyTransaction.class);
- doReturn(rtx).when(mpDataBroker).newReadOnlyTransaction();
- CheckedFuture<Optional<Streams>, ReadFailedException> checkFeature = (CheckedFuture<Optional<Streams>, ReadFailedException>)mock(CheckedFuture.class);
- InstanceIdentifier<Streams> pathStream = InstanceIdentifier.builder(Netconf.class).child(Streams.class).build();
- doReturn(checkFeature).when(rtx).read(LogicalDatastoreType.OPERATIONAL, pathStream);
- Optional<Streams> avStreams = NetconfTestUtils.getAvailableStream("stream01", true);
- doReturn(avStreams).when(checkFeature).checkedGet();
-
- EventSourceRegistration esrMock = mock(EventSourceRegistration.class);
-
- netconfEventSourceManager =
- NetconfEventSourceManager
- .create(dataBrokerMock, domNotificationPublishServiceMock, domMountPointServiceMock,
- mountPointServiceMock, eventSourceRegistry, namespaceToStreamList);
- }
-
- @Test
- public void onDataChangedCreateEventSourceTestByCreateEntry() throws Exception {
- onDataChangedTestHelper(true,false,true, NetconfTestUtils.notification_capability_prefix);
- netconfEventSourceManager.onDataChanged(asyncDataChangeEventMock);
- verify(eventSourceRegistry, times(1)).registerEventSource(any(EventSource.class));
- }
-
- @Test
- public void onDataChangedCreateEventSourceTestByUpdateEntry() throws Exception {
- onDataChangedTestHelper(false,true,true, NetconfTestUtils.notification_capability_prefix);
- netconfEventSourceManager.onDataChanged(asyncDataChangeEventMock);
- verify(eventSourceRegistry, times(1)).registerEventSource(any(EventSource.class));
- }
-
- @Test
- public void onDataChangedCreateEventSourceTestNotNeconf() throws Exception {
- onDataChangedTestHelper(false,true,false, NetconfTestUtils.notification_capability_prefix);
- netconfEventSourceManager.onDataChanged(asyncDataChangeEventMock);
- verify(eventSourceRegistry, times(0)).registerEventSource(any(EventSource.class));
- }
-
- @Test
- public void onDataChangedCreateEventSourceTestNotNotificationCapability() throws Exception {
- onDataChangedTestHelper(true,false,true,"bad-prefix");
- netconfEventSourceManager.onDataChanged(asyncDataChangeEventMock);
- verify(eventSourceRegistry, times(0)).registerEventSource(any(EventSource.class));
- }
-
- private void onDataChangedTestHelper(boolean create, boolean update, boolean isNetconf, String notificationCapabilityPrefix) throws Exception{
- asyncDataChangeEventMock = mock(AsyncDataChangeEvent.class);
- Map<InstanceIdentifier, DataObject> mapCreate = new HashMap<>();
- Map<InstanceIdentifier, DataObject> mapUpdate = new HashMap<>();
-
- Node node01;
- String nodeId = "Node01";
- doReturn(mapCreate).when(asyncDataChangeEventMock).getCreatedData();
- doReturn(mapUpdate).when(asyncDataChangeEventMock).getUpdatedData();
-
- if(isNetconf){
- node01 = NetconfTestUtils
- .getNetconfNode(nodeId, "node01.test.local", ConnectionStatus.Connected, notificationCapabilityPrefix);
-
- } else {
- node01 = NetconfTestUtils.getNode(nodeId);
- }
-
- if(create){
- mapCreate.put(NetconfTestUtils.getInstanceIdentifier(node01), node01);
- }
- if(update){
- mapUpdate.put(NetconfTestUtils.getInstanceIdentifier(node01), node01);
- }
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import java.net.URI;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.md.sal.binding.api.BindingService;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.MountPoint;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.api.DOMService;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.NotificationPattern;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventaggregator.rev141202.TopicId;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.messagebus.eventsource.rev141202.JoinTopicInput;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.NotificationsService;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields.ConnectionStatus;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public class NetconfEventSourceTest {
-
- NetconfEventSource netconfEventSource;
- DOMMountPoint domMountPointMock;
- MountPoint mountPointMock;
- JoinTopicInput joinTopicInputMock;
-
- @Before
- public void setUp() throws Exception {
- Map<String, String> streamMap = new HashMap<>();
- streamMap.put("uriStr1", "string2");
- domMountPointMock = mock(DOMMountPoint.class);
- mountPointMock = mock(MountPoint.class);
- DOMNotificationPublishService domNotificationPublishServiceMock = mock(DOMNotificationPublishService.class);
- RpcConsumerRegistry rpcConsumerRegistryMock = mock(RpcConsumerRegistry.class);
- Optional<BindingService> onlyOptionalMock = (Optional<BindingService>) mock(Optional.class);
- NotificationsService notificationsServiceMock = mock(NotificationsService.class);
- doReturn(notificationsServiceMock).when(rpcConsumerRegistryMock).getRpcService(NotificationsService.class);
-
- Optional<DataBroker> optionalMpDataBroker = (Optional<DataBroker>) mock(Optional.class);
- DataBroker mpDataBroker = mock(DataBroker.class);
- doReturn(optionalMpDataBroker).when(mountPointMock).getService(DataBroker.class);
- doReturn(true).when(optionalMpDataBroker).isPresent();
- doReturn(mpDataBroker).when(optionalMpDataBroker).get();
-
- ReadOnlyTransaction rtx = mock(ReadOnlyTransaction.class);
- doReturn(rtx).when(mpDataBroker).newReadOnlyTransaction();
- CheckedFuture<Optional<Streams>, ReadFailedException> checkFeature = (CheckedFuture<Optional<Streams>, ReadFailedException>)mock(CheckedFuture.class);
- InstanceIdentifier<Streams> pathStream = InstanceIdentifier.builder(Netconf.class).child(Streams.class).build();
- doReturn(checkFeature).when(rtx).read(LogicalDatastoreType.OPERATIONAL, pathStream);
- Optional<Streams> avStreams = NetconfTestUtils.getAvailableStream("stream01", true);
- doReturn(avStreams).when(checkFeature).checkedGet();
-
- netconfEventSource = new NetconfEventSource(
- NetconfTestUtils.getNetconfNode("NodeId1", "node.test.local", ConnectionStatus.Connected,
- NetconfTestUtils.notification_capability_prefix),
- streamMap,
- domMountPointMock,
- mountPointMock ,
- domNotificationPublishServiceMock);
-
- }
-
- @Test
- public void joinTopicTest() throws Exception{
- joinTopicTestHelper();
- assertNotNull("JoinTopic return value has not been created correctly.", netconfEventSource.joinTopic(joinTopicInputMock));
- }
-
- private void joinTopicTestHelper() throws Exception{
- joinTopicInputMock = mock(JoinTopicInput.class);
- TopicId topicId = new TopicId("topicID007");
- doReturn(topicId).when(joinTopicInputMock).getTopicId();
- NotificationPattern notificationPatternMock = mock(NotificationPattern.class);
- doReturn(notificationPatternMock).when(joinTopicInputMock).getNotificationPattern();
- doReturn("uriStr1").when(notificationPatternMock).getValue();
-
- SchemaContext schemaContextMock = mock(SchemaContext.class);
- doReturn(schemaContextMock).when(domMountPointMock).getSchemaContext();
- Set<NotificationDefinition> notificationDefinitionSet = new HashSet<>();
- NotificationDefinition notificationDefinitionMock = mock(NotificationDefinition.class);
- notificationDefinitionSet.add(notificationDefinitionMock);
-
- URI uri = new URI("uriStr1");
- QName qName = new QName(uri, "localName1");
- org.opendaylight.yangtools.yang.model.api.SchemaPath schemaPath = SchemaPath.create(true, qName);
- doReturn(notificationDefinitionSet).when(schemaContextMock).getNotifications();
- doReturn(schemaPath).when(notificationDefinitionMock).getPath();
-
- Optional<DOMNotificationService> domNotificationServiceOptionalMock = (Optional<DOMNotificationService>) mock(Optional.class);
- doReturn(domNotificationServiceOptionalMock).when(domMountPointMock).getService(DOMNotificationService.class);
- doReturn(true).when(domNotificationServiceOptionalMock).isPresent();
-
- DOMNotificationService domNotificationServiceMock = mock(DOMNotificationService.class);
- doReturn(domNotificationServiceMock).when(domNotificationServiceOptionalMock).get();
- ListenerRegistration<NetconfEventSource> listenerRegistrationMock = (ListenerRegistration<NetconfEventSource>)mock(ListenerRegistration.class);
- doReturn(listenerRegistrationMock).when(domNotificationServiceMock).registerNotificationListener(any(NetconfEventSource.class), any(SchemaPath.class));
-
- Optional<DOMService> optionalMock = (Optional<DOMService>) mock(Optional.class);
- doReturn(optionalMock).when(domMountPointMock).getService(DOMRpcService.class);
- doReturn(true).when(optionalMock).isPresent();
- DOMRpcService domRpcServiceMock = mock(DOMRpcService.class);
- doReturn(domRpcServiceMock).when(optionalMock).get();
- CheckedFuture checkedFutureMock = mock(CheckedFuture.class);
- doReturn(checkedFutureMock).when(domRpcServiceMock).invokeRpc(any(SchemaPath.class), any(ContainerNode.class));
-
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.messagebus.eventsources.netconf;
-
-import com.google.common.base.Optional;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.StreamsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.AvailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public final class NetconfTestUtils {
-
- public static final String notification_capability_prefix = "(urn:ietf:params:xml:ns:netconf:notification";
-
- private NetconfTestUtils() {
- }
-
- public static Node getNetconfNode(String nodeIdent, String hostName, ConnectionStatus cs,
- String notificationCapabilityPrefix) {
-
- DomainName dn = new DomainName(hostName);
- Host host = new Host(dn);
-
- List<String> avCapList = new ArrayList<>();
- avCapList.add(notificationCapabilityPrefix + "_availableCapabilityString1");
- AvailableCapabilities avCaps = new AvailableCapabilitiesBuilder().setAvailableCapability(avCapList).build();
- NetconfNode nn = new NetconfNodeBuilder().setConnectionStatus(cs).setHost(host).setAvailableCapabilities(avCaps)
- .build();
-
- NodeId nodeId = new NodeId(nodeIdent);
- NodeKey nk = new NodeKey(nodeId);
- NodeBuilder nb = new NodeBuilder();
- nb.setKey(nk);
-
- nb.addAugmentation(NetconfNode.class, nn);
- return nb.build();
- }
-
- public static Node getNode(String nodeIdent) {
- NodeId nodeId = new NodeId(nodeIdent);
- NodeKey nk = new NodeKey(nodeId);
- NodeBuilder nb = new NodeBuilder();
- nb.setKey(nk);
- return nb.build();
- }
-
- public static InstanceIdentifier<Node> getInstanceIdentifier(Node node) {
- TopologyKey NETCONF_TOPOLOGY_KEY = new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName()));
- InstanceIdentifier<Node> nodeII = InstanceIdentifier.create(NetworkTopology.class)
- .child(Topology.class, NETCONF_TOPOLOGY_KEY).child(Node.class, node.getKey());
- return nodeII;
- }
-
- public static Optional<Streams> getAvailableStream(String Name, boolean replaySupport) {
- Stream stream = new StreamBuilder().setName(new StreamNameType(Name)).setReplaySupport(replaySupport).build();
- List<Stream> streamList = new ArrayList<>();
- streamList.add(stream);
- Streams streams = new StreamsBuilder().setStream(streamList).build();
- return Optional.of(streams);
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-models</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210,</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-module ietf-netconf-monitoring-extension {
-
- yang-version 1;
-
- namespace
- "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension";
-
- prefix ncme;
-
- import ietf-netconf-monitoring {
- prefix ncm;
- }
-
- revision "2013-12-10" {
- description "Initial revision.";
-
- }
-
- identity netconf-tcp {
- base ncm:transport;
- description
- "NETCONF over TCP.";
- }
-
- augment "/ncm:netconf-state/ncm:sessions/ncm:session" {
- leaf session-identifier {
- type string;
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-models</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>ietf-netconf-monitoring</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
-
-
-/**
-**/
-public final class LocationBuilder {
-
- public static Location getDefaultInstance(String defaultValue) {
- return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri(
- defaultValue));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
-
-/**
- * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
- * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
- *
- * The reason behind putting it under src/main/java is:
- * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
- * loss of user code.
- */
-public class SchemaLocationBuilder {
-
- public static Location getDefaultInstance(final String defaultValue) {
- throw new java.lang.UnsupportedOperationException("Not yet implemented");
- }
-
-}
+++ /dev/null
-module ietf-netconf-monitoring {
-
- yang-version 1;
-
- namespace
- "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
-
- prefix ncm;
-
- import ietf-yang-types {
- prefix yang;
- revision-date "2010-09-24";
- }
-
- import ietf-inet-types {
- prefix inet;
- revision-date "2010-09-24";
- }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
-
- WG Chair: Bert Wijnen
- <mailto:bertietf@bwijnen.net>
-
- Editor: Mark Scott
- <mailto:mark.scott@ericsson.com>
-
- Editor: Martin Bjorklund
- <mailto:mbj@tail-f.com>";
-
- description
- "NETCONF Monitoring Module.
- All elements in this module are read-only.
-
- Copyright (c) 2010 IETF Trust and the persons identified as
- authors of the code. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD
- License set forth in Section 4.c of the IETF Trust's
- Legal Provisions Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6022; see
- the RFC itself for full legal notices.";
-
- revision "2010-10-04" {
- description "Initial revision.";
- reference
- "RFC 6022: YANG Module for NETCONF Monitoring";
-
- }
-
-
- typedef netconf-datastore-type {
- type enumeration {
- enum "running" {
- value 0;
- }
- enum "candidate" {
- value 1;
- }
- enum "startup" {
- value 2;
- }
- }
- description
- "Enumeration of possible NETCONF datastore types.";
- reference
- "RFC 4741: NETCONF Configuration Protocol";
-
- }
-
- identity transport {
- description
- "Base identity for NETCONF transport types.";
- }
-
- identity netconf-ssh {
- base transport;
- description
- "NETCONF over Secure Shell (SSH).";
- reference
- "RFC 4742: Using the NETCONF Configuration Protocol
- over Secure SHell (SSH)";
-
- }
-
- identity netconf-soap-over-beep {
- base transport;
- description
- "NETCONF over Simple Object Access Protocol (SOAP) over
- Blocks Extensible Exchange Protocol (BEEP).";
- reference
- "RFC 4743: Using NETCONF over the Simple Object
- Access Protocol (SOAP)";
-
- }
-
- identity netconf-soap-over-https {
- base transport;
- description
- "NETCONF over Simple Object Access Protocol (SOAP)
- over Hypertext Transfer Protocol Secure (HTTPS).";
- reference
- "RFC 4743: Using NETCONF over the Simple Object
- Access Protocol (SOAP)";
-
- }
-
- identity netconf-beep {
- base transport;
- description
- "NETCONF over Blocks Extensible Exchange Protocol (BEEP).";
- reference
- "RFC 4744: Using the NETCONF Protocol over the
- Blocks Extensible Exchange Protocol (BEEP)";
-
- }
-
- identity netconf-tls {
- base transport;
- description
- "NETCONF over Transport Layer Security (TLS).";
- reference
- "RFC 5539: NETCONF over Transport Layer Security (TLS)";
-
- }
-
- identity schema-format {
- description
- "Base identity for data model schema languages.";
- }
-
- identity xsd {
- base schema-format;
- description
- "W3C XML Schema Definition.";
- reference
- "W3C REC REC-xmlschema-1-20041028:
- XML Schema Part 1: Structures";
-
- }
-
- identity yang {
- base schema-format;
- description
- "The YANG data modeling language for NETCONF.";
- reference
- "RFC 6020: YANG - A Data Modeling Language for the
- Network Configuration Protocol (NETCONF)";
-
- }
-
- identity yin {
- base schema-format;
- description "The YIN syntax for YANG.";
- reference
- "RFC 6020: YANG - A Data Modeling Language for the
- Network Configuration Protocol (NETCONF)";
-
- }
-
- identity rng {
- base schema-format;
- description
- "Regular Language for XML Next Generation (RELAX NG).";
- reference
- "ISO/IEC 19757-2:2008: RELAX NG";
-
- }
-
- identity rnc {
- base schema-format;
- description "Relax NG Compact Syntax";
- reference
- "ISO/IEC 19757-2:2008: RELAX NG";
-
- }
-
- grouping common-counters {
- description
- "Counters that exist both per session, and also globally,
- accumulated from all sessions.";
- leaf in-rpcs {
- type yang:zero-based-counter32;
- description
- "Number of correct <rpc> messages received.";
- }
-
- leaf in-bad-rpcs {
- type yang:zero-based-counter32;
- description
- "Number of messages received when an <rpc> message was expected,
- that were not correct <rpc> messages. This includes XML parse
- errors and errors on the rpc layer.";
- }
-
- leaf out-rpc-errors {
- type yang:zero-based-counter32;
- description
- "Number of <rpc-reply> messages sent that contained an
- <rpc-error> element.";
- }
-
- leaf out-notifications {
- type yang:zero-based-counter32;
- description
- "Number of <notification> messages sent.";
- }
- } // grouping common-counters
-
- container netconf-state {
- config false;
- description
- "The netconf-state container is the root of the monitoring
- data model.";
- container capabilities {
- description
- "Contains the list of NETCONF capabilities supported by the
- server.";
- leaf-list capability {
- type inet:uri;
- description
- "List of NETCONF capabilities supported by the server.";
- }
- } // container capabilities
-
- container datastores {
- description
- "Contains the list of NETCONF configuration datastores.";
- list datastore {
- key "name";
- description
- "List of NETCONF configuration datastores supported by
- the NETCONF server and related information.";
- leaf name {
- type netconf-datastore-type;
- description
- "Name of the datastore associated with this list entry.";
- }
-
- container locks {
- presence
- "This container is present only if the datastore
- is locked.";
- description
- "The NETCONF <lock> and <partial-lock> operations allow
- a client to lock specific resources in a datastore. The
- NETCONF server will prevent changes to the locked
- resources by all sessions except the one that acquired
- the lock(s).
-
- Monitoring information is provided for each datastore
- entry including details such as the session that acquired
- the lock, the type of lock (global or partial) and the
- list of locked resources. Multiple locks per datastore
- are supported.";
- grouping lock-info {
- description
- "Lock related parameters, common to both global and
- partial locks.";
- leaf locked-by-session {
- type uint32;
- mandatory true;
- description
- "The session ID of the session that has locked
- this resource. Both a global lock and a partial
- lock MUST contain the NETCONF session-id.
-
- If the lock is held by a session that is not managed
- by the NETCONF server (e.g., a CLI session), a session
- id of 0 (zero) is reported.";
- reference
- "RFC 4741: NETCONF Configuration Protocol";
-
- }
-
- leaf locked-time {
- type yang:date-and-time;
- mandatory true;
- description
- "The date and time of when the resource was
- locked.";
- }
- } // grouping lock-info
- choice lock-type {
- description
- "Indicates if a global lock or a set of partial locks
- are set.";
- container global-lock {
- description
- "Present if the global lock is set.";
- uses lock-info;
- } // container global-lock
- list partial-lock {
- key "lock-id";
- description
- "List of partial locks.";
- reference
- "RFC 5717: Partial Lock Remote Procedure Call (RPC) for
- NETCONF";
-
- leaf lock-id {
- type uint32;
- description
- "This is the lock id returned in the <partial-lock>
- response.";
- }
-
- uses lock-info;
-
- leaf-list select {
- type yang:xpath1.0;
- min-elements 1;
- description
- "The xpath expression that was used to request
- the lock. The select expression indicates the
- original intended scope of the lock.";
- }
-
- leaf-list locked-node {
- type instance-identifier;
- description
- "The list of instance-identifiers (i.e., the
- locked nodes).
-
- The scope of the partial lock is defined by the list
- of locked nodes.";
- }
- } // list partial-lock
- } // choice lock-type
- } // container locks
- } // list datastore
- } // container datastores
-
- container schemas {
- description
- "Contains the list of data model schemas supported by the
- server.";
- list schema {
- key "identifier version format";
- description
- "List of data model schemas supported by the server.";
- leaf identifier {
- type string;
- description
- "Identifier to uniquely reference the schema. The
- identifier is used in the <get-schema> operation and may
- be used for other purposes such as file retrieval.
-
- For modeling languages that support or require a data
- model name (e.g., YANG module name) the identifier MUST
- match that name. For YANG data models, the identifier is
- the name of the module or submodule. In other cases, an
- identifier such as a filename MAY be used instead.";
- }
-
- leaf version {
- type string;
- description
- "Version of the schema supported. Multiple versions MAY be
- supported simultaneously by a NETCONF server. Each
- version MUST be reported individually in the schema list,
- i.e., with same identifier, possibly different location,
- but different version.
-
- For YANG data models, version is the value of the most
- recent YANG 'revision' statement in the module or
- submodule, or the empty string if no 'revision' statement
- is present.";
- }
-
- leaf format {
- type identityref {
- base schema-format;
- }
- description
- "The data modeling language the schema is written
- in (currently xsd, yang, yin, rng, or rnc).
- For YANG data models, 'yang' format MUST be supported and
- 'yin' format MAY also be provided.";
- }
-
- leaf namespace {
- type inet:uri;
- mandatory true;
- description
- "The XML namespace defined by the data model.
-
- For YANG data models, this is the module's namespace.
- If the list entry describes a submodule, this field
- contains the namespace of the module to which the
- submodule belongs.";
- }
-
- leaf-list location {
- type union {
- type enumeration {
- enum "NETCONF" {
- value 0;
- }
- }
- type inet:uri;
- }
- description
- "One or more locations from which the schema can be
- retrieved. This list SHOULD contain at least one
- entry per schema.
-
- A schema entry may be located on a remote file system
- (e.g., reference to file system for ftp retrieval) or
- retrieved directly from a server supporting the
- <get-schema> operation (denoted by the value 'NETCONF').";
- }
- } // list schema
- } // container schemas
-
- container sessions {
- description
- "The sessions container includes session-specific data for
- NETCONF management sessions. The session list MUST include
- all currently active NETCONF sessions.";
- list session {
- key "session-id";
- description
- "All NETCONF sessions managed by the NETCONF server
- MUST be reported in this list.";
- leaf session-id {
- type uint32 {
- range "1..max";
- }
- description
- "Unique identifier for the session. This value is the
- NETCONF session identifier, as defined in RFC 4741.";
- reference
- "RFC 4741: NETCONF Configuration Protocol";
-
- }
-
- leaf transport {
- type identityref {
- base transport;
- }
- mandatory true;
- description
- "Identifies the transport for each session, e.g.,
- 'netconf-ssh', 'netconf-soap', etc.";
- }
-
- leaf username {
- type string;
- mandatory true;
- description
- "The username is the client identity that was authenticated
- by the NETCONF transport protocol. The algorithm used to
- derive the username is NETCONF transport protocol specific
- and in addition specific to the authentication mechanism
- used by the NETCONF transport protocol.";
- }
-
- leaf source-host {
- type inet:host;
- description
- "Host identifier of the NETCONF client. The value
- returned is implementation specific (e.g., hostname,
- IPv4 address, IPv6 address)";
- }
-
- leaf login-time {
- type yang:date-and-time;
- mandatory true;
- description
- "Time at the server at which the session was established.";
- }
-
- uses common-counters {
- description
- "Per-session counters. Zero based with following reset
- behaviour:
- - at start of a session
- - when max value is reached";
- }
- } // list session
- } // container sessions
-
- container statistics {
- description
- "Statistical data pertaining to the NETCONF server.";
- leaf netconf-start-time {
- type yang:date-and-time;
- description
- "Date and time at which the management subsystem was
- started.";
- }
-
- leaf in-bad-hellos {
- type yang:zero-based-counter32;
- description
- "Number of sessions silently dropped because an
- invalid <hello> message was received. This includes <hello>
- messages with a 'session-id' attribute, bad namespace, and
- bad capability declarations.";
- }
-
- leaf in-sessions {
- type yang:zero-based-counter32;
- description
- "Number of sessions started. This counter is incremented
- when a <hello> message with a <session-id> is sent.
-
- 'in-sessions' - 'in-bad-hellos' =
- 'number of correctly started netconf sessions'";
- }
-
- leaf dropped-sessions {
- type yang:zero-based-counter32;
- description
- "Number of sessions that were abnormally terminated, e.g.,
- due to idle timeout or transport close. This counter is not
- incremented when a session is properly closed by a
- <close-session> operation, or killed by a <kill-session>
- operation.";
- }
-
- uses common-counters {
- description
- "Global counters, accumulated from all sessions.
- Zero based with following reset behaviour:
- - re-initialization of NETCONF server
- - when max value is reached";
- }
- } // container statistics
- } // container netconf-state
-
- rpc get-schema {
- description
- "This operation is used to retrieve a schema from the
- NETCONF server.
-
- Positive Response:
- The NETCONF server returns the requested schema.
-
- Negative Response:
- If requested schema does not exist, the <error-tag> is
- 'invalid-value'.
-
- If more than one schema matches the requested parameters, the
- <error-tag> is 'operation-failed', and <error-app-tag> is
- 'data-not-unique'.";
- input {
- leaf identifier {
- type string;
- mandatory true;
- description
- "Identifier for the schema list entry.";
- }
-
- leaf version {
- type string;
- description
- "Version of the schema requested. If this parameter is not
- present, and more than one version of the schema exists on
- the server, a 'data-not-unique' error is returned, as
- described above.";
- }
-
- leaf format {
- type identityref {
- base schema-format;
- }
- description
- "The data modeling language of the schema. If this
- parameter is not present, and more than one formats of
- the schema exists on the server, a 'data-not-unique' error
- is returned, as described above.";
- }
- }
-
- output {
- anyxml data {
- description
- "Contains the schema content.";
- }
- }
- } // rpc get-schema
-} // module
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-models</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>ietf-netconf-notifications</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.*,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.*,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.*
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-module ietf-netconf-notifications {
-
- namespace
- "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications";
-
- prefix ncn;
-
- import ietf-inet-types { prefix inet; revision-date "2010-09-24";}
- import ietf-netconf { prefix nc; revision-date "2011-06-01";}
-
- organization
- "IETF NETCONF (Network Configuration Protocol) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netconf/>
- WG List: <mailto:netconf@ietf.org>
-
- WG Chair: Bert Wijnen
- <mailto:bertietf@bwijnen.net>
-
- WG Chair: Mehmet Ersue
- <mailto:mehmet.ersue@nsn.com>
-
- Editor: Andy Bierman
- <mailto:andy@netconfcentral.org>";
-
- description
- "This module defines a YANG data model for use with the
- NETCONF protocol that allows the NETCONF client to
- receive common NETCONF base event notifications.
-
- Copyright (c) 2012 IETF Trust and the persons identified as
- the document authors. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
-
-
-
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6470; see
- the RFC itself for full legal notices.";
-
- revision "2012-02-06" {
- description
- "Initial version. Errata 3957 added.";
- reference
- "RFC 6470: NETCONF Base Notifications";
- }
-
- grouping common-session-parms {
- description
- "Common session parameters to identify a
- management session.";
-
- leaf username {
- type string;
- mandatory true;
- description
- "Name of the user for the session.";
- }
-
- leaf session-id {
- type nc:session-id-or-zero-type;
- mandatory true;
- description
- "Identifier of the session.
- A NETCONF session MUST be identified by a non-zero value.
- A non-NETCONF session MAY be identified by the value zero.";
- }
-
- leaf source-host {
- type inet:ip-address;
- description
- "Address of the remote host for the session.";
- }
- }
-
-
-
-
-
-
-
-
- grouping changed-by-parms {
- description
- "Common parameters to identify the source
- of a change event, such as a configuration
- or capability change.";
-
- container changed-by {
- description
- "Indicates the source of the change.
- If caused by internal action, then the
- empty leaf 'server' will be present.
- If caused by a management session, then
- the name, remote host address, and session ID
- of the session that made the change will be reported.";
- choice server-or-user {
- mandatory true;
- leaf server {
- type empty;
- description
- "If present, the change was caused
- by the server.";
- }
-
- case by-user {
- uses common-session-parms;
- }
- } // choice server-or-user
- } // container changed-by-parms
- }
-
-
- notification netconf-config-change {
- description
- "Generated when the NETCONF server detects that the
- <running> or <startup> configuration datastore
- has been changed by a management session.
- The notification summarizes the edits that
- have been detected.
-
- The server MAY choose to also generate this
- notification while loading a datastore during the
- boot process for the device.";
-
- uses changed-by-parms;
-
-
-
-
-
- leaf datastore {
- type enumeration {
- enum running {
- description "The <running> datastore has changed.";
- }
- enum startup {
- description "The <startup> datastore has changed";
- }
- }
- default "running";
- description
- "Indicates which configuration datastore has changed.";
- }
-
- list edit {
- description
- "An edit record SHOULD be present for each distinct
- edit operation that the server has detected on
- the target datastore. This list MAY be omitted
- if the detailed edit operations are not known.
- The server MAY report entries in this list for
- changes not made by a NETCONF session (e.g., CLI).";
-
- leaf target {
- type instance-identifier;
- description
- "Topmost node associated with the configuration change.
- A server SHOULD set this object to the node within
- the datastore that is being altered. A server MAY
- set this object to one of the ancestors of the actual
- node that was changed, or omit this object, if the
- exact node is not known.";
- }
-
- leaf operation {
- type nc:edit-operation-type;
- description
- "Type of edit operation performed.
- A server MUST set this object to the NETCONF edit
- operation performed on the target datastore.";
- }
- } // list edit
- } // notification netconf-config-change
-
-
-
-
-
-
- notification netconf-capability-change {
- description
- "Generated when the NETCONF server detects that
- the server capabilities have changed.
- Indicates which capabilities have been added, deleted,
- and/or modified. The manner in which a server
- capability is changed is outside the scope of this
- document.";
-
- uses changed-by-parms;
-
- leaf-list added-capability {
- type inet:uri;
- description
- "List of capabilities that have just been added.";
- }
-
- leaf-list deleted-capability {
- type inet:uri;
- description
- "List of capabilities that have just been deleted.";
- }
-
- leaf-list modified-capability {
- type inet:uri;
- description
- "List of capabilities that have just been modified.
- A capability is considered to be modified if the
- base URI for the capability has not changed, but
- one or more of the parameters encoded at the end of
- the capability URI have changed.
- The new modified value of the complete URI is returned.";
- }
- } // notification netconf-capability-change
-
-
- notification netconf-session-start {
- description
- "Generated when a NETCONF server detects that a
- NETCONF session has started. A server MAY generate
- this event for non-NETCONF management sessions.
- Indicates the identity of the user that started
- the session.";
- uses common-session-parms;
- } // notification netconf-session-start
-
-
-
-
- notification netconf-session-end {
- description
- "Generated when a NETCONF server detects that a
- NETCONF session has terminated.
- A server MAY optionally generate this event for
- non-NETCONF management sessions. Indicates the
- identity of the user that owned the session,
- and why the session was terminated.";
-
- uses common-session-parms;
-
- leaf killed-by {
- when "../termination-reason = 'killed'";
- type nc:session-id-type;
- description
- "The ID of the session that directly caused this session
- to be abnormally terminated. If this session was abnormally
- terminated by a non-NETCONF session unknown to the server,
- then this leaf will not be present.";
- }
-
- leaf termination-reason {
- type enumeration {
- enum "closed" {
- description
- "The session was terminated by the client in normal
- fashion, e.g., by the NETCONF <close-session>
- protocol operation.";
- }
- enum "killed" {
- description
- "The session was terminated in abnormal
- fashion, e.g., by the NETCONF <kill-session>
- protocol operation.";
- }
- enum "dropped" {
- description
- "The session was terminated because the transport layer
- connection was unexpectedly closed.";
- }
- enum "timeout" {
- description
- "The session was terminated because of inactivity,
- e.g., waiting for the <hello> message or <rpc>
- messages.";
- }
-
-
-
- enum "bad-hello" {
- description
- "The client's <hello> message was invalid.";
- }
- enum "other" {
- description
- "The session was terminated for some other reason.";
- }
- }
- mandatory true;
- description
- "Reason the session was terminated.";
- }
- } // notification netconf-session-end
-
-
- notification netconf-confirmed-commit {
- description
- "Generated when a NETCONF server detects that a
- confirmed-commit event has occurred. Indicates the event
- and the current state of the confirmed-commit procedure
- in progress.";
- reference
- "RFC 6241, Section 8.4";
-
- uses common-session-parms {
- when "confirm-event != 'timeout'";
- }
-
- leaf confirm-event {
- type enumeration {
- enum "start" {
- description
- "The confirmed-commit procedure has started.";
- }
- enum "cancel" {
- description
- "The confirmed-commit procedure has been canceled,
- e.g., due to the session being terminated, or an
- explicit <cancel-commit> operation.";
- }
- enum "timeout" {
- description
- "The confirmed-commit procedure has been canceled
- due to the confirm-timeout interval expiring.
- The common session parameters will not be present
- in this sub-mode.";
- }
-
- enum "extend" {
- description
- "The confirmed-commit timeout has been extended,
- e.g., by a new <confirmed-commit> operation.";
- }
- enum "complete" {
- description
- "The confirmed-commit procedure has been completed.";
- }
- }
- mandatory true;
- description
- "Indicates the event that caused the notification.";
- }
-
- leaf timeout {
- when
- "../confirm-event = 'start' or ../confirm-event = 'extend'";
- type uint32;
- units "seconds";
- description
- "The configured timeout value if the event type
- is 'start' or 'extend'. This value represents
- the approximate number of seconds from the event
- time when the 'timeout' event might occur.";
- }
- } // notification netconf-confirmed-commit
-
-}
+++ /dev/null
-module nc-notifications {
-
- namespace "urn:ietf:params:xml:ns:netmod:notification";
- prefix "manageEvent";
-
- import ietf-yang-types{ prefix yang; revision-date "2010-09-24";}
- import notifications { prefix ncEvent; revision-date "2008-07-14";}
-
- organization
- "IETF NETCONF WG";
-
- contact
- "netconf@ietf.org";
-
- description
- "Conversion of the 'manageEvent' XSD in the NETCONF
- Notifications RFC.";
-
- reference
- "RFC 5277";
-
- revision 2008-07-14 {
- description "RFC 5277 version.";
- }
-
- container netconf {
- description "Top-level element in the notification namespace";
-
- config false;
-
- container streams {
- description
- "The list of event streams supported by the system. When
- a query is issued, the returned set of streams is
- determined based on user privileges.";
-
- list stream {
- description
- "Stream name, description and other information.";
- key name;
- min-elements 1;
-
- leaf name {
- description
- "The name of the event stream. If this is the default
- NETCONF stream, this must have the value 'NETCONF'.";
- type ncEvent:streamNameType;
- }
-
- leaf description {
- description
- "A description of the event stream, including such
- information as the type of events that are sent over
- this stream.";
- type string;
- mandatory true;
- }
-
- leaf replaySupport {
- description
- "A description of the event stream, including such
- information as the type of events that are sent over
- this stream.";
- type boolean;
- mandatory true;
- }
-
- leaf replayLogCreationTime {
- description
- "The timestamp of the creation of the log used to support
- the replay function on this stream. Note that this might
- be earlier then the earliest available notification in
- the log. This object is updated if the log resets for
- some reason. This object MUST be present if replay is
- supported.";
- type yang:date-and-time; // xsd:dateTime is wrong!
- }
- }
- }
- }
-
- notification replayComplete {
- description
- "This notification is sent to signal the end of a replay
- portion of a subscription.";
- }
-
- notification notificationComplete {
- description
- "This notification is sent to signal the end of a notification
- subscription. It is sent in the case that stopTime was
- specified during the creation of the subscription..";
- }
-
-}
+++ /dev/null
-module notifications {
-
- namespace "urn:ietf:params:xml:ns:netconf:notification:1.0";
- prefix "ncEvent";
-
- import ietf-yang-types { prefix yang; revision-date "2010-09-24";}
-
- organization
- "IETF NETCONF WG";
-
- contact
- "netconf@ops.ietf.org";
-
- description
- "Conversion of the 'ncEvent' XSD in the
- NETCONF Notifications RFC.";
-
- reference
- "RFC 5277.";
-
- revision 2008-07-14 {
- description "RFC 5277 version.";
- }
-
- typedef streamNameType {
- description
- "The name of an event stream.";
- type string;
- }
-
- rpc create-subscription {
- description
- "The command to create a notification subscription. It
- takes as argument the name of the notification stream
- and filter. Both of those options limit the content of
- the subscription. In addition, there are two time-related
- parameters, startTime and stopTime, which can be used to
- select the time interval of interest to the notification
- replay feature.";
-
- input {
- leaf stream {
- description
- "An optional parameter that indicates which stream of events
- is of interest. If not present, then events in the default
- NETCONF stream will be sent.";
- type streamNameType;
- default "NETCONF";
- }
-
- anyxml filter {
- description
- "An optional parameter that indicates which subset of all
- possible events is of interest. The format of this
- parameter is the same as that of the filter parameter
- in the NETCONF protocol operations. If not present,
- all events not precluded by other parameters will
- be sent.";
- }
-
- leaf startTime {
- description
- "A parameter used to trigger the replay feature and
- indicates that the replay should start at the time
- specified. If start time is not present, this is not a
- replay subscription.";
- type yang:date-and-time;
- }
-
- leaf stopTime {
- // must ". >= ../startTime";
- description
- "An optional parameter used with the optional replay
- feature to indicate the newest notifications of
- interest. If stop time is not present, the notifications
- will continue until the subscription is terminated.
- Must be used with startTime.";
- type yang:date-and-time;
- }
- }
- }
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-models</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>ietf-netconf</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
-
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-module ietf-netconf {
-
- // the namespace for NETCONF XML definitions is unchanged
- // from RFC 4741, which this document replaces
- namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
-
- prefix nc;
-
- import ietf-inet-types {
- prefix inet;
- }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netconf/>
- WG List: <netconf@ietf.org>
-
- WG Chair: Bert Wijnen
- <bertietf@bwijnen.net>
-
- WG Chair: Mehmet Ersue
- <mehmet.ersue@nsn.com>
-
- Editor: Martin Bjorklund
- <mbj@tail-f.com>
-
- Editor: Juergen Schoenwaelder
- <j.schoenwaelder@jacobs-university.de>
-
- Editor: Andy Bierman
- <andy.bierman@brocade.com>";
- description
- "NETCONF Protocol Data Types and Protocol Operations.
-
- Copyright (c) 2011 IETF Trust and the persons identified as
- the document authors. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6241; see
- the RFC itself for full legal notices.";
-
- revision 2011-06-01 {
- description
- "Initial revision;";
- reference
- "RFC 6241: Network Configuration Protocol";
- }
-
- extension get-filter-element-attributes {
- description
- "If this extension is present within an 'anyxml'
- statement named 'filter', which must be conceptually
- defined within the RPC input section for the <get>
- and <get-config> protocol operations, then the
- following unqualified XML attribute is supported
- within the <filter> element, within a <get> or
- <get-config> protocol operation:
-
- type : optional attribute with allowed
- value strings 'subtree' and 'xpath'.
- If missing, the default value is 'subtree'.
-
- If the 'xpath' feature is supported, then the
- following unqualified XML attribute is
- also supported:
-
- select: optional attribute containing a
- string representing an XPath expression.
- The 'type' attribute must be equal to 'xpath'
- if this attribute is present.";
- }
-
- // NETCONF capabilities defined as features
- feature writable-running {
- description
- "NETCONF :writable-running capability;
- If the server advertises the :writable-running
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.2";
- }
-
- feature candidate {
- description
- "NETCONF :candidate capability;
- If the server advertises the :candidate
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.3";
- }
-
- feature confirmed-commit {
- if-feature candidate;
- description
- "NETCONF :confirmed-commit:1.1 capability;
- If the server advertises the :confirmed-commit:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
-
- reference "RFC 6241, Section 8.4";
- }
-
- feature rollback-on-error {
- description
- "NETCONF :rollback-on-error capability;
- If the server advertises the :rollback-on-error
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.5";
- }
-
- feature validate {
- description
- "NETCONF :validate:1.1 capability;
- If the server advertises the :validate:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.6";
- }
-
- feature startup {
- description
- "NETCONF :startup capability;
- If the server advertises the :startup
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.7";
- }
-
- feature url {
- description
- "NETCONF :url capability;
- If the server advertises the :url
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.8";
- }
-
- feature xpath {
- description
- "NETCONF :xpath capability;
- If the server advertises the :xpath
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.9";
- }
-
- // NETCONF Simple Types
-
- typedef session-id-type {
- type uint32 {
- range "1..max";
- }
- description
- "NETCONF Session Id";
- }
-
- typedef session-id-or-zero-type {
- type uint32;
- description
- "NETCONF Session Id or Zero to indicate none";
- }
- typedef error-tag-type {
- type enumeration {
- enum in-use {
- description
- "The request requires a resource that
- already is in use.";
- }
- enum invalid-value {
- description
- "The request specifies an unacceptable value for one
- or more parameters.";
- }
- enum too-big {
- description
- "The request or response (that would be generated) is
- too large for the implementation to handle.";
- }
- enum missing-attribute {
- description
- "An expected attribute is missing.";
- }
- enum bad-attribute {
- description
- "An attribute value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-attribute {
- description
- "An unexpected attribute is present.";
- }
- enum missing-element {
- description
- "An expected element is missing.";
- }
- enum bad-element {
- description
- "An element value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-element {
- description
- "An unexpected element is present.";
- }
- enum unknown-namespace {
- description
- "An unexpected namespace is present.";
- }
- enum access-denied {
- description
- "Access to the requested protocol operation or
- data model is denied because authorization failed.";
- }
- enum lock-denied {
- description
- "Access to the requested lock is denied because the
- lock is currently held by another entity.";
- }
- enum resource-denied {
- description
- "Request could not be completed because of
- insufficient resources.";
- }
- enum rollback-failed {
- description
- "Request to roll back some configuration change (via
- rollback-on-error or <discard-changes> operations)
- was not completed for some reason.";
-
- }
- enum data-exists {
- description
- "Request could not be completed because the relevant
- data model content already exists. For example,
- a 'create' operation was attempted on data that
- already exists.";
- }
- enum data-missing {
- description
- "Request could not be completed because the relevant
- data model content does not exist. For example,
- a 'delete' operation was attempted on
- data that does not exist.";
- }
- enum operation-not-supported {
- description
- "Request could not be completed because the requested
- operation is not supported by this implementation.";
- }
- enum operation-failed {
- description
- "Request could not be completed because the requested
- operation failed for some reason not covered by
- any other error condition.";
- }
- enum partial-operation {
- description
- "This error-tag is obsolete, and SHOULD NOT be sent
- by servers conforming to this document.";
- }
- enum malformed-message {
- description
- "A message could not be handled because it failed to
- be parsed correctly. For example, the message is not
- well-formed XML or it uses an invalid character set.";
- }
- }
- description "NETCONF Error Tag";
- reference "RFC 6241, Appendix A";
- }
-
- typedef error-severity-type {
- type enumeration {
- enum error {
- description "Error severity";
- }
- enum warning {
- description "Warning severity";
- }
- }
- description "NETCONF Error Severity";
- reference "RFC 6241, Section 4.3";
- }
-
- typedef edit-operation-type {
- type enumeration {
- enum merge {
- description
- "The configuration data identified by the
- element containing this attribute is merged
- with the configuration at the corresponding
- level in the configuration datastore identified
- by the target parameter.";
- }
- enum replace {
- description
- "The configuration data identified by the element
- containing this attribute replaces any related
- configuration in the configuration datastore
- identified by the target parameter. If no such
- configuration data exists in the configuration
- datastore, it is created. Unlike a
- <copy-config> operation, which replaces the
- entire target configuration, only the configuration
- actually present in the config parameter is affected.";
- }
- enum create {
- description
- "The configuration data identified by the element
- containing this attribute is added to the
- configuration if and only if the configuration
- data does not already exist in the configuration
- datastore. If the configuration data exists, an
- <rpc-error> element is returned with an
- <error-tag> value of 'data-exists'.";
- }
- enum delete {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if and only if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, an <rpc-error> element is returned with
- an <error-tag> value of 'data-missing'.";
- }
- enum remove {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, the 'remove' operation is silently ignored
- by the server.";
- }
- }
- default "merge";
- description "NETCONF 'operation' attribute values";
- reference "RFC 6241, Section 7.2";
- }
-
- // NETCONF Standard Protocol Operations
-
- rpc get-config {
- description
- "Retrieve all or part of a specified configuration.";
-
- reference "RFC 6241, Section 7.1";
-
- input {
- container source {
- description
- "Particular configuration to retrieve.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration to retrieve.";
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.
- This is optional-to-implement on the server because
- not all servers will support filtering for this
- datastore.";
- }
- }
- }
-
- anyxml filter {
- description
- "Subtree or XPath filter to use.";
- nc:get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the source datastore subset that matched
- the filter criteria (if any). An empty data container
- indicates that the request did not produce any results.";
- }
- }
- }
-
- rpc edit-config {
- description
- "The <edit-config> operation loads all or part of a specified
- configuration to the specified target configuration.";
-
- reference "RFC 6241, Section 7.2";
-
- input {
- container target {
- description
- "Particular configuration to edit.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config source.";
- }
- }
- }
-
- leaf default-operation {
- type enumeration {
- enum merge {
- description
- "The default operation is merge.";
- }
- enum replace {
- description
- "The default operation is replace.";
- }
- enum none {
- description
- "There is no default operation.";
- }
- }
- default "merge";
- description
- "The default operation to use.";
- }
-
- leaf test-option {
- if-feature validate;
- type enumeration {
- enum test-then-set {
- description
- "The server will test and then set if no errors.";
- }
- enum set {
- description
- "The server will set without a test first.";
- }
-
- enum test-only {
- description
- "The server will only test and not set, even
- if there are no errors.";
- }
- }
- default "test-then-set";
- description
- "The test option to use.";
- }
-
- leaf error-option {
- type enumeration {
- enum stop-on-error {
- description
- "The server will stop on errors.";
- }
- enum continue-on-error {
- description
- "The server may continue on errors.";
- }
- enum rollback-on-error {
- description
- "The server will roll back on errors.
- This value can only be used if the 'rollback-on-error'
- feature is supported.";
- }
- }
- default "stop-on-error";
- description
- "The error option to use.";
- }
-
- choice edit-content {
- mandatory true;
- description
- "The content for the edit operation.";
-
- anyxml config {
- description
- "Inline Config content.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "URL-based config content.";
- }
- }
- }
- }
-
- rpc copy-config {
- description
- "Create or replace an entire configuration datastore with the
- contents of another complete configuration datastore.";
-
- reference "RFC 6241, Section 7.3";
-
- input {
- container target {
- description
- "Particular configuration to copy to.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target of the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config target.
- This is optional-to-implement on the server.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
-
- container source {
- description
- "Particular configuration to copy from.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source for the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
- rpc delete-config {
- description
- "Delete a configuration datastore.";
-
- reference "RFC 6241, Section 7.4";
-
- input {
- container target {
- description
- "Particular configuration to delete.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to delete.";
-
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc lock {
- description
- "The lock operation allows the client to lock the configuration
- system of a device.";
-
- reference "RFC 6241, Section 7.5";
-
- input {
- container target {
- description
- "Particular configuration to lock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to lock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc unlock {
- description
- "The unlock operation is used to release a configuration lock,
- previously obtained with the 'lock' operation.";
-
- reference "RFC 6241, Section 7.6";
-
- input {
- container target {
- description
- "Particular configuration to unlock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to unlock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc get {
- description
- "Retrieve running configuration and device state information.";
-
- reference "RFC 6241, Section 7.7";
-
- input {
- anyxml filter {
- description
- "This parameter specifies the portion of the system
- configuration and state data to retrieve.";
- nc:get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the running datastore subset and/or state
- data that matched the filter criteria (if any).
- An empty data container indicates that the request did not
- produce any results.";
- }
- }
- }
-
- rpc close-session {
- description
- "Request graceful termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.8";
- }
-
- rpc kill-session {
- description
- "Force the termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.9";
-
- input {
- leaf session-id {
- type session-id-type;
- mandatory true;
- description
- "Particular session to kill.";
- }
- }
- }
-
- rpc commit {
- if-feature candidate;
-
- description
- "Commit the candidate configuration as the device's new
- current configuration.";
-
- reference "RFC 6241, Section 8.3.4.1";
-
- input {
- leaf confirmed {
- if-feature confirmed-commit;
- type empty;
- description
- "Requests a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf confirm-timeout {
- if-feature confirmed-commit;
- type uint32 {
- range "1..max";
- }
- units "seconds";
- default "600"; // 10 minutes
- description
- "The timeout interval for a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is used to make a confirmed commit
- persistent. A persistent confirmed commit is not aborted
- if the NETCONF session terminates. The only way to abort
- a persistent confirmed commit is to let the timer expire,
- or to use the <cancel-commit> operation.
-
- The value of this parameter is a token that must be given
- in the 'persist-id' parameter of <commit> or
- <cancel-commit> operations in order to confirm or cancel
- the persistent confirmed commit.
-
- The token should be a random string.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist-id {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is given in order to commit a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- }
- }
-
- rpc discard-changes {
- if-feature candidate;
-
- description
- "Revert the candidate configuration to the current
- running configuration.";
- reference "RFC 6241, Section 8.3.4.2";
- }
-
- rpc cancel-commit {
- if-feature confirmed-commit;
- description
- "This operation is used to cancel an ongoing confirmed commit.
- If the confirmed commit is persistent, the parameter
- 'persist-id' must be given, and it must match the value of the
- 'persist' parameter.";
- reference "RFC 6241, Section 8.4.4.1";
-
- input {
- leaf persist-id {
- type string;
- description
- "This parameter is given in order to cancel a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- }
- }
- }
-
- rpc validate {
- if-feature validate;
-
- description
- "Validates the contents of the specified configuration.";
-
- reference "RFC 6241, Section 8.6.4.1";
-
- input {
- container source {
- description
- "Particular configuration to validate.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source to validate.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-models</artifactId>
-
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <modules>
- <module>ietf-netconf</module>
- <module>ietf-netconf-monitoring</module>
- <module>ietf-netconf-notifications</module>
- <module>ietf-netconf-monitoring-extension</module>
- </modules>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
-
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <failsOnError>false</failsOnError>
- <failOnViolation>true</failOnViolation>
- <configLocation>checkstyle-logging.xml</configLocation>
- <consoleOutput>true</consoleOutput>
- <includeTestSourceDirectory>true</includeTestSourceDirectory>
- <sourceDirectory>${project.basedir}</sourceDirectory>
- <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang</includes>
- <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java</excludes>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>checkstyle-logging</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-api</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>protocol-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-/**
- * The only input for the start of a NETCONF session is hello-message.
- */
-public final class NetconfClientSessionPreferences extends NetconfSessionPreferences {
-
- private final NetconfMessage startExiMessage;
-
- public NetconfClientSessionPreferences(final NetconfMessage helloMessage,
- final NetconfMessage startExiMessage) {
- super(helloMessage);
- this.startExiMessage = startExiMessage;
- }
-
- /**
- * @return the startExiMessage
- */
- public NetconfMessage getStartExiMessage() {
- return startExiMessage;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-/**
- * This exception is thrown by
- * {@link NetconfSessionListener#onMessage(NetconfMessage)} to indicate fatal
- * communication problem after which the session should be closed.
- */
-public class NetconfDeserializerException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public NetconfDeserializerException(final String message) {
- super(message);
- }
-
- public NetconfDeserializerException(final String message, final Exception e) {
- super(message, e);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.w3c.dom.Document;
-
-/**
- * Checked exception to communicate an error that needs to be sent to the
- * netconf client.
- */
-public class NetconfDocumentedException extends DocumentedException {
-
- public NetconfDocumentedException(final String message) {
- super(message);
- }
-
- public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) {
- super(message, errorType, errorTag, errorSeverity);
- }
-
- public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
- super(message, errorType, errorTag, errorSeverity, errorInfo);
- }
-
- public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) {
- super(message, cause, errorType, errorTag, errorSeverity);
- }
-
- public NetconfDocumentedException(final String message, final Exception cause, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity, final Map<String, String> errorInfo) {
- super(message, cause, errorType, errorTag, errorSeverity, errorInfo);
- }
-
- public NetconfDocumentedException(DocumentedException e) {
- super(e.getMessage(), e.getErrorType(), e.getErrorTag(), e.getErrorSeverity(), e.getErrorInfo());
- }
-
- public static NetconfDocumentedException fromXMLDocument( Document fromDoc) {
- return new NetconfDocumentedException(DocumentedException.fromXMLDocument(fromDoc));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.api;
-
-/**
- * Session capable of exi communication according to http://tools.ietf.org/html/draft-varga-netconf-exi-capability-02
- */
-public interface NetconfExiSession {
-
- /**
- * Start exi communication with parameters included in start-exi message
- */
- void startExiCommunication(NetconfMessage startExiMessage);
-
- /**
- * Stop exi communication, initiated by stop-exi message
- */
- void stopExiCommunication();
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import java.io.StringWriter;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.w3c.dom.Document;
-
-/**
- * NetconfMessage represents a wrapper around org.w3c.dom.Document. Needed for
- * implementing ProtocolMessage interface.
- */
-public class NetconfMessage {
- private static final Transformer TRANSFORMER;
-
- static {
- final Transformer t;
- try {
- t = TransformerFactory.newInstance().newTransformer();
- } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
- throw new ExceptionInInitializerError(e);
- }
- t.setOutputProperty(OutputKeys.INDENT, "yes");
- t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
-
- TRANSFORMER = t;
- }
-
- private final Document doc;
-
- public NetconfMessage(final Document doc) {
- this.doc = doc;
- }
-
- public Document getDocument() {
- return this.doc;
- }
-
- @Override
- public String toString() {
- final StreamResult result = new StreamResult(new StringWriter());
- final DOMSource source = new DOMSource(doc.getDocumentElement());
-
- try {
- // Slight critical section is a tradeoff. This should be reasonably fast.
- synchronized (TRANSFORMER) {
- TRANSFORMER.transform(source, result);
- }
- } catch (TransformerException e) {
- throw new IllegalStateException("Failed to encode document", e);
- }
-
- return result.getWriter().toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-
-public interface NetconfServerDispatcher {
-
- ChannelFuture createServer(InetSocketAddress address);
-
- ChannelFuture createLocalServer(LocalAddress address);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-/**
- * The only input for the start of a NETCONF session is hello-message.
- */
-public final class NetconfServerSessionPreferences extends NetconfSessionPreferences {
-
- private final long sessionId;
-
- public NetconfServerSessionPreferences(final NetconfMessage helloMessage,
- long sessionId) {
- super(helloMessage);
- this.sessionId = sessionId;
- }
-
- public long getSessionId() {
- return sessionId;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.api;
-
-import io.netty.channel.ChannelFuture;
-import org.opendaylight.protocol.framework.ProtocolSession;
-
-public interface NetconfSession extends ProtocolSession<NetconfMessage> {
-
- ChannelFuture sendMessage(NetconfMessage message);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import org.opendaylight.protocol.framework.SessionListener;
-
-public interface NetconfSessionListener<S extends NetconfSession> extends SessionListener<NetconfMessage, S, NetconfTerminationReason> {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-public class NetconfSessionPreferences {
-
- private final NetconfMessage helloMessage;
-
- public NetconfSessionPreferences(final NetconfMessage helloMessage) {
- this.helloMessage = helloMessage;
- }
-
- /**
- * @return the helloMessage
- */
- public NetconfMessage getHelloMessage() {
- return this.helloMessage;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import org.opendaylight.protocol.framework.TerminationReason;
-
-public class NetconfTerminationReason implements TerminationReason {
-
- private final String reason;
-
- public NetconfTerminationReason(String reason) {
- this.reason = reason;
- }
-
- @Override
- public String getErrorMessage() {
- return reason;
- }
-
- @Override
- public String toString() {
- return reason;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.monitoring;
-
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-
-public interface CapabilityListener {
-
- void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.api.monitoring;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-
-public interface NetconfManagementSession {
-
- Session toManagementSession();
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.api.monitoring;
-
-import com.google.common.base.Optional;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
-
-public interface NetconfMonitoringService extends CapabilityListener, SessionListener {
-
- Sessions getSessions();
-
- Schemas getSchemas();
-
- String getSchemaForCapability(String moduleName, Optional<String> revision);
-
- Capabilities getCapabilities();
-
- /**
- * Allows push based state information transfer. After the listener is registered, current state is pushed to the listener.
- */
- AutoCloseable registerListener(MonitoringListener listener);
-
- interface MonitoringListener {
-
- // TODO more granular updates would make sense
- void onStateChanged(NetconfState state);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.monitoring;
-
-/**
- * Created by mmarsale on 13.2.2015.
- */
-public interface SessionListener {
- void onSessionUp(NetconfManagementSession session);
-
- void onSessionDown(NetconfManagementSession session);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api.util;
-
-/**
- * These constants mark operation service factories that are auto wired with netconf endpoint
- * for config subsystem
- */
-public final class NetconfConstants {
- /*
- * TODO define marker interface in mapping-api that the serviceFactories in cofing subsystem
- * will implement so we can check for services with instanceof instead of constants
- */
- public static final String SERVICE_NAME = "name";
- public static final String CONFIG_NETCONF_CONNECTOR = "config-netconf-connector";
- public static final String NETCONF_MONITORING = "ietf-netconf-monitoring";
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.api.xml;
-
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-
-public final class XmlNetconfConstants {
-
- private XmlNetconfConstants() {}
-
- public static final String CAPABILITY = "capability";
- public static final String CAPABILITIES = "capabilities";
- public static final String COMMIT = "commit";
- public static final String OPERATION_ATTR_KEY = "operation";
- public static final String CONFIG_KEY = "config";
- public static final String DATA_KEY = "data";
- public static final String OK = "ok";
- public static final String FILTER = "filter";
- public static final String SOURCE_KEY = "source";
- public static final String RPC_KEY = "rpc";
- public static final String NOTIFICATION_ELEMENT_NAME = "notification";
-
- public static final String MESSAGE_ID = "message-id";
- public static final String SESSION_ID = "session-id";
-
- public static final String GET = "get";
- public static final String GET_CONFIG = "get-config";
-
- public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = XmlMappingConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
- public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0";
- public static final String URN_IETF_PARAMS_NETCONF_BASE_1_1 = "urn:ietf:params:netconf:base:1.1";
- public static final String URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0 = "urn:ietf:params:xml:ns:netconf:exi:1.0";
-
- public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 = "urn:ietf:params:netconf:capability:exi:1.0";
- public static final String URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
-}
+++ /dev/null
-module netconf-northbound {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound";
- prefix "nn";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- netconf northbound server API";
-
- revision "2015-01-14" {
- description
- "Initial revision.";
- }
-
- identity netconf-server-dispatcher {
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.api.NetconfServerDispatcher";
- }
-
- identity netconf-server-monitoring {
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService";
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import java.util.Iterator;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-
-/**
- * Unit tests for NetconfDocumentedException.
- *
- * @author Thomas Pantelis
- */
-public class NetconfDocumentedExceptionTest {
-
- private XPath xpath;
-
- @Before
- public void setUp() throws Exception {
- XPathFactory xPathfactory = XPathFactory.newInstance();
- xpath = xPathfactory.newXPath();
- xpath.setNamespaceContext( new NamespaceContext() {
- @Override
- public Iterator<?> getPrefixes( String namespaceURI ) {
- return Collections.singletonList( "netconf" ).iterator();
- }
-
- @Override
- public String getPrefix( String namespaceURI ) {
- return "netconf";
- }
-
- @Override
- public String getNamespaceURI( String prefix ) {
- return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
- }
- } );
- }
-
- @Test
- public void testToAndFromXMLDocument() throws XPathExpressionException {
- String errorMessage = "mock error message";
- DocumentedException ex = new NetconfDocumentedException( errorMessage, null,
- DocumentedException.ErrorType.protocol,
- DocumentedException.ErrorTag.data_exists,
- DocumentedException.ErrorSeverity.warning,
- ImmutableMap.of( "foo", "bar" ) );
-
- Document doc = ex.toXMLDocument();
- assertNotNull( "Document is null", doc );
-
- Node rootNode = doc.getDocumentElement();
-
- assertEquals( "getNamespaceURI", "urn:ietf:params:xml:ns:netconf:base:1.0", rootNode.getNamespaceURI() );
- assertEquals( "getLocalName", "rpc-reply", rootNode.getLocalName() );
-
- Node rpcErrorNode = getNode( "/netconf:rpc-reply/netconf:rpc-error", rootNode );
- assertNotNull( "rpc-error not found", rpcErrorNode );
-
- Node errorTypeNode = getNode( "netconf:error-type", rpcErrorNode );
- assertNotNull( "error-type not found", errorTypeNode );
- assertEquals( "error-type", DocumentedException.ErrorType.protocol.getTagValue(),
- errorTypeNode.getTextContent() );
-
- Node errorTagNode = getNode( "netconf:error-tag", rpcErrorNode );
- assertNotNull( "error-tag not found", errorTagNode );
- assertEquals( "error-tag", DocumentedException.ErrorTag.data_exists.getTagValue(),
- errorTagNode.getTextContent() );
-
- Node errorSeverityNode = getNode( "netconf:error-severity", rpcErrorNode );
- assertNotNull( "error-severity not found", errorSeverityNode );
- assertEquals( "error-severity", DocumentedException.ErrorSeverity.warning.getTagValue(),
- errorSeverityNode.getTextContent() );
-
- Node errorInfoNode = getNode( "netconf:error-info/netconf:foo", rpcErrorNode );
- assertNotNull( "foo not found", errorInfoNode );
- assertEquals( "foo", "bar", errorInfoNode.getTextContent() );
-
- Node errorMsgNode = getNode( "netconf:error-message", rpcErrorNode );
- assertNotNull( "error-message not found", errorMsgNode );
- assertEquals( "error-message", errorMessage, errorMsgNode.getTextContent() );
-
- // Test fromXMLDocument
-
- ex = DocumentedException.fromXMLDocument( doc );
-
- assertNotNull( "NetconfDocumentedException is null", ex );
- assertEquals( "getErrorSeverity", DocumentedException.ErrorSeverity.warning, ex.getErrorSeverity() );
- assertEquals( "getErrorTag", DocumentedException.ErrorTag.data_exists, ex.getErrorTag() );
- assertEquals( "getErrorType", DocumentedException.ErrorType.protocol, ex.getErrorType() );
- assertEquals( "getLocalizedMessage", errorMessage, ex.getLocalizedMessage() );
- assertEquals( "getErrorInfo", ImmutableMap.of( "foo", "bar" ), ex.getErrorInfo() );
- }
-
- @SuppressWarnings("unchecked")
- <T> T getNode( String xpathExp, Node node ) throws XPathExpressionException {
- return (T)xpath.compile( xpathExp ).evaluate( node, XPathConstants.NODE );
- }
-}
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-artifacts</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
-
- <properties>
- <mdsal.version>1.3.0-SNAPSHOT</mdsal.version>
- </properties>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-config-dispatcher</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-netconf-connector</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-persister-impl</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-auth</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-cli</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-config</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-connector-config</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mdsal-config</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>mdsal-netconf-connector</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-monitoring</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>mdsal-netconf-monitoring</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>mdsal-netconf-monitoring</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-ssh</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-tcp</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-testtool</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mdsal-config</artifactId>
- <version>${project.version}</version>
- <classifier>config</classifier>
- <type>xml</type>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>messagebus-netconf</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>features-netconf-connector</artifactId>
- <version>${mdsal.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-notifications</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-notifications-impl</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-ssh</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>features-netconf</artifactId>
- <version>${project.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-</project>
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../</relativePath>
- </parent>
- <artifactId>netconf-auth</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>config</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-jmx-generator-plugin</artifactId>
- <version>${config.version}</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.auth;
-
-public class AuthConstants {
-
- /**
- * This property should be set for every implementation of AuthService published to OSGi.
- * Netconf SSH will pick the service with highest preference in case of multiple services present in OSGi.
- */
- public static final String SERVICE_PREFERENCE_KEY = "preference";
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.auth;
-
-/**
- * Authentication Service definition for netconf.
- */
-public interface AuthProvider {
-
- /**
- * Authenticate user by username/password.
- *
- * @param username username
- * @param password password
- * @return true if authentication is successful, false otherwise
- */
- boolean authenticated(String username, String password);
-
-}
+++ /dev/null
-module netconf-auth {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:auth";
- prefix "na";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- netconf northbound server API";
-
- revision "2015-07-15" {
- description
- "Initial revision.";
- }
-
- identity netconf-auth-provider {
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.auth.AuthProvider";
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-client</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>protocol-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.controller.netconf.client.*,</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client;
-
-import io.netty.util.concurrent.Future;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-
-public interface NetconfClientDispatcher {
-
- /**
- *
- * Create netconf client. Network communication has to be set up based on network protocol specified in clientConfiguration
- *
- * @param clientConfiguration
- * @return netconf client based on provided configuration
- */
- Future<NetconfClientSession> createClient(NetconfClientConfiguration clientConfiguration);
-
- Future<Void> createReconnectingClient(NetconfReconnectingClientConfiguration clientConfiguration);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.Promise;
-import java.io.Closeable;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener>
- implements NetconfClientDispatcher, Closeable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
-
- private final Timer timer;
-
- public NetconfClientDispatcherImpl(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
- super(bossGroup, workerGroup);
- this.timer = timer;
- }
-
- protected Timer getTimer() {
- return timer;
- }
-
- @Override
- public Future<NetconfClientSession> createClient(final NetconfClientConfiguration clientConfiguration) {
- switch (clientConfiguration.getProtocol()) {
- case TCP:
- return createTcpClient(clientConfiguration);
- case SSH:
- return createSshClient(clientConfiguration);
- }
- throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
- }
-
- @Override
- public Future<Void> createReconnectingClient(final NetconfReconnectingClientConfiguration clientConfiguration) {
- switch (clientConfiguration.getProtocol()) {
- case TCP:
- return createReconnectingTcpClient(clientConfiguration);
- case SSH:
- return createReconnectingSshClient(clientConfiguration);
- default:
- throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
- }
- }
-
- private Future<NetconfClientSession> createTcpClient(final NetconfClientConfiguration currentConfiguration) {
- LOG.debug("Creating TCP client with configuration: {}", currentConfiguration);
- return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
- new PipelineInitializer<NetconfClientSession>() {
-
- @Override
- public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
- initialize(ch, promise);
- }
-
- private void initialize(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
- new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration), currentConfiguration
- .getSessionListener()).initialize(ch, promise);
- }
- });
- }
-
- private Future<Void> createReconnectingTcpClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
- LOG.debug("Creating reconnecting TCP client with configuration: {}", currentConfiguration);
- final TcpClientChannelInitializer init = new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
- currentConfiguration.getSessionListener());
-
- return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(),
- currentConfiguration.getReconnectStrategy(), new PipelineInitializer<NetconfClientSession>() {
- @Override
- public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
- init.initialize(ch, promise);
- }
- });
- }
-
- private Future<NetconfClientSession> createSshClient(final NetconfClientConfiguration currentConfiguration) {
- LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
- return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
- new PipelineInitializer<NetconfClientSession>() {
-
- @Override
- public void initializeChannel(final SocketChannel ch,
- final Promise<NetconfClientSession> sessionPromise) {
- new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
- getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
- .initialize(ch, sessionPromise);
- }
-
- });
- }
-
- private Future<Void> createReconnectingSshClient(final NetconfReconnectingClientConfiguration currentConfiguration) {
- LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
- final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
- getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener());
-
- return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration.getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
- new PipelineInitializer<NetconfClientSession>() {
- @Override
- public void initializeChannel(final SocketChannel ch, final Promise<NetconfClientSession> promise) {
- init.initialize(ch, promise);
- }
- });
- }
-
- protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
- return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
- cfg.getConnectionTimeoutMillis());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import io.netty.channel.Channel;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.util.Collection;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.nettyutil.AbstractNetconfSession;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfClientSession extends AbstractNetconfSession<NetconfClientSession, NetconfClientSessionListener> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSession.class);
- private final Collection<String> capabilities;
-
- /**
- * Construct a new session.
- *
- * @param sessionListener
- * @param channel
- * @param sessionId
- * @param capabilities set of advertised capabilities. Expected to be immutable.
- */
- public NetconfClientSession(final NetconfClientSessionListener sessionListener, final Channel channel, final long sessionId,
- final Collection<String> capabilities) {
- super(sessionListener, channel, sessionId);
- this.capabilities = capabilities;
- LOG.debug("Client Session {} created", this);
- }
-
- public Collection<String> getServerCapabilities() {
- return capabilities;
- }
-
- @Override
- protected NetconfClientSession thisInstance() {
- return this;
- }
-
- @Override
- protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {
- // TODO used only in negotiator, client supports only auto start-exi
- replaceMessageDecoder(decoder);
- replaceMessageEncoder(encoder);
- }
-
- @Override
- public void stopExiCommunication() {
- // TODO never used, Netconf client does not support stop-exi
- replaceMessageDecoder(new NetconfXMLToMessageDecoder());
- replaceMessageEncoder(new NetconfMessageToXMLEncoder());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client;
-
-import org.opendaylight.controller.netconf.api.NetconfSessionListener;
-
-public interface NetconfClientSessionListener extends NetconfSessionListener<NetconfClientSession> {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
-import java.util.Collection;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.controller.netconf.nettyutil.AbstractNetconfSessionNegotiator;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class NetconfClientSessionNegotiator extends
- AbstractNetconfSessionNegotiator<NetconfClientSessionPreferences, NetconfClientSession, NetconfClientSessionListener>
-{
- private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSessionNegotiator.class);
-
- private static final XPathExpression sessionIdXPath = XMLNetconfUtil
- .compileXPath("/netconf:hello/netconf:session-id");
-
- private static final XPathExpression sessionIdXPathNoNamespace = XMLNetconfUtil
- .compileXPath("/hello/session-id");
-
- private static final String EXI_1_0_CAPABILITY_MARKER = "exi:1.0";
-
- protected NetconfClientSessionNegotiator(final NetconfClientSessionPreferences sessionPreferences,
- final Promise<NetconfClientSession> promise,
- final Channel channel,
- final Timer timer,
- final NetconfClientSessionListener sessionListener,
- final long connectionTimeoutMillis) {
- super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis);
- }
-
- @Override
- protected void handleMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
- final NetconfClientSession session = getSessionForHelloMessage(netconfMessage);
- replaceHelloMessageInboundHandler(session);
-
- // If exi should be used, try to initiate exi communication
- // Call negotiationSuccessFul after exi negotiation is finished successfully or not
- if (shouldUseExi(netconfMessage)) {
- LOG.debug("Netconf session {} should use exi.", session);
- NetconfStartExiMessage startExiMessage = (NetconfStartExiMessage) sessionPreferences.getStartExiMessage();
- tryToInitiateExi(session, startExiMessage);
- } else {
- // Exi is not supported, release session immediately
- LOG.debug("Netconf session {} isn't capable of using exi.", session);
- negotiationSuccessful(session);
- }
- }
-
- /**
- * Initiates exi communication by sending start-exi message and waiting for positive/negative response.
- *
- * @param startExiMessage
- */
- void tryToInitiateExi(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
- channel.pipeline().addAfter(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER,
- ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER,
- new ExiConfirmationInboundHandler(session, startExiMessage));
-
- session.sendMessage(startExiMessage).addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(final ChannelFuture f) {
- if (!f.isSuccess()) {
- LOG.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause());
- channel.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
- } else {
- LOG.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this);
- }
- }
- });
- }
-
- private boolean shouldUseExi(final NetconfHelloMessage helloMsg) {
- return containsExi10Capability(helloMsg.getDocument())
- && containsExi10Capability(sessionPreferences.getHelloMessage().getDocument());
- }
-
- private static boolean containsExi10Capability(final Document doc) {
- final NodeList nList = doc.getElementsByTagName(XmlNetconfConstants.CAPABILITY);
- for (int i = 0; i < nList.getLength(); i++) {
- if (nList.item(i).getTextContent().contains(EXI_1_0_CAPABILITY_MARKER)) {
- return true;
- }
- }
- return false;
- }
-
- private static long extractSessionId(final Document doc) {
- String textContent = getSessionIdWithXPath(doc, sessionIdXPath);
- if (Strings.isNullOrEmpty(textContent)) {
- textContent = getSessionIdWithXPath(doc, sessionIdXPathNoNamespace);
- if (Strings.isNullOrEmpty(textContent)) {
- throw new IllegalStateException("Session id not received from server, hello message: " + XmlUtil.toString(doc));
- }
- }
-
- return Long.valueOf(textContent);
- }
-
- private static String getSessionIdWithXPath(final Document doc, final XPathExpression sessionIdXPath) {
- final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE);
- return sessionIdNode != null ? sessionIdNode.getTextContent() : null;
- }
-
- @Override
- protected NetconfClientSession getSession(final NetconfClientSessionListener sessionListener, final Channel channel,
- final NetconfHelloMessage message) throws NetconfDocumentedException {
- long sessionId = extractSessionId(message.getDocument());
-
- // Copy here is important: it disconnects the strings from the document
- Collection<String> capabilities = ImmutableList.copyOf(NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()));
-
- // FIXME: scalability: we could instantiate a cache to share the same collections
- return new NetconfClientSession(sessionListener, channel, sessionId, capabilities);
- }
-
- /**
- * Handler to process response for start-exi message
- */
- private final class ExiConfirmationInboundHandler extends ChannelInboundHandlerAdapter {
- private static final String EXI_CONFIRMED_HANDLER = "exiConfirmedHandler";
-
- private final NetconfClientSession session;
- private final NetconfStartExiMessage startExiMessage;
-
- ExiConfirmationInboundHandler(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) {
- this.session = session;
- this.startExiMessage = startExiMessage;
- }
-
- @Override
- public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
- ctx.pipeline().remove(ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER);
-
- NetconfMessage netconfMessage = (NetconfMessage) msg;
-
- // Ok response to start-exi, try to add exi handlers
- if (NetconfMessageUtil.isOKMessage(netconfMessage)) {
- LOG.trace("Positive response on start-exi call received on session {}", session);
- try {
- session.startExiCommunication(startExiMessage);
- } catch (RuntimeException e) {
- // Unable to add exi, continue without exi
- LOG.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e);
- }
-
- // Error response
- } else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) {
- LOG.warn(
- "Error response to start-exi message {}, Communication will continue without exi on session {}",
- netconfMessage, session);
-
- // Unexpected response to start-exi, throwing message away, continue without exi
- } else {
- LOG.warn("Unexpected response to start-exi message, should be ok, was {}, " +
- "Communication will continue without exi and response message will be thrown away on session {}",
- netconfMessage, session);
- }
-
- negotiationSuccessful(session);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import io.netty.channel.Channel;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
-import java.util.Set;
-import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.EXIOptions;
-import org.openexi.proc.common.EXIOptionsException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfMessage, NetconfClientSession, NetconfClientSessionListener> {
-
- public static final Set<String> EXI_CLIENT_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);
-
- public static final Set<String> LEGACY_EXI_CLIENT_CAPABILITIES = ImmutableSet.of(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0);
-
- public static final Set<String> DEFAULT_CLIENT_CAPABILITIES = ImmutableSet.of(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
-
- public static final Set<String> LEGACY_FRAMING_CLIENT_CAPABILITIES = ImmutableSet.of(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0);
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfClientSessionNegotiatorFactory.class);
- private static final String START_EXI_MESSAGE_ID = "default-start-exi";
- private static final EXIOptions DEFAULT_OPTIONS;
-
- private final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader;
- private final long connectionTimeoutMillis;
- private final Timer timer;
- private final EXIOptions options;
-
- static {
- final EXIOptions opts = new EXIOptions();
- try {
- opts.setPreserveDTD(true);
- opts.setPreserveNS(true);
- opts.setPreserveLexicalValues(true);
- opts.setAlignmentType(AlignmentType.byteAligned);
- } catch (EXIOptionsException e) {
- throw new ExceptionInInitializerError(e);
- }
-
- DEFAULT_OPTIONS = opts;
- }
-
- private final Set<String> clientCapabilities;
-
- public NetconfClientSessionNegotiatorFactory(final Timer timer,
- final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
- final long connectionTimeoutMillis) {
- this(timer, additionalHeader, connectionTimeoutMillis, DEFAULT_OPTIONS);
- }
-
- public NetconfClientSessionNegotiatorFactory(final Timer timer,
- final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
- final long connectionTimeoutMillis, final Set<String> capabilities) {
- this(timer, additionalHeader, connectionTimeoutMillis, DEFAULT_OPTIONS, capabilities);
-
- }
-
- public NetconfClientSessionNegotiatorFactory(final Timer timer,
- final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
- final long connectionTimeoutMillis, final EXIOptions exiOptions) {
- this(timer, additionalHeader, connectionTimeoutMillis, exiOptions, EXI_CLIENT_CAPABILITIES);
- }
-
- public NetconfClientSessionNegotiatorFactory(final Timer timer,
- final Optional<NetconfHelloMessageAdditionalHeader> additionalHeader,
- final long connectionTimeoutMillis, final EXIOptions exiOptions, final Set<String> capabilities) {
- this.timer = Preconditions.checkNotNull(timer);
- this.additionalHeader = additionalHeader;
- this.connectionTimeoutMillis = connectionTimeoutMillis;
- this.options = exiOptions;
- this.clientCapabilities = capabilities;
- }
-
- @Override
- public SessionNegotiator<NetconfClientSession> getSessionNegotiator(final SessionListenerFactory<NetconfClientSessionListener> sessionListenerFactory,
- final Channel channel,
- final Promise<NetconfClientSession> promise) {
-
- NetconfMessage startExiMessage = NetconfStartExiMessage.create(options, START_EXI_MESSAGE_ID);
- NetconfHelloMessage helloMessage = null;
- try {
- helloMessage = NetconfHelloMessage.createClientHello(clientCapabilities, additionalHeader);
- } catch (NetconfDocumentedException e) {
- LOG.error("Unable to create client hello message with capabilities {} and additional handler {}", clientCapabilities,additionalHeader);
- throw new IllegalStateException(e);
- }
-
- NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage, startExiMessage);
- return new NetconfClientSessionNegotiator(proposal, promise, channel, timer,
- sessionListenerFactory.getSessionListener(),connectionTimeoutMillis);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Preconditions;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import io.netty.util.concurrent.Promise;
-import java.util.ArrayDeque;
-import java.util.Queue;
-import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SimpleNetconfClientSessionListener implements NetconfClientSessionListener {
- private static final class RequestEntry {
- private final Promise<NetconfMessage> promise;
- private final NetconfMessage request;
-
- public RequestEntry(Promise<NetconfMessage> future, NetconfMessage request) {
- this.promise = Preconditions.checkNotNull(future);
- this.request = Preconditions.checkNotNull(request);
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(SimpleNetconfClientSessionListener.class);
-
- @GuardedBy("this")
- private final Queue<RequestEntry> requests = new ArrayDeque<>();
-
- @GuardedBy("this")
- private NetconfClientSession clientSession;
-
- @GuardedBy("this")
- private void dispatchRequest() {
- while (!requests.isEmpty()) {
- final RequestEntry e = requests.peek();
- if (e.promise.setUncancellable()) {
- LOG.debug("Sending message {}", e.request);
- clientSession.sendMessage(e.request);
- break;
- }
-
- LOG.debug("Message {} has been cancelled, skipping it", e.request);
- requests.poll();
- }
- }
-
- @Override
- public final synchronized void onSessionUp(NetconfClientSession clientSession) {
- this.clientSession = Preconditions.checkNotNull(clientSession);
- LOG.debug("Client session {} went up", clientSession);
- dispatchRequest();
- }
-
- private synchronized void tearDown(final Exception cause) {
- final RequestEntry e = requests.poll();
- if (e != null) {
- e.promise.setFailure(cause);
- }
-
- this.clientSession = null;
- }
-
- @Override
- public final void onSessionDown(NetconfClientSession clientSession, Exception e) {
- LOG.debug("Client Session {} went down unexpectedly", clientSession, e);
- tearDown(e);
- }
-
- @Override
- public final void onSessionTerminated(NetconfClientSession clientSession,
- NetconfTerminationReason netconfTerminationReason) {
- LOG.debug("Client Session {} terminated, reason: {}", clientSession,
- netconfTerminationReason.getErrorMessage());
- tearDown(new RuntimeException(netconfTerminationReason.getErrorMessage()));
- }
-
- @Override
- public synchronized void onMessage(NetconfClientSession session, NetconfMessage message) {
- LOG.debug("New message arrived: {}", message);
-
- final RequestEntry e = requests.poll();
- if (e != null) {
- e.promise.setSuccess(message);
- dispatchRequest();
- } else {
- LOG.info("Ignoring unsolicited message {}", message);
- }
- }
-
- public final synchronized Future<NetconfMessage> sendRequest(NetconfMessage message) {
- final RequestEntry req = new RequestEntry(GlobalEventExecutor.INSTANCE.<NetconfMessage>newPromise(), message);
-
- requests.add(req);
- if (clientSession != null) {
- dispatchRequest();
- }
-
- return req.promise;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client;
-
-import io.netty.channel.Channel;
-import io.netty.util.concurrent.Promise;
-import java.io.IOException;
-import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-
-final class SshClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
-
- private final AuthenticationHandler authenticationHandler;
- private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
- private final NetconfClientSessionListener sessionListener;
-
- public SshClientChannelInitializer(final AuthenticationHandler authHandler,
- final NetconfClientSessionNegotiatorFactory negotiatorFactory,
- final NetconfClientSessionListener sessionListener) {
- this.authenticationHandler = authHandler;
- this.negotiatorFactory = negotiatorFactory;
- this.sessionListener = sessionListener;
- }
-
- @Override
- public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
- try {
- // ssh handler has to be the first handler in pipeline
- ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler));
- super.initialize(ch,promise);
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- protected void initializeSessionNegotiator(final Channel ch,
- final Promise<NetconfClientSession> promise) {
- ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
- negotiatorFactory.getSessionNegotiator(new SessionListenerFactory<NetconfClientSessionListener>() {
- @Override
- public NetconfClientSessionListener getSessionListener() {
- return sessionListener;
- }
- }, ch, promise));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client;
-
-import io.netty.channel.Channel;
-import io.netty.util.concurrent.Promise;
-import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-
-class TcpClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
-
- private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
- private final NetconfClientSessionListener sessionListener;
-
- TcpClientChannelInitializer(final NetconfClientSessionNegotiatorFactory negotiatorFactory,
- final NetconfClientSessionListener sessionListener) {
- this.negotiatorFactory = negotiatorFactory;
- this.sessionListener = sessionListener;
- }
-
- @Override
- protected void initializeSessionNegotiator(final Channel ch, final Promise<NetconfClientSession> promise) {
- ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
- negotiatorFactory.getSessionNegotiator(new SessionListenerFactory<NetconfClientSessionListener>() {
- @Override
- public NetconfClientSessionListener getSessionListener() {
- return sessionListener;
- }
- }, ch, promise));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client.conf;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-
-public class NetconfClientConfiguration {
-
- private final NetconfClientProtocol clientProtocol;
- private final InetSocketAddress address;
- private final Long connectionTimeoutMillis;
-
- private final NetconfHelloMessageAdditionalHeader additionalHeader;
- private final NetconfClientSessionListener sessionListener;
-
- private final ReconnectStrategy reconnectStrategy;
-
- private final AuthenticationHandler authHandler;
-
- NetconfClientConfiguration(final NetconfClientProtocol protocol, final InetSocketAddress address, final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader, final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy, final AuthenticationHandler authHandler) {
- this.address = address;
- this.connectionTimeoutMillis = connectionTimeoutMillis;
- this.additionalHeader = additionalHeader;
- this.sessionListener = sessionListener;
- this.clientProtocol = protocol;
- this.reconnectStrategy = reconnectStrategy;
- this.authHandler = authHandler;
- validateConfiguration();
- }
-
- public final InetSocketAddress getAddress() {
- return address;
- }
-
- public final Long getConnectionTimeoutMillis() {
- return connectionTimeoutMillis;
- }
-
- public final Optional<NetconfHelloMessageAdditionalHeader> getAdditionalHeader() {
- return Optional.fromNullable(additionalHeader);
- }
-
- public final NetconfClientSessionListener getSessionListener() {
- return sessionListener;
- }
-
- public final ReconnectStrategy getReconnectStrategy() {
- return reconnectStrategy;
- }
-
- public final AuthenticationHandler getAuthHandler() {
- return authHandler;
- }
-
- public NetconfClientProtocol getProtocol() {
- return clientProtocol;
- }
-
- private void validateConfiguration() {
- Preconditions.checkNotNull(clientProtocol, " ");
- switch (clientProtocol) {
- case SSH:
- validateSshConfiguration();
- // Fall through intentional (ssh validation is a superset of tcp validation)
- case TCP:
- validateTcpConfiguration();
- }
- }
-
- protected void validateSshConfiguration() {
- Preconditions.checkNotNull(authHandler, "authHandler");
- }
-
- protected void validateTcpConfiguration() {
- Preconditions.checkNotNull(address, "address");
- Preconditions.checkNotNull(clientProtocol, "clientProtocol");
- Preconditions.checkNotNull(connectionTimeoutMillis, "connectionTimeoutMillis");
- Preconditions.checkNotNull(sessionListener, "sessionListener");
- Preconditions.checkNotNull(reconnectStrategy, "reconnectStrategy");
- }
-
- @Override
- public final String toString() {
- return buildToStringHelper().toString();
- }
-
- protected ToStringHelper buildToStringHelper() {
- return MoreObjects.toStringHelper(this)
- .add("address", address)
- .add("connectionTimeoutMillis", connectionTimeoutMillis)
- .add("additionalHeader", additionalHeader)
- .add("sessionListener", sessionListener)
- .add("reconnectStrategy", reconnectStrategy)
- .add("clientProtocol", clientProtocol)
- .add("authHandler", authHandler);
- }
-
- public static enum NetconfClientProtocol {
- TCP, SSH
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client.conf;
-
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-
-public class NetconfClientConfigurationBuilder {
-
- public static final int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 5000;
- public static final NetconfClientConfiguration.NetconfClientProtocol DEFAULT_CLIENT_PROTOCOL = NetconfClientConfiguration.NetconfClientProtocol.TCP;
-
- private InetSocketAddress address;
- private long connectionTimeoutMillis = DEFAULT_CONNECTION_TIMEOUT_MILLIS;
- private NetconfHelloMessageAdditionalHeader additionalHeader;
- private NetconfClientSessionListener sessionListener;
- private ReconnectStrategy reconnectStrategy;
- private AuthenticationHandler authHandler;
- private NetconfClientConfiguration.NetconfClientProtocol clientProtocol = DEFAULT_CLIENT_PROTOCOL;
-
- protected NetconfClientConfigurationBuilder() {
- }
-
- public static NetconfClientConfigurationBuilder create() {
- return new NetconfClientConfigurationBuilder();
- }
-
- public NetconfClientConfigurationBuilder withAddress(final InetSocketAddress address) {
- this.address = address;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withConnectionTimeoutMillis(final long connectionTimeoutMillis) {
- this.connectionTimeoutMillis = connectionTimeoutMillis;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withProtocol(final NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
- this.clientProtocol = clientProtocol;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
- this.additionalHeader = additionalHeader;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withSessionListener(final NetconfClientSessionListener sessionListener) {
- this.sessionListener = sessionListener;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withReconnectStrategy(final ReconnectStrategy reconnectStrategy) {
- this.reconnectStrategy = reconnectStrategy;
- return this;
- }
-
- public NetconfClientConfigurationBuilder withAuthHandler(final AuthenticationHandler authHandler) {
- this.authHandler = authHandler;
- return this;
- }
-
- final InetSocketAddress getAddress() {
- return address;
- }
-
- final long getConnectionTimeoutMillis() {
- return connectionTimeoutMillis;
- }
-
- final NetconfHelloMessageAdditionalHeader getAdditionalHeader() {
- return additionalHeader;
- }
-
- final NetconfClientSessionListener getSessionListener() {
- return sessionListener;
- }
-
- final ReconnectStrategy getReconnectStrategy() {
- return reconnectStrategy;
- }
-
- final AuthenticationHandler getAuthHandler() {
- return authHandler;
- }
-
- final NetconfClientConfiguration.NetconfClientProtocol getProtocol() {
- return clientProtocol;
- }
-
- public NetconfClientConfiguration build() {
- return new NetconfClientConfiguration(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy, authHandler);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client.conf;
-
-import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.base.Preconditions;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-
-public final class NetconfReconnectingClientConfiguration extends NetconfClientConfiguration {
-
- private final ReconnectStrategyFactory connectStrategyFactory;
-
- NetconfReconnectingClientConfiguration(final NetconfClientProtocol clientProtocol, final InetSocketAddress address,
- final Long connectionTimeoutMillis, final NetconfHelloMessageAdditionalHeader additionalHeader,
- final NetconfClientSessionListener sessionListener, final ReconnectStrategy reconnectStrategy,
- final ReconnectStrategyFactory connectStrategyFactory, final AuthenticationHandler authHandler) {
- super(clientProtocol, address, connectionTimeoutMillis, additionalHeader, sessionListener, reconnectStrategy,
- authHandler);
- this.connectStrategyFactory = connectStrategyFactory;
- validateReconnectConfiguration();
- }
-
- public ReconnectStrategyFactory getConnectStrategyFactory() {
- return connectStrategyFactory;
- }
-
- private void validateReconnectConfiguration() {
- Preconditions.checkNotNull(connectStrategyFactory);
- }
-
- @Override
- protected ToStringHelper buildToStringHelper() {
- return super.buildToStringHelper().add("connectStrategyFactory", connectStrategyFactory);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.client.conf;
-
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-
-public class NetconfReconnectingClientConfigurationBuilder extends NetconfClientConfigurationBuilder {
-
- private ReconnectStrategyFactory connectStrategyFactory;
-
- private NetconfReconnectingClientConfigurationBuilder() {
- }
-
- public static NetconfReconnectingClientConfigurationBuilder create() {
- return new NetconfReconnectingClientConfigurationBuilder();
- }
-
-
- public NetconfReconnectingClientConfigurationBuilder withConnectStrategyFactory(final ReconnectStrategyFactory connectStrategyFactory) {
- this.connectStrategyFactory = connectStrategyFactory;
- return this;
- }
-
- @Override
- public NetconfReconnectingClientConfiguration build() {
- return new NetconfReconnectingClientConfiguration(getProtocol(), getAddress(), getConnectionTimeoutMillis(), getAdditionalHeader(), getSessionListener(), getReconnectStrategy(), connectStrategyFactory, getAuthHandler());
- }
-
- // Override setter methods to return subtype
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withAddress(final InetSocketAddress address) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withAddress(address);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withConnectionTimeoutMillis(final long connectionTimeoutMillis) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withConnectionTimeoutMillis(connectionTimeoutMillis);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withAdditionalHeader(final NetconfHelloMessageAdditionalHeader additionalHeader) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withAdditionalHeader(additionalHeader);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withSessionListener(final NetconfClientSessionListener sessionListener) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withSessionListener(sessionListener);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withReconnectStrategy(final ReconnectStrategy reconnectStrategy) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withReconnectStrategy(reconnectStrategy);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withAuthHandler(final AuthenticationHandler authHandler) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withAuthHandler(authHandler);
- }
-
- @Override
- public NetconfReconnectingClientConfigurationBuilder withProtocol(NetconfClientConfiguration.NetconfClientProtocol clientProtocol) {
- return (NetconfReconnectingClientConfigurationBuilder) super.withProtocol(clientProtocol);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Optional;
-import java.net.InetSocketAddress;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-
-public class NetconfClientConfigurationTest {
- @Test
- public void testNetconfClientConfiguration() throws Exception {
- Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
- NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
- InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
- ReconnectStrategy strategy = Mockito.mock(ReconnectStrategy.class);
- AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
- NetconfClientConfiguration cfg = NetconfClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(strategy).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withAuthHandler(handler).build();
-
- Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
- Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
- Assert.assertEquals(listener, cfg.getSessionListener());
- Assert.assertEquals(handler, cfg.getAuthHandler());
- Assert.assertEquals(strategy, cfg.getReconnectStrategy());
- Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, cfg.getProtocol());
- Assert.assertEquals(address, cfg.getAddress());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.EventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.GenericFutureListener;
-import java.net.InetSocketAddress;
-import java.util.concurrent.Future;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-
-public class NetconfClientDispatcherImplTest {
- @Test
- public void testNetconfClientDispatcherImpl() throws Exception {
- EventLoopGroup bossGroup = Mockito.mock(EventLoopGroup.class);
- EventLoopGroup workerGroup = Mockito.mock(EventLoopGroup.class);
- Timer timer = new HashedWheelTimer();
-
- ChannelFuture chf = Mockito.mock(ChannelFuture.class);
- Channel ch = Mockito.mock(Channel.class);
- doReturn(ch).when(chf).channel();
- Throwable thr = Mockito.mock(Throwable.class);
- doReturn(chf).when(workerGroup).register(any(Channel.class));
-
- ChannelPromise promise = Mockito.mock(ChannelPromise.class);
- doReturn(promise).when(chf).addListener(any(GenericFutureListener.class));
- doReturn(thr).when(chf).cause();
-
- Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
- NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
- InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
- ReconnectStrategyFactory reconnectStrategyFactory = Mockito.mock(ReconnectStrategyFactory.class);
- AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
- ReconnectStrategy reconnect = Mockito.mock(ReconnectStrategy.class);
-
- doReturn(5).when(reconnect).getConnectTimeout();
- doReturn("").when(reconnect).toString();
- doReturn("").when(handler).toString();
- doReturn("").when(reconnectStrategyFactory).toString();
- doReturn(reconnect).when(reconnectStrategyFactory).createReconnectStrategy();
-
- NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(reconnectStrategyFactory).
- withAuthHandler(handler).build();
-
- NetconfReconnectingClientConfiguration cfg2 = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(reconnectStrategyFactory).
- withAuthHandler(handler).build();
-
- NetconfClientDispatcherImpl dispatcher = new NetconfClientDispatcherImpl(bossGroup, workerGroup, timer);
- Future<NetconfClientSession> sshSession = dispatcher.createClient(cfg);
- Future<NetconfClientSession> tcpSession = dispatcher.createClient(cfg2);
-
- Future<Void> sshReconn = dispatcher.createReconnectingClient(cfg);
- Future<Void> tcpReconn = dispatcher.createReconnectingClient(cfg2);
-
- assertNotNull(sshSession);
- assertNotNull(tcpSession);
- assertNotNull(sshReconn);
- assertNotNull(tcpReconn);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Optional;
-import io.netty.channel.Channel;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-
-public class NetconfClientSessionNegotiatorFactoryTest {
- @Test
- public void testGetSessionNegotiator() throws Exception {
- NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
- Timer timer = new HashedWheelTimer();
- SessionListenerFactory<NetconfClientSessionListener> listenerFactory = mock(SessionListenerFactory.class);
- doReturn(sessionListener).when(listenerFactory).getSessionListener();
-
- Channel channel = mock(Channel.class);
- Promise<NetconfClientSession> promise = mock(Promise.class);
- NetconfClientSessionNegotiatorFactory negotiatorFactory = new NetconfClientSessionNegotiatorFactory(timer,
- Optional.<NetconfHelloMessageAdditionalHeader>absent(), 200L);
-
- SessionNegotiator<?> sessionNegotiator = negotiatorFactory.getSessionNegotiator(listenerFactory, channel, promise);
- assertNotNull(sessionNegotiator);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import com.google.common.base.Optional;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.ChannelProgressivePromise;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.GenericFutureListener;
-import io.netty.util.concurrent.Promise;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.internal.util.collections.Sets;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.netconf.api.NetconfClientSessionPreferences;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.openexi.proc.common.EXIOptions;
-import org.w3c.dom.Document;
-
-public class NetconfClientSessionNegotiatorTest {
-
- private NetconfHelloMessage helloMessage;
- private ChannelPipeline pipeline;
- private ChannelFuture future;
- private Channel channel;
- private ChannelInboundHandlerAdapter channelInboundHandlerAdapter;
-
- @Before
- public void setUp() throws Exception {
- helloMessage = NetconfHelloMessage.createClientHello(Sets.newSet("exi:1.0"), Optional.<NetconfHelloMessageAdditionalHeader>absent());
- pipeline = mockChannelPipeline();
- future = mockChannelFuture();
- channel = mockChannel();
- }
-
- private static ChannelHandler mockChannelHandler() {
- ChannelHandler handler = mock(ChannelHandler.class);
- return handler;
- }
-
- private Channel mockChannel() {
- Channel channel = mock(Channel.class);
- ChannelHandler channelHandler = mockChannelHandler();
- doReturn("").when(channel).toString();
- doReturn(future).when(channel).close();
- doReturn(future).when(channel).writeAndFlush(anyObject());
- doReturn(true).when(channel).isOpen();
- doReturn(pipeline).when(channel).pipeline();
- doReturn("").when(pipeline).toString();
- doReturn(pipeline).when(pipeline).remove(any(ChannelHandler.class));
- doReturn(channelHandler).when(pipeline).remove(anyString());
- return channel;
- }
-
- private static ChannelFuture mockChannelFuture() {
- ChannelFuture future = mock(ChannelFuture.class);
- doReturn(future).when(future).addListener(any(GenericFutureListener.class));
- return future;
- }
-
- private static ChannelPipeline mockChannelPipeline() {
- ChannelPipeline pipeline = mock(ChannelPipeline.class);
- ChannelHandler handler = mock(ChannelHandler.class);
- doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
- doReturn(null).when(pipeline).get(SslHandler.class);
- doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
- doReturn(handler).when(pipeline).replace(anyString(), anyString(), any(ChunkedFramingMechanismEncoder.class));
-
- NetconfXMLToHelloMessageDecoder messageDecoder = new NetconfXMLToHelloMessageDecoder();
- doReturn(messageDecoder).when(pipeline).replace(anyString(), anyString(), any(NetconfXMLToMessageDecoder.class));
- doReturn(pipeline).when(pipeline).replace(any(ChannelHandler.class), anyString(), any(NetconfClientSession.class));
- return pipeline;
- }
-
- private NetconfClientSessionNegotiator createNetconfClientSessionNegotiator(final Promise<NetconfClientSession> promise,
- final NetconfMessage startExi) {
- ChannelProgressivePromise progressivePromise = mock(ChannelProgressivePromise.class);
- NetconfClientSessionPreferences preferences = new NetconfClientSessionPreferences(helloMessage, startExi);
- doReturn(progressivePromise).when(promise).setFailure(any(Throwable.class));
-
- long timeout = 10L;
- NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
- Timer timer = new HashedWheelTimer();
- return new NetconfClientSessionNegotiator(preferences, promise, channel, timer, sessionListener, timeout);
- }
-
- @Test
- public void testNetconfClientSessionNegotiator() throws Exception {
- Promise promise = mock(Promise.class);
- doReturn(promise).when(promise).setSuccess(anyObject());
- NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, null);
-
- negotiator.channelActive(null);
- Set<String> caps = Sets.newSet("a", "b");
- NetconfHelloMessage helloServerMessage = NetconfHelloMessage.createServerHello(caps, 10);
- negotiator.handleMessage(helloServerMessage);
- verify(promise).setSuccess(anyObject());
- }
-
- @Test
- public void testNetconfClientSessionNegotiatorWithEXI() throws Exception {
- Promise promise = mock(Promise.class);
- EXIOptions exiOptions = new EXIOptions();
- NetconfStartExiMessage exiMessage = NetconfStartExiMessage.create(exiOptions, "msg-id");
- doReturn(promise).when(promise).setSuccess(anyObject());
- NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, exiMessage);
-
- negotiator.channelActive(null);
- Set<String> caps = Sets.newSet("exi:1.0");
- NetconfHelloMessage helloMessage = NetconfHelloMessage.createServerHello(caps, 10);
-
- doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
- channelInboundHandlerAdapter = ((ChannelInboundHandlerAdapter) invocationOnMock.getArguments()[2]);
- return null;
- }
- }).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
-
- ChannelHandlerContext handlerContext = mock(ChannelHandlerContext.class);
- doReturn(pipeline).when(handlerContext).pipeline();
- negotiator.handleMessage(helloMessage);
- Document expectedResult = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc-reply_ok.xml");
- channelInboundHandlerAdapter.channelRead(handlerContext, new NetconfMessage(expectedResult));
-
- verify(promise).setSuccess(anyObject());
-
- // two calls for exiMessage, 2 for hello message
- verify(pipeline, times(4)).replace(anyString(), anyString(), any(ChannelHandler.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import com.google.common.collect.Lists;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
-import org.openexi.proc.common.EXIOptions;
-
-public class NetconfClientSessionTest {
-
- @Mock
- ChannelHandler channelHandler;
-
- @Mock
- Channel channel;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testNetconfClientSession() throws Exception {
- NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
- long sessId = 20L;
- Collection<String> caps = Lists.newArrayList("cap1", "cap2");
-
- NetconfEXICodec codec = new NetconfEXICodec(new EXIOptions());
- ChannelPipeline pipeline = mock(ChannelPipeline.class);
-
- Mockito.doReturn(pipeline).when(channel).pipeline();
- Mockito.doReturn(channelHandler).when(pipeline).replace(anyString(), anyString(), any(ChannelHandler.class));
- Mockito.doReturn("").when(channelHandler).toString();
-
- NetconfClientSession session = new NetconfClientSession(sessionListener, channel, sessId, caps);
- final NetconfMessageToEXIEncoder exiEncoder = NetconfMessageToEXIEncoder.create(codec);
- final NetconfEXIToMessageDecoder exiDecoder = NetconfEXIToMessageDecoder.create(codec);
- session.addExiHandlers(exiDecoder, exiEncoder);
- session.stopExiCommunication();
-
- assertEquals(caps, session.getServerCapabilities());
- assertEquals(session, session.thisInstance());
-
- Mockito.verify(pipeline, Mockito.times(4)).replace(anyString(), anyString(), Mockito.any(ChannelHandler.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Optional;
-import java.net.InetSocketAddress;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-
-public class NetconfReconnectingClientConfigurationTest {
- @Test
- public void testNetconfReconnectingClientConfiguration() throws Exception {
- Long timeout = 200L;
- NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader("a", "host", "port", "trans", "id");
- NetconfClientSessionListener listener = new SimpleNetconfClientSessionListener();
- InetSocketAddress address = InetSocketAddress.createUnresolved("host", 830);
- ReconnectStrategyFactory strategy = Mockito.mock(ReconnectStrategyFactory.class);
- AuthenticationHandler handler = Mockito.mock(AuthenticationHandler.class);
- ReconnectStrategy reconnect = Mockito.mock(ReconnectStrategy.class);
-
- NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create().
- withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH).
- withAddress(address).
- withConnectionTimeoutMillis(timeout).
- withReconnectStrategy(reconnect).
- withAdditionalHeader(header).
- withSessionListener(listener).
- withConnectStrategyFactory(strategy).
- withAuthHandler(handler).build();
-
- Assert.assertEquals(timeout, cfg.getConnectionTimeoutMillis());
- Assert.assertEquals(Optional.fromNullable(header), cfg.getAdditionalHeader());
- Assert.assertEquals(listener, cfg.getSessionListener());
- Assert.assertEquals(handler, cfg.getAuthHandler());
- Assert.assertEquals(strategy, cfg.getConnectStrategyFactory());
- Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, cfg.getProtocol());
- Assert.assertEquals(address, cfg.getAddress());
- Assert.assertEquals(reconnect, cfg.getReconnectStrategy());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.util.concurrent.Future;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.internal.util.collections.Sets;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-
-public class SimpleNetconfClientSessionListenerTest {
-
- private Channel channel;
- private ChannelFuture channelFuture;
- Set<String> caps;
- private NetconfHelloMessage helloMessage;
- private NetconfMessage message;
- private NetconfClientSessionListener sessionListener;
- private NetconfClientSession clientSession;
-
- @Before
- public void setUp() throws Exception {
- channel = mock(Channel.class);
- channelFuture = mock(ChannelFuture.class);
- doReturn(channelFuture).when(channel).writeAndFlush(anyObject());
- caps = Sets.newSet("a", "b");
- helloMessage = NetconfHelloMessage.createServerHello(caps, 10);
- message = new NetconfMessage(helloMessage.getDocument());
- sessionListener = mock(NetconfClientSessionListener.class);
- clientSession = new NetconfClientSession(sessionListener, channel, 20L, caps);
- }
-
- @Test
- public void testSessionDown() throws Exception {
- SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
- simpleListener.onSessionUp(clientSession);
- verify(channel, times(1)).writeAndFlush(anyObject());
-
- simpleListener.onSessionDown(clientSession, new Exception());
- assertFalse(promise.isSuccess());
- }
-
- @Test
- public void testSendRequest() throws Exception {
- SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
- simpleListener.onSessionUp(clientSession);
- verify(channel, times(1)).writeAndFlush(anyObject());
-
- simpleListener.sendRequest(message);
- assertFalse(promise.isSuccess());
- }
-
- @Test
- public void testOnMessage() throws Exception {
- SimpleNetconfClientSessionListener simpleListener = new SimpleNetconfClientSessionListener();
- Future<NetconfMessage> promise = simpleListener.sendRequest(message);
- simpleListener.onSessionUp(clientSession);
- verify(channel, times(1)).writeAndFlush(anyObject());
-
- simpleListener.onMessage(clientSession, message);
- assertTrue(promise.isSuccess());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import io.netty.util.concurrent.Promise;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-
-public class SshClientChannelInitializerTest {
- @Test
- public void test() throws Exception {
-
- AuthenticationHandler authenticationHandler = mock(AuthenticationHandler.class);
- NetconfClientSessionNegotiatorFactory negotiatorFactory = mock(NetconfClientSessionNegotiatorFactory.class);
- NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
-
- SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
- doReturn("").when(sessionNegotiator).toString();
- doReturn(sessionNegotiator).when(negotiatorFactory).getSessionNegotiator(any(SessionListenerFactory.class), any(Channel.class), any(Promise.class));
- ChannelPipeline pipeline = mock(ChannelPipeline.class);
- doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
- Channel channel = mock(Channel.class);
- doReturn(pipeline).when(channel).pipeline();
- doReturn("").when(channel).toString();
- doReturn(pipeline).when(pipeline).addFirst(any(ChannelHandler.class));
- doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
-
- Promise<NetconfClientSession> promise = mock(Promise.class);
- doReturn("").when(promise).toString();
-
- SshClientChannelInitializer initializer = new SshClientChannelInitializer(authenticationHandler, negotiatorFactory,
- sessionListener);
- initializer.initialize(channel, promise);
- verify(pipeline, times(1)).addFirst(any(ChannelHandler.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import io.netty.util.concurrent.Promise;
-import org.junit.Test;
-import org.opendaylight.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-
-public class TcpClientChannelInitializerTest {
- @Test
- public void testInitializeSessionNegotiator() throws Exception {
- NetconfClientSessionNegotiatorFactory factory = mock(NetconfClientSessionNegotiatorFactory.class);
- SessionNegotiator<?> sessionNegotiator = mock(SessionNegotiator.class);
- doReturn("").when(sessionNegotiator).toString();
- doReturn(sessionNegotiator).when(factory).getSessionNegotiator(any(SessionListenerFactory.class), any(Channel.class), any(Promise.class));
- NetconfClientSessionListener listener = mock(NetconfClientSessionListener.class);
- TcpClientChannelInitializer initializer = new TcpClientChannelInitializer(factory, listener);
- ChannelPipeline pipeline = mock(ChannelPipeline.class);
- doReturn(pipeline).when(pipeline).addAfter(anyString(), anyString(), any(ChannelHandler.class));
- Channel channel = mock(Channel.class);
- doReturn(pipeline).when(channel).pipeline();
- doReturn("").when(channel).toString();
-
- Promise<NetconfClientSession> promise = mock(Promise.class);
- doReturn("").when(promise).toString();
-
- initializer.initializeSessionNegotiator(channel, promise);
- verify(pipeline, times(1)).addAfter(anyString(), anyString(), any(ChannelHandler.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.client;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration.NetconfClientProtocol;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-
-
-/**
- * Synchronous netconf client suitable for testing
- */
-public class TestingNetconfClient implements Closeable {
-
- public static final int DEFAULT_CONNECT_TIMEOUT = 5000;
-
- private final String label;
- private final NetconfClientSession clientSession;
- private final NetconfClientSessionListener sessionListener;
- private final long sessionId;
-
- public TestingNetconfClient(String clientLabel,
- NetconfClientDispatcher netconfClientDispatcher, final NetconfClientConfiguration config) throws InterruptedException {
- this.label = clientLabel;
- sessionListener = config.getSessionListener();
- Future<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(config);
- clientSession = get(clientFuture);//TODO: make static
- this.sessionId = clientSession.getSessionId();
- }
-
- private NetconfClientSession get(Future<NetconfClientSession> clientFuture) throws InterruptedException {
- try {
- return clientFuture.get();
- } catch (CancellationException e) {
- throw new RuntimeException("Cancelling " + this, e);
- } catch (ExecutionException e) {
- throw new IllegalStateException("Unable to create " + this, e);
- }
- }
-
- public Future<NetconfMessage> sendRequest(NetconfMessage message) {
- return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message);
- }
-
- public NetconfMessage sendMessage(NetconfMessage message, int attemptMsDelay) throws ExecutionException,
- InterruptedException, TimeoutException {
- return sendRequest(message).get(attemptMsDelay, TimeUnit.MILLISECONDS);
- }
-
- public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException,
- InterruptedException, TimeoutException {
- return sendMessage(message, DEFAULT_CONNECT_TIMEOUT);
- }
-
- @Override
- public void close() throws IOException {
- clientSession.close();
- }
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer("TestingNetconfClient{");
- sb.append("label=").append(label);
- sb.append(", sessionId=").append(sessionId);
- sb.append('}');
- return sb.toString();
- }
-
- public long getSessionId() {
- return sessionId;
- }
-
- public Set<String> getCapabilities() {
- Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
- return Sets.newHashSet(clientSession.getServerCapabilities());
- }
-
- public static void main(String[] args) throws Exception {
- HashedWheelTimer hashedWheelTimer = new HashedWheelTimer();
- NioEventLoopGroup nettyGroup = new NioEventLoopGroup();
- NetconfClientDispatcherImpl netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyGroup, nettyGroup, hashedWheelTimer);
- LoginPassword authHandler = new LoginPassword("admin", "admin");
- TestingNetconfClient client = new TestingNetconfClient("client", netconfClientDispatcher, getClientConfig("127.0.0.1", 1830, true, Optional.of(authHandler)));
- System.console().writer().println(client.getCapabilities());
- }
-
- private static NetconfClientConfiguration getClientConfig(String host ,int port, boolean ssh, Optional<? extends AuthenticationHandler> maybeAuthHandler) throws UnknownHostException {
- InetSocketAddress netconfAddress = new InetSocketAddress(InetAddress.getByName(host), port);
- final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
- b.withAddress(netconfAddress);
- b.withSessionListener(new SimpleNetconfClientSessionListener());
- b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
- NetconfClientConfigurationBuilder.DEFAULT_CONNECTION_TIMEOUT_MILLIS));
- if (ssh) {
- b.withProtocol(NetconfClientProtocol.SSH);
- b.withAuthHandler(maybeAuthHandler.get());
- } else {
- b.withProtocol(NetconfClientProtocol.TCP);
- }
- return b.build();
- }
-}
+++ /dev/null
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
- <identifier>ietf-netconf-monitoring</identifier>
- <format
- xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">ncm:yang
- </format>
- </get-schema>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>netconf-config-dispatcher</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-util</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netty-threadgroup-config</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netty-timer-config</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
-
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-
-/**
-*
-*/
-public final class NetconfClientDispatcherModule extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModule {
-
- public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfClientDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
- NetconfClientDispatcherModule oldModule, java.lang.AutoCloseable oldInstance) {
-
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- protected void customValidation(){
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- return new NetconfClientDispatcherImpl(getBossThreadGroupDependency(), getWorkerThreadGroupDependency(), getTimerDependency());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
-
-/**
-*
-*/
-public class NetconfClientDispatcherModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.client.dispatcher.AbstractNetconfClientDispatcherModuleFactory
-{
-
-
-}
+++ /dev/null
-// vi: set smarttab et sw=4 tabstop=4:
-module odl-netconf-cfg {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf";
- prefix "cfg-net";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- netconf related services.
-
- Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
-
- This program and the accompanying materials are made available
- under the terms of the Eclipse Public License v1.0 which
- accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html";
-
- revision "2014-04-08" {
- description
- "Initial revision.";
- }
-
- identity netconf-client-dispatcher {
-
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.client.NetconfClientDispatcher";
- }
-}
\ No newline at end of file
+++ /dev/null
-// vi: set smarttab et sw=4 tabstop=4:
-module odl-netconfig-client-cfg {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher";
- prefix "cfg-net-client";
-
- import config { prefix config; revision-date 2013-04-05; }
- import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
- import netty {prefix netty; }
-
- description
- "This module contains the base YANG definitions for
- netconf-client-dispatcher implementation.
-
- Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
-
- This program and the accompanying materials are made available
- under the terms of the Eclipse Public License v1.0 which
- accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html";
-
- revision "2014-04-08" {
- description
- "Initial revision.";
- }
-
- identity netconf-client-dispatcher {
- base config:module-type;
- config:provided-service cfg-net:netconf-client-dispatcher;
- config:java-name-prefix NetconfClientDispatcher;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-client-dispatcher {
- when "/config:modules/config:module/config:type = 'netconf-client-dispatcher'";
-
- container boss-thread-group {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- container worker-thread-group {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- container timer {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-timer;
- }
- }
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-package org.opendaylight.controller.config.yang.config.netconf.client.dispatcher;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
-import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
-import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleMXBean;
-import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
-
-public class NetconfClientDispatcherModuleTest extends AbstractConfigTest{
-
- private NetconfClientDispatcherModuleFactory factory;
- private final String instanceName = "dispatch";
-
- @Before
- public void setUp() {
- factory = new NetconfClientDispatcherModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
- new NettyThreadgroupModuleFactory(),
- new HashedWheelTimerModuleFactory()));
- }
-
- @Test
- public void testCreateBean() throws InstanceAlreadyExistsException, ValidationException, ConflictingVersionException {
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-
- createInstance(transaction, instanceName, "timer", "thGroup");
- createInstance(transaction, instanceName + 2, "timer2", "thGroup2");
- transaction.validateConfig();
- CommitStatus status = transaction.commit();
-
- assertBeanCount(2, factory.getImplementationName());
- assertStatus(status, 2 + 4, 0, 0);
- }
-
- @Test
- public void testReusingOldInstance() throws InstanceAlreadyExistsException, ConflictingVersionException, ValidationException {
-
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
- createInstance(transaction, instanceName, "timer", "thGroup");
-
- transaction.commit();
-
- transaction = configRegistryClient.createTransaction();
- assertBeanCount(1, factory.getImplementationName());
- CommitStatus status = transaction.commit();
-
- assertBeanCount(1, factory.getImplementationName());
- assertStatus(status, 0, 0, 3);
- }
-
- @Test
- public void testReconfigure() throws InstanceAlreadyExistsException, ConflictingVersionException,
- ValidationException, InstanceNotFoundException {
-
- ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
- createInstance(transaction, instanceName, "timer", "thGroup");
-
- transaction.commit();
-
- transaction = configRegistryClient.createTransaction();
- assertBeanCount(1, factory.getImplementationName());
- NetconfClientDispatcherModuleMXBean mxBean = transaction.newMBeanProxy(
- transaction.lookupConfigBean(NetconfClientDispatcherModuleFactory.NAME, instanceName),
- NetconfClientDispatcherModuleMXBean.class);
- mxBean.setBossThreadGroup(getThreadGroup(transaction, "group2"));
- CommitStatus status = transaction.commit();
-
- assertBeanCount(1, factory.getImplementationName());
- assertStatus(status, 1, 1, 2);
- }
-
- private ObjectName createInstance(ConfigTransactionJMXClient transaction, String instanceName, String timerName, String threadGroupName)
- throws InstanceAlreadyExistsException {
- ObjectName nameCreated = transaction.createModule(factory.getImplementationName(), instanceName);
- NetconfClientDispatcherModuleMXBean mxBean = transaction.newMBeanProxy(nameCreated, NetconfClientDispatcherModuleMXBean.class);
- ObjectName thGroup = getThreadGroup(transaction, threadGroupName);
- mxBean.setBossThreadGroup(thGroup);
- mxBean.setWorkerThreadGroup(thGroup);
- mxBean.setTimer(getTimer(transaction, timerName));
- return nameCreated;
- }
-
- private ObjectName getTimer(ConfigTransactionJMXClient transaction, String name) throws InstanceAlreadyExistsException {
- return transaction.createModule(HashedWheelTimerModuleFactory.NAME, name);
- }
-
- private ObjectName getThreadGroup(ConfigTransactionJMXClient transaction, String name) throws InstanceAlreadyExistsException {
- ObjectName nameCreated = transaction.createModule(NettyThreadgroupModuleFactory.NAME, name);
- NettyThreadgroupModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, NettyThreadgroupModuleMXBean.class);
- mxBean.setThreadCount(1);
- return nameCreated;
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-config</artifactId>
- <description>Configuration files for netconf</description>
- <packaging>jar</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/initial/01-netconf.xml</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <!-- Netconf dispatcher to be used by all netconf-connectors -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-boss-group</name>
- </boss-thread-group>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <name>global-timer</name>
- </timer>
- </module>
-
- <!-- Thread factory to be used by all threadpools in netconf-connectors -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
- </module>
- <!-- flexible threadpool for all netconf connectors, Max thread count is set to 4. -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">prefix:threadpool-flexible</type>
- <name>global-netconf-processing-executor</name>
- <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1</minThreadCount>
- <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4</max-thread-count>
- <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000</keepAliveMillis>
-
- <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- </threadFactory>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled">prefix:threadpool-scheduled</type>
- <name>global-netconf-ssh-scheduled-executor</name>
- <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled">8</max-thread-count>
-
- <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- </threadFactory>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <instance>
- <name>global-netconf-dispatcher</name>
- <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <instance>
- <name>global-netconf-processing-executor-threadfactory</name>
- <provider>/modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <instance>
- <name>global-netconf-processing-executor</name>
- <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
- </instance>
- <instance>
- <name>global-netconf-ssh-scheduled-executor</name>
- <provider>/modules/module[type='threadpool-scheduled'][name='global-netconf-ssh-scheduled-executor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
- <instance>
- <name>global-netconf-ssh-scheduled-executor</name>
- <provider>/modules/module[type='threadpool-scheduled'][name='global-netconf-ssh-scheduled-executor']</provider>
- </instance>
- </service>
- </services>
-
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher?module=odl-netconfig-client-cfg&revision=2014-04-08</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible?module=threadpool-impl-flexible&revision=2013-12-01</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled?module=threadpool-impl-scheduled&revision=2013-12-01</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-connector-config</artifactId>
- <description>Configuration files for netconf-connector</description>
- <packaging>jar</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/initial/99-netconf-connector.xml</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <!-- Loopback connection to netconf server in controller using netconf-connector -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
- <name>controller-config</name>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
- <reconnect-on-changed-schema xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">true</reconnect-on-changed-schema>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <keepalive-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:scheduled-threadpool</type>
- <name>global-netconf-ssh-scheduled-executor</name>
- </keepalive-executor>
- </module>
- </modules>
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&revision=2013-10-28</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-impl</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- </dependency>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.logback_settings</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>protocol-framework</artifactId>
- </dependency>
- <!-- test dependencies -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.impl.osgi.NetconfImplActivator</Bundle-Activator>
- <Export-Package>org.opendaylight.controller.netconf.impl.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-
-public class NetconfMapperAggregatorModule extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfMapperAggregatorModule {
- public NetconfMapperAggregatorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfMapperAggregatorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfMapperAggregatorModule oldModule, final java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {}
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- return new AggregatedNetconfOperationServiceFactory();
- }
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-northbound-impl yang module local name: netconf-mapper-aggregator
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Tue Feb 17 17:24:19 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-public class NetconfMapperAggregatorModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfMapperAggregatorModuleFactory {
-
-}
+++ /dev/null
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-
-import org.opendaylight.controller.config.api.JmxAttributeValidationException;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-
-public class NetconfServerDispatcherModule extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfServerDispatcherModule {
- public NetconfServerDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfServerDispatcherModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfServerDispatcherModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- JmxAttributeValidationException.checkCondition(getConnectionTimeoutMillis() > 0, "Invalid connection timeout", connectionTimeoutMillisJmxAttribute);
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
-
- final AggregatedNetconfOperationServiceFactory aggregatedOpProvider = getAggregatedOpProvider();
- final NetconfMonitoringService monitoringService = getServerMonitorDependency();
- final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- getTimerDependency(), aggregatedOpProvider, new SessionIdProvider(), getConnectionTimeoutMillis(), monitoringService);
- final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
- serverNegotiatorFactory);
-
- return new NetconfServerDispatcherImpl(serverChannelInitializer, getBossThreadGroupDependency(), getWorkerThreadGroupDependency()) {
-
- @Override
- public void close() {
- // NOOP, close should not be present here, the deprecated method closes injected evet loop groups
- }
- };
-
- }
-
- private AggregatedNetconfOperationServiceFactory getAggregatedOpProvider() {
- final AggregatedNetconfOperationServiceFactory netconfOperationProvider = new AggregatedNetconfOperationServiceFactory();
- for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getMappersDependency()) {
- netconfOperationProvider.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
- }
- return netconfOperationProvider;
- }
-
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-northbound-impl yang module local name: netconf-server-dispatcher-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Thu Feb 12 11:32:29 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-public class NetconfServerDispatcherModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfServerDispatcherModuleFactory {
-
-}
+++ /dev/null
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-
-import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
-
-public class NetconfServerMonitoringModule extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfServerMonitoringModule {
- public NetconfServerMonitoringModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfServerMonitoringModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.netconf.northbound.impl.NetconfServerMonitoringModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- return new NetconfMonitoringServiceImpl(getAggregatorDependency());
- }
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-northbound-impl yang module local name: netconf-server-monitoring-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Tue Feb 17 17:24:19 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.netconf.northbound.impl;
-public class NetconfServerMonitoringModuleFactory extends org.opendaylight.controller.config.yang.config.netconf.northbound.impl.AbstractNetconfServerMonitoringModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import io.netty.channel.local.LocalServerChannel;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.api.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler;
-import org.opendaylight.controller.netconf.nettyutil.AbstractChannelInitializer;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
-
-public class NetconfServerDispatcherImpl extends AbstractDispatcher<NetconfServerSession, NetconfServerSessionListener> implements NetconfServerDispatcher {
-
- private final ServerChannelInitializer initializer;
-
- public NetconfServerDispatcherImpl(ServerChannelInitializer serverChannelInitializer, EventLoopGroup bossGroup,
- EventLoopGroup workerGroup) {
- super(bossGroup, workerGroup);
- this.initializer = serverChannelInitializer;
- }
-
- @Override
- public ChannelFuture createServer(InetSocketAddress address) {
- return super.createServer(address, new PipelineInitializer<NetconfServerSession>() {
- @Override
- public void initializeChannel(final SocketChannel ch, final Promise<NetconfServerSession> promise) {
- initializer.initialize(ch, promise);
- }
- });
- }
-
- @Override
- public ChannelFuture createLocalServer(LocalAddress address) {
- return super.createServer(address, LocalServerChannel.class, new ChannelPipelineInitializer<LocalChannel, NetconfServerSession>() {
- @Override
- public void initializeChannel(final LocalChannel ch, final Promise<NetconfServerSession> promise) {
- initializer.initialize(ch, promise);
- }
- });
- }
-
- public static class ServerChannelInitializer extends AbstractChannelInitializer<NetconfServerSession> {
-
- public static final String DESERIALIZER_EX_HANDLER_KEY = "deserializerExHandler";
-
- private final NetconfServerSessionNegotiatorFactory negotiatorFactory;
-
-
- public ServerChannelInitializer(NetconfServerSessionNegotiatorFactory negotiatorFactory) {
- this.negotiatorFactory = negotiatorFactory;
-
- }
-
- @Override
- protected void initializeMessageDecoder(Channel ch) {
- super.initializeMessageDecoder(ch);
- ch.pipeline().addLast(DESERIALIZER_EX_HANDLER_KEY, new DeserializerExceptionHandler());
- }
-
- @Override
- protected void initializeSessionNegotiator(Channel ch, Promise<NetconfServerSession> promise) {
- ch.pipeline().addAfter(DESERIALIZER_EX_HANDLER_KEY, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
- negotiatorFactory.getSessionNegotiator(null, ch, promise));
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.nettyutil.AbstractNetconfSession;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1Builder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Transport;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfServerSession extends AbstractNetconfSession<NetconfServerSession, NetconfServerSessionListener> implements NetconfManagementSession {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSession.class);
-
- private final NetconfHelloMessageAdditionalHeader header;
-
- private Date loginTime;
- private long inRpcSuccess, inRpcFail, outRpcError;
- private volatile boolean delayedClose;
-
- public NetconfServerSession(final NetconfServerSessionListener sessionListener, final Channel channel, final long sessionId,
- final NetconfHelloMessageAdditionalHeader header) {
- super(sessionListener, channel, sessionId);
- this.header = header;
- LOG.debug("Session {} created", toString());
- }
-
- @Override
- protected void sessionUp() {
- Preconditions.checkState(loginTime == null, "Session is already up");
- this.loginTime = new Date();
- super.sessionUp();
- }
-
- /**
- * Close this session after next message is sent.
- * Suitable for close rpc that needs to send ok response before the session is closed.
- */
- public void delayedClose() {
- this.delayedClose = true;
- }
-
- @Override
- public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
- final ChannelFuture channelFuture = super.sendMessage(netconfMessage);
- // delayed close was set, close after the message was sent
- if(delayedClose) {
- channelFuture.addListener(new ChannelFutureListener() {
- @Override
- public void operationComplete(final ChannelFuture future) throws Exception {
- close();
- }
- });
- }
- return channelFuture;
- }
-
- public void onIncommingRpcSuccess() {
- inRpcSuccess++;
- }
-
- public void onIncommingRpcFail() {
- inRpcFail++;
- }
-
- public void onOutgoingRpcError() {
- outRpcError++;
- }
-
- public static final String ISO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
-
- private static final String dateTimePatternString = DateAndTime.PATTERN_CONSTANTS.get(0);
- private static final Pattern dateTimePattern = Pattern.compile(dateTimePatternString);
-
- @Override
- public Session toManagementSession() {
- SessionBuilder builder = new SessionBuilder();
-
- builder.setSessionId(getSessionId());
- builder.setSourceHost(new Host(new DomainName(header.getAddress())));
-
- Preconditions.checkState(DateAndTime.PATTERN_CONSTANTS.size() == 1);
- String formattedDateTime = formatDateTime(loginTime);
-
- Matcher matcher = dateTimePattern.matcher(formattedDateTime);
- Preconditions.checkState(matcher.matches(), "Formatted datetime %s does not match pattern %s", formattedDateTime, dateTimePattern);
- builder.setLoginTime(new DateAndTime(formattedDateTime));
-
- builder.setInBadRpcs(new ZeroBasedCounter32(inRpcFail));
- builder.setInRpcs(new ZeroBasedCounter32(inRpcSuccess));
- builder.setOutRpcErrors(new ZeroBasedCounter32(outRpcError));
-
- builder.setUsername(header.getUserName());
- builder.setTransport(getTransportForString(header.getTransport()));
-
- builder.setOutNotifications(new ZeroBasedCounter32(0L));
-
- builder.setKey(new SessionKey(getSessionId()));
-
- Session1Builder builder1 = new Session1Builder();
- builder1.setSessionIdentifier(header.getSessionIdentifier());
- builder.addAugmentation(Session1.class, builder1.build());
-
- return builder.build();
- }
-
- private static Class<? extends Transport> getTransportForString(final String transport) {
- switch(transport) {
- case "ssh" :
- return NetconfSsh.class;
- case "tcp" :
- return NetconfTcp.class;
- default:
- throw new IllegalArgumentException("Unknown transport type " + transport);
- }
- }
-
- private static String formatDateTime(final Date loginTime) {
- // FIXME: thread-local cache?
- SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_DATE_FORMAT);
- return dateFormat.format(loginTime);
- }
-
- @Override
- protected NetconfServerSession thisInstance() {
- return this;
- }
-
- @Override
- protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {
- replaceMessageDecoder(decoder);
- replaceMessageEncoderAfterNextMessage(encoder);
- }
-
- @Override
- public void stopExiCommunication() {
- replaceMessageDecoder(new NetconfXMLToMessageDecoder());
- replaceMessageEncoderAfterNextMessage(new NetconfMessageToXMLEncoder());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-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.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter;
-import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-public class NetconfServerSessionListener implements NetconfSessionListener<NetconfServerSession> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionListener.class);
- private final NetconfMonitoringService monitoringService;
- private final NetconfOperationRouter operationRouter;
- private final AutoCloseable onSessionDownCloseable;
-
- public NetconfServerSessionListener(final NetconfOperationRouter operationRouter, final NetconfMonitoringService monitoringService,
- final AutoCloseable onSessionDownCloseable) {
- this.operationRouter = operationRouter;
- this.monitoringService = monitoringService;
- this.onSessionDownCloseable = onSessionDownCloseable;
- }
-
- @Override
- public void onSessionUp(final NetconfServerSession netconfNetconfServerSession) {
- monitoringService.onSessionUp(netconfNetconfServerSession);
- // FIXME monitoring service should be also notified about all the other changes to netconf session (from ietf-netconf-monitoring point of view)
- // This means also notifying after every message is processed
- }
-
- @Override
- 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);
-
- 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(final NetconfServerSession netconfNetconfServerSession,
- final NetconfTerminationReason netconfTerminationReason) {
- LOG.debug("Session {} terminated, reason: {}", netconfNetconfServerSession,
- netconfTerminationReason.getErrorMessage());
- onDown(netconfNetconfServerSession);
- }
-
- @Override
- public void onMessage(final NetconfServerSession session, final NetconfMessage netconfMessage) {
- try {
-
- Preconditions.checkState(operationRouter != null, "Cannot handle message, session up was not yet received");
- // FIXME: there is no validation since the document may contain yang
- // schemas
- final NetconfMessage message = processDocument(netconfMessage,
- session);
- LOG.debug("Responding with message {}", message);
- session.sendMessage(message);
- } catch (final RuntimeException e) {
- // TODO: should send generic error or close session?
- LOG.error("Unexpected exception", e);
- session.onIncommingRpcFail();
- throw new IllegalStateException("Unable to process incoming message " + netconfMessage, e);
- } catch (DocumentedException e) {
- LOG.trace("Error occurred while processing message",e);
- session.onOutgoingRpcError();
- session.onIncommingRpcFail();
- SendErrorExceptionUtil.sendErrorMessage(session, e, netconfMessage);
- }
- }
-
- private NetconfMessage processDocument(final NetconfMessage netconfMessage, final NetconfServerSession session)
- throws DocumentedException {
-
- final Document incomingDocument = netconfMessage.getDocument();
- final Node rootNode = incomingDocument.getDocumentElement();
-
- if (rootNode.getLocalName().equals(XmlNetconfConstants.RPC_KEY)) {
- final Document responseDocument = XmlUtil.newDocument();
- checkMessageId(rootNode);
-
- Document rpcReply = operationRouter.onNetconfMessage(incomingDocument, session);
-
- rpcReply = SubtreeFilter.applySubtreeFilter(incomingDocument, rpcReply);
-
- session.onIncommingRpcSuccess();
-
- responseDocument.appendChild(responseDocument.importNode(rpcReply.getDocumentElement(), true));
- return new NetconfMessage(responseDocument);
- } else {
- // unknown command, send RFC 4741 p.70 unknown-element
- /*
- * Tag: unknown-element Error-type: rpc, protocol, application
- * Severity: error Error-info: <bad-element> : name of the
- * unexpected element Description: An unexpected element is present.
- */
- // TODO add message to error info
- throw new DocumentedException("Unknown tag " + rootNode.getNodeName(),
- DocumentedException.ErrorType.protocol, DocumentedException.ErrorTag.unknown_element,
- DocumentedException.ErrorSeverity.error, ImmutableMap.of("bad-element",
- rootNode.getNodeName()));
- }
- }
-
- private static void checkMessageId(final Node rootNode) throws DocumentedException {
-
- 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 DocumentedException("Missing attribute" + rootNode.getNodeName(),
- DocumentedException.ErrorType.protocol, DocumentedException.ErrorTag.missing_attribute,
- DocumentedException.ErrorSeverity.error,
- ImmutableMap.of(DocumentedException.ErrorTag.missing_attribute.toString(),
- XmlNetconfConstants.MESSAGE_ID));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import com.google.common.base.Optional;
-import io.netty.channel.Channel;
-import io.netty.channel.local.LocalAddress;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Promise;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.AbstractMap;
-import java.util.Map;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
-import org.opendaylight.controller.netconf.nettyutil.AbstractNetconfSessionNegotiator;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfServerSessionNegotiator
- extends
- AbstractNetconfSessionNegotiator<NetconfServerSessionPreferences, NetconfServerSession, NetconfServerSessionListener> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionNegotiator.class);
-
- private static final String UNKNOWN = "unknown";
-
- protected NetconfServerSessionNegotiator(
- NetconfServerSessionPreferences sessionPreferences,
- Promise<NetconfServerSession> promise, Channel channel,
- Timer timer, NetconfServerSessionListener sessionListener,
- long connectionTimeoutMillis) {
- super(sessionPreferences, promise, channel, timer, sessionListener,
- connectionTimeoutMillis);
- }
-
- @Override
- protected void handleMessage(NetconfHelloMessage netconfMessage)
- throws NetconfDocumentedException {
- NetconfServerSession session = getSessionForHelloMessage(netconfMessage);
- replaceHelloMessageInboundHandler(session);
- // Negotiation successful after all non hello messages were processed
- negotiationSuccessful(session);
- }
-
- @Override
- protected NetconfServerSession getSession(
- NetconfServerSessionListener sessionListener, Channel channel,
- NetconfHelloMessage message) {
- Optional<NetconfHelloMessageAdditionalHeader> additionalHeader = message
- .getAdditionalHeader();
-
- NetconfHelloMessageAdditionalHeader parsedHeader;
- if (additionalHeader.isPresent()) {
- parsedHeader = additionalHeader.get();
- } else {
-
- parsedHeader = new NetconfHelloMessageAdditionalHeader(UNKNOWN,
- getHostName(channel.localAddress()).getValue(),
- getHostName(channel.localAddress()).getKey(), "tcp",
- "client");
-
- }
-
- LOG.debug("Additional header from hello parsed as {} from {}",
- parsedHeader, additionalHeader);
-
- return new NetconfServerSession(sessionListener, channel,
- getSessionPreferences().getSessionId(), parsedHeader);
- }
-
- /**
- * @param socketAddress
- * type of socket address LocalAddress, or
- * InetSocketAddress, for others returns unknown
- * @return Map<port, host > two values - port and host of socket address
- */
- protected static Map.Entry<String, String> getHostName(
- SocketAddress socketAddress) {
-
- if (socketAddress instanceof InetSocketAddress) {
-
- InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
-
- return new AbstractMap.SimpleImmutableEntry<>(
- Integer.toString(inetSocketAddress.getPort()),
- inetSocketAddress.getHostString());
-
- } else if (socketAddress instanceof LocalAddress) {
-
- return new AbstractMap.SimpleImmutableEntry<>(UNKNOWN,
- ((LocalAddress) socketAddress).id());
-
- }
- return new AbstractMap.SimpleImmutableEntry<>(UNKNOWN, UNKNOWN);
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-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.util.Set;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
-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.protocol.framework.SessionListenerFactory;
-import org.opendaylight.protocol.framework.SessionNegotiator;
-import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory<NetconfHelloMessage, NetconfServerSession, NetconfServerSessionListener> {
-
- public static final Set<String> 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 final SessionIdProvider idProvider;
- private final NetconfOperationServiceFactory aggregatedOpService;
- private final long connectionTimeoutMillis;
- private final NetconfMonitoringService monitoringService;
- private static final Logger LOG = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class);
- private final Set<String> baseCapabilities;
-
- // TODO too many params, refactor
- public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider,
- final SessionIdProvider idProvider, final long connectionTimeoutMillis,
- final NetconfMonitoringService monitoringService) {
- this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, monitoringService, DEFAULT_BASE_CAPABILITIES);
- }
-
- // TODO too many params, refactor
- public NetconfServerSessionNegotiatorFactory(final Timer timer, final NetconfOperationServiceFactory netconfOperationProvider,
- final SessionIdProvider idProvider, final long connectionTimeoutMillis,
- final NetconfMonitoringService monitoringService, final Set<String> baseCapabilities) {
- this.timer = timer;
- this.aggregatedOpService = netconfOperationProvider;
- this.idProvider = idProvider;
- this.connectionTimeoutMillis = connectionTimeoutMillis;
- this.monitoringService = monitoringService;
- this.baseCapabilities = validateBaseCapabilities(baseCapabilities);
- }
-
- private static ImmutableSet<String> validateBaseCapabilities(final Set<String> baseCapabilities) {
- // Check base capabilities to be supported by the server
- final Sets.SetView<String> 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<String> 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();
- }
-
- /**
- *
- * @param defunctSessionListenerFactory will not be taken into account as session listener factory can
- * only be created after snapshot is opened, thus this method constructs
- * proper session listener factory.
- * @param channel Underlying channel
- * @param promise Promise to be notified
- * @return session negotiator
- */
- @Override
- public SessionNegotiator<NetconfServerSession> getSessionNegotiator(final SessionListenerFactory<NetconfServerSessionListener> defunctSessionListenerFactory,
- final Channel channel, final Promise<NetconfServerSession> 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,
- getListener(Long.toString(sessionId)), connectionTimeoutMillis);
- }
-
- private NetconfServerSessionListener getListener(final String netconfSessionIdForReporting) {
- final NetconfOperationService service =
- this.aggregatedOpService.createService(netconfSessionIdForReporting);
- final NetconfOperationRouter operationRouter =
- new NetconfOperationRouterImpl(service, monitoringService, netconfSessionIdForReporting);
- return new NetconfServerSessionListener(operationRouter, monitoringService, service);
-
- }
-
- private NetconfHelloMessage createHelloMessage(final long sessionId, final NetconfMonitoringService capabilityProvider) throws NetconfDocumentedException {
- return NetconfHelloMessage.createServerHello(Sets.union(transformCapabilities(capabilityProvider.getCapabilities()), baseCapabilities), sessionId);
- }
-
- public static Set<String> transformCapabilities(final Capabilities capabilities) {
- return Sets.newHashSet(Collections2.transform(capabilities.getCapability(), new Function<Uri, String>() {
- @Override
- public String apply(final Uri uri) {
- return uri.getValue();
- }
- }));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import java.util.concurrent.atomic.AtomicLong;
-
-public final class SessionIdProvider {
-
- private final AtomicLong sessionCounter = new AtomicLong(0);
-
- public long getNextSessionId() {
- return sessionCounter.incrementAndGet();
- }
-
- public long getCurrentSessionId() {
- return sessionCounter.get();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import com.google.common.base.Optional;
-import java.io.IOException;
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation.OperationNameAndNamespace;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-/**
- * See <a href="http://tools.ietf.org/html/rfc6241#section-6">rfc6241</a> for details.
- */
-public class SubtreeFilter {
- private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilter.class);
-
- static Document applySubtreeFilter(Document requestDocument, Document rpcReply) throws DocumentedException {
- OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(requestDocument);
- if (XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0.equals(operationNameAndNamespace.getNamespace()) &&
- XmlNetconfConstants.GET.equals(operationNameAndNamespace.getOperationName()) ||
- XmlNetconfConstants.GET_CONFIG.equals(operationNameAndNamespace.getOperationName())) {
- // process subtree filtering here, in case registered netconf operations do
- // not implement filtering.
- Optional<XmlElement> maybeFilter = operationNameAndNamespace.getOperationElement().getOnlyChildElementOptionally(
- XmlNetconfConstants.FILTER, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- if (!maybeFilter.isPresent()) {
- return rpcReply;
- }
-
- // FIXME: rpcReply document must be reread otherwise some nodes do not inherit namespaces. (services/service)
- try {
- rpcReply = XmlUtil.readXmlToDocument(XmlUtil.toString(rpcReply, true));
- } catch (SAXException | IOException e) {
- LOG.error("Cannot transform document", e);
- throw new DocumentedException("Cannot transform document" + e);
- }
- XmlElement filter = maybeFilter.get();
- if ("subtree".equals(filter.getAttribute("type"))||
- "subtree".equals(filter.getAttribute("type", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0))) {
-
- // do
- return filtered(maybeFilter.get(), rpcReply);
- }
- }
-
- return rpcReply; // return identical document
- }
-
- private static Document filtered(XmlElement filter, Document originalReplyDocument) throws DocumentedException {
- Document result = XmlUtil.newDocument();
- // even if filter is empty, copy /rpc/data
- Element rpcReply = originalReplyDocument.getDocumentElement();
- Node rpcReplyDst = result.importNode(rpcReply, false);
- result.appendChild(rpcReplyDst);
- XmlElement dataSrc = XmlElement.fromDomElement(rpcReply).getOnlyChildElement("data", XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- Element dataDst = (Element) result.importNode(dataSrc.getDomElement(), false);
- rpcReplyDst.appendChild(dataDst);
- addSubtree(filter, dataSrc, XmlElement.fromDomElement(dataDst));
-
- return result;
- }
-
- private static void addSubtree(XmlElement filter, XmlElement src, XmlElement dst) throws DocumentedException {
- for (XmlElement srcChild : src.getChildElements()) {
- for (XmlElement filterChild : filter.getChildElements()) {
- addSubtree2(filterChild, srcChild, dst);
- }
- }
- }
-
- private static MatchingResult addSubtree2(XmlElement filter, XmlElement src, XmlElement dstParent) throws DocumentedException {
- Document document = dstParent.getDomElement().getOwnerDocument();
- MatchingResult matches = matches(src, filter);
- if (matches != MatchingResult.NO_MATCH && matches != MatchingResult.CONTENT_MISMATCH) {
- // copy srcChild to dst
- boolean filterHasChildren = filter.getChildElements().isEmpty() == false;
- // copy to depth if this is leaf of filter tree
- Element copied = (Element) document.importNode(src.getDomElement(), filterHasChildren == false);
- boolean shouldAppend = filterHasChildren == false;
- if (filterHasChildren) { // this implies TAG_MATCH
- // do the same recursively
- int numberOfTextMatchingChildren = 0;
- for (XmlElement srcChild : src.getChildElements()) {
- for (XmlElement filterChild : filter.getChildElements()) {
- MatchingResult childMatch = addSubtree2(filterChild, srcChild, XmlElement.fromDomElement(copied));
- if (childMatch == MatchingResult.CONTENT_MISMATCH) {
- return MatchingResult.NO_MATCH;
- }
- if (childMatch == MatchingResult.CONTENT_MATCH) {
- numberOfTextMatchingChildren++;
- }
- shouldAppend |= childMatch != MatchingResult.NO_MATCH;
- }
- }
- // if only text matching child filters are specified..
- if (numberOfTextMatchingChildren == filter.getChildElements().size()) {
- // force all children to be added (to depth). This is done by copying parent node to depth.
- // implies shouldAppend == true
- copied = (Element) document.importNode(src.getDomElement(), true);
- }
- }
- if (shouldAppend) {
- dstParent.getDomElement().appendChild(copied);
- }
- }
- return matches;
- }
-
- /**
- * Shallow compare src node to filter: tag name and namespace must match.
- * If filter node has no children and has text content, it also must match.
- */
- private static MatchingResult matches(XmlElement src, XmlElement filter) throws DocumentedException {
- boolean tagMatch = src.getName().equals(filter.getName()) &&
- src.getNamespaceOptionally().equals(filter.getNamespaceOptionally());
- MatchingResult result = null;
- if (tagMatch) {
- // match text content
- Optional<String> maybeText = filter.getOnlyTextContentOptionally();
- if (maybeText.isPresent()) {
- if (maybeText.equals(src.getOnlyTextContentOptionally()) || prefixedContentMatches(filter, src)) {
- result = MatchingResult.CONTENT_MATCH;
- } else {
- result = MatchingResult.CONTENT_MISMATCH;
- }
- }
- // match attributes, combination of content and tag is not supported
- if (result == null) {
- for (Attr attr : filter.getAttributes().values()) {
- // ignore namespace declarations
- if (XmlUtil.XMLNS_URI.equals(attr.getNamespaceURI()) == false ) {
- // find attr with matching localName(), namespaceURI(), == value() in src
- String found = src.getAttribute(attr.getLocalName(), attr.getNamespaceURI());
- if (attr.getValue().equals(found) && result != MatchingResult.NO_MATCH) {
- result = MatchingResult.TAG_MATCH;
- } else {
- result = MatchingResult.NO_MATCH;
- }
- }
- }
- }
- if (result == null) {
- result = MatchingResult.TAG_MATCH;
- }
- }
- if (result == null) {
- result = MatchingResult.NO_MATCH;
- }
- LOG.debug("Matching {} to {} resulted in {}", src, filter, result);
- return result;
- }
-
- private static boolean prefixedContentMatches(final XmlElement filter, final XmlElement src) throws DocumentedException {
- final Map.Entry<String, String> prefixToNamespaceOfFilter;
- final Map.Entry<String, String> prefixToNamespaceOfSrc;
- try {
- prefixToNamespaceOfFilter = filter.findNamespaceOfTextContent();
- prefixToNamespaceOfSrc = src.findNamespaceOfTextContent();
- } catch (IllegalArgumentException e) {
- //if we can't find namespace of prefix - it's not a prefix, so it doesn't match
- return false;
- }
-
- final String prefix = prefixToNamespaceOfFilter.getKey();
- // If this is not a prefixed content, we do not need to continue since content do not match
- if (prefix.equals(XmlElement.DEFAULT_NAMESPACE_PREFIX)) {
- return false;
- }
- // Namespace mismatch
- if (!prefixToNamespaceOfFilter.getValue().equals(prefixToNamespaceOfSrc.getValue())) {
- return false;
- }
-
- final String unprefixedFilterContent = filter.getTextContent().substring(prefixToNamespaceOfFilter.getKey().length() + 1);
- final String unprefixedSrcContnet = src.getTextContent().substring(prefixToNamespaceOfSrc.getKey().length() + 1);
- // Finally compare unprefixed content
- return unprefixedFilterContent.equals(unprefixedSrcContnet);
- }
-
- enum MatchingResult {
- NO_MATCH, TAG_MATCH, CONTENT_MATCH, CONTENT_MISMATCH
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DefaultCloseSession extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {
- private static final Logger LOG = LoggerFactory.getLogger(DefaultCloseSession.class);
-
- public static final String CLOSE_SESSION = "close-session";
-
- private final AutoCloseable sessionResources;
- private NetconfServerSession session;
-
- public DefaultCloseSession(String netconfSessionIdForReporting, AutoCloseable sessionResources) {
- super(netconfSessionIdForReporting);
- this.sessionResources = sessionResources;
- }
-
- @Override
- protected String getOperationName() {
- return CLOSE_SESSION;
- }
-
- /**
- * Close netconf operation router associated to this session, which in turn
- * closes NetconfOperationServiceSnapshot with all NetconfOperationService
- * instances
- */
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement)
- throws DocumentedException {
- try {
- sessionResources.close();
- Preconditions.checkNotNull(session, "Session was not set").delayedClose();
- LOG.info("Session {} closing", session.getSessionId());
- } catch (Exception e) {
- throw new DocumentedException("Unable to properly close session "
- + getNetconfSessionIdForReporting(), DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error, Collections.singletonMap(
- DocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
- }
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- public void setNetconfSession(final NetconfServerSession s) {
- this.session = s;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-
-public interface DefaultNetconfOperation {
- void setNetconfSession(NetconfServerSession s);
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag;
-import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DefaultStartExi extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {
- public static final String START_EXI = "start-exi";
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultStartExi.class);
- private NetconfServerSession netconfSession;
-
- public DefaultStartExi(final String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- public Document handle(final Document message,
- final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Received start-exi message {} ", XmlUtil.toString(message));
- }
-
- try {
- netconfSession.startExiCommunication(new NetconfMessage(message));
- } catch (IllegalArgumentException e) {
- throw new DocumentedException("Failed to parse EXI parameters", ErrorType.protocol,
- ErrorTag.operation_failed, ErrorSeverity.error);
- }
-
- return super.handle(message, subsequentOperation);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- Element getSchemaResult = document.createElementNS( XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlNetconfConstants.OK);
- LOG.trace("{} operation successful", START_EXI);
- return getSchemaResult;
- }
-
- @Override
- protected String getOperationName() {
- return START_EXI;
- }
-
- @Override
- protected String getOperationNamespace() {
- return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0;
- }
-
- @Override
- public void setNetconfSession(final NetconfServerSession s) {
- netconfSession = s;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class DefaultStopExi extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {
-
- public static final String STOP_EXI = "stop-exi";
- private NetconfServerSession netconfSession;
-
- private static final Logger LOG = LoggerFactory
- .getLogger(DefaultStopExi.class);
-
- public DefaultStopExi(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException {
- LOG.debug("Received stop-exi message {} ", XmlUtil.toString(operationElement));
-
- netconfSession.stopExiCommunication();
-
- Element getSchemaResult = document.createElementNS( XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlNetconfConstants.OK);
- LOG.trace("{} operation successful", STOP_EXI);
- return getSchemaResult;
- }
-
- @Override
- protected String getOperationName() {
- return STOP_EXI;
- }
-
- @Override
- protected String getOperationNamespace() {
- return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0;
- }
-
- @Override
- public void setNetconfSession(NetconfServerSession s) {
- this.netconfSession = s;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
-import org.opendaylight.controller.netconf.util.CloseableUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * NetconfOperationService aggregator. Makes a collection of operation services accessible as one.
- */
-public class AggregatedNetconfOperationServiceFactory implements NetconfOperationServiceFactory, NetconfOperationServiceFactoryListener, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(AggregatedNetconfOperationServiceFactory.class);
-
- private final Set<NetconfOperationServiceFactory> factories = new HashSet<>();
- private final Multimap<NetconfOperationServiceFactory, AutoCloseable> registrations = HashMultimap.create();
- private final Set<CapabilityListener> listeners = Sets.newHashSet();
-
- @Override
- public synchronized void onAddNetconfOperationServiceFactory(NetconfOperationServiceFactory service) {
- factories.add(service);
-
- for (final CapabilityListener listener : listeners) {
- AutoCloseable reg = service.registerCapabilityListener(listener);
- registrations.put(service, reg);
- }
- }
-
- @Override
- public synchronized void onRemoveNetconfOperationServiceFactory(NetconfOperationServiceFactory service) {
- factories.remove(service);
-
- for (final AutoCloseable autoCloseable : registrations.get(service)) {
- try {
- autoCloseable.close();
- } catch (Exception e) {
- LOG.warn("Unable to close listener registration", e);
- }
- }
-
- registrations.removeAll(service);
- }
-
- @Override
- public synchronized Set<Capability> getCapabilities() {
- final HashSet<Capability> capabilities = Sets.newHashSet();
- for (final NetconfOperationServiceFactory factory : factories) {
- capabilities.addAll(factory.getCapabilities());
- }
- return capabilities;
- }
-
- @Override
- public synchronized AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- final Map<NetconfOperationServiceFactory, AutoCloseable> regs = Maps.newHashMap();
-
- for (final NetconfOperationServiceFactory factory : factories) {
- final AutoCloseable reg = factory.registerCapabilityListener(listener);
- regs.put(factory, reg);
- }
- listeners.add(listener);
-
- return new AutoCloseable() {
- @Override
- public void close() throws Exception {
- synchronized (AggregatedNetconfOperationServiceFactory.this) {
- listeners.remove(listener);
- CloseableUtil.closeAll(regs.values());
- for (final Map.Entry<NetconfOperationServiceFactory, AutoCloseable> reg : regs.entrySet()) {
- registrations.remove(reg.getKey(), reg.getValue());
- }
- }
- }
- };
- }
-
- @Override
- public synchronized NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return new AggregatedNetconfOperation(factories, netconfSessionIdForReporting);
- }
-
- @Override
- public synchronized void close() throws Exception {
- factories.clear();
- for (AutoCloseable reg : registrations.values()) {
- reg.close();
- }
- registrations.clear();
- listeners.clear();
- }
-
- private static final class AggregatedNetconfOperation implements NetconfOperationService {
-
- private final Set<NetconfOperationService> services;
-
- public AggregatedNetconfOperation(final Set<NetconfOperationServiceFactory> factories, final String netconfSessionIdForReporting) {
- final Builder<NetconfOperationService> b = ImmutableSet.builder();
- for (final NetconfOperationServiceFactory factory : factories) {
- b.add(factory.createService(netconfSessionIdForReporting));
- }
- this.services = b.build();
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- final HashSet<NetconfOperation> operations = Sets.newHashSet();
- for (final NetconfOperationService service : services) {
- operations.addAll(service.getNetconfOperations());
- }
- return operations;
- }
-
- @Override
- public void close() {
- try {
- CloseableUtil.closeAll(services);
- } catch (final Exception e) {
- throw new IllegalStateException("Unable to properly close all aggregated services", e);
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.concurrent.TimeUnit;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
-import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfImplActivator implements BundleActivator {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfImplActivator.class);
-
- private NetconfOperationServiceFactoryTracker factoriesTracker;
- private NioEventLoopGroup eventLoopGroup;
- private HashedWheelTimer timer;
- private ServiceRegistration<NetconfMonitoringService> regMonitoring;
-
- private BaseNotificationPublisherRegistration listenerReg;
-
- @Override
- public void start(final BundleContext context) {
- try {
- AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
- startOperationServiceFactoryTracker(context, factoriesListener);
-
- SessionIdProvider idProvider = new SessionIdProvider();
- timer = new HashedWheelTimer();
- long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context);
-
- final NetconfMonitoringServiceImpl monitoringService = startMonitoringService(context, factoriesListener);
-
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- timer, factoriesListener, idProvider, connectionTimeoutMillis, monitoringService);
-
- eventLoopGroup = new NioEventLoopGroup();
-
- NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
- serverNegotiatorFactory);
- NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, eventLoopGroup, eventLoopGroup);
-
- LocalAddress address = NetconfConfigUtil.getNetconfLocalAddress();
- LOG.trace("Starting local netconf server at {}", address);
- dispatch.createLocalServer(address);
-
- final ServiceTracker<NetconfNotificationCollector, NetconfNotificationCollector> notificationServiceTracker =
- new ServiceTracker<>(context, NetconfNotificationCollector.class, new ServiceTrackerCustomizer<NetconfNotificationCollector, NetconfNotificationCollector>() {
- @Override
- public NetconfNotificationCollector addingService(ServiceReference<NetconfNotificationCollector> reference) {
- listenerReg = context.getService(reference).registerBaseNotificationPublisher();
- monitoringService.setNotificationPublisher(listenerReg);
- return null;
- }
-
- @Override
- public void modifiedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
-
- }
-
- @Override
- public void removedService(ServiceReference<NetconfNotificationCollector> reference, NetconfNotificationCollector service) {
- listenerReg.close();
- listenerReg = null;
- monitoringService.setNotificationPublisher(listenerReg);
- }
- });
- notificationServiceTracker.open();
- } catch (Exception e) {
- LOG.warn("Unable to start NetconfImplActivator", e);
- }
- }
-
- private void startOperationServiceFactoryTracker(BundleContext context, NetconfOperationServiceFactoryListener factoriesListener) {
- factoriesTracker = new NetconfOperationServiceFactoryTracker(context, factoriesListener);
- factoriesTracker.open();
- }
-
- private NetconfMonitoringServiceImpl startMonitoringService(BundleContext context, AggregatedNetconfOperationServiceFactory factoriesListener) {
- NetconfMonitoringServiceImpl netconfMonitoringServiceImpl = new NetconfMonitoringServiceImpl(factoriesListener);
- Dictionary<String, ?> dic = new Hashtable<>();
- regMonitoring = context.registerService(NetconfMonitoringService.class, netconfMonitoringServiceImpl, dic);
-
- return netconfMonitoringServiceImpl;
- }
-
- @Override
- public void stop(final BundleContext context) {
- LOG.info("Shutting down netconf because YangStoreService service was removed");
-
- eventLoopGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS);
- timer.stop();
-
- regMonitoring.unregister();
- factoriesTracker.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import io.netty.util.internal.ConcurrentSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.config.util.capability.BasicCapability;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfStateBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.ChangedByBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.changed.by.parms.changed.by.server.or.user.ServerBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, AutoCloseable {
-
- private static final Schema.Location NETCONF_LOCATION = new Schema.Location(Schema.Location.Enumeration.NETCONF);
- private static final List<Schema.Location> NETCONF_LOCATIONS = ImmutableList.of(NETCONF_LOCATION);
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMonitoringServiceImpl.class);
- private static final Function<NetconfManagementSession, Session> SESSION_FUNCTION = new Function<NetconfManagementSession, Session>() {
- @Override
- public Session apply(@Nonnull final NetconfManagementSession input) {
- return input.toManagementSession();
- }
- };
- private static final Function<Capability, Uri> CAPABILITY_TO_URI = new Function<Capability, Uri>() {
- @Override
- public Uri apply(final Capability input) {
- return new Uri(input.getCapabilityUri());
- }
- };
-
- private final Set<NetconfManagementSession> sessions = new ConcurrentSet<>();
- private final NetconfOperationServiceFactory netconfOperationProvider;
- private final Map<Uri, Capability> capabilities = new ConcurrentHashMap<>();
-
- private final Set<MonitoringListener> listeners = Sets.newHashSet();
- private volatile BaseNotificationPublisherRegistration notificationPublisher;
-
- public NetconfMonitoringServiceImpl(final NetconfOperationServiceFactory netconfOperationProvider) {
- this.netconfOperationProvider = netconfOperationProvider;
- netconfOperationProvider.registerCapabilityListener(this);
- }
-
- @Override
- public synchronized void onSessionUp(final NetconfManagementSession session) {
- LOG.debug("Session {} up", session);
- Preconditions.checkState(!sessions.contains(session), "Session %s was already added", session);
- sessions.add(session);
- notifyListeners();
- }
-
- @Override
- public synchronized void onSessionDown(final NetconfManagementSession session) {
- LOG.debug("Session {} down", session);
- Preconditions.checkState(sessions.contains(session), "Session %s not present", session);
- sessions.remove(session);
- notifyListeners();
- }
-
- @Override
- public synchronized Sessions getSessions() {
- return new SessionsBuilder().setSession(ImmutableList.copyOf(Collections2.transform(sessions, SESSION_FUNCTION))).build();
- }
-
- @Override
- public synchronized Schemas getSchemas() {
- try {
- return transformSchemas(netconfOperationProvider.getCapabilities());
- } catch (final RuntimeException e) {
- throw e;
- } catch (final Exception e) {
- throw new IllegalStateException("Exception while closing", e);
- }
- }
-
- @Override
- public synchronized String getSchemaForCapability(final String moduleName, final Optional<String> revision) {
-
- // FIXME not effective at all
-
- Map<String, Map<String, String>> mappedModulesToRevisionToSchema = Maps.newHashMap();
-
- final Collection<Capability> caps = capabilities.values();
-
- for (Capability cap : caps) {
- if (!cap.getModuleName().isPresent()
- || !cap.getRevision().isPresent()
- || !cap.getCapabilitySchema().isPresent()){
- continue;
- }
-
- final String currentModuleName = cap.getModuleName().get();
- Map<String, String> revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName);
- if (revisionMap == null) {
- revisionMap = Maps.newHashMap();
- mappedModulesToRevisionToSchema.put(currentModuleName, revisionMap);
- }
-
- String currentRevision = cap.getRevision().get();
- revisionMap.put(currentRevision, cap.getCapabilitySchema().get());
- }
-
- Map<String, String> revisionMapRequest = mappedModulesToRevisionToSchema.get(moduleName);
- Preconditions.checkState(revisionMapRequest != null, "Capability for module %s not present, " + ""
- + "available modules : %s", moduleName, Collections2.transform(caps, CAPABILITY_TO_URI));
-
- if (revision.isPresent()) {
- String schema = revisionMapRequest.get(revision.get());
-
- Preconditions.checkState(schema != null,
- "Capability for module %s:%s not present, available revisions for module: %s", moduleName,
- revision.get(), revisionMapRequest.keySet());
-
- return schema;
- } else {
- Preconditions.checkState(revisionMapRequest.size() == 1,
- "Expected 1 capability for module %s, available revisions : %s", moduleName,
- revisionMapRequest.keySet());
- return revisionMapRequest.values().iterator().next();
- }
- }
-
- @Override
- public synchronized Capabilities getCapabilities() {
- return new CapabilitiesBuilder().setCapability(Lists.newArrayList(capabilities.keySet())).build();
- }
-
- @Override
- public synchronized AutoCloseable registerListener(final MonitoringListener listener) {
- listeners.add(listener);
- listener.onStateChanged(getCurrentNetconfState());
- return new AutoCloseable() {
- @Override
- public void close() throws Exception {
- listeners.remove(listener);
- }
- };
- }
-
- private NetconfState getCurrentNetconfState() {
- return new NetconfStateBuilder()
- .setCapabilities(getCapabilities())
- .setSchemas(getSchemas())
- .setSessions(getSessions())
- .build();
- }
-
- private static Schemas transformSchemas(final Set<Capability> caps) {
- final List<Schema> schemas = new ArrayList<>(caps.size());
- for (final Capability cap : caps) {
- if (cap.getCapabilitySchema().isPresent()) {
- final SchemaBuilder builder = new SchemaBuilder();
- Preconditions.checkState(cap.getModuleNamespace().isPresent());
- builder.setNamespace(new Uri(cap.getModuleNamespace().get()));
-
- Preconditions.checkState(cap.getRevision().isPresent());
- final String version = cap.getRevision().get();
- builder.setVersion(version);
-
- Preconditions.checkState(cap.getModuleName().isPresent());
- final String identifier = cap.getModuleName().get();
- builder.setIdentifier(identifier);
-
- builder.setFormat(Yang.class);
-
- builder.setLocation(transformLocations(cap.getLocation()));
-
- builder.setKey(new SchemaKey(Yang.class, identifier, version));
-
- schemas.add(builder.build());
- }
- }
-
- return new SchemasBuilder().setSchema(schemas).build();
- }
-
- private static List<Schema.Location> transformLocations(final Collection<String> locations) {
- if (locations.isEmpty()) {
- return NETCONF_LOCATIONS;
- }
-
- final Builder<Schema.Location> b = ImmutableList.builder();
- b.add(NETCONF_LOCATION);
-
- for (final String location : locations) {
- b.add(new Schema.Location(new Uri(location)));
- }
-
- return b.build();
- }
-
- public static Set<Capability> setupCapabilities(final Set<Capability> caps) {
- Set<Capability> capabilities = new HashSet<>(caps);
- capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
- // TODO rollback on error not supported EditConfigXmlParser:100
- // [RFC6241] 8.5. Rollback-on-Error Capability
- // capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
- return capabilities;
- }
-
- @Override
- public synchronized void close() throws Exception {
- listeners.clear();
- sessions.clear();
- capabilities.clear();
- }
-
- @Override
- public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
- onCapabilitiesAdded(added);
- onCapabilitiesRemoved(removed);
- notifyListeners();
-
- // publish notification to notification collector about changed capabilities
- if (notificationPublisher != null) {
- notificationPublisher.onCapabilityChanged(computeDiff(added, removed));
- }
- }
-
- static NetconfCapabilityChange computeDiff(final Set<Capability> removed, final Set<Capability> added) {
- final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
- netconfCapabilityChangeBuilder.setChangedBy(new ChangedByBuilder().setServerOrUser(new ServerBuilder().setServer(true).build()).build());
- netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(Collections2.transform(removed, CAPABILITY_TO_URI)));
- netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(Collections2.transform(added, CAPABILITY_TO_URI)));
- // TODO modified should be computed ... but why ?
- netconfCapabilityChangeBuilder.setModifiedCapability(Collections.<Uri>emptyList());
- return netconfCapabilityChangeBuilder.build();
- }
-
-
- private synchronized void onCapabilitiesAdded(final Set<Capability> addedCaps) {
- // FIXME howto check for duplicates
- this.capabilities.putAll(Maps.uniqueIndex(setupCapabilities(addedCaps), CAPABILITY_TO_URI));
- }
-
- private void notifyListeners() {
- for (final MonitoringListener listener : listeners) {
- listener.onStateChanged(getCurrentNetconfState());
- }
- }
-
- private synchronized void onCapabilitiesRemoved(final Set<Capability> addedCaps) {
- for (final Capability addedCap : addedCaps) {
- capabilities.remove(CAPABILITY_TO_URI.apply(addedCap));
- }
- }
-
- public void setNotificationPublisher(final BaseNotificationPublisherRegistration notificationPublisher) {
- this.notificationPublisher = notificationPublisher;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.w3c.dom.Document;
-
-public interface NetconfOperationRouter extends AutoCloseable {
-
- Document onNetconfMessage(Document message, NetconfServerSession session)
- throws DocumentedException;
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-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 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.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
-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.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.SessionAwareNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-public class NetconfOperationRouterImpl implements NetconfOperationRouter {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfOperationRouterImpl.class);
- private final NetconfOperationService netconfOperationServiceSnapshot;
- private final Collection<NetconfOperation> allNetconfOperations;
-
- public NetconfOperationRouterImpl(final NetconfOperationService netconfOperationServiceSnapshot,
- final NetconfMonitoringService netconfMonitoringService, final String sessionId) {
- this.netconfOperationServiceSnapshot = Preconditions.checkNotNull(netconfOperationServiceSnapshot);
-
- final Set<NetconfOperation> ops = new HashSet<>();
- ops.add(new DefaultCloseSession(sessionId, this));
- ops.add(new DefaultStartExi(sessionId));
- ops.add(new DefaultStopExi(sessionId));
-
- ops.addAll(netconfOperationServiceSnapshot.getNetconfOperations());
-
- allNetconfOperations = ImmutableSet.copyOf(ops);
- }
-
- @Override
- public Document onNetconfMessage(final Document message, final NetconfServerSession session) throws DocumentedException {
- Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
-
- final NetconfOperationExecution netconfOperationExecution;
- try {
- netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session);
- } catch (IllegalArgumentException | IllegalStateException e) {
- final String messageAsString = XmlUtil.toString(message);
- LOG.warn("Unable to handle rpc {} on session {}", messageAsString, session, e);
-
- final DocumentedException.ErrorTag tag;
- if (e instanceof IllegalArgumentException) {
- tag = DocumentedException.ErrorTag.operation_not_supported;
- } else {
- tag = DocumentedException.ErrorTag.operation_failed;
- }
-
- throw new DocumentedException(
- String.format("Unable to handle rpc %s on session %s", messageAsString, session),
- e, DocumentedException.ErrorType.application,
- tag, DocumentedException.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);
- } catch (RuntimeException e) {
- throw handleUnexpectedEx("Unexpected exception during netconf operation execution", e);
- }
- }
-
- @Override
- public void close() throws Exception {
- netconfOperationServiceSnapshot.close();
- }
-
- private static DocumentedException handleUnexpectedEx(final String s, final Exception e) throws DocumentedException {
- LOG.error("{}", s, e);
- return new DocumentedException("Unexpected error",
- DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error,
- Collections.singletonMap(DocumentedException.ErrorSeverity.error.toString(), e.toString()));
- }
-
- private Document executeOperationWithHighestPriority(final Document message,
- final NetconfOperationExecution netconfOperationExecution)
- throws DocumentedException {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Forwarding netconf message {} to {}", XmlUtil.toString(message), netconfOperationExecution.netconfOperation);
- }
-
- return netconfOperationExecution.execute(message);
- }
-
- private NetconfOperationExecution getNetconfOperationWithHighestPriority(
- final Document message, final NetconfServerSession session) throws DocumentedException {
-
- NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
- message, session);
-
- 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<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(final Document message,
- final NetconfServerSession session) throws DocumentedException {
- TreeMap<HandlingPriority, NetconfOperation> sortedPriority = Maps.newTreeMap();
-
- for (NetconfOperation netconfOperation : allNetconfOperations) {
- final HandlingPriority handlingPriority = netconfOperation.canHandle(message);
- if (netconfOperation instanceof DefaultNetconfOperation) {
- ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session);
- }
- if(netconfOperation instanceof SessionAwareNetconfOperation) {
- ((SessionAwareNetconfOperation) netconfOperation).setSession(session);
- }
- if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) {
-
- 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 DocumentedException {
- throw new DocumentedException("This execution represents the termination point in operation execution and cannot be executed itself",
- DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error);
- }
- };
-
- private static class NetconfOperationExecution implements NetconfOperationChainedExecution {
- private final NetconfOperation netconfOperation;
- private final NetconfOperationChainedExecution subsequentExecution;
-
- private NetconfOperationExecution(final NetconfOperation netconfOperation, final NetconfOperationChainedExecution subsequentExecution) {
- this.netconfOperation = netconfOperation;
- this.subsequentExecution = subsequentExecution;
- }
-
- @Override
- public boolean isExecutionTermination() {
- return false;
- }
-
- @Override
- public Document execute(final Document message) throws DocumentedException {
- return netconfOperation.handle(message, subsequentExecution);
- }
-
- public static NetconfOperationExecution createExecutionChain(
- final NavigableMap<HandlingPriority, NetconfOperation> sortedByPriority, final HandlingPriority handlingPriority) {
- NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority);
- HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);
-
- NetconfOperationChainedExecution subsequentExecution = null;
-
- if (subsequentHandlingPriority != null) {
- subsequentExecution = createExecutionChain(sortedByPriority, subsequentHandlingPriority);
- } else {
- subsequentExecution = EXECUTION_TERMINATION_POINT;
- }
-
- return new NetconfOperationExecution(netconfOperation, subsequentExecution);
- }
- }
-
- @Override
- public String toString() {
- return "NetconfOperationRouterImpl{" + "netconfOperationServiceSnapshot=" + netconfOperationServiceSnapshot
- + '}';
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import org.opendaylight.controller.netconf.api.util.NetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-class NetconfOperationServiceFactoryTracker extends
- ServiceTracker<NetconfOperationServiceFactory, NetconfOperationServiceFactory> {
- private final NetconfOperationServiceFactoryListener factoriesListener;
-
- NetconfOperationServiceFactoryTracker(BundleContext context,
- final NetconfOperationServiceFactoryListener factoriesListener) {
- super(context, NetconfOperationServiceFactory.class, null);
- this.factoriesListener = factoriesListener;
- }
-
- @Override
- public NetconfOperationServiceFactory addingService(ServiceReference<NetconfOperationServiceFactory> reference) {
- Object property = reference.getProperty(NetconfConstants.SERVICE_NAME);
- if (property != null
- && (property.equals(NetconfConstants.CONFIG_NETCONF_CONNECTOR)
- || property.equals(NetconfConstants.NETCONF_MONITORING))) {
- NetconfOperationServiceFactory netconfOperationServiceFactory = super.addingService(reference);
- factoriesListener.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
- return netconfOperationServiceFactory;
- }
-
- return null;
- }
-
- @Override
- public void removedService(ServiceReference<NetconfOperationServiceFactory> reference,
- NetconfOperationServiceFactory netconfOperationServiceFactory) {
- if (netconfOperationServiceFactory != null) {
- factoriesListener.onRemoveNetconfOperationServiceFactory(netconfOperationServiceFactory);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.util;
-
-import com.google.common.collect.Maps;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class DeserializerExceptionHandler implements ChannelHandler {
-
- private static final Logger LOG = LoggerFactory.getLogger(DeserializerExceptionHandler.class);
-
- @Override
- public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
- // NOOP
- }
-
- @Override
- public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
- // NOOP
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- LOG.warn("An exception occurred during message handling", cause);
- handleDeserializerException(ctx, cause);
- }
-
- private void handleDeserializerException(ChannelHandlerContext ctx, Throwable cause) {
-
- Map<String, String> info = Maps.newHashMap();
- info.put("cause", cause.getMessage());
- DocumentedException ex = new DocumentedException(cause.getMessage(),
- DocumentedException.ErrorType.rpc, DocumentedException.ErrorTag.malformed_message,
- DocumentedException.ErrorSeverity.error, info);
-
- SendErrorExceptionUtil.sendErrorMessage(ctx.channel(), ex);
- }
-}
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="commitNotification">
- <get-config>
- <source>
- <candidate/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-// vi: set smarttab et sw=4 tabstop=4:
-module netconf-northbound-impl {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl";
- prefix "cfg-net-s-i";
-
- import config { prefix config; revision-date 2013-04-05; }
- import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
- import netconf-northbound { prefix nn; revision-date 2015-01-14; }
- import netty {prefix netty; }
-
- description
- "This module contains the base YANG definitions for
- netconf-server-dispatcher implementation.
-
- Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
-
- This program and the accompanying materials are made available
- under the terms of the Eclipse Public License v1.0 which
- accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html";
-
- revision "2015-01-12" {
- description
- "Initial revision.";
- }
-
- identity netconf-server-dispatcher-impl {
- base config:module-type;
- config:provided-service nn:netconf-server-dispatcher;
- config:java-name-prefix NetconfServerDispatcher;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-server-dispatcher-impl {
- when "/config:modules/config:module/config:type = 'netconf-server-dispatcher-impl'";
-
- leaf connection-timeout-millis {
- description "Specifies timeout in milliseconds after which connection must be established.";
- type uint32;
- default 20000;
- }
-
- container boss-thread-group {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- container worker-thread-group {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- list mappers {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity nnm:netconf-northbound-mapper;
- }
- }
- }
-
- container server-monitor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity nn:netconf-server-monitoring;
- }
- }
- }
-
- container timer {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-timer;
- }
- }
- }
- }
- }
-
-
- identity netconf-server-monitoring-impl {
- base config:module-type;
- config:provided-service nn:netconf-server-monitoring;
- config:java-name-prefix NetconfServerMonitoring;
- }
-
- // TODO Monitoring could expose the monitoring data over JMX...
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-server-monitoring-impl {
- when "/config:modules/config:module/config:type = 'netconf-server-monitoring-impl'";
-
- container aggregator {
- uses config:service-ref {
- refine type {
- config:required-identity nnm:netconf-northbound-mapper;
- }
- }
- }
-
- }
- }
-
- identity netconf-mapper-aggregator {
- base config:module-type;
- config:provided-service nnm:netconf-northbound-mapper;
- config:provided-service nnm:netconf-mapper-registry;
- config:java-name-prefix NetconfMapperAggregator;
- description "Aggregated operation provider for netconf servers. Joins all the operations and capabilities of all the mappers it aggregates and exposes them as a single service. The dependency orientation is reversed in order to prevent cyclic dependencies when monitoring service is considered";
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-mapper-aggregator {
- when "/config:modules/config:module/config:type = 'netconf-mapper-aggregator'";
-
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-
-public class AdditionalHeaderParserTest {
-
- @Test
- public void testParsing() throws Exception {
- String s = "[netconf;10.12.0.102:48528;ssh;;;;;;]";
- NetconfHelloMessageAdditionalHeader header = NetconfHelloMessageAdditionalHeader.fromString(s);
- assertEquals("netconf", header.getUserName());
- assertEquals("10.12.0.102", header.getAddress());
- assertEquals("ssh", header.getTransport());
- }
-
- @Test
- public void testParsing2() throws Exception {
- String s = "[tomas;10.0.0.0/10000;tcp;1000;1000;;/home/tomas;;]";
- NetconfHelloMessageAdditionalHeader header = NetconfHelloMessageAdditionalHeader.fromString(s);
- assertEquals("tomas", header.getUserName());
- assertEquals("10.0.0.0", header.getAddress());
- assertEquals("tcp", header.getTransport());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testParsingNoUsername() throws Exception {
- String s = "[10.12.0.102:48528;ssh;;;;;;]";
- NetconfHelloMessageAdditionalHeader.fromString(s);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anySetOf;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.io.ByteStreams;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicLong;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-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.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-@RunWith(Parameterized.class)
-public class ConcurrentClientsTest {
- private static final Logger LOG = LoggerFactory.getLogger(ConcurrentClientsTest.class);
-
- private static ExecutorService clientExecutor;
-
- private static final int CONCURRENCY = 32;
- private static final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303);
-
- private int nettyThreads;
- private Class<? extends Runnable> clientRunnable;
- private Set<String> serverCaps;
-
- public ConcurrentClientsTest(int nettyThreads, Class<? extends Runnable> clientRunnable, Set<String> serverCaps) {
- this.nettyThreads = nettyThreads;
- this.clientRunnable = clientRunnable;
- this.serverCaps = serverCaps;
- }
-
- @Parameterized.Parameters()
- public static Collection<Object[]> data() {
- return Arrays.asList(new Object[][]{{4, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES},
- {1, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES},
- // empty set of capabilities = only base 1.0 netconf capability
- {4, TestingNetconfClientRunnable.class, Collections.emptySet()},
- {4, TestingNetconfClientRunnable.class, getOnlyExiServerCaps()},
- {4, TestingNetconfClientRunnable.class, getOnlyChunkServerCaps()},
- {4, BlockingClientRunnable.class, getOnlyExiServerCaps()},
- {1, BlockingClientRunnable.class, getOnlyExiServerCaps()},
- });
- }
-
- private EventLoopGroup nettyGroup;
- private NetconfClientDispatcher netconfClientDispatcher;
-
- HashedWheelTimer hashedWheelTimer;
- private TestingNetconfOperation testingNetconfOperation;
-
- public static NetconfMonitoringService createMockedMonitoringService() {
- NetconfMonitoringService monitoring = mock(NetconfMonitoringService.class);
- doNothing().when(monitoring).onSessionUp(any(NetconfServerSession.class));
- doNothing().when(monitoring).onSessionDown(any(NetconfServerSession.class));
- doReturn(new AutoCloseable() {
- @Override
- public void close() throws Exception {
-
- }
- }).when(monitoring).registerListener(any(NetconfMonitoringService.MonitoringListener.class));
- doNothing().when(monitoring).onCapabilitiesChanged(anySetOf(Capability.class), anySetOf(Capability.class));
- doReturn(new CapabilitiesBuilder().setCapability(Collections.<Uri>emptyList()).build()).when(monitoring).getCapabilities();
- return monitoring;
- }
-
- @BeforeClass
- public static void setUpClientExecutor() {
- clientExecutor = Executors.newFixedThreadPool(CONCURRENCY, new ThreadFactory() {
- int i = 1;
-
- @Override
- public Thread newThread(final Runnable r) {
- Thread thread = new Thread(r);
- thread.setName("client-" + i++);
- thread.setDaemon(true);
- return thread;
- }
- });
- }
-
- @Before
- public void setUp() throws Exception {
- hashedWheelTimer = new HashedWheelTimer();
- nettyGroup = new NioEventLoopGroup(nettyThreads);
- netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyGroup, nettyGroup, hashedWheelTimer);
-
- AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
-
- testingNetconfOperation = new TestingNetconfOperation();
- factoriesListener.onAddNetconfOperationServiceFactory(new TestingOperationServiceFactory(testingNetconfOperation));
-
- SessionIdProvider idProvider = new SessionIdProvider();
-
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- hashedWheelTimer, factoriesListener, idProvider, 5000, createMockedMonitoringService(), serverCaps);
-
- NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
- final NetconfServerDispatcherImpl dispatch = new NetconfServerDispatcherImpl(serverChannelInitializer, nettyGroup, nettyGroup);
-
- ChannelFuture s = dispatch.createServer(netconfAddress);
- s.await();
- }
-
- @After
- public void tearDown(){
- hashedWheelTimer.stop();
- try {
- nettyGroup.shutdownGracefully().get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Ignoring exception while cleaning up after test", e);
- }
- }
-
- @AfterClass
- public static void tearDownClientExecutor() {
- clientExecutor.shutdownNow();
- }
-
- @Test(timeout = CONCURRENCY * 1000)
- public void testConcurrentClients() throws Exception {
-
- List<Future<?>> futures = Lists.newArrayListWithCapacity(CONCURRENCY);
-
- for (int i = 0; i < CONCURRENCY; i++) {
- futures.add(clientExecutor.submit(getInstanceOfClientRunnable()));
- }
-
- for (Future<?> future : futures) {
- try {
- future.get();
- } catch (InterruptedException e) {
- throw new IllegalStateException(e);
- } catch (ExecutionException e) {
- LOG.error("Thread for testing client failed", e);
- fail("Client failed: " + e.getMessage());
- }
- }
-
- assertEquals(CONCURRENCY, testingNetconfOperation.getMessageCount());
- }
-
- public static Set<String> getOnlyExiServerCaps() {
- return Sets.newHashSet(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0
- );
- }
-
- public static Set<String> getOnlyChunkServerCaps() {
- return Sets.newHashSet(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1
- );
- }
-
- public Runnable getInstanceOfClientRunnable() throws Exception {
- return clientRunnable.getConstructor(ConcurrentClientsTest.class).newInstance(this);
- }
-
- /**
- * Responds to all operations except start-exi and counts all requests
- */
- private static class TestingNetconfOperation implements NetconfOperation {
-
- private final AtomicLong counter = new AtomicLong();
-
- @Override
- public HandlingPriority canHandle(Document message) {
- return XmlUtil.toString(message).contains(NetconfStartExiMessage.START_EXI) ?
- HandlingPriority.CANNOT_HANDLE :
- HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
- }
-
- @Override
- public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- try {
- LOG.info("Handling netconf message from test {}", XmlUtil.toString(requestMessage));
- counter.getAndIncrement();
- return XmlUtil.readXmlToDocument("<test/>");
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- public long getMessageCount() {
- return counter.get();
- }
- }
-
- /**
- * Hardcoded operation service factory
- */
- private static class TestingOperationServiceFactory implements NetconfOperationServiceFactory {
- private final NetconfOperation[] operations;
-
- public TestingOperationServiceFactory(final NetconfOperation... operations) {
- this.operations = operations;
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- return Collections.emptySet();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return new AutoCloseable(){
- @Override
- public void close() throws Exception {}
- };
- }
-
- @Override
- public NetconfOperationService createService(String netconfSessionIdForReporting) {
- return new NetconfOperationService() {
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return Sets.newHashSet(operations);
- }
-
- @Override
- public void close() {}
- };
- }
- }
-
- /**
- * Pure socket based blocking client
- */
- public final class BlockingClientRunnable implements Runnable {
-
- @Override
- public void run() {
- try {
- run2();
- } catch (Exception e) {
- throw new IllegalStateException(Thread.currentThread().getName(), e);
- }
- }
-
- private void run2() throws Exception {
- InputStream clientHello = checkNotNull(XmlFileLoader
- .getResourceAsStream("netconfMessages/client_hello.xml"));
- InputStream getConfig = checkNotNull(XmlFileLoader.getResourceAsStream("netconfMessages/getConfig.xml"));
-
- Socket clientSocket = new Socket(netconfAddress.getHostString(), netconfAddress.getPort());
- DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
- InputStreamReader inFromServer = new InputStreamReader(clientSocket.getInputStream());
-
- StringBuffer sb = new StringBuffer();
- while (sb.toString().endsWith("]]>]]>") == false) {
- sb.append((char) inFromServer.read());
- }
- LOG.info(sb.toString());
-
- outToServer.write(ByteStreams.toByteArray(clientHello));
- outToServer.write("]]>]]>".getBytes());
- outToServer.flush();
- // Thread.sleep(100);
- outToServer.write(ByteStreams.toByteArray(getConfig));
- outToServer.write("]]>]]>".getBytes());
- outToServer.flush();
- Thread.sleep(100);
- sb = new StringBuffer();
- while (sb.toString().endsWith("]]>]]>") == false) {
- sb.append((char) inFromServer.read());
- }
- LOG.info(sb.toString());
- clientSocket.close();
- }
- }
-
- /**
- * TestingNetconfClient based runnable
- */
- public final class TestingNetconfClientRunnable implements Runnable {
-
- @Override
- public void run() {
- try {
- final TestingNetconfClient netconfClient =
- new TestingNetconfClient(Thread.currentThread().getName(), netconfClientDispatcher, getClientConfig());
- long sessionId = netconfClient.getSessionId();
- LOG.info("Client with session id {}: hello exchanged", sessionId);
-
- final NetconfMessage getMessage = XmlFileLoader
- .xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
- NetconfMessage result = netconfClient.sendRequest(getMessage).get();
- LOG.info("Client with session id {}: got result {}", sessionId, result);
-
- Preconditions.checkState(NetconfMessageUtil.isErrorMessage(result) == false,
- "Received error response: " + XmlUtil.toString(result.getDocument()) + " to request: "
- + XmlUtil.toString(getMessage.getDocument()));
-
- netconfClient.close();
- LOG.info("Client with session id {}: ended", sessionId);
- } catch (final Exception e) {
- throw new IllegalStateException(Thread.currentThread().getName(), e);
- }
- }
-
- private NetconfClientConfiguration getClientConfig() {
- final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
- b.withAddress(netconfAddress);
- b.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp",
- "client"));
- b.withSessionListener(new SimpleNetconfClientSessionListener());
- b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE,
- NetconfClientConfigurationBuilder.DEFAULT_CONNECTION_TIMEOUT_MILLIS));
- return b.build();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.impl;
-
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-
-public class ExiEncodeDecodeTest {
- @Test
- public void encodeExi() throws Exception{
-
- String startExiString = XmlFileLoader.xmlFileToString("netconfMessages/startExi.xml");
- assertNotNull(startExiString);
-
- NetconfMessage startExiMessage = XmlFileLoader.xmlFileToNetconfMessage(("netconfMessages/startExi.xml"));
- assertNotNull(startExiMessage);
-
- /*
- ExiParameters exiParams = new ExiParameters();
- exiParams.setParametersFromXmlElement(XmlElement.fromDomElement(startExiMessage.getDocument().getDocumentElement()));
- assertNotNull(exiParams);
-
- ByteBuf encodedBuf = Unpooled.buffer();
- ByteBuf sourceBuf = Unpooled.copiedBuffer(startExiString.getBytes());
- ExiUtil.encode(sourceBuf, encodedBuf, exiParams);
-
- List<Object> newOut = new ArrayList<Object>();
- ExiUtil.decode(encodedBuf, newOut, exiParams);
-
- ByteBuf decodedBuf = (ByteBuf)newOut.get(0);
- String decodedString = new String(decodedBuf.array(),"UTF-8");
- assertNotNull(decodedString);
- */
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageHeader;
-
-@Deprecated
-public class MessageHeaderTest {
- @Test
- public void testFromBytes() {
- final byte[] raw = new byte[] { (byte) 0x0a, (byte) 0x23, (byte) 0x35, (byte) 0x38, (byte) 0x0a };
- NetconfMessageHeader header = NetconfMessageHeader.fromBytes(raw);
- assertEquals(58, header.getLength());
- }
-
- @Test
- public void testToBytes() {
- NetconfMessageHeader header = new NetconfMessageHeader(123);
- assertArrayEquals(new byte[] { (byte) 0x0a, (byte) 0x23, (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x0a },
- header.toBytes());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.embedded.EmbeddedChannel;
-import java.util.Queue;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.nettyutil.handler.ChunkedFramingMechanismEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfChunkAggregator;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEOMAggregator;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
-import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageHeader;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-
-public class MessageParserTest {
-
- private NetconfMessage msg;
-
- @Before
- public void setUp() throws Exception {
- this.msg = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
- }
-
- @Test
- public void testChunkedFramingMechanismOnPipeline() throws Exception {
- EmbeddedChannel testChunkChannel = new EmbeddedChannel(
- FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK),
- new NetconfMessageToXMLEncoder(),
-
- new NetconfChunkAggregator(),
- new NetconfXMLToMessageDecoder());
-
- testChunkChannel.writeOutbound(this.msg);
- Queue<Object> messages = testChunkChannel.outboundMessages();
- assertFalse(messages.isEmpty());
-
- final NetconfMessageToXMLEncoder enc = new NetconfMessageToXMLEncoder();
- final ByteBuf out = Unpooled.buffer();
- enc.encode(null, msg, out);
- int msgLength = out.readableBytes();
-
- int chunkCount = msgLength / ChunkedFramingMechanismEncoder.DEFAULT_CHUNK_SIZE;
- if ((msgLength % ChunkedFramingMechanismEncoder.DEFAULT_CHUNK_SIZE) != 0) {
- chunkCount++;
- }
- for (int i = 1; i <= chunkCount; i++) {
- ByteBuf recievedOutbound = (ByteBuf) messages.poll();
- int exptHeaderLength = ChunkedFramingMechanismEncoder.DEFAULT_CHUNK_SIZE;
- if (i == chunkCount) {
- exptHeaderLength = msgLength - (ChunkedFramingMechanismEncoder.DEFAULT_CHUNK_SIZE * (i - 1));
- byte[] eom = new byte[NetconfMessageConstants.END_OF_CHUNK.length];
- recievedOutbound.getBytes(recievedOutbound.readableBytes() - NetconfMessageConstants.END_OF_CHUNK.length,
- eom);
- assertArrayEquals(NetconfMessageConstants.END_OF_CHUNK, eom);
- }
-
- byte[] header = new byte[String.valueOf(exptHeaderLength).length()
- + NetconfMessageConstants.MIN_HEADER_LENGTH - 1];
- recievedOutbound.getBytes(0, header);
- NetconfMessageHeader messageHeader = NetconfMessageHeader.fromBytes(header);
- assertEquals(exptHeaderLength, messageHeader.getLength());
-
- testChunkChannel.writeInbound(recievedOutbound);
- }
- assertTrue(messages.isEmpty());
-
- NetconfMessage receivedMessage = (NetconfMessage) testChunkChannel.readInbound();
- assertNotNull(receivedMessage);
- assertXMLEqual(this.msg.getDocument(), receivedMessage.getDocument());
- }
-
- @Test
- public void testEOMFramingMechanismOnPipeline() throws Exception {
- EmbeddedChannel testChunkChannel = new EmbeddedChannel(
- FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM),
- new NetconfMessageToXMLEncoder(), new NetconfEOMAggregator(), new NetconfXMLToMessageDecoder());
-
- testChunkChannel.writeOutbound(this.msg);
- ByteBuf recievedOutbound = (ByteBuf) testChunkChannel.readOutbound();
-
- byte[] eom = new byte[NetconfMessageConstants.END_OF_MESSAGE.length];
- recievedOutbound.getBytes(recievedOutbound.readableBytes() - NetconfMessageConstants.END_OF_MESSAGE.length, eom);
- assertArrayEquals(NetconfMessageConstants.END_OF_MESSAGE, eom);
-
- testChunkChannel.writeInbound(recievedOutbound);
- NetconfMessage receivedMessage = (NetconfMessage) testChunkChannel.readInbound();
- assertNotNull(receivedMessage);
- assertXMLEqual(this.msg.getDocument(), receivedMessage.getDocument());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.net.InetSocketAddress;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-
-public class NetconfDispatcherImplTest {
-
- private EventLoopGroup nettyGroup;
- private NetconfServerDispatcherImpl dispatch;
- private HashedWheelTimer hashedWheelTimer;
-
-
- @Before
- public void setUp() throws Exception {
- nettyGroup = new NioEventLoopGroup();
-
- AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
-
- SessionIdProvider idProvider = new SessionIdProvider();
- hashedWheelTimer = new HashedWheelTimer();
- NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- hashedWheelTimer, factoriesListener, idProvider, 5000, ConcurrentClientsTest.createMockedMonitoringService());
-
- NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(serverNegotiatorFactory);
-
- dispatch = new NetconfServerDispatcherImpl(
- serverChannelInitializer, nettyGroup, nettyGroup);
- }
-
- @After
- public void tearDown() throws Exception {
- hashedWheelTimer.stop();
- nettyGroup.shutdownGracefully();
- }
-
- @Test
- public void test() throws Exception {
- InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 8333);
- ChannelFuture s = dispatch.createServer(addr);
- s.get();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-public class NetconfMonitoringServiceImplTest {
-
- // TODO redo test
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-import org.apache.sshd.common.SshdSocketAddress;
-import org.junit.Test;
-
-public class NetconfServerSessionNegotiatorTest {
-
- @Test
- public void testGetInetSocketAddress() throws Exception {
-
- InetSocketAddress socketAddress = new InetSocketAddress(10);
-
- assertNotNull(NetconfServerSessionNegotiator.getHostName(socketAddress));
-
- assertEquals(socketAddress.getHostName(),
- NetconfServerSessionNegotiator.getHostName(socketAddress)
- .getValue());
-
- socketAddress = new InetSocketAddress("TestPortInet", 20);
-
- assertEquals(socketAddress.getHostName(),
- NetconfServerSessionNegotiator.getHostName(socketAddress)
- .getValue());
-
- assertEquals(String.valueOf(socketAddress.getPort()),
- NetconfServerSessionNegotiator.getHostName(socketAddress)
- .getKey());
-
- LocalAddress localAddress = new LocalAddress("TestPortLocal");
-
- assertEquals(String.valueOf(localAddress.id()),
- NetconfServerSessionNegotiator.getHostName(localAddress)
- .getValue());
-
- SshdSocketAddress embeddedAddress = new SshdSocketAddress(
- "TestSshdName", 10);
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl;
-
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-@RunWith(value = Parameterized.class)
-public class SubtreeFilterTest {
- private static final Logger LOG = LoggerFactory.getLogger(SubtreeFilterTest.class);
-
- private final int directoryIndex;
-
- @Parameters
- public static Collection<Object[]> data() {
- List<Object[]> result = new ArrayList<>();
- for (int i = 0; i <= 10; i++) {
- result.add(new Object[]{i});
- }
- return result;
- }
-
- public SubtreeFilterTest(int directoryIndex) {
- this.directoryIndex = directoryIndex;
- }
-
- @Before
- public void setUp(){
- XMLUnit.setIgnoreWhitespace(true);
- }
-
- @Test
- public void test() throws Exception {
- Document requestDocument = getDocument("request.xml");
- Document preFilterDocument = getDocument("pre-filter.xml");
- Document postFilterDocument = getDocument("post-filter.xml");
- Document actualPostFilterDocument = SubtreeFilter.applySubtreeFilter(requestDocument, preFilterDocument);
- LOG.info("Actual document: {}", XmlUtil.toString(actualPostFilterDocument));
- Diff diff = XMLUnit.compareXML(postFilterDocument, actualPostFilterDocument);
- assertTrue(diff.toString(), diff.similar());
-
- }
-
- public Document getDocument(String fileName) throws SAXException, IOException {
- return XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/subtree/" + directoryIndex + "/" +
- fileName));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.util.concurrent.GenericFutureListener;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionListener;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.w3c.dom.Document;
-
-public class DefaultCloseSessionTest {
-
- @Test
- public void testDefaultCloseSession() throws Exception {
- AutoCloseable res = mock(AutoCloseable.class);
- doNothing().when(res).close();
- DefaultCloseSession close = new DefaultCloseSession("", res);
- Document doc = XmlUtil.newDocument();
- XmlElement elem = XmlElement.fromDomElement(XmlUtil.readXmlToElement("<elem/>"));
- final Channel channel = mock(Channel.class);
- doReturn("channel").when(channel).toString();
- doReturn(mock(ChannelFuture.class)).when(channel).close();
-
- final ChannelFuture sendFuture = mock(ChannelFuture.class);
- doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocation) throws Throwable {
- ((GenericFutureListener) invocation.getArguments()[0]).operationComplete(sendFuture);
- return null;
- }
- }).when(sendFuture).addListener(any(GenericFutureListener.class));
- doReturn(sendFuture).when(channel).writeAndFlush(anyObject());
- final NetconfServerSessionListener listener = mock(NetconfServerSessionListener.class);
- doNothing().when(listener).onSessionTerminated(any(NetconfServerSession.class), any(NetconfTerminationReason.class));
- final NetconfServerSession session =
- new NetconfServerSession(listener, channel, 1L,
- NetconfHelloMessageAdditionalHeader.fromString("[netconf;10.12.0.102:48528;ssh;;;;;;]"));
- close.setNetconfSession(session);
- close.handleWithNoSubsequentOperations(doc, elem);
- // Fake close response to trigger delayed close
- session.sendMessage(new NetconfMessage(XmlUtil.readXmlToDocument("<rpc-reply message-id=\"101\"\n" +
- "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<ok/>\n" +
- "</rpc-reply>")));
- verify(channel).close();
- verify(listener).onSessionTerminated(any(NetconfServerSession.class), any(NetconfTerminationReason.class));
- }
-
- @Test(expected = DocumentedException.class)
- public void testDefaultCloseSession2() throws Exception {
- AutoCloseable res = mock(AutoCloseable.class);
- doThrow(NetconfDocumentedException.class).when(res).close();
- DefaultCloseSession session = new DefaultCloseSession("", res);
- Document doc = XmlUtil.newDocument();
- XmlElement elem = XmlElement.fromDomElement(XmlUtil.readXmlToElement("<elem/>"));
- session.handleWithNoSubsequentOperations(doc, elem);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.mapping.operations;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.w3c.dom.Document;
-
-public class DefaultStopExiTest {
- @Test
- public void testHandleWithNoSubsequentOperations() throws Exception {
- DefaultStopExi exi = new DefaultStopExi("");
- Document doc = XmlUtil.newDocument();
- Channel channel = mock(Channel.class);
- doReturn("mockChannel").when(channel).toString();
- ChannelPipeline pipeline = mock(ChannelPipeline.class);
- doReturn(pipeline).when(channel).pipeline();
- ChannelHandler channelHandler = mock(ChannelHandler.class);
- doReturn(channelHandler).when(pipeline).replace(anyString(), anyString(), any(ChannelHandler.class));
-
- NetconfServerSession serverSession = new NetconfServerSession(null, channel, 2L, null);
- exi.setNetconfSession(serverSession);
-
- assertNotNull(exi.handleWithNoSubsequentOperations(doc, XmlElement.fromDomElement(XmlUtil.readXmlToElement("<elem/>"))));
- verify(pipeline, times(1)).replace(anyString(), anyString(), any(ChannelHandler.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import java.util.Arrays;
-import java.util.Dictionary;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-public class NetconfImplActivatorTest {
-
- @Mock
- private BundleContext bundle;
- @Mock
- private Filter filter;
- @Mock
- private ServiceReference<?> reference;
- @Mock
- private ServiceRegistration<?> registration;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(filter).when(bundle).createFilter(anyString());
- doNothing().when(bundle).addServiceListener(any(ServiceListener.class), anyString());
-
- ServiceReference<?>[] refs = {};
- doReturn(refs).when(bundle).getServiceReferences(anyString(), anyString());
- doReturn(Arrays.asList(refs)).when(bundle).getServiceReferences(any(Class.class), anyString());
- doReturn("").when(bundle).getProperty(anyString());
- doReturn(registration).when(bundle).registerService(any(Class.class), any(AggregatedNetconfOperationServiceFactory.class), any(Dictionary.class));
- doNothing().when(registration).unregister();
- doNothing().when(bundle).removeServiceListener(any(ServiceListener.class));
- }
-
- @Test
- public void testStart() throws Exception {
- NetconfImplActivator activator = new NetconfImplActivator();
- activator.start(bundle);
- verify(bundle).registerService(any(Class.class), any(AggregatedNetconfOperationServiceFactory.class), any(Dictionary.class));
- activator.stop(bundle);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.osgi;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.api.util.NetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceReference;
-
-public class NetconfOperationServiceFactoryTrackerTest {
-
- @Mock
- private Filter filter;
- @Mock
- private BundleContext context;
- @Mock
- private NetconfOperationServiceFactoryListener listener;
- @Mock
- private NetconfOperationServiceFactory factory;
- @Mock
- private ServiceReference<NetconfOperationServiceFactory> reference;
-
- private NetconfOperationServiceFactoryTracker tracker;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doNothing().when(listener).onRemoveNetconfOperationServiceFactory(any(NetconfOperationServiceFactory.class));
- doReturn(filter).when(context).createFilter(anyString());
- doReturn("").when(reference).toString();
- doReturn(NetconfConstants.CONFIG_NETCONF_CONNECTOR).when(reference).getProperty(NetconfConstants.SERVICE_NAME);
- doReturn(factory).when(context).getService(any(ServiceReference.class));
- doReturn("").when(factory).toString();
- doNothing().when(listener).onAddNetconfOperationServiceFactory(any(NetconfOperationServiceFactory.class));
- tracker = new NetconfOperationServiceFactoryTracker(context, listener);
- }
-
- @Test
- public void testNetconfOperationServiceFactoryTracker() throws Exception {
- tracker.removedService(null, factory);
- verify(listener, times(1)).onRemoveNetconfOperationServiceFactory(any(NetconfOperationServiceFactory.class));
- }
-
- @Test
- public void testAddingService() throws Exception {
- assertNotNull(tracker.addingService(reference));
- verify(listener, times(1)).onAddNetconfOperationServiceFactory(any(NetconfOperationServiceFactory.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.impl.util;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyObject;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.util.concurrent.GenericFutureListener;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DeserializerExceptionHandlerTest {
-
- private DeserializerExceptionHandler handler;
- private ChannelFuture channelFuture;
- private ChannelHandlerContext context;
- private Channel channel;
-
- @Before
- public void setUp() throws Exception {
- handler = new DeserializerExceptionHandler();
- context = mock(ChannelHandlerContext.class);
- channel = mock(Channel.class);
- doReturn(channel).when(context).channel();
- channelFuture = mock(ChannelFuture.class);
- doReturn(channelFuture).when(channelFuture).addListener(any(GenericFutureListener.class));
- doReturn(channelFuture).when(channel).writeAndFlush(anyObject());
- }
-
- @Test
- public void testExceptionCaught() throws Exception {
- handler.exceptionCaught(context, new Exception());
- verify(context, times(1)).channel();
- }
-}
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-2">
- <data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- prefix:toaster-provider-impl
- </type>
- <name>toaster-provider-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-notification-service
- </type>
- <name>binding-notification-broker</name>
- </notification-service>
- <rpc-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-rpc-registry
- </type>
- <name>binding-rpc-broker</name>
- </rpc-registry>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-data-broker
- </type>
- <name>binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- prefix:sal-netconf-connector
- </type>
- <name>controller-config</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
- <connection-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- 20000
- </connection-timeout-millis>
- <between-attempts-timeout-millis
- xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">2000
- </between-attempts-timeout-millis>
- <sleep-factor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1.5</sleep-factor>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- prefix:dom-broker-osgi-registry
- </type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">
- prefix:netconf-client-dispatcher
- </type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-broker-osgi-registry
- </type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <max-connection-attempts xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">0
- </max-connection-attempts>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- prefix:netconf-client-dispatcher
- </type>
- <name>global-netconf-dispatcher</name>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <name>global-timer</name>
- </timer>
- <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-boss-group</name>
- </boss-thread-group>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:logback:config">prefix:logback</type>
- <name>singleton</name>
- <console-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <threshold-filter>ERROR</threshold-filter>
- <name>STDOUT</name>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</encoder-pattern>
- </console-appenders>
- <file-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <append>true</append>
- <file-name>logs/audit.log</file-name>
- <name>audit-file</name>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n</encoder-pattern>
- </file-appenders>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>WARN</level>
- <logger-name>org.opendaylight.controller.logging.bridge</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>audit</logger-name>
- <appenders>audit-file</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>ERROR</level>
- <logger-name>ROOT</logger-name>
- <appenders>STDOUT</appenders>
- <appenders>opendaylight.log</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>org.opendaylight</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort</logger-name>
- <appenders>opendaylight.log</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>TRACE</level>
- <logger-name>org.opendaylight.controller.netconf</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>WARN</level>
- <logger-name>io.netty</logger-name>
- </loggers>
- <rolling-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <append>true</append>
- <max-file-size>10MB</max-file-size>
- <file-name>logs/opendaylight.log</file-name>
- <name>opendaylight.log</name>
- <file-name-pattern>logs/opendaylight.%d.log.zip</file-name-pattern>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</encoder-pattern>
- <clean-history-on-start>false</clean-history-on-start>
- <max-history>1</max-history>
- <rolling-policy-type>TimeBasedRollingPolicy</rolling-policy-type>
- </rolling-appenders>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl">prefix:shutdown</type>
- <name>shutdown</name>
- <secret xmlns="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl"/>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">
- prefix:netty-hashed-wheel-timer
- </type>
- <name>global-timer</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">
- prefix:netty-threadgroup-fixed
- </type>
- <name>global-boss-group</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">
- prefix:netty-threadgroup-fixed
- </type>
- <name>global-worker-group</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:schema-service-singleton
- </type>
- <name>yang-schema-service</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl
- </type>
- <name>inmemory-dom-broker</name>
- <async-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker
- </type>
- <name>inmemory-data-broker</name>
- </async-data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:dom-inmemory-data-broker
- </type>
- <name>inmemory-data-broker</name>
- <schema-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</type>
- <name>yang-schema-service</name>
- </schema-service>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
- prefix:threadpool-flexible
- </type>
- <name>global-netconf-processing-executor</name>
- <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- </threadFactory>
- <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1
- </minThreadCount>
- <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4
- </max-thread-count>
- <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000
- </keepAliveMillis>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">
- prefix:netty-global-event-executor
- </type>
- <name>singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-broker-impl
- </type>
- <name>binding-broker-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-notification-service
- </type>
- <name>binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-data-broker
- </type>
- <name>binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:runtime-generated-mapping
- </type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-notification-broker
- </type>
- <name>binding-notification-broker</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-data-compatible-broker
- </type>
- <name>inmemory-binding-data-broker</name>
- <dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- prefix:dom-broker-osgi-registry
- </type>
- <name>dom-broker</name>
- </dom-async-broker>
- <binding-mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-dom-mapping-service
- </type>
- <name>runtime-mapping-singleton</name>
- </binding-mapping-service>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefix:threadfactory-naming
- </type>
- <name>global-netconf-processing-executor-threadfactory</name>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- remote-connector-processing-executor
- </name-prefix>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- prefix:kitchen-service-impl
- </type>
- <name>kitchen-service-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-notification-service
- </type>
- <name>binding-notification-broker</name>
- </notification-service>
- <rpc-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-rpc-registry
- </type>
- <name>binding-rpc-broker</name>
- </rpc-registry>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- prefix:remote-zeromq-rpc-server
- </type>
- <name>remoter</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- prefix:dom-broker-osgi-registry
- </type>
- <name>dom-broker</name>
- </dom-broker>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</type>
- <instance>
- <name>yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry
- </type>
- <instance>
- <name>dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker
- </type>
- <instance>
- <name>inmemory-data-broker</name>
- <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <instance>
- <name>global-netconf-processing-executor</name>
- <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <instance>
- <name>global-netconf-processing-executor-threadfactory</name>
- <provider>
- /modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-dom-mapping-service
- </type>
- <instance>
- <name>runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <instance>
- <name>global-timer</name>
- <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <instance>
- <name>global-boss-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
- </instance>
- <instance>
- <name>global-worker-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <instance>
- <name>global-event-executor</name>
- <provider>/modules/module[type='netty-global-event-executor'][name='singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry
- </type>
- <instance>
- <name>binding-rpc-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-notification-service
- </type>
- <instance>
- <name>binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- prefix:binding-broker-osgi-registry
- </type>
- <instance>
- <name>binding-osgi-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker
- </type>
- <instance>
- <name>binding-data-broker</name>
- <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- prefix:kitchen-service
- </type>
- <instance>
- <name>kitchen-service</name>
- <provider>/modules/module[type='kitchen-service-impl'][name='kitchen-service-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">
- prefix:netconf-client-dispatcher
- </type>
- <instance>
- <name>global-netconf-dispatcher</name>
- <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
- </instance>
- </service>
- </services>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<configuration scan="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="error">
- <appender-ref ref="STDOUT" />
- </root>
- <logger name="org.opendaylight.controller.netconf" level="TRACE"/>
-</configuration>
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="0" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="0"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get>
- </get>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="1"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- </data>
-</rpc-reply>
+++ /dev/null
-<rpc-reply message-id="1" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="1"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get>
- <filter type="subtree">
- </filter>
- </get>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-10">
- <data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
- <name>controller-config</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
- <connection-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">20000</connection-timeout-millis>
- <between-attempts-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">2000</between-attempts-timeout-millis>
- <sleep-factor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1.5</sleep-factor>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <max-connection-attempts xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">0</max-connection-attempts>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- </module>
- </modules>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-10">
- <data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
- <name>controller-config</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
- <connection-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">20000</connection-timeout-millis>
- <between-attempts-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">2000</between-attempts-timeout-millis>
- <sleep-factor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1.5</sleep-factor>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <max-connection-attempts xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">0</max-connection-attempts>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl">prefix:shutdown</type>
- <name>shutdown</name>
- <secret xmlns="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl"/>
- </module>
- </modules>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-9">
- <get-config>
- <source>
- <running/>
- </source>
- <filter xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:type="subtree">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:x="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">x:sal-netconf-connector</type>
- <name>controller-config</name>
- </module>
- </modules>
- </filter>
- </get-config>
-</rpc>
+++ /dev/null
-<rpc-reply message-id="2" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="2" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users/>
- </top>
- </filter>
- </get-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="3"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- </user>
- <user>
- <name>fred</name>
- </user>
- <user>
- <name>barney</name>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="3" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="3"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name/>
- </user>
- </users>
- </top>
- </filter>
- </get-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="4"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="4" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="4"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- </user>
- </users>
- </top>
- </filter>
- </get-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="5"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="5" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="5"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- <type/>
- <full-name/>
- </user>
- </users>
- </top>
- </filter>
- </get-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <company-info>
- <id>2</id>
- </company-info>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc-reply message-id="6" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <company-info/>
- </user>
- <user>
- <name>fred</name>
- <company-info>
- <id/>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>superuser</type>
- <company-info>
- <dept/>
- </company-info>
- </user>
- </users>
- </top>
- </filter>
- </get-config>
-</rpc>
-
+++ /dev/null
-<rpc-reply message-id="7"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <t:top xmlns:t="http://example.com/schema/1.2/stats">
- <t:interfaces>
- <t:interface t:ifName="eth0">
- <t:ifInOctets>45621</t:ifInOctets>
- <t:ifOutOctets>774344</t:ifOutOctets>
- </t:interface>
- </t:interfaces>
- </t:top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="7" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type>admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- <prefix:top xmlns:prefix="http://example.com/schema/1.2/stats">
- <prefix:interfaces>
- <prefix:interface prefix:ifName="eth0">
- <prefix:ifInOctets>45621</prefix:ifInOctets>
- <prefix:ifOutOctets>774344</prefix:ifOutOctets>
- </prefix:interface>
- <prefix:interface prefix:ifName="eth1">
- <prefix:ifInOctets>1</prefix:ifInOctets>
- <prefix:ifOutOctets>1</prefix:ifOutOctets>
- </prefix:interface>
- </prefix:interfaces>
- </prefix:top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="7"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get>
- <filter type="subtree">
- <t:top xmlns:t="http://example.com/schema/1.2/stats">
- <t:interfaces>
- <t:interface t:ifName="eth0"/>
- </t:interfaces>
- </t:top>
- </filter>
- </get>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-6">
- <data>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</type>
- <instance>
- <name>yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <instance>
- <name>dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker</type>
- <instance>
- <name>inmemory-data-broker</name>
- <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <instance>
- <name>global-netconf-processing-executor</name>
- <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <instance>
- <name>global-netconf-processing-executor-threadfactory</name>
- <provider>/modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
- <instance>
- <name>runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <instance>
- <name>global-timer</name>
- <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <instance>
- <name>global-boss-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
- </instance>
- <instance>
- <name>global-worker-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <instance>
- <name>global-event-executor</name>
- <provider>/modules/module[type='netty-global-event-executor'][name='singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry</type>
- <instance>
- <name>binding-rpc-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</type>
- <instance>
- <name>binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <instance>
- <name>binding-osgi-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</type>
- <instance>
- <name>binding-data-broker</name>
- <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">prefix:kitchen-service</type>
- <instance>
- <name>kitchen-service</name>
- <provider>/modules/module[type='kitchen-service-impl'][name='kitchen-service-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <instance>
- <name>global-netconf-dispatcher</name>
- <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
- </instance>
- </service>
- </services>
- </data>
-</rpc-reply>
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-6">
- <data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">prefix:toaster-provider-impl</type>
- <name>toaster-provider-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</type>
- <name>binding-notification-broker</name>
- </notification-service>
- <rpc-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry</type>
- <name>binding-rpc-broker</name>
- </rpc-registry>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</type>
- <name>binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
- <name>controller-config</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1830</port>
- <connection-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">20000</connection-timeout-millis>
- <between-attempts-timeout-millis xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">2000</between-attempts-timeout-millis>
- <sleep-factor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">1.5</sleep-factor>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">127.0.0.1</address>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</tcp-only>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <max-connection-attempts xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">0</max-connection-attempts>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <name>global-timer</name>
- </timer>
- <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-boss-group</name>
- </boss-thread-group>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:logback:config">prefix:logback</type>
- <name>singleton</name>
- <console-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <threshold-filter>ERROR</threshold-filter>
- <name>STDOUT</name>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</encoder-pattern>
- </console-appenders>
- <file-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <append>true</append>
- <file-name>logs/audit.log</file-name>
- <name>audit-file</name>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n</encoder-pattern>
- </file-appenders>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>WARN</level>
- <logger-name>org.opendaylight.controller.logging.bridge</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>audit</logger-name>
- <appenders>audit-file</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>ERROR</level>
- <logger-name>ROOT</logger-name>
- <appenders>STDOUT</appenders>
- <appenders>opendaylight.log</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>org.opendaylight</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>INFO</level>
- <logger-name>org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort</logger-name>
- <appenders>opendaylight.log</appenders>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>TRACE</level>
- <logger-name>org.opendaylight.controller.netconf</logger-name>
- </loggers>
- <loggers xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <level>WARN</level>
- <logger-name>io.netty</logger-name>
- </loggers>
- <rolling-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
- <append>true</append>
- <max-file-size>10MB</max-file-size>
- <file-name>logs/opendaylight.log</file-name>
- <name>opendaylight.log</name>
- <file-name-pattern>logs/opendaylight.%d.log.zip</file-name-pattern>
- <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</encoder-pattern>
- <clean-history-on-start>false</clean-history-on-start>
- <max-history>1</max-history>
- <rolling-policy-type>TimeBasedRollingPolicy</rolling-policy-type>
- </rolling-appenders>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl">prefix:shutdown</type>
- <name>shutdown</name>
- <secret xmlns="urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl"/>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">prefix:netty-hashed-wheel-timer</type>
- <name>global-timer</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">prefix:netty-threadgroup-fixed</type>
- <name>global-boss-group</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">prefix:netty-threadgroup-fixed</type>
- <name>global-worker-group</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
- <name>yang-schema-service</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
- <name>inmemory-dom-broker</name>
- <async-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker</type>
- <name>inmemory-data-broker</name>
- </async-data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
- <name>inmemory-data-broker</name>
- <schema-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</type>
- <name>yang-schema-service</name>
- </schema-service>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">prefix:threadpool-flexible</type>
- <name>global-netconf-processing-executor</name>
- <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- </threadFactory>
- <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1</minThreadCount>
- <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4</max-thread-count>
- <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000</keepAliveMillis>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">prefix:netty-global-event-executor</type>
- <name>singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
- <name>binding-broker-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</type>
- <name>binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</type>
- <name>binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
- <name>binding-notification-broker</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
- <name>inmemory-binding-data-broker</name>
- <dom-async-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-async-broker>
- <binding-mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
- <name>runtime-mapping-singleton</name>
- </binding-mapping-service>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">prefix:kitchen-service-impl</type>
- <name>kitchen-service-impl</name>
- <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</type>
- <name>binding-notification-broker</name>
- </notification-service>
- <rpc-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry</type>
- <name>binding-rpc-broker</name>
- </rpc-registry>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">prefix:remote-zeromq-rpc-server</type>
- <name>remoter</name>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:schema-service</type>
- <instance>
- <name>yang-schema-service</name>
- <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <instance>
- <name>dom-broker</name>
- <provider>/modules/module[type='dom-broker-impl'][name='inmemory-dom-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker</type>
- <instance>
- <name>inmemory-data-broker</name>
- <provider>/modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <instance>
- <name>global-netconf-processing-executor</name>
- <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <instance>
- <name>global-netconf-processing-executor-threadfactory</name>
- <provider>/modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
- <instance>
- <name>runtime-mapping-singleton</name>
- <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <instance>
- <name>global-timer</name>
- <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <instance>
- <name>global-boss-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
- </instance>
- <instance>
- <name>global-worker-group</name>
- <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <instance>
- <name>global-event-executor</name>
- <provider>/modules/module[type='netty-global-event-executor'][name='singleton']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-rpc-registry</type>
- <instance>
- <name>binding-rpc-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-notification-service</type>
- <instance>
- <name>binding-notification-broker</name>
- <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <instance>
- <name>binding-osgi-broker</name>
- <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-data-broker</type>
- <instance>
- <name>binding-data-broker</name>
- <provider>/modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl">prefix:kitchen-service</type>
- <instance>
- <name>kitchen-service</name>
- <provider>/modules/module[type='kitchen-service-impl'][name='kitchen-service-impl']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <instance>
- <name>global-netconf-dispatcher</name>
- <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
- </instance>
- </service>
- </services>
- </data>
-</rpc-reply>
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="m-10">
- <get-config>
- <filter xmlns:ns0="urn:ietf:params:xml:ns:netconf:base:1.0" ns0:type="subtree">
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service/>
- </services>
- </filter>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<rpc-reply message-id="5"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- <type xmlns:x="http://java.sun.com/dtd/properties.dtd">x:admin</type>
- <full-name>Fred Flintstone</full-name>
- </user>
- </users>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="5" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>root</name>
- <type>superuser</type>
- <full-name>Charlie Root</full-name>
- <company-info>
- <dept>1</dept>
- <id>1</id>
- </company-info>
- </user>
- <user>
- <name>fred</name>
- <type xmlns:x="http://java.sun.com/dtd/properties.dtd">x:admin</type>
- <full-name>Fred Flintstone</full-name>
- <company-info>
- <dept>2</dept>
- <id>2</id>
- </company-info>
- </user>
- <user>
- <name>barney</name>
- <type>admin</type>
- <full-name>Barney Rubble</full-name>
- <company-info>
- <dept>2</dept>
- <id>3</id>
- </company-info>
- </user>
- </users>
- <groups>
- <group>
- <name>admin</name>
- </group>
- </groups>
- </top>
- </data>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="5"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="subtree">
- <top xmlns="http://example.com/schema/1.2/config">
- <users>
- <user>
- <name>fred</name>
- <type xmlns:a="http://java.sun.com/dtd/properties.dtd">a:admin</type>
- <full-name/>
- </user>
- </users>
- </top>
- </filter>
- </get-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>netconf-it</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.logback_settings</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>logback-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- </dependency>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>object-cache-guava</artifactId>
- </dependency>
-
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-netconf-connector</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-persister-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-util</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- <version>${project.version}</version>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-monitoring</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-ssh</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-testtool</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-ssh</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netty-config-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.it;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import com.google.common.io.ByteStreams;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import org.junit.After;
-import org.junit.Before;
-import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacadeFactory;
-import org.opendaylight.controller.config.facade.xml.osgi.EnumResolver;
-import org.opendaylight.controller.config.facade.xml.osgi.YangStoreService;
-import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
-import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
-import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.yang.binding.BindingMapping;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-public abstract class AbstractNetconfConfigTest extends AbstractConfigTest {
-
- public static final String LOOPBACK_ADDRESS = "127.0.0.1";
- public static final int SERVER_CONNECTION_TIMEOUT_MILLIS = 5000;
- private static final int RESOURCE_TIMEOUT_MINUTES = 2;
-
- static ModuleFactory[] FACTORIES = {new TestImplModuleFactory(),
- new DepTestImplModuleFactory(),
- new NetconfTestImplModuleFactory(),
- new IdentityTestModuleFactory(),
- new MultipleDependenciesModuleFactory() };
-
- protected ConfigSubsystemFacadeFactory configSubsystemFacadeFactory;
- private EventLoopGroup nettyThreadgroup;
- private HashedWheelTimer hashedWheelTimer;
-
- private NetconfClientDispatcherImpl clientDispatcher;
- private Channel serverTcpChannel;
-
- private NetconfMessage getConfig;
- private NetconfMessage get;
-
- /**
- * @Before in subclasses is called after this method.
- */
- @Before
- public void setUpAbstractNetconfConfigTest() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, FACTORIES));
-
- nettyThreadgroup = new NioEventLoopGroup();
- hashedWheelTimer = new HashedWheelTimer();
-
- loadMessages();
-
- setUpTestInitial();
-
- final AggregatedNetconfOperationServiceFactory factoriesListener = new AggregatedNetconfOperationServiceFactory();
- final NetconfMonitoringService netconfMonitoringService = getNetconfMonitoringService(factoriesListener);
- configSubsystemFacadeFactory = new ConfigSubsystemFacadeFactory(configRegistryClient, configRegistryClient, getYangStore());
- factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(configSubsystemFacadeFactory));
- factoriesListener.onAddNetconfOperationServiceFactory(new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(new NetconfMonitoringOperationService(netconfMonitoringService)));
-
- for (final NetconfOperationServiceFactory netconfOperationServiceFactory : getAdditionalServiceFactories(factoriesListener)) {
- factoriesListener.onAddNetconfOperationServiceFactory(netconfOperationServiceFactory);
- }
-
- serverTcpChannel = startNetconfTcpServer(factoriesListener, netconfMonitoringService);
- clientDispatcher = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
- }
-
- /**
- * Called before setUp method is executed, so test classes can set up resources before setUpAbstractNetconfConfigTest method is called.
- */
- protected void setUpTestInitial() throws Exception {}
-
- private void loadMessages() throws Exception {
- this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
- this.get = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml");
- }
-
- public NetconfMessage getGetConfig() {
- return getConfig;
- }
-
- public NetconfMessage getGet() {
- return get;
- }
-
- private Channel startNetconfTcpServer(final AggregatedNetconfOperationServiceFactory listener, final NetconfMonitoringService monitoring) throws Exception {
- final NetconfServerDispatcherImpl dispatch = createDispatcher(listener, monitoring);
-
- final ChannelFuture s;
- if(getTcpServerAddress() instanceof LocalAddress) {
- s = dispatch.createLocalServer(((LocalAddress) getTcpServerAddress()));
- } else {
- s = dispatch.createServer(((InetSocketAddress) getTcpServerAddress()));
- }
- s.await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
- return s.channel();
- }
-
- protected Iterable<NetconfOperationServiceFactory> getAdditionalServiceFactories(final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
- return Collections.emptySet();
- }
-
- protected NetconfMonitoringService getNetconfMonitoringService(final AggregatedNetconfOperationServiceFactory factoriesListener) throws Exception {
- return new NetconfMonitoringServiceImpl(factoriesListener);
- }
-
- protected abstract SocketAddress getTcpServerAddress();
-
- public NetconfClientDispatcherImpl getClientDispatcher() {
- return clientDispatcher;
- }
-
- private HardcodedYangStoreService getYangStore() throws IOException {
- final Collection<InputStream> yangDependencies = getBasicYangs();
- return new HardcodedYangStoreService(yangDependencies, getBindingRuntimeContext());
- }
-
- static Collection<InputStream> getBasicYangs() throws IOException {
-
- final List<String> paths = Arrays.asList(
- "/META-INF/yang/config.yang",
- "/META-INF/yang/rpc-context.yang",
- "/META-INF/yang/config-test.yang",
- "/META-INF/yang/config-test-impl.yang",
- "/META-INF/yang/test-types.yang",
- "/META-INF/yang/test-groups.yang",
- "/META-INF/yang/ietf-inet-types.yang");
-
- final Collection<InputStream> yangDependencies = new ArrayList<>();
- final List<String> failedToFind = new ArrayList<>();
- for (final String path : paths) {
- final InputStream resourceAsStream = NetconfITTest.class.getResourceAsStream(path);
- if (resourceAsStream == null) {
- failedToFind.add(path);
- } else {
- yangDependencies.add(resourceAsStream);
- }
- }
- assertEquals("Some yang files were not found", Collections.<String>emptyList(), failedToFind);
- return yangDependencies;
- }
-
- protected NetconfServerDispatcherImpl createDispatcher(
- final AggregatedNetconfOperationServiceFactory factoriesListener, final NetconfMonitoringService sessionMonitoringService) {
- final SessionIdProvider idProvider = new SessionIdProvider();
-
- final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- hashedWheelTimer, factoriesListener, idProvider, SERVER_CONNECTION_TIMEOUT_MILLIS, sessionMonitoringService);
-
- final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
- serverNegotiatorFactory);
- return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
- }
-
- protected HashedWheelTimer getHashedWheelTimer() {
- return hashedWheelTimer;
- }
-
- protected EventLoopGroup getNettyThreadgroup() {
- return nettyThreadgroup;
- }
-
- /**
- * @After in subclasses is be called before this.
- */
- @After
- public void cleanUpNetconf() throws Exception {
- serverTcpChannel.close().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
- hashedWheelTimer.stop();
- nettyThreadgroup.shutdownGracefully().await(RESOURCE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
- }
-
- public NetconfClientConfiguration getClientConfiguration(final InetSocketAddress tcpAddress, final int timeout) {
- final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
- b.withAddress(tcpAddress);
- b.withSessionListener(new SimpleNetconfClientSessionListener());
- b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, timeout));
- b.withConnectionTimeoutMillis(timeout);
- return b.build();
- }
-
- public static final class HardcodedYangStoreService extends YangStoreService {
- public HardcodedYangStoreService(final Collection<? extends InputStream> inputStreams, final BindingRuntimeContext bindingRuntimeContext) throws IOException {
- super(new SchemaContextProvider() {
- @Override
- public SchemaContext getSchemaContext() {
- return getSchema(inputStreams);
- }
- });
-
- refresh(bindingRuntimeContext);
- }
-
- private static SchemaContext getSchema(final Collection<? extends InputStream> inputStreams) {
- final ArrayList<InputStream> byteArrayInputStreams = new ArrayList<>();
- for (final InputStream inputStream : inputStreams) {
- assertNotNull(inputStream);
- final byte[] content;
- try {
- content = ByteStreams.toByteArray(inputStream);
- } catch (IOException e) {
- throw new IllegalStateException("Cannot read " + inputStream, e);
- }
- final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(content);
- byteArrayInputStreams.add(byteArrayInputStream);
- }
-
- for (final InputStream inputStream : byteArrayInputStreams) {
- try {
- inputStream.reset();
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- final YangParserImpl yangParser = new YangParserImpl();
- return yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(byteArrayInputStreams).values()));
- }
-
- @Override
- public EnumResolver getEnumResolver() {
- return new EnumResolver() {
- @Override
- public String fromYang(final String enumType, final String enumYangValue) {
- return BindingMapping.getClassName(enumYangValue);
- }
-
- @Override
- public String toYang(final String enumType, final String enumJavaValue) {
- return enumJavaValue.toLowerCase();
- }
- };
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.it;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.controller.config.util.xml.XmlUtil.readXmlToDocument;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithName;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertElementsCount;
-
-import com.google.common.collect.HashBiMap;
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.List;
-import javax.management.InstanceNotFoundException;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.config.api.jmx.notifications.CommitJMXNotification;
-import org.opendaylight.controller.config.api.jmx.notifications.ConfigJMXNotification;
-import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
-import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.persist.impl.ConfigPersisterNotificationHandler;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
-
- public static final int PORT = 12026;
- private static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
-
- @Override
- protected SocketAddress getTcpServerAddress() {
- return TCP_ADDRESS;
- }
-
- @Test
- public void testNetconfCommitNotifications() throws Exception {
- final VerifyingNotificationListener notificationVerifier = createCommitNotificationListener();
- final VerifyingPersister mockedAggregator = mockAggregator();
-
- try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
- try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler(
- platformMBeanServer, mockedAggregator, configSubsystemFacadeFactory)) {
-
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 4000))) {
- NetconfMessage response = netconfClient.sendMessage(loadEditConfigMessage());
- assertContainsElementWithName(response.getDocument(), "ok");
- response = netconfClient.sendMessage(loadCommitMessage());
- assertContainsElementWithName(response.getDocument(), "ok");
-
- response = netconfClient.sendMessage(loadGetConfigMessage());
- assertContainsElementWithName(response.getDocument(), "modules");
- assertContainsElementWithName(response.getDocument(), "services");
- }
- }
- }
-
- notificationVerifier.assertNotificationCount(1);
-
- mockedAggregator.assertSnapshotCount(1);
- // Capabilities are stripped for persister
- mockedAggregator.assertSnapshotContent(0, 4, 3, 3);
- }
-
- @Override
- protected BindingRuntimeContext getBindingRuntimeContext() {
- final BindingRuntimeContext ret = super.getBindingRuntimeContext();
- doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
- doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
- final HashBiMap<String, String> toBeReturned = HashBiMap.create();
- toBeReturned.put("two", "Two");
- toBeReturned.put("one", "One");
- toBeReturned.put("version1", "Version1");
- doReturn(toBeReturned).when(ret).getEnumMapping(anyString());
- return ret;
- }
-
- private VerifyingPersister mockAggregator() throws IOException {
- return new VerifyingPersister();
- }
-
- private VerifyingNotificationListener createCommitNotificationListener() throws InstanceNotFoundException {
- final VerifyingNotificationListener listener = new VerifyingNotificationListener();
- platformMBeanServer.addNotificationListener(ConfigJMXNotification.OBJECT_NAME, listener, null, null);
- return listener;
- }
-
- private NetconfMessage loadGetConfigMessage() throws Exception {
- return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
- }
-
- private NetconfMessage loadEditConfigMessage() throws Exception {
- return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig.xml");
- }
-
- private NetconfMessage loadCommitMessage() throws Exception {
- return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
- }
-
- private static class VerifyingNotificationListener implements NotificationListener {
- public List<Notification> notifications = Lists.newArrayList();
-
- @Override
- public void handleNotification(final Notification notification, final Object handback) {
- this.notifications.add(notification);
- }
-
- void assertNotificationCount(final Object size) {
- assertEquals(size, notifications.size());
- }
-
- void assertNotificationContent(final int notificationIndex) {
- final Notification notification = notifications.get(notificationIndex);
- assertEquals(CommitJMXNotification.class, notification.getClass());
- }
- }
-
- private static class VerifyingPersister implements Persister {
-
- public List<ConfigSnapshotHolder> snapshots = Lists.newArrayList();
- private Persister mockedPersister;
-
- public VerifyingPersister() throws IOException {
- final Persister mockedAggregator = mock(Persister.class);
-
- doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocation) throws Throwable {
- final ConfigSnapshotHolder configSnapshot = (ConfigSnapshotHolder) invocation.getArguments()[0];
- snapshots.add(configSnapshot);
- return null;
- }
- }).when(mockedAggregator).persistConfig(any(ConfigSnapshotHolder.class));
-
- this.mockedPersister = mockedAggregator;
- }
-
- void assertSnapshotCount(final Object size) {
- assertEquals(size, snapshots.size());
- }
-
- void assertSnapshotContent(final int notificationIndex, final int expectedModulesSize, final int expectedServicesSize, final int expectedCapsSize)
- throws SAXException, IOException {
- final ConfigSnapshotHolder snapshot = snapshots.get(notificationIndex);
- final int capsSize = snapshot.getCapabilities().size();
- assertEquals("Expected capabilities count should be " + expectedCapsSize + " but was " + snapshot.getCapabilities(), expectedCapsSize, capsSize);
- final Document configSnapshot = readXmlToDocument(snapshot.getConfigSnapshot());
- assertElementsCount(configSnapshot, "module", expectedModulesSize);
- assertElementsCount(configSnapshot, "instance", expectedServicesSize);
- }
-
- @Override
- public void persistConfig(final ConfigSnapshotHolder configSnapshotHolder) throws IOException {
- mockedPersister.persistConfig(configSnapshotHolder);
- }
-
- @Override
- public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
- return mockedPersister.loadLastConfigs();
- }
-
- @Override
- public void close() {
- mockedPersister.close();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.it;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.w3c.dom.Document;
-
-public class NetconfITMonitoringTest extends AbstractNetconfConfigTest {
-
- public static final int PORT = 12025;
- public static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
- public static final TestingCapability TESTING_CAPABILITY = new TestingCapability();
-
- @Override
- protected InetSocketAddress getTcpServerAddress() {
- return TCP_ADDRESS;
- }
-
- @Test
- public void testGetResponseFromMonitoring() throws Exception {
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("client-monitoring", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 10000))) {
- try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("client-monitoring2", getClientDispatcher(), getClientConfiguration(TCP_ADDRESS, 10000))) {
- Thread.sleep(500);
- final NetconfMessage response = netconfClient2.sendMessage(getGet());
- assertSessionElementsInResponse(response.getDocument(), 2);
- }
- Thread.sleep(500);
- final NetconfMessage response = netconfClient.sendMessage(getGet());
- assertSessionElementsInResponse(response.getDocument(), 1);
- }
- }
-
- @Test(timeout = 13 * 10000)
- public void testClientHelloWithAuth() throws Exception {
- String fileName = "netconfMessages/client_hello_with_auth.xml";
- final String hello = XmlFileLoader.fileToString(fileName);
-
- fileName = "netconfMessages/get.xml";
- final String get = XmlFileLoader.fileToString(fileName);
-
- final Socket sock = new Socket(TCP_ADDRESS.getHostName(), TCP_ADDRESS.getPort());
- sock.getOutputStream().write(hello.getBytes(Charsets.UTF_8));
- final String separator = "]]>]]>";
-
- sock.getOutputStream().write(separator.getBytes(Charsets.UTF_8));
- sock.getOutputStream().write(get.getBytes(Charsets.UTF_8));
- sock.getOutputStream().write(separator.getBytes(Charsets.UTF_8));
-
- final StringBuilder responseBuilder = new StringBuilder();
-
- try (InputStream inputStream = sock.getInputStream();
- InputStreamReader reader = new InputStreamReader(inputStream);
- BufferedReader buff = new BufferedReader(reader)) {
- String line;
- while ((line = buff.readLine()) != null) {
-
- responseBuilder.append(line);
- responseBuilder.append(System.lineSeparator());
-
- if(line.contains("</rpc-reply>"))
- break;
- }
- }
-
- sock.close();
-
- final String helloMsg = responseBuilder.substring(0, responseBuilder.indexOf(separator));
- Document doc = XmlUtil.readXmlToDocument(helloMsg);
- assertContainsElementWithText(doc, "urn:ietf:params:netconf:capability:candidate:1.0");
-
- final String replyMsg = responseBuilder.substring(responseBuilder.indexOf(separator) + separator.length());
- doc = XmlUtil.readXmlToDocument(replyMsg);
- assertContainsElementWithText(doc, "tomas");
- }
-
- private void assertSessionElementsInResponse(final Document document, final int i) {
- final int elementSize = document.getElementsByTagName("session-id").getLength();
- assertEquals("Incorrect number of session-id tags in " + XmlUtil.toString(document), i, elementSize);
- }
-
- public static AggregatedNetconfOperationServiceFactory getNetconfOperationProvider() throws Exception {
- final AggregatedNetconfOperationServiceFactory factoriesListener = mock(AggregatedNetconfOperationServiceFactory.class);
- final NetconfOperationService snap = mock(NetconfOperationService.class);
- try {
- doNothing().when(snap).close();
- } catch (final Exception e) {
- // not happening
- throw new IllegalStateException(e);
- }
- final Set<Capability> caps = Sets.newHashSet();
- caps.add(TESTING_CAPABILITY);
-
- doReturn(caps).when(factoriesListener).getCapabilities();
- doReturn(snap).when(factoriesListener).createService(anyString());
-
- AutoCloseable mock = mock(AutoCloseable.class);
- doNothing().when(mock).close();
- doReturn(mock).when(factoriesListener).registerCapabilityListener(any(CapabilityListener.class));
-
- return factoriesListener;
- }
-
- private static class TestingCapability implements Capability {
- @Override
- public String getCapabilityUri() {
- return "namespaceModuleRevision";
- }
-
- @Override
- public Optional<String> getModuleNamespace() {
- return Optional.of("namespace");
- }
-
- @Override
- public Optional<String> getModuleName() {
- return Optional.of("name");
- }
-
- @Override
- public Optional<String> getRevision() {
- return Optional.of("revision");
- }
-
- @Override
- public Optional<String> getCapabilitySchema() {
- return Optional.of("content");
- }
-
- @Override
- public List<String> getLocation() {
- return Collections.emptyList();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.it;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.file.Files;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.auth.AuthProvider;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.xml.sax.SAXException;
-
-public class NetconfITSecureTest extends AbstractNetconfConfigTest {
-
- public static final int PORT = 12024;
- private static final InetSocketAddress TLS_ADDRESS = new InetSocketAddress("127.0.0.1", PORT);
-
- public static final String USERNAME = "user";
- public static final String PASSWORD = "pwd";
-
- private SshProxyServer sshProxyServer;
-
- private ExecutorService nioExec;
- private EventLoopGroup clientGroup;
- private ScheduledExecutorService minaTimerEx;
-
- @Before
- public void setUp() throws Exception {
- nioExec = Executors.newFixedThreadPool(1);
- clientGroup = new NioEventLoopGroup();
- minaTimerEx = Executors.newScheduledThreadPool(1);
- sshProxyServer = new SshProxyServer(minaTimerEx, clientGroup, nioExec);
- sshProxyServer.bind(
- new SshProxyServerConfigurationBuilder()
- .setBindingAddress(TLS_ADDRESS)
- .setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress())
- .setAuthenticator(new PasswordAuthenticator() {
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- return true;
- }
- }
- )
- .setKeyPairProvider(new PEMGeneratorHostKeyProvider(Files.createTempFile("prefix", "suffix").toAbsolutePath().toString()))
- .setIdleTimeout(Integer.MAX_VALUE)
- .createSshProxyServerConfiguration());
- }
-
- @After
- public void tearDown() throws Exception {
- sshProxyServer.close();
- clientGroup.shutdownGracefully();
- minaTimerEx.shutdownNow();
- nioExec.shutdownNow();
- }
-
- @Test(timeout = 2*60*1000)
- public void testSecure() throws Exception {
- final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(new SimpleNetconfClientSessionListener(), TLS_ADDRESS))) {
- NetconfMessage response = netconfClient.sendMessage(getGetConfig());
- assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
- NetconfMessageUtil.isErrorMessage(response));
-
- final NetconfMessage gs = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc message-id=\"2\"\n" +
- " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- " <identifier>config</identifier>\n" +
- " </get-schema>\n" +
- "</rpc>\n"));
-
- response = netconfClient.sendMessage(gs);
- assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
- NetconfMessageUtil.isErrorMessage(response));
- }
- }
-
- /**
- * Test all requests are handled properly and no mismatch occurs in listener
- */
- @Test(timeout = 6*60*1000)
- public void testSecureStress() throws Exception {
- final int requests = 4000;
-
- final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
- final NetconfDeviceCommunicator sessionListener = getSessionListener();
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(sessionListener, TLS_ADDRESS))) {
-
- final AtomicInteger responseCounter = new AtomicInteger(0);
- final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
-
- for (int i = 0; i < requests; i++) {
- NetconfMessage getConfig = getGetConfig();
- getConfig = changeMessageId(getConfig, i);
- final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture = sessionListener.sendRequest(getConfig, QName.create("namespace", "2012-12-12", "get"));
- futures.add(netconfMessageFuture);
- Futures.addCallback(netconfMessageFuture, new FutureCallback<RpcResult<NetconfMessage>>() {
- @Override
- public void onSuccess(final RpcResult<NetconfMessage> result) {
- responseCounter.incrementAndGet();
- }
-
- @Override
- public void onFailure(final Throwable t) {
- throw new RuntimeException(t);
- }
- });
- }
-
- // Wait for every future
- for (final ListenableFuture<RpcResult<NetconfMessage>> future : futures) {
- try {
- future.get(3, TimeUnit.MINUTES);
- } catch (final TimeoutException e) {
- fail("Request " + futures.indexOf(future) + " is not responding");
- }
- }
-
- // Give future listeners some time to finish counter incrementation
- Thread.sleep(5000);
-
- assertEquals(requests, responseCounter.get());
- }
- }
-
- public static NetconfMessage changeMessageId(final NetconfMessage getConfig, final int i) throws IOException, SAXException {
- String s = XmlUtil.toString(getConfig.getDocument(), false);
- s = s.replace("101", Integer.toString(i));
- return new NetconfMessage(XmlUtil.readXmlToDocument(s));
- }
-
- static NetconfClientConfiguration getClientConfiguration(final NetconfClientSessionListener sessionListener,final InetSocketAddress tlsAddress) throws IOException {
- final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
- b.withAddress(tlsAddress);
- // Using session listener from sal-netconf-connector since stress test cannot be performed with simple listener
- b.withSessionListener(sessionListener);
- b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
- b.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
- b.withConnectionTimeoutMillis(5000);
- b.withAuthHandler(getAuthHandler());
- return b.build();
- }
-
- static NetconfDeviceCommunicator getSessionListener() {
- RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> mockedRemoteDevice = mock(RemoteDevice.class);
- doNothing().when(mockedRemoteDevice).onRemoteSessionUp(any(NetconfSessionPreferences.class), any(NetconfDeviceCommunicator.class));
- doNothing().when(mockedRemoteDevice).onRemoteSessionDown();
- return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", InetSocketAddress.createUnresolved("localhost", 22)), mockedRemoteDevice);
- }
-
- public AuthProvider getAuthProvider() throws Exception {
- final AuthProvider mockAuth = mock(AuthProvider.class);
- doReturn("mockedAuth").when(mockAuth).toString();
- doReturn(true).when(mockAuth).authenticated(anyString(), anyString());
- return mockAuth;
- }
-
- public static AuthenticationHandler getAuthHandler() throws IOException {
- return new LoginPassword(USERNAME, PASSWORD);
- }
-
- @Override
- protected LocalAddress getTcpServerAddress() {
- return NetconfConfigUtil.getNetconfLocalAddress();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.it;
-
-import static java.lang.Thread.sleep;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.opendaylight.controller.netconf.it.NetconfITSecureTest.getSessionListener;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.test.tool.Main.Params;
-import org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class NetconfITSecureTestTool
-{
-
- //set up port both for testool device and test
- public static final int PORT = 17833;
- private static final InetSocketAddress TLS_ADDRESS = new InetSocketAddress("127.0.0.1", PORT);
-
- private String xmlFile = "netconfMessages/editConfig.xml";
-
- private ExecutorService msgExec = Executors.newFixedThreadPool(8);
-
- Collection<Future<?>> tasks = new LinkedList<Future<?>>();
-
- final NetconfDeviceSimulator netconfDeviceSimulator = new NetconfDeviceSimulator();
-
- @Before
- public void setUp() throws Exception {
-
- //Set up parameters for testtool device
- Params params = new Params();
- params.debug = true;
- params.deviceCount = 1;
- params.startingPort = PORT;
- params.ssh = true;
- params.exi = true;
-
- final List<Integer> openDevices = netconfDeviceSimulator.start(params);
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- /**
- * Test all requests are handled properly and no mismatch occurs in listener
- */
- @Test(timeout = 6*60*1000)
- public void testSecureStress() throws Exception {
-
- final int requests = 4000;
-
- List<Future<?>> tasks = new ArrayList<>();
-
- final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(), new HashedWheelTimer());
-
- final NetconfDeviceCommunicator sessionListener = getSessionListener();
-
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, NetconfITSecureTest.getClientConfiguration(sessionListener, TLS_ADDRESS));)
- {
-
- final AtomicInteger responseCounter = new AtomicInteger(0);
- final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
-
- for (int i = 0; i < requests; i++) {
-
- NetconfMessage getConfig = XmlFileLoader.xmlFileToNetconfMessage(xmlFile);
-
- getConfig = NetconfITSecureTest.changeMessageId(getConfig,i);
-
- Runnable worker = new NetconfITSecureTestToolRunnable(getConfig,i, sessionListener, futures, responseCounter);
-
- tasks.add(msgExec.submit(worker));
-
- }
-
- msgExec.shutdown();
-
- // Wait for every future
- for (final Future<?> task : tasks){
- try
- {
-
- task.get(3, TimeUnit.MINUTES);
- } catch (final TimeoutException e) {
- fail(String.format("Request %d is not responding", tasks.indexOf(task)));
- }
- }
-
- for (final ListenableFuture<RpcResult<NetconfMessage>> future : futures) {
- try {
-
- future.get(3, TimeUnit.MINUTES);
- } catch (final TimeoutException e) {
- fail(String.format("Reply %d is not responding", futures.indexOf(future)));
- }
- }
-
- sleep(5000);
-
- assertEquals(requests, responseCounter.get());
-
- }
- }
-
- class NetconfITSecureTestToolRunnable implements Runnable {
-
- private NetconfMessage getConfig;
- private int it;
- private NetconfDeviceCommunicator sessionListener;
- private List<ListenableFuture<RpcResult<NetconfMessage>>> futures;
- private AtomicInteger responseCounter;
-
- public NetconfITSecureTestToolRunnable(NetconfMessage getConfig, int it, NetconfDeviceCommunicator sessionListener, List<ListenableFuture<RpcResult<NetconfMessage>>> futures, AtomicInteger responseCounter){
- this.getConfig = getConfig;
- this.it = it;
- this.sessionListener = sessionListener;
- this.futures = futures;
- this.responseCounter = responseCounter;
- }
-
- @Override
- public void run(){
-
- ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture;
-
- netconfMessageFuture = sessionListener.sendRequest(getConfig, QName.create("namespace", "2012-12-12", "get"));
-
- futures.add(netconfMessageFuture);
- Futures.addCallback(netconfMessageFuture, new FutureCallback<RpcResult<NetconfMessage>>() {
-
- @Override
- public void onSuccess(final RpcResult<NetconfMessage> result) {
-
- if(result.isSuccessful()&result.getErrors().isEmpty()) {
- responseCounter.incrementAndGet();
- } else {
-
- fail(String.format("Message result not ok %s", result.getErrors().toString()));
-
- }
- }
-
- @Override
- public void onFailure(final Throwable t) {
-
- fail(String.format("Message failed %s", Throwables.getStackTraceAsString(t)));
-
- }
- }
- );
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.it;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doReturn;
-
-import com.google.common.base.Function;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.MultipleDependenciesModuleMXBean;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
-import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-public class NetconfITTest extends AbstractNetconfConfigTest {
-
- public static final int PORT = 12023;
- public static final InetSocketAddress TCP_ADDRESS = new InetSocketAddress(LOOPBACK_ADDRESS, PORT);
-
- private NetconfMessage getConfigCandidate, editConfig, closeSession;
- private NetconfClientDispatcher clientDispatcher;
-
- @Before
- public void setUp() throws Exception {
- loadMessages();
- clientDispatcher = getClientDispatcher();
- }
-
- @Override
- protected InetSocketAddress getTcpServerAddress() {
- return TCP_ADDRESS;
- }
-
- private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
- this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml");
- this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml");
- this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml");
- }
-
- @Test
- public void testNetconfClientDemonstration() throws Exception {
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 4000))) {
-
- final Set<String> capabilitiesFromNetconfServer = netconfClient.getCapabilities();
- final long sessionId = netconfClient.getSessionId();
-
- // NetconfMessage can be created :
- // new NetconfMessage(XmlUtil.readXmlToDocument("<xml/>"));
-
- final NetconfMessage response = netconfClient.sendMessage(getGetConfig());
- response.getDocument();
- }
- }
-
- @Test
- public void testTwoSessions() throws Exception {
- try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000))) {
- try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", clientDispatcher, getClientConfiguration(TCP_ADDRESS, 10000))) {
- assertNotNull(netconfClient2.getCapabilities());
- }
- }
- }
-
- @Test
- public void rpcReplyContainsAllAttributesTest() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- final String rpc = "<rpc message-id=\"5\" a=\"a\" b=\"44\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><get/>" + "</rpc>";
- final Document doc = XmlUtil.readXmlToDocument(rpc);
- final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
- assertNotNull(message);
- final NamedNodeMap expectedAttributes = doc.getDocumentElement().getAttributes();
- final NamedNodeMap returnedAttributes = message.getDocument().getDocumentElement().getAttributes();
-
- assertSameAttributes(expectedAttributes, returnedAttributes);
- }
- }
-
- private void assertSameAttributes(final NamedNodeMap expectedAttributes, final NamedNodeMap returnedAttributes) {
- assertNotNull("Expecting 4 attributes", returnedAttributes);
- assertEquals(expectedAttributes.getLength(), returnedAttributes.getLength());
-
- for (int i = 0; i < expectedAttributes.getLength(); i++) {
- final Node expAttr = expectedAttributes.item(i);
- final Node attr = returnedAttributes.item(i);
- assertEquals(expAttr.getNodeName(), attr.getNodeName());
- assertEquals(expAttr.getNamespaceURI(), attr.getNamespaceURI());
- assertEquals(expAttr.getTextContent(), attr.getTextContent());
- }
- }
-
- @Test
- public void rpcReplyErrorContainsAllAttributesTest() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- final String rpc = "<rpc message-id=\"1\" a=\"adada\" b=\"4\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><commit/>" + "</rpc>";
- final Document doc = XmlUtil.readXmlToDocument(rpc);
- final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
- final NamedNodeMap expectedAttributes = doc.getDocumentElement().getAttributes();
- final NamedNodeMap returnedAttributes = message.getDocument().getDocumentElement().getAttributes();
-
- assertSameAttributes(expectedAttributes, returnedAttributes);
- }
- }
-
- @Test
- public void rpcOutputContainsCorrectNamespace() throws Exception {
- final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
- final ObjectName dep = transaction.createModule(DepTestImplModuleFactory.NAME, "instanceD");
- final ObjectName impl = transaction.createModule(NetconfTestImplModuleFactory.NAME, "instance");
- final NetconfTestImplModuleMXBean proxy = configRegistryClient
- .newMXBeanProxy(impl, NetconfTestImplModuleMXBean.class);
- proxy.setTestingDep(dep);
- proxy.setSimpleShort((short) 0);
-
- transaction.commit();
-
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- final String expectedNamespace = "urn:opendaylight:params:xml:ns:yang:controller:test:impl";
-
- final String rpc = "<rpc message-id=\"5\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
- + "<no-arg xmlns=\""
- + expectedNamespace
- + "\"> "
- + "<context-instance>/modules/module[type='impl-netconf'][name='instance']</context-instance>"
- + "<arg1>argument1</arg1>" + "</no-arg>" + "</rpc>";
- final Document doc = XmlUtil.readXmlToDocument(rpc);
- final NetconfMessage message = netconfClient.sendMessage(new NetconfMessage(doc));
-
- final Element rpcReply = message.getDocument().getDocumentElement();
- final XmlElement resultElement = XmlElement.fromDomElement(rpcReply).getOnlyChildElement();
- assertEquals("result", resultElement.getName());
-
- final String namespace = resultElement.getNamespaceAttribute();
- assertEquals(expectedNamespace, namespace);
- }
- }
-
- @Test
- public void testCloseSession() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
-
- // edit config
- Document rpcReply = netconfClient.sendMessage(this.editConfig)
- .getDocument();
- assertIsOK(rpcReply);
-
- rpcReply = netconfClient.sendMessage(this.closeSession)
- .getDocument();
-
- assertIsOK(rpcReply);
- }
- }
-
- @Test
- public void testEditConfig() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- // send edit_config.xml
- final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument();
- assertIsOK(rpcReply);
- }
- }
-
- @Test
- public void testValidate() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- // begin transaction
- Document rpcReply = netconfClient.sendMessage(getConfigCandidate).getDocument();
- assertEquals("data", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
-
- // operations empty
- rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/validate.xml"))
- .getDocument();
- assertIsOK(rpcReply);
- }
- }
-
- private void assertIsOK(final Document rpcReply) throws DocumentedException {
- assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName());
- assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName());
- }
-
- private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
- return assertGetConfigWorks(netconfClient, getGetConfig());
- }
-
- private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage)
- throws InterruptedException, ExecutionException, TimeoutException, DocumentedException {
- final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage);
- assertNotNull(rpcReply);
- assertEquals("data", XmlElement.fromDomDocument(rpcReply.getDocument()).getOnlyChildElement().getName());
- return rpcReply.getDocument();
- }
-
- @Test
- public void testGetConfig() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- assertGetConfigWorks(netconfClient);
- }
- }
-
- @Test
- public void createYangTestBasedOnYuma() throws Exception {
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- Document rpcReply = netconfClient.sendMessage(
- XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_yang-test.xml"))
- .getDocument();
- assertEquals("rpc-reply", rpcReply.getDocumentElement().getTagName());
- assertIsOK(rpcReply);
- assertGetConfigWorks(netconfClient, this.getConfigCandidate);
- rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"))
- .getDocument();
- assertIsOK(rpcReply);
-
- final ObjectName on = new ObjectName(
- "org.opendaylight.controller:instanceName=impl-dep-instance,type=Module,moduleFactoryName=impl-dep");
- final Set<ObjectName> cfgBeans = configRegistryClient.lookupConfigBeans();
- assertEquals(cfgBeans, Sets.newHashSet(on));
- }
- }
-
- private TestingNetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception {
- final TestingNetconfClient netconfClient = new TestingNetconfClient("test " + address.toString(), clientDispatcher, getClientConfiguration(address, 5000));
- assertEquals(expected, Long.toString(netconfClient.getSessionId()));
- return netconfClient;
- }
-
- @Test
- public void testIdRef() throws Exception {
- final NetconfMessage editId = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
- final NetconfMessage commit = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml");
-
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- assertIsOK(netconfClient.sendMessage(editId).getDocument());
- assertIsOK(netconfClient.sendMessage(commit).getDocument());
-
- final NetconfMessage response = netconfClient.sendMessage(getGetConfig());
-
- assertThat(XmlUtil.toString(response.getDocument()), containsString("<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>"));
- assertThat(XmlUtil.toString(response.getDocument()), containsString("<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>"));
- assertThat(XmlUtil.toString(response.getDocument()), containsString("<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>"));
- assertThat(XmlUtil.toString(response.getDocument()), containsString("<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>"));
-
- } catch (final Exception e) {
- fail(Throwables.getStackTraceAsString(e));
- }
- }
-
- @Override
- protected BindingRuntimeContext getBindingRuntimeContext() {
- final BindingRuntimeContext ret = super.getBindingRuntimeContext();
- doReturn(TestIdentity1.class).when(ret).getIdentityClass(TestIdentity1.QNAME);
- doReturn(TestIdentity2.class).when(ret).getIdentityClass(TestIdentity2.QNAME);
- return ret;
- }
-
- @Test
- public void testMultipleDependencies() throws Exception {
- // push first xml, should add parent and d1,d2 dependencies
- try (TestingNetconfClient netconfClient = createSession(TCP_ADDRESS, "1")) {
- final Document rpcReply = netconfClient.sendMessage(
- XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps1.xml"))
- .getDocument();
- assertIsOK(rpcReply);
- commit(netconfClient);
- }
- // verify that parent.getTestingDeps == d1,d2
- final MultipleDependenciesModuleMXBean parentProxy = configRegistryClient.newMXBeanProxy(
- configRegistryClient.lookupConfigBean(MultipleDependenciesModuleFactory.NAME, "parent"),
- MultipleDependenciesModuleMXBean.class);
- {
- final List<ObjectName> testingDeps = parentProxy.getTestingDeps();
- assertEquals(2, testingDeps.size());
- final Set<String> actualRefs = getServiceReferences(testingDeps);
- assertEquals(Sets.newHashSet("ref_d1", "ref_d2"), actualRefs);
- }
-
- // push second xml, should add d3 to parent's dependencies
- mergeD3(parentProxy);
- // push second xml again, to test that d3 is not added again
- mergeD3(parentProxy);
- }
-
- public void mergeD3(final MultipleDependenciesModuleMXBean parentProxy) throws Exception {
- try (TestingNetconfClient netconfClient = new TestingNetconfClient(
- "test " + TCP_ADDRESS.toString(), clientDispatcher, getClientConfiguration(TCP_ADDRESS, 5000))) {
-
- final Document rpcReply = netconfClient.sendMessage(
- XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_multiple-deps2.xml"))
- .getDocument();
- assertIsOK(rpcReply);
- commit(netconfClient);
- }
- {
- final List<ObjectName> testingDeps = parentProxy.getTestingDeps();
- assertEquals(3, testingDeps.size());
- final Set<String> actualRefs = getServiceReferences(testingDeps);
- assertEquals(Sets.newHashSet("ref_d1", "ref_d2", "ref_d3"), actualRefs);
- }
- }
-
- public Set<String> getServiceReferences(final List<ObjectName> testingDeps) {
- return new HashSet<>(Lists.transform(testingDeps, new Function<ObjectName, String>() {
- @Override
- public String apply(final ObjectName input) {
- return ObjectNameUtil.getReferenceName(input);
- }
- }));
- }
-
- public void commit(final TestingNetconfClient netconfClient) throws Exception {
- final Document rpcReply;
- rpcReply = netconfClient.sendMessage(XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/commit.xml"))
- .getDocument();
- assertIsOK(rpcReply);
- }
-}
+++ /dev/null
-<configuration scan="true">
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <logger name="org.opendaylight.controller.netconf" level="INFO"/>
- <logger name="org.opendaylight.controller.sal.connect.netconf" level="DEBUG"/>
-
- <root level="error">
- <appender-ref ref="STDOUT" />
- </root>
-
-</configuration>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
-<edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-identity-test
- </type>
- <name>id-test</name>
- <identities>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</safi>
- </identities>
- <identities>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</afi>
- <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</safi>
- </identities>
- <identities-container>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</afi>
- </identities-container>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- </services>
- </config>
-</edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-mapping-api</artifactId>
-
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </dependency>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-public final class HandlingPriority implements Comparable<HandlingPriority> {
-
- public static final HandlingPriority CANNOT_HANDLE = new HandlingPriority();
- public static final HandlingPriority HANDLE_WITH_DEFAULT_PRIORITY = new HandlingPriority(Integer.MIN_VALUE);
- public static final HandlingPriority HANDLE_WITH_MAX_PRIORITY = new HandlingPriority(Integer.MAX_VALUE);
-
- private Integer priority;
-
- public static HandlingPriority getHandlingPriority(int priority) {
- return new HandlingPriority(priority);
- }
-
- private HandlingPriority(int priority) {
- this.priority = priority;
- }
-
- private HandlingPriority() {
- }
-
- /**
- * @return priority number or Optional.absent otherwise
- */
- public Optional<Integer> getPriority() {
- return Optional.fromNullable(priority);
- }
-
- public HandlingPriority increasePriority(int priorityIncrease) {
- Preconditions.checkState(priority!=null, "Unable to increase priority for %s", this);
- Preconditions.checkArgument(priorityIncrease > 0, "Negative increase");
- Preconditions.checkArgument(Long.valueOf(priority) + priorityIncrease < Integer.MAX_VALUE,
- "Resulting priority cannot be higher than %s", Integer.MAX_VALUE);
- return getHandlingPriority(priority + priorityIncrease);
- }
-
- public boolean isCannotHandle() {
- return this.equals(CANNOT_HANDLE);
- }
-
- @Override
- public int compareTo(HandlingPriority o) {
- if (this == o) {
- return 0;
- }
- if (isCannotHandle()) {
- return -1;
- }
- if (o.isCannotHandle()) {
- return 1;
- }
-
- if (priority > o.priority){
- return 1;
- }
- if (priority.equals(o.priority)){
- return 0;
- }
- if (priority < o.priority){
- return -1;
- }
-
- throw new IllegalStateException("Unexpected state comparing " + this + " with " + o);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o){
- return true;
- }
- if (!(o instanceof HandlingPriority)){
- return false;
- }
-
- HandlingPriority that = (HandlingPriority) o;
-
- if (priority != null ? !priority.equals(that.priority) : that.priority != null){
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return priority != null ? priority.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("priority", priority)
- .toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.w3c.dom.Document;
-
-/**
- * NetconfOperation handles netconf requests. Multiple operations might be
- * capable of handling one request at the same time. In such case, these
- * operations are chained (ordered by HandlingPriority returned by canHandle
- * method) and executed.
- *
- * Operation can be declared as singleton or last in chain (see abstract
- * implementations in netconf-util). If the operation is not singleton or last,
- * it is responsible for the execution of subsequent operation and for merging
- * the results.
- *
- */
-public interface NetconfOperation {
-
- /**
- * Singleton operations should return
- * HandlingPriority.HANDLE_WITH_MAX_PRIORITY, last operations
- * HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.
- *
- * @param requestMessage
- * @return
- */
- HandlingPriority canHandle(Document message) throws DocumentedException;
-
- /**
- * Execute current netconf operation and trigger execution of subsequent
- * operations. subsequentOperation parameter will provide information, if
- * current operation is the termination point in execution. In case of
- * last/singleton operation, subsequentOperation must indicate termination
- * point.
- *
- * @param requestMessage
- * @param subsequentOperation
- * execution of subsequent netconf operation
- * @return
- * @throws DocumentedException
- */
- Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
- throws DocumentedException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.mapping.api;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.w3c.dom.Document;
-
-/**
- * Single link in netconf operation execution chain.
- * Wraps the execution of a single netconf operation.
- */
-public interface NetconfOperationChainedExecution {
-
- /**
- * @return true if this is termination point in operation execution, false
- * if there is a subsequent operation present that needs to be
- * executed
- */
- boolean isExecutionTermination();
-
- /**
- * Do not execute if this is termination point
- */
- Document execute(Document requestMessage) throws DocumentedException;
-
- public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() {
- @Override
- public boolean isExecutionTermination() {
- return true;
- }
-
- @Override
- public Document execute(Document requestMessage) throws DocumentedException {
- throw new IllegalStateException("This execution represents the termination point in operation execution and cannot be executed itself");
- }
- };
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import java.util.Set;
-
-/**
- *
- */
-public interface NetconfOperationService extends AutoCloseable {
-
- /**
- * Get set of netconf operations that are handled by this service.
- */
- Set<NetconfOperation> getNetconfOperations();
-
- /**
- * Called when netconf session is destroyed.
- */
- @Override
- void close();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-
-/**
- * Factory that must be registered in OSGi service registry in order to be used
- * by netconf-impl. Responsible for creating per-session instances of
- * {@link NetconfOperationService}.
- */
-public interface NetconfOperationServiceFactory {
-
- /**
- * Get capabilities supported by current operation service.
- */
- Set<Capability> getCapabilities();
-
- /**
- * Supported capabilities may change over time, registering a listener allows for push based information retrieval about current notifications
- */
- AutoCloseable registerCapabilityListener(CapabilityListener listener);
-
- NetconfOperationService createService(String netconfSessionIdForReporting);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-public interface NetconfOperationServiceFactoryListener {
-
- void onAddNetconfOperationServiceFactory(NetconfOperationServiceFactory service);
-
- void onRemoveNetconfOperationServiceFactory(NetconfOperationServiceFactory service);
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import org.opendaylight.controller.netconf.api.NetconfSession;
-
-public interface SessionAwareNetconfOperation extends NetconfOperation {
-
- void setSession(NetconfSession session);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.mapping.api;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-public class HandlingPriorityTest {
-
- @Test public void testHandlingPriority() throws Exception {
- assertTrue(
- HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY)
- == 0);
- assertTrue(HandlingPriority.CANNOT_HANDLE.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == -1);
- assertTrue(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.CANNOT_HANDLE) == 1);
-
- assertTrue(
- HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_MAX_PRIORITY) == -1);
- assertTrue(
- HandlingPriority.HANDLE_WITH_MAX_PRIORITY.compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 1);
- assertTrue(HandlingPriority.getHandlingPriority(Integer.MIN_VALUE)
- .compareTo(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY) == 0);
-
- HandlingPriority prio = HandlingPriority.getHandlingPriority(10);
- assertTrue(prio.increasePriority(1).compareTo(HandlingPriority.getHandlingPriority(11)) == 0);
-
- assertFalse(HandlingPriority.CANNOT_HANDLE.getPriority().isPresent());
- assertFalse(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.equals(new Object()));
- assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY,
- HandlingPriority.getHandlingPriority(Integer.MAX_VALUE));
- assertEquals(HandlingPriority.HANDLE_WITH_MAX_PRIORITY.hashCode(),
- HandlingPriority.getHandlingPriority(Integer.MAX_VALUE).hashCode());
- }
-}
+++ /dev/null
-module netconf-northbound-mapper {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper";
- prefix "nnm";
-
- import config { prefix config; revision-date 2013-04-05; }
-
- description
- "This module contains the base YANG definitions for
- mapping services plugged into a netconf northbound server";
-
- revision "2015-01-14" {
- description
- "Initial revision.";
- }
-
- identity netconf-northbound-mapper {
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory";
- }
-
- identity netconf-mapper-registry {
- base "config:service-type";
- config:java-class "org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactoryListener";
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-mdsal-config</artifactId>
- <description>Configuration files for netconf for mdsal</description>
- <packaging>jar</packaging>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>attach-artifacts</id>
- <goals>
- <goal>attach-artifact</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <artifacts>
- <artifact>
- <file>${project.build.directory}/classes/initial/08-netconf-mdsal.xml</file>
- <type>xml</type>
- <classifier>config</classifier>
- </artifact>
- </artifacts>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper">prefix:netconf-mdsal-mapper</type>
- <name>netconf-mdsal-mapper</name>
- <root-schema-service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <name>yang-schema-service</name>
- </root-schema-service>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-broker>
- <mapper-aggregator xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-mapper-registry</type>
- <name>mapper-aggregator-registry</name>
- </mapper-aggregator>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">prefix:netconf-server-dispatcher-impl</type>
- <name>netconf-mdsal-server-dispatcher</name>
- <mappers xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">dom:netconf-northbound-mapper</type>
- <name>mapper-aggregator</name>
- </mappers>
- <server-monitor xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-monitoring</type>
- <name>server-monitor</name>
- </server-monitor>
- <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-boss-group</name>
- </boss-thread-group>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <name>global-timer</name>
- </timer>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring">prefix:netconf-mdsal-monitoring-mapper</type>
- <name>netconf-mdsal-monitoring-mapper</name>
- <server-monitoring xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-monitoring</type>
- <name>server-monitor</name>
- </server-monitoring>
- <binding-aware-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-aware-broker>
- <aggregator xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-mapper-registry</type>
- <name>mapper-aggregator-registry</name>
- </aggregator>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">prefix:netconf-mapper-aggregator</type>
- <name>mapper-aggregator</name>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">prefix:netconf-server-monitoring-impl</type>
- <name>server-monitor</name>
- <aggregator xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">dom:netconf-northbound-mapper</type>
- <name>mapper-aggregator</name>
- </aggregator>
- </module>
-
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">prefix:netconf-northbound-ssh</type>
- <name>netconf-mdsal-ssh-server</name>
-
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-ssh-scheduled-executor</name>
- </processing-executor>
- <dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-dispatcher</type>
- <name>netconf-mdsal-server-dispatcher</name>
- </dispatcher>
-
- <username>admin</username>
- <password>admin</password>
- </module>
-
-
- <!--TCP endpoint for MD-SAL netconf server -->
- <!--<module>-->
- <!--<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp">prefix:netconf-northbound-tcp</type>-->
- <!--<name>netconf-mdsal-tcp-server</name>-->
- <!--<dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp">-->
- <!--<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-dispatcher</type>-->
- <!--<name>netconf-mdsal-server-dispatcher</name>-->
- <!--</dispatcher>-->
- <!--</module>-->
-
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-monitoring</type>
- <instance>
- <name>server-monitor</name>
- <provider>/modules/module[type='netconf-server-monitoring-impl'][name='server-monitor']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-northbound-mapper</type>
- <instance>
- <name>netconf-mdsal-mapper</name>
- <provider>/modules/module[type='netconf-mdsal-mapper'][name='netconf-mdsal-mapper']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-northbound-mapper</type>
- <instance>
- <name>mapper-aggregator</name>
- <provider>/modules/module[type='netconf-mapper-aggregator'][name='mapper-aggregator']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netconf:north:mapper">prefix:netconf-mapper-registry</type>
- <instance>
- <name>mapper-aggregator-registry</name>
- <provider>/modules/module[type='netconf-mapper-aggregator'][name='mapper-aggregator']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound">prefix:netconf-server-dispatcher</type>
- <instance>
- <name>netconf-mdsal-server-dispatcher</name>
- <provider>/modules/module[type='netconf-server-dispatcher-impl'][name='netconf-mdsal-server-dispatcher']</provider>
- </instance>
- </service>
- </services>
-
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:mapper?module=netconf-mdsal-mapper&revision=2015-01-14</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:mdsal:monitoring?module=netconf-mdsal-monitoring&revision=2015-02-18</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh?module=netconf-northbound-ssh&revision=2015-01-14</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp?module=netconf-northbound-tcp&revision=2015-04-23</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:northbound:impl?module=netconf-northbound-impl&revision=2015-01-12</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled?module=threadpool-impl-scheduled&revision=2013-12-01</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-monitoring</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring;
-
-import java.util.Collections;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.monitoring.xml.JaxBSerializer;
-import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class Get extends AbstractNetconfOperation {
-
- private static final Logger LOG = LoggerFactory.getLogger(Get.class);
- private final NetconfMonitoringService netconfMonitor;
-
- public Get(final NetconfMonitoringService netconfMonitor) {
- super(MonitoringConstants.MODULE_NAME);
- this.netconfMonitor = netconfMonitor;
- }
-
- private Element getPlaceholder(final Document innerResult)
- throws DocumentedException {
- final XmlElement rootElement = XmlElement.fromDomElementWithExpected(
- innerResult.getDocumentElement(), XmlMappingConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.GET;
- }
-
- @Override
- protected HandlingPriority getHandlingPriority() {
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
- }
-
- @Override
- public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation)
- throws DocumentedException {
- if (subsequentOperation.isExecutionTermination()){
- throw new DocumentedException(String.format("Subsequent netconf operation expected by %s", this),
- DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error);
- }
-
- try {
- final Document innerResult = subsequentOperation.execute(requestMessage);
-
- final NetconfState netconfMonitoring = new NetconfState(netconfMonitor);
- Element monitoringXmlElement = new JaxBSerializer().toXml(netconfMonitoring);
-
- monitoringXmlElement = (Element) innerResult.importNode(monitoringXmlElement, true);
- final Element monitoringXmlElementPlaceholder = getPlaceholder(innerResult);
- monitoringXmlElementPlaceholder.appendChild(monitoringXmlElement);
-
- return innerResult;
- } catch (final RuntimeException e) {
- final String errorMessage = "Get operation for netconf-state subtree failed";
- LOG.warn(errorMessage, e);
-
- throw new DocumentedException(errorMessage, DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error,
- Collections.singletonMap(DocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
- }
- }
-
- @Override
- protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation)
- throws DocumentedException {
- throw new UnsupportedOperationException("Never gets called");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class GetSchema extends AbstractSingletonNetconfOperation {
- public static final String GET_SCHEMA = "get-schema";
- public static final String IDENTIFIER = "identifier";
- public static final String VERSION = "version";
-
- private static final Logger LOG = LoggerFactory.getLogger(GetSchema.class);
- private final NetconfMonitoringService cap;
-
- public GetSchema(final NetconfMonitoringService cap) {
- super(MonitoringConstants.MODULE_NAME);
- this.cap = cap;
- }
-
- @Override
- protected String getOperationName() {
- return GET_SCHEMA;
- }
-
- @Override
- protected String getOperationNamespace() {
- return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement xml) throws DocumentedException {
- final GetSchemaEntry entry;
-
- entry = new GetSchemaEntry(xml);
-
- final String schema;
- try {
- schema = cap.getSchemaForCapability(entry.identifier, entry.version);
- } catch (final IllegalStateException e) {
- final Map<String, String> errorInfo = Maps.newHashMap();
- errorInfo.put(entry.identifier, e.getMessage());
- LOG.warn("Rpc error: {}", DocumentedException.ErrorTag.operation_failed, e);
- throw new DocumentedException(e.getMessage(), DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.operation_failed,
- DocumentedException.ErrorSeverity.error, errorInfo);
- }
-
- final Element getSchemaResult;
- getSchemaResult = XmlUtil.createTextElement(document, XmlNetconfConstants.DATA_KEY, schema,
- Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING));
- LOG.trace("{} operation successful", GET_SCHEMA);
-
- return getSchemaResult;
- }
-
- private static final class GetSchemaEntry {
- private final String identifier;
- private final Optional<String> version;
-
- GetSchemaEntry(final XmlElement getSchemaElement) throws DocumentedException {
- getSchemaElement.checkName(GET_SCHEMA);
- getSchemaElement.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING);
-
- XmlElement identifierElement = null;
- try {
- identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER);
- } catch (final DocumentedException e) {
- LOG.trace("Can't get identifier element as only child element with same namespace due to ",e);
- throw DocumentedException.wrap(e);
- }
- identifier = identifierElement.getTextContent();
- final Optional<XmlElement> versionElement = getSchemaElement
- .getOnlyChildElementWithSameNamespaceOptionally(VERSION);
- if (versionElement.isPresent()) {
- version = Optional.of(versionElement.get().getTextContent());
- } else {
- version = Optional.absent();
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring;
-
-public final class MonitoringConstants {
-
- private MonitoringConstants(){
- // not called - private constructor for utility class
- }
- public static final String MODULE_NAME = "ietf-netconf-monitoring";
- public static final String MODULE_REVISION = "2010-10-04";
-
- public static final String NAMESPACE = "urn:ietf:params:xml:ns:yang:" + MODULE_NAME;
- public static final String EXTENSION_NAMESPACE = NAMESPACE + "-extension";
-
- public static final String EXTENSION_NAMESPACE_PREFIX = "ncme";
-
- public static final String URI = String.format("%s?module=%s&revision=%s", NAMESPACE, MODULE_NAME, MODULE_REVISION);
-
- public static final String NETCONF_MONITORING_XML_ROOT_ELEMENT = "netconf-state";
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import java.util.Collections;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfMonitoringActivator implements BundleActivator {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMonitoringActivator.class);
-
- private NetconfMonitoringServiceTracker monitor;
-
- @Override
- public void start(final BundleContext context) {
- monitor = new NetconfMonitoringServiceTracker(context);
- monitor.open();
- }
-
- @Override
- public void stop(final BundleContext context) {
- if(monitor!=null) {
- try {
- monitor.close();
- } catch (final Exception e) {
- LOG.warn("Ignoring exception while closing {}", monitor, e);
- }
- }
- }
-
- public static class NetconfMonitoringOperationServiceFactory implements NetconfOperationServiceFactory, AutoCloseable {
-
- private final NetconfMonitoringOperationService operationService;
-
- private static final AutoCloseable AUTO_CLOSEABLE = new AutoCloseable() {
- @Override
- public void close() throws Exception {
- // NOOP
- }
- };
-
- public NetconfMonitoringOperationServiceFactory(final NetconfMonitoringOperationService operationService) {
- this.operationService = operationService;
- }
-
- @Override
- public NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return operationService;
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- return Collections.emptySet();
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- return AUTO_CLOSEABLE;
- }
-
- @Override
- public void close() {}
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.monitoring.Get;
-import org.opendaylight.controller.netconf.monitoring.GetSchema;
-
-public class NetconfMonitoringOperationService implements NetconfOperationService {
-
- private final NetconfMonitoringService monitor;
-
- public NetconfMonitoringOperationService(final NetconfMonitoringService monitor) {
- this.monitor = monitor;
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return Sets.<NetconfOperation>newHashSet(new Get(monitor), new GetSchema(monitor));
- }
-
- @Override
- public void close() {
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import com.google.common.base.Preconditions;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.util.NetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfMonitoringServiceTracker extends ServiceTracker<NetconfMonitoringService, NetconfMonitoringService> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMonitoringServiceTracker.class);
-
- private ServiceRegistration<NetconfOperationServiceFactory> reg;
- private NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory factory;
-
- NetconfMonitoringServiceTracker(final BundleContext context) {
- super(context, NetconfMonitoringService.class, null);
- }
-
- @Override
- public NetconfMonitoringService addingService(final ServiceReference<NetconfMonitoringService> reference) {
- Preconditions.checkState(reg == null, "Monitoring service was already added");
-
- final NetconfMonitoringService netconfMonitoringService = super.addingService(reference);
-
- final NetconfMonitoringOperationService operationService = new NetconfMonitoringOperationService(
- netconfMonitoringService);
- factory = new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
- operationService);
-
- Dictionary<String, String> properties = new Hashtable<>();
- properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.NETCONF_MONITORING);
- reg = context.registerService(NetconfOperationServiceFactory.class, factory, properties);
-
- return netconfMonitoringService;
- }
-
- @Override
- public void removedService(final ServiceReference<NetconfMonitoringService> reference,
- final NetconfMonitoringService netconfMonitoringService) {
- if(reg!=null) {
- try {
- reg.unregister();
- } catch (final Exception e) {
- LOG.warn("Ignoring exception while unregistering {}", reg, e);
- }
- }
- if(factory!=null) {
- factory.close();
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring.xml;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class JaxBSerializer {
- private static final JAXBContext JAXB_CONTEXT;
-
- static {
- try {
- JAXB_CONTEXT = JAXBContext.newInstance(NetconfState.class);
- } catch (JAXBException e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- public Element toXml(final NetconfState monitoringModel) {
- final DOMResult res;
- try {
- final Marshaller marshaller = JAXB_CONTEXT.createMarshaller();
-
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
-
- res = new DOMResult();
- marshaller.marshal(monitoringModel, res);
- } catch (final JAXBException e) {
- throw new RuntimeException("Unable to serialize netconf state " + monitoringModel, e);
- }
- return ((Document)res.getNode()).getDocumentElement();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.xml.model;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import java.util.Collection;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.xml.bind.annotation.XmlElement;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-
-final class MonitoringSchema {
-
- private final Schema schema;
-
- public MonitoringSchema(Schema schema) {
- this.schema = schema;
- }
-
- @XmlElement(name = "identifier")
- public String getIdentifier() {
- return schema.getIdentifier();
- }
-
- @XmlElement(name = "namespace")
- public String getNamespace() {
- return schema.getNamespace().getValue().toString();
- }
-
- @XmlElement(name = "location")
- public Collection<String> getLocation() {
- return Collections2.transform(schema.getLocation(), new Function<Schema.Location, String>() {
- @Nullable
- @Override
- public String apply(@Nonnull Schema.Location input) {
- return input.getEnumeration().toString();
- }
- });
- }
-
- @XmlElement(name = "version")
- public String getVersion() {
- return schema.getVersion();
- }
-
- @XmlElement(name = "format")
- public String getFormat() {
- Preconditions.checkState(schema.getFormat() == Yang.class, "Only yang format permitted, but was %s", schema.getFormat());
- return "yang";
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring.xml.model;
-
-import com.google.common.base.Joiner;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlTransient;
-import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-import org.opendaylight.yangtools.yang.common.QName;
-
-final class MonitoringSession {
-
- @XmlTransient
- private Session managementSession;
-
- public MonitoringSession(Session managementSession) {
- this.managementSession = managementSession;
- }
-
- public MonitoringSession() {
- }
-
- public void setManagementSession(Session managementSession) {
- this.managementSession = managementSession;
- }
-
- @XmlElement(name = "session-id")
- public long getId() {
- return managementSession.getSessionId();
- }
-
- @XmlElement(name = "source-host")
- public String getSourceHost() {
- return managementSession.getSourceHost().getDomainName().getValue();
- }
-
- @XmlElement(name = "login-time")
- public String getLoginTime() {
- return managementSession.getLoginTime().getValue();
- }
-
- @XmlElement(name = "in-bad-rpcs")
- public Long getInBadRpcs() {
- return managementSession.getInBadRpcs().getValue();
- }
-
- @XmlElement(name = "in-rpcs")
- public Long getInRpcs() {
- return managementSession.getInRpcs().getValue();
- }
-
- @XmlElement(name = "out-notifications")
- public Long getOutNotifications() {
- return managementSession.getOutNotifications().getValue();
- }
-
- @XmlElement(name = "out-rpc-errors")
- public Long getOutRpcErrors() {
- return managementSession.getOutRpcErrors().getValue();
- }
-
- @XmlElement(name = "transport")
- public String getTransport() {
- try {
- QName qName = (QName) managementSession.getTransport().getField("QNAME").get(null);
- // Add extension prefix if transport type is from extension yang module
- if (qName.getNamespace().toString().equals(MonitoringConstants.EXTENSION_NAMESPACE)) {
- return Joiner.on(':').join(MonitoringConstants.EXTENSION_NAMESPACE_PREFIX, qName.getLocalName());
- } else {
- return qName.getLocalName();
- }
- } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
- throw new IllegalArgumentException("Unknown transport type " + managementSession.getTransport(), e);
- }
- }
-
- @XmlElement(name= "session-identifier", namespace = MonitoringConstants.EXTENSION_NAMESPACE)
- public String getSessionType() {
- return managementSession.getAugmentation(Session1.class).getSessionIdentifier();
- }
-
- @XmlElement(name = "username")
- public String getUsername() {
- return managementSession.getUsername();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.monitoring.xml.model;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import java.util.Collection;
-import javax.annotation.Nullable;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-
-@XmlRootElement(name = MonitoringConstants.NETCONF_MONITORING_XML_ROOT_ELEMENT)
-public final class NetconfState {
-
- private Schemas schemas;
- private Sessions sessions;
-
- public NetconfState(final NetconfMonitoringService monitoringService) {
- this.sessions = monitoringService.getSessions();
- this.schemas = monitoringService.getSchemas();
- }
-
- public NetconfState() {}
-
- @XmlElementWrapper(name="schemas")
- @XmlElement(name="schema")
- public Collection<MonitoringSchema> getSchemas() {
- return Collections2.transform(schemas.getSchema(), new Function<Schema, MonitoringSchema>() {
- @Nullable
- @Override
- public MonitoringSchema apply(@Nullable final Schema input) {
- return new MonitoringSchema(input);
- }
- });
- }
-
- @XmlElementWrapper(name="sessions")
- @XmlElement(name="session")
- public Collection<MonitoringSession> getSessions() {
- return Collections2.transform(sessions.getSession(), new Function<Session, MonitoringSession>() {
- @Nullable
- @Override
- public MonitoringSession apply(@Nullable final Session input) {
- return new MonitoringSession(input);
- }
- });
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-@XmlSchema(
- elementFormDefault = XmlNsForm.QUALIFIED,
- xmlns = {
- @XmlNs(namespaceURI = MonitoringConstants.EXTENSION_NAMESPACE, prefix = MonitoringConstants.EXTENSION_NAMESPACE_PREFIX),
- @XmlNs(namespaceURI = MonitoringConstants.NAMESPACE, prefix = "")
- },
- namespace = MonitoringConstants.NAMESPACE
-)
-package org.opendaylight.controller.netconf.monitoring.xml.model;
-
-import javax.xml.bind.annotation.XmlNs;
-import javax.xml.bind.annotation.XmlNsForm;
-import javax.xml.bind.annotation.XmlSchema;
-import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Optional;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.w3c.dom.Document;
-
-public class GetSchemaTest {
-
-
- private NetconfMonitoringService cap;
- private Document doc;
- private String getSchema;
-
- @Before
- public void setUp() throws Exception {
- cap = mock(NetconfMonitoringService.class);
- doc = XmlUtil.newDocument();
- getSchema = "<get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- " <identifier>threadpool-api</identifier>\n" +
- " <version>2010-09-24</version>\n" +
- " <format\n" +
- " xmlns:ncm=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">ncm:yang\n" +
- " </format>\n" +
- " </get-schema>";
- }
-
- @Test(expected = DocumentedException.class)
- public void testDefaultGetSchema() throws Exception {
- GetSchema schema = new GetSchema(cap);
- doThrow(IllegalStateException.class).when(cap).getSchemaForCapability(anyString(), any(Optional.class));
- schema.handleWithNoSubsequentOperations(doc, XmlElement.fromDomElement(XmlUtil.readXmlToElement(getSchema)));
- }
-
- @Test
- public void handleWithNoSubsequentOperations() throws Exception {
- GetSchema schema = new GetSchema(cap);
- doReturn("").when(cap).getSchemaForCapability(anyString(), any(Optional.class));
- assertNotNull(schema.handleWithNoSubsequentOperations(doc, XmlElement.fromDomElement(XmlUtil.readXmlToElement(getSchema))));
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-
-import java.util.Collections;
-import org.hamcrest.CoreMatchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-import org.w3c.dom.Document;
-
-public class GetTest {
-
- @Mock
- private NetconfMonitoringService monitor;
- @Mock
- private Document request;
- @Mock
- private NetconfOperationChainedExecution subsequentOperation;
- private Document incorrectSubsequentResult;
- private Document correctSubsequentResult;
-
- private Get get;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- incorrectSubsequentResult = XmlUtil.readXmlToDocument("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>");
- correctSubsequentResult = XmlUtil.readXmlToDocument("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><data></data></rpc-reply>");
-
- doReturn(new SessionsBuilder().setSession(Collections.<Session>emptyList()).build()).when(monitor).getSessions();
- doReturn(new SchemasBuilder().setSchema(Collections.<Schema>emptyList()).build()).when(monitor).getSchemas();
- doReturn(false).when(subsequentOperation).isExecutionTermination();
-
- get = new Get(monitor);
- }
-
- @Test
- public void testHandleNoSubsequent() throws Exception {
- try {
- get.handle(null, NetconfOperationChainedExecution.EXECUTION_TERMINATION_POINT);
- } catch (final DocumentedException e) {
- assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.operation_failed, DocumentedException.ErrorType.application);
- return;
- }
-
- fail("Get should fail without subsequent operation");
- }
-
- @Test
- public void testHandleWrongPlaceholder() throws Exception {
- doReturn(incorrectSubsequentResult).when(subsequentOperation).execute(request);
- try {
- get.handle(request, subsequentOperation);
- } catch (final DocumentedException e) {
- assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.invalid_value, DocumentedException.ErrorType.application);
- return;
- }
-
- fail("Get should fail with wrong xml");
- }
-
- @Test
- public void testHandleRuntimeEx() throws Exception {
- doThrow(RuntimeException.class).when(subsequentOperation).execute(request);
- try {
- get.handle(request, subsequentOperation);
- } catch (final DocumentedException e) {
- assertNetconfDocumentedEx(e, DocumentedException.ErrorSeverity.error, DocumentedException.ErrorTag.operation_failed, DocumentedException.ErrorType.application);
- assertEquals(1, e.getErrorInfo().size());
- return;
- }
-
- fail("Get should fail with wrong xml");
- }
-
- @Test
- public void testSuccessHandle() throws Exception {
- doReturn(correctSubsequentResult).when(subsequentOperation).execute(request);
- assertTrue(get.getHandlingPriority().getPriority().get() > HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.getPriority().get());
- final Document result = get.handle(request, subsequentOperation);
- assertThat(XmlUtil.toString(result), CoreMatchers.containsString("sessions"));
- assertThat(XmlUtil.toString(result), CoreMatchers.containsString("schemas"));
-
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void testHandle() throws Exception {
- get.handle(null, null, null);
-
- }
-
- private void assertNetconfDocumentedEx(final DocumentedException e, final DocumentedException.ErrorSeverity severity, final DocumentedException.ErrorTag errorTag, final DocumentedException.ErrorType type) {
- assertEquals(severity, e.getErrorSeverity());
- assertEquals(errorTag, e.getErrorTag());
- assertEquals(type, e.getErrorType());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.Arrays;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-public class NetconfMonitoringActivatorTest {
-
- @Mock
- BundleContext context;
- @Mock
- Filter filter;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(filter).when(context).createFilter(anyString());
- doNothing().when(context).addServiceListener(any(ServiceListener.class), anyString());
- ServiceReference<?>[] refs = new ServiceReference[2];
- doReturn(Arrays.asList(refs)).when(context).getServiceReferences(any(Class.class), anyString());
- doReturn(refs).when(context).getServiceReferences(anyString(), anyString());
- doNothing().when(context).removeServiceListener(any(ServiceListener.class));
- }
-
- @Test
- public void testNetconfMonitoringActivator() throws Exception {
- NetconfMonitoringActivator activator = new NetconfMonitoringActivator();
- activator.start(context);
- verify(context, times(1)).addServiceListener(any(ServiceListener.class), anyString());
-
- activator.stop(context);
- verify(context, times(1)).removeServiceListener(any(ServiceListener.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-
-public class NetconfMonitoringOperationServiceTest {
- @Test
- public void testGetters() throws Exception {
- NetconfMonitoringService monitor = mock(NetconfMonitoringService.class);
- NetconfMonitoringOperationService service = new NetconfMonitoringOperationService(monitor);
- NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory serviceFactory = new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(service);
-
- assertEquals(2, service.getNetconfOperations().size());
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.osgi;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.util.Hashtable;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-public class NetconfMonitoringServiceTrackerTest {
-
- @Mock
- private ServiceReference<NetconfMonitoringService> reference;
- @Mock
- private BundleContext context;
- @Mock
- private ServiceRegistration<?> serviceRegistration;
- @Mock
- private Filter filter;
- @Mock
- private NetconfMonitoringService monitoringService;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(serviceRegistration).when(context).registerService(any(Class.class), any(NetconfOperationServiceFactory.class), any(Hashtable.class));
- doNothing().when(serviceRegistration).unregister();
- doReturn(filter).when(context).createFilter(anyString());
- doReturn("").when(reference).toString();
- doReturn(monitoringService).when(context).getService(any(ServiceReference.class));
- }
-
- @Test
- public void testAddingService() throws Exception {
- NetconfMonitoringServiceTracker tracker = new NetconfMonitoringServiceTracker(context);
- tracker.addingService(reference);
- verify(context, times(1)).registerService(any(Class.class), any(NetconfOperationServiceFactory.class), any(Hashtable.class));
- tracker.removedService(reference, null);
- verify(serviceRegistration, times(1)).unregister();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.monitoring.xml;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import java.util.Set;
-import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Transport;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
-
-public class JaxBSerializerTest {
-
- @Test
- public void testSerialization() throws Exception {
-
- final NetconfMonitoringService service = new NetconfMonitoringService() {
-
- @Override
- public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
-
- }
-
- @Override
- public void onSessionUp(final NetconfManagementSession session) {
-
- }
-
- @Override
- public void onSessionDown(final NetconfManagementSession session) {
-
- }
-
- @Override
- public Sessions getSessions() {
- return new SessionsBuilder().setSession(Lists.newArrayList(getMockSession(NetconfTcp.class), getMockSession(NetconfSsh.class))).build();
- }
-
- @Override
- public Schemas getSchemas() {
- return new SchemasBuilder().setSchema(Lists.newArrayList(getMockSchema("id", "v1", Yang.class), getMockSchema("id2", "", Yang.class))).build();
- }
-
- @Override
- public String getSchemaForCapability(final String moduleName, final Optional<String> revision) {
- return null;
- }
-
- @Override
- public Capabilities getCapabilities() {
- return null;
- }
-
- @Override
- public AutoCloseable registerListener(final MonitoringListener listener) {
- return new AutoCloseable() {
- @Override
- public void close() throws Exception {
- // NOOP
- }
- };
- }
- };
- final NetconfState model = new NetconfState(service);
- final String xml = XmlUtil.toString(new JaxBSerializer().toXml(model)).replaceAll("\\s", "");
-
- assertThat(xml, CoreMatchers.containsString(
- "<schema>" +
- "<format>yang</format>" +
- "<identifier>id</identifier>" +
- "<location>NETCONF</location>" +
- "<namespace>localhost</namespace>" +
- "<version>v1</version>" +
- "</schema>"));
-
- assertThat(xml, CoreMatchers.containsString(
- "<session>" +
- "<session-id>1</session-id>" +
- "<in-bad-rpcs>0</in-bad-rpcs>" +
- "<in-rpcs>0</in-rpcs>" +
- "<login-time>2010-10-10T12:32:32Z</login-time>" +
- "<out-notifications>0</out-notifications>" +
- "<out-rpc-errors>0</out-rpc-errors>" +
- "<ncme:session-identifier>client</ncme:session-identifier>" +
- "<source-host>192.168.1.1</source-host>" +
- "<transport>ncme:netconf-tcp</transport>" +
- "<username>username</username>" +
- "</session>"));
- }
-
- private Schema getMockSchema(final String id, final String version, final Class<Yang> format) {
- final Schema mock = mock(Schema.class);
-
- doReturn(format).when(mock).getFormat();
- doReturn(id).when(mock).getIdentifier();
- doReturn(new Uri("localhost")).when(mock).getNamespace();
- doReturn(version).when(mock).getVersion();
- doReturn(Lists.newArrayList(new Schema.Location(Schema.Location.Enumeration.NETCONF))).when(mock).getLocation();
- doReturn(new SchemaKey(format, id, version)).when(mock).getKey();
- return mock;
- }
-
- private Session getMockSession(final Class<? extends Transport> transportType) {
- final Session mocked = mock(Session.class);
- final Session1 mockedSession1 = mock(Session1.class);
- doReturn("client").when(mockedSession1).getSessionIdentifier();
- doReturn(1L).when(mocked).getSessionId();
- doReturn(new DateAndTime("2010-10-10T12:32:32Z")).when(mocked).getLoginTime();
- doReturn(new Host(new DomainName("192.168.1.1"))).when(mocked).getSourceHost();
- doReturn(new ZeroBasedCounter32(0L)).when(mocked).getInBadRpcs();
- doReturn(new ZeroBasedCounter32(0L)).when(mocked).getInRpcs();
- doReturn(new ZeroBasedCounter32(0L)).when(mocked).getOutNotifications();
- doReturn(new ZeroBasedCounter32(0L)).when(mocked).getOutRpcErrors();
- doReturn(transportType).when(mocked).getTransport();
- doReturn("username").when(mocked).getUsername();
- doReturn(mockedSession1).when(mocked).getAugmentation(Session1.class);
- return mocked;
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-netty-util</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <!-- compile dependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>protocol-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sshd</groupId>
- <artifactId>sshd-core</artifactId>
- </dependency>
- <dependency>
- <groupId>openexi</groupId>
- <artifactId>nagasena</artifactId>
- </dependency>
- <dependency>
- <groupId>openexi</groupId>
- <artifactId>nagasena-rta</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.controller.netconf.nettyutil.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil;
-
-import io.netty.channel.Channel;
-import io.netty.util.concurrent.Promise;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEOMAggregator;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfHelloMessageToXMLEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
-import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
-
-public abstract class AbstractChannelInitializer<S extends NetconfSession> {
-
- public static final String NETCONF_MESSAGE_DECODER = "netconfMessageDecoder";
- public static final String NETCONF_MESSAGE_AGGREGATOR = "aggregator";
- public static final String NETCONF_MESSAGE_ENCODER = "netconfMessageEncoder";
- public static final String NETCONF_MESSAGE_FRAME_ENCODER = "frameEncoder";
- public static final String NETCONF_SESSION_NEGOTIATOR = "negotiator";
-
- public void initialize(Channel ch, Promise<S> promise) {
- ch.pipeline().addLast(NETCONF_MESSAGE_AGGREGATOR, new NetconfEOMAggregator());
- initializeMessageDecoder(ch);
- ch.pipeline().addLast(NETCONF_MESSAGE_FRAME_ENCODER, FramingMechanismHandlerFactory.createHandler(FramingMechanism.EOM));
- initializeMessageEncoder(ch);
-
- initializeSessionNegotiator(ch, promise);
- }
-
- protected void initializeMessageEncoder(Channel ch) {
- // Special encoding handler for hello message to include additional header if available,
- // it is thrown away after successful negotiation
- ch.pipeline().addLast(NETCONF_MESSAGE_ENCODER, new NetconfHelloMessageToXMLEncoder());
- }
-
- protected void initializeMessageDecoder(Channel ch) {
- // Special decoding handler for hello message to parse additional header if available,
- // it is thrown away after successful negotiation
- ch.pipeline().addLast(NETCONF_MESSAGE_DECODER, new NetconfXMLToHelloMessageDecoder());
- }
-
- /**
- * Insert session negotiator into the pipeline. It must be inserted after message decoder
- * identified by {@link AbstractChannelInitializer#NETCONF_MESSAGE_DECODER}, (or any other custom decoder processor)
- */
- protected abstract void initializeSessionNegotiator(Channel ch, Promise<S> promise);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.io.IOException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.NetconfExiSession;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.api.NetconfSessionListener;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXICodec;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.EXIParameters;
-import org.opendaylight.protocol.framework.AbstractProtocolSession;
-import org.openexi.proc.common.EXIOptionsException;
-import org.openexi.sax.TransmogrifierException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractNetconfSession<S extends NetconfSession, L extends NetconfSessionListener<S>> extends AbstractProtocolSession<NetconfMessage> implements NetconfSession, NetconfExiSession {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSession.class);
- private final L sessionListener;
- private final long sessionId;
- private boolean up = false;
-
- private ChannelHandler delayedEncoder;
-
- private final Channel channel;
-
- protected AbstractNetconfSession(final L sessionListener, final Channel channel, final long sessionId) {
- this.sessionListener = sessionListener;
- this.channel = channel;
- this.sessionId = sessionId;
- LOG.debug("Session {} created", sessionId);
- }
-
- protected abstract S thisInstance();
-
- @Override
- public void close() {
- channel.close();
- up = false;
- sessionListener.onSessionTerminated(thisInstance(), new NetconfTerminationReason("Session closed"));
- }
-
- @Override
- protected void handleMessage(final NetconfMessage netconfMessage) {
- LOG.debug("handling incoming message");
- sessionListener.onMessage(thisInstance(), netconfMessage);
- }
-
- @Override
- public ChannelFuture sendMessage(final NetconfMessage netconfMessage) {
- final ChannelFuture future = channel.writeAndFlush(netconfMessage);
- if (delayedEncoder != null) {
- replaceMessageEncoder(delayedEncoder);
- delayedEncoder = null;
- }
-
- return future;
- }
-
- @Override
- protected void endOfInput() {
- LOG.debug("Session {} end of input detected while session was in state {}", toString(), isUp() ? "up"
- : "initialized");
- if (isUp()) {
- this.sessionListener.onSessionDown(thisInstance(), new IOException("End of input detected. Close the session."));
- }
- }
-
- @Override
- protected void sessionUp() {
- LOG.debug("Session {} up", toString());
- sessionListener.onSessionUp(thisInstance());
- this.up = true;
- }
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer(getClass().getSimpleName() + "{");
- sb.append("sessionId=").append(sessionId);
- sb.append(", channel=").append(channel);
- sb.append('}');
- return sb.toString();
- }
-
- protected final void replaceMessageDecoder(final ChannelHandler handler) {
- replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, handler);
- }
-
- protected final void replaceMessageEncoder(final ChannelHandler handler) {
- replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, handler);
- }
-
- protected final void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) {
- this.delayedEncoder = handler;
- }
-
- protected final void replaceChannelHandler(final String handlerName, final ChannelHandler handler) {
- channel.pipeline().replace(handlerName, handlerName, handler);
- }
-
- @Override
- public final void startExiCommunication(final NetconfMessage startExiMessage) {
- final EXIParameters exiParams;
- try {
- exiParams = EXIParameters.fromXmlElement(XmlElement.fromDomDocument(startExiMessage.getDocument()));
- } catch (final EXIOptionsException e) {
- LOG.warn("Unable to parse EXI parameters from {} on session {}", startExiMessage, this, e);
- throw new IllegalArgumentException("Cannot parse options", e);
- }
-
- final NetconfEXICodec exiCodec = new NetconfEXICodec(exiParams.getOptions());
- final NetconfMessageToEXIEncoder exiEncoder;
- try {
- exiEncoder = NetconfMessageToEXIEncoder.create(exiCodec);
- } catch (EXIOptionsException | TransmogrifierException e) {
- LOG.warn("Failed to instantiate EXI encoder for {} on session {}", exiCodec, this, e);
- throw new IllegalStateException("Cannot instantiate encoder for options", e);
- }
-
- final NetconfEXIToMessageDecoder exiDecoder;
- try {
- exiDecoder = NetconfEXIToMessageDecoder.create(exiCodec);
- } catch (EXIOptionsException e) {
- LOG.warn("Failed to instantiate EXI decodeer for {} on session {}", exiCodec, this, e);
- throw new IllegalStateException("Cannot instantiate encoder for options", e);
- }
-
- addExiHandlers(exiDecoder, exiEncoder);
- LOG.debug("Session {} EXI handlers added to pipeline", this);
- }
-
- /**
- * Add a set encoder/decoder tuple into the channel pipeline as appropriate.
- *
- * @param decoder EXI decoder
- * @param encoder EXI encoder
- */
- protected abstract void addExiHandlers(ByteToMessageDecoder decoder, MessageToByteEncoder<NetconfMessage> encoder);
-
- public final boolean isUp() {
- return up;
- }
-
- public final long getSessionId() {
- return sessionId;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.handler.ssl.SslHandler;
-import io.netty.util.Timeout;
-import io.netty.util.Timer;
-import io.netty.util.TimerTask;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GenericFutureListener;
-import io.netty.util.concurrent.Promise;
-import java.util.concurrent.TimeUnit;
-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.NetconfSessionPreferences;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.nettyutil.handler.FramingMechanismHandlerFactory;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfChunkAggregator;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToHelloMessageDecoder;
-import org.opendaylight.controller.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
-import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.NodeList;
-
-public abstract class AbstractNetconfSessionNegotiator<P extends NetconfSessionPreferences, S extends AbstractNetconfSession<S, L>, L extends NetconfSessionListener<S>>
- extends AbstractSessionNegotiator<NetconfHelloMessage, S> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractNetconfSessionNegotiator.class);
-
- public static final String NAME_OF_EXCEPTION_HANDLER = "lastExceptionHandler";
-
- protected final P sessionPreferences;
-
- private final L sessionListener;
- private Timeout timeout;
-
- /**
- * Possible states for Finite State Machine
- */
- protected enum State {
- IDLE, OPEN_WAIT, FAILED, ESTABLISHED
- }
-
- private State state = State.IDLE;
- private final Promise<S> promise;
- private final Timer timer;
- private final long connectionTimeoutMillis;
-
- // TODO shrink constructor
- protected AbstractNetconfSessionNegotiator(final P sessionPreferences, final Promise<S> promise, final Channel channel, final Timer timer,
- final L sessionListener, final long connectionTimeoutMillis) {
- super(promise, channel);
- this.sessionPreferences = sessionPreferences;
- this.promise = promise;
- this.timer = timer;
- this.sessionListener = sessionListener;
- this.connectionTimeoutMillis = connectionTimeoutMillis;
- }
-
- @Override
- protected final void startNegotiation() {
- final Optional<SslHandler> sslHandler = getSslHandler(channel);
- if (sslHandler.isPresent()) {
- Future<Channel> future = sslHandler.get().handshakeFuture();
- future.addListener(new GenericFutureListener<Future<? super Channel>>() {
- @Override
- public void operationComplete(final Future<? super Channel> future) {
- Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful");
- LOG.debug("Ssl handshake complete");
- start();
- }
- });
- } else {
- start();
- }
- }
-
- private static Optional<SslHandler> getSslHandler(final Channel channel) {
- final SslHandler sslHandler = channel.pipeline().get(SslHandler.class);
- return sslHandler == null ? Optional.<SslHandler> absent() : Optional.of(sslHandler);
- }
-
- public P getSessionPreferences() {
- return sessionPreferences;
- }
-
- private void start() {
- final NetconfMessage helloMessage = this.sessionPreferences.getHelloMessage();
- LOG.debug("Session negotiation started with hello message {} on channel {}", helloMessage, channel);
-
- channel.pipeline().addLast(NAME_OF_EXCEPTION_HANDLER, new ExceptionHandlingInboundChannelHandler());
-
- // FIXME, make sessionPreferences return HelloMessage, move NetconfHelloMessage to API
- sendMessage((NetconfHelloMessage)helloMessage);
-
- replaceHelloMessageOutboundHandler();
- changeState(State.OPEN_WAIT);
-
- timeout = this.timer.newTimeout(new TimerTask() {
- @Override
- public void run(final Timeout timeout) {
- synchronized (this) {
- if (state != State.ESTABLISHED) {
-
- LOG.debug("Connection timeout after {}, session is in state {}", timeout, state);
-
- // Do not fail negotiation if promise is done or canceled
- // It would result in setting result of the promise second time and that throws exception
- if (isPromiseFinished() == false) {
- negotiationFailed(new IllegalStateException("Session was not established after " + timeout));
- changeState(State.FAILED);
-
- channel.closeFuture().addListener(new GenericFutureListener<ChannelFuture>() {
- @Override
- public void operationComplete(final ChannelFuture future) throws Exception {
- if(future.isSuccess()) {
- LOG.debug("Channel {} closed: success", future.channel());
- } else {
- LOG.warn("Channel {} closed: fail", future.channel());
- }
- }
- });
- }
- } else if(channel.isOpen()) {
- channel.pipeline().remove(NAME_OF_EXCEPTION_HANDLER);
- }
- }
- }
-
- private boolean isPromiseFinished() {
- return promise.isDone() || promise.isCancelled();
- }
-
- }, connectionTimeoutMillis, TimeUnit.MILLISECONDS);
- }
-
- private void cancelTimeout() {
- if(timeout!=null) {
- timeout.cancel();
- }
- }
-
- protected final S getSessionForHelloMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException {
- Preconditions.checkNotNull(netconfMessage, "netconfMessage");
-
- final Document doc = netconfMessage.getDocument();
-
- if (shouldUseChunkFraming(doc)) {
- insertChunkFramingToPipeline();
- }
-
- changeState(State.ESTABLISHED);
- return getSession(sessionListener, channel, netconfMessage);
- }
-
- /**
- * Insert chunk framing handlers into the pipeline
- */
- private void insertChunkFramingToPipeline() {
- replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER,
- FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK));
- replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR,
- new NetconfChunkAggregator());
- }
-
- private boolean shouldUseChunkFraming(final Document doc) {
- return containsBase11Capability(doc)
- && containsBase11Capability(sessionPreferences.getHelloMessage().getDocument());
- }
-
- /**
- * Remove special inbound handler for hello message. Insert regular netconf xml message (en|de)coders.
- *
- * Inbound hello message handler should be kept until negotiation is successful
- * It caches any non-hello messages while negotiation is still in progress
- */
- protected final void replaceHelloMessageInboundHandler(final S session) {
- ChannelHandler helloMessageHandler = replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder());
-
- Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder,
- "Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline());
- Iterable<NetconfMessage> netconfMessagesFromNegotiation =
- ((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages();
-
- // Process messages received during negotiation
- // The hello message handler does not have to be synchronized, since it is always call from the same thread by netty
- // It means, we are now using the thread now
- for (NetconfMessage message : netconfMessagesFromNegotiation) {
- session.handleMessage(message);
- }
- }
-
- /**
- * Remove special outbound handler for hello message. Insert regular netconf xml message (en|de)coders.
- */
- private void replaceHelloMessageOutboundHandler() {
- replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder());
- }
-
- private static ChannelHandler replaceChannelHandler(final Channel channel, final String handlerKey, final ChannelHandler decoder) {
- return channel.pipeline().replace(handlerKey, handlerKey, decoder);
- }
-
- protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException;
-
- private synchronized void changeState(final State newState) {
- LOG.debug("Changing state from : {} to : {} for channel: {}", state, newState, channel);
- Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s for chanel %s", state,
- newState, channel);
- this.state = newState;
- }
-
- private static boolean containsBase11Capability(final Document doc) {
- final NodeList nList = doc.getElementsByTagName(XmlNetconfConstants.CAPABILITY);
- for (int i = 0; i < nList.getLength(); i++) {
- if (nList.item(i).getTextContent().contains(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isStateChangePermitted(final State state, final State newState) {
- if (state == State.IDLE && newState == State.OPEN_WAIT) {
- return true;
- }
- if (state == State.OPEN_WAIT && newState == State.ESTABLISHED) {
- return true;
- }
- if (state == State.OPEN_WAIT && newState == State.FAILED) {
- return true;
- }
- LOG.debug("Transition from {} to {} is not allowed", state, newState);
- return false;
- }
-
- /**
- * Handler to catch exceptions in pipeline during negotiation
- */
- private final class ExceptionHandlingInboundChannelHandler extends ChannelInboundHandlerAdapter {
- @Override
- public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
- LOG.warn("An exception occurred during negotiation with {}", channel.remoteAddress(), cause);
- cancelTimeout();
- negotiationFailed(cause);
- changeState(State.FAILED);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.io.Writer;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * Custom BufferedWriter optimized for netconf pipeline implemented instead of default BufferedWriter provided by jdk.
- * <p/>
- * The line separator instance field in java.io.BufferedWriter is
- * assigned using AccessController and takes considerable amount of time especially
- * if lots of BufferedWriters are created in the system.
- * <p/>
- * This implementation should only be used if newLine method is not required
- * such as netconf message to XML encoders.
- * Methods in this implementation are not synchronized.
- */
-@NotThreadSafe
-public final class BufferedWriter extends Writer {
-
- private static final int DEFAULT_CHAR_BUFFER_SIZE = 8192;
-
- private final Writer writer;
- private final char buffer[];
- private final int bufferSize;
-
- private int nextChar = 0;
-
- public BufferedWriter(final Writer writer) {
- this(writer, DEFAULT_CHAR_BUFFER_SIZE);
- }
-
- public BufferedWriter(final Writer writer, final int bufferSize) {
- super(writer);
- Preconditions.checkArgument(bufferSize > 0, "Buffer size <= 0");
- this.writer = writer;
- this.buffer = new char[bufferSize];
- this.bufferSize = bufferSize;
- }
-
- private void flushBuffer() throws IOException {
- if (nextChar == 0)
- return;
- writer.write(buffer, 0, nextChar);
- nextChar = 0;
- }
-
- @Override
- public void write(final int c) throws IOException {
- if (nextChar >= bufferSize)
- flushBuffer();
- buffer[nextChar++] = (char) c;
- }
-
- @Override
- public void write(final char[] buffer, final int offset, final int length) throws IOException {
- if ((offset < 0) || (offset > buffer.length) || (length < 0) ||
- ((offset + length) > buffer.length) || ((offset + length) < 0)) {
- throw new IndexOutOfBoundsException(String.format("Buffer size: %d, Offset: %d, Length: %d", buffer.length, offset, length));
- } else if (length == 0) {
- return;
- }
-
- if (length >= bufferSize) {
- flushBuffer();
- writer.write(buffer, offset, length);
- return;
- }
-
- int b = offset;
- final int t = offset + length;
- while (b < t) {
- final int d = Math.min(bufferSize - nextChar, t - b);
- System.arraycopy(buffer, b, this.buffer, nextChar, d);
- b += d;
- nextChar += d;
- if (nextChar >= bufferSize)
- flushBuffer();
- }
- }
-
- @Override
- public void write(final String string, final int offset, final int length) throws IOException {
- int b = offset;
- final int t = offset + length;
- while (b < t) {
- final int d = Math.min(bufferSize - nextChar, t - b);
- string.getChars(b, b + d, buffer, nextChar);
- b += d;
- nextChar += d;
- if (nextChar >= bufferSize)
- flushBuffer();
- }
- }
-
- @Override
- public void flush() throws IOException {
- flushBuffer();
- writer.flush();
- }
-
- @Override
- public void close() throws IOException {
- try {
- flushBuffer();
- } finally {
- writer.close();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-
-public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
- public static final int DEFAULT_CHUNK_SIZE = 8192;
- public static final int MIN_CHUNK_SIZE = 128;
- public static final int MAX_CHUNK_SIZE = 16 * 1024 * 1024;
-
- private final int chunkSize;
-
- public ChunkedFramingMechanismEncoder() {
- this(DEFAULT_CHUNK_SIZE);
- }
-
- public ChunkedFramingMechanismEncoder(final int chunkSize) {
- Preconditions.checkArgument(chunkSize >= MIN_CHUNK_SIZE && chunkSize <= MAX_CHUNK_SIZE, "Unsupported chunk size %s", chunkSize);
- this.chunkSize = chunkSize;
- }
-
- public final int getChunkSize() {
- return chunkSize;
- }
-
- @Override
- protected void encode(final ChannelHandlerContext ctx, final ByteBuf msg, final ByteBuf out) {
- do {
- final int xfer = Math.min(chunkSize, msg.readableBytes());
-
- out.writeBytes(NetconfMessageConstants.START_OF_CHUNK);
- out.writeBytes(String.valueOf(xfer).getBytes(Charsets.US_ASCII));
- out.writeByte('\n');
-
- out.writeBytes(msg, xfer);
- } while (msg.isReadable());
-
- out.writeBytes(NetconfMessageConstants.END_OF_CHUNK);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-
-public class EOMFramingMechanismEncoder extends MessageToByteEncoder<ByteBuf> {
- @Override
- protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) {
- out.writeBytes(msg);
- out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.handler.codec.MessageToByteEncoder;
-import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class FramingMechanismHandlerFactory {
-
- private static final Logger LOG = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class);
-
- private FramingMechanismHandlerFactory() {
- // not called - private constructor for utility class
- }
-
- public static MessageToByteEncoder<ByteBuf> createHandler(FramingMechanism framingMechanism) {
- LOG.debug("{} framing mechanism was selected.", framingMechanism);
- if (framingMechanism == FramingMechanism.EOM) {
- return new EOMFramingMechanismEncoder();
- } else {
- return new ChunkedFramingMechanismEncoder();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.CompositeByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfChunkAggregator extends ByteToMessageDecoder {
- private final static Logger LOG = LoggerFactory.getLogger(NetconfChunkAggregator.class);
- private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}";
- private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}";
- public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024;
-
- private static enum State {
- HEADER_ONE, // \n
- HEADER_TWO, // #
- HEADER_LENGTH_FIRST, // [1-9]
- HEADER_LENGTH_OTHER, // [0-9]*\n
- DATA,
- FOOTER_ONE, // \n
- FOOTER_TWO, // #
- FOOTER_THREE, // #
- FOOTER_FOUR, // \n
- }
-
- private final int maxChunkSize = DEFAULT_MAXIMUM_CHUNK_SIZE;
- private State state = State.HEADER_ONE;
- private long chunkSize;
- private CompositeByteBuf chunk;
-
- private static void checkNewLine(final byte b,final String errorMessage) {
- if (b != '\n') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n');
- throw new IllegalStateException(errorMessage);
- }
- }
-
- private static void checkHash(final byte b,final String errorMessage) {
- if (b != '#') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#');
- throw new IllegalStateException(errorMessage);
- }
- }
-
- private void checkChunkSize() {
- if (chunkSize > maxChunkSize) {
- LOG.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize);
- throw new IllegalStateException("Maximum chunk size exceeded");
- }
- }
-
- @Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IllegalStateException {
- while (in.isReadable()) {
- switch (state) {
- case HEADER_ONE:
- {
- final byte b = in.readByte();
- checkNewLine(b, "Malformed chunk header encountered (byte 0)");
-
- state = State.HEADER_TWO;
-
- initChunk();
- break;
- }
- case HEADER_TWO:
- {
- final byte b = in.readByte();
- checkHash(b, "Malformed chunk header encountered (byte 1)");
-
- state = State.HEADER_LENGTH_FIRST;
- break;
- }
- case HEADER_LENGTH_FIRST:
- {
- final byte b = in.readByte();
- chunkSize = processHeaderLengthFirst(b);
- state = State.HEADER_LENGTH_OTHER;
- break;
- }
- case HEADER_LENGTH_OTHER:
- {
- final byte b = in.readByte();
- if (b == '\n') {
- state = State.DATA;
- break;
- }
-
- if (b < '0' || b > '9') {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9');
- throw new IllegalStateException("Invalid chunk size encountered");
- }
-
- chunkSize *= 10;
- chunkSize += b - '0';
- checkChunkSize();
- break;
- }
- case DATA:
- /*
- * FIXME: this gathers all data into one big chunk before passing
- * it on. Make sure the pipeline can work with partial data
- * and then change this piece to pass the data on as it
- * comes through.
- */
- if (in.readableBytes() < chunkSize) {
- LOG.debug("Buffer has {} bytes, need {} to complete chunk", in.readableBytes(), chunkSize);
- in.discardReadBytes();
- return;
- }
- aggregateChunks(in.readBytes((int) chunkSize));
- state = State.FOOTER_ONE;
- break;
- case FOOTER_ONE:
- {
- final byte b = in.readByte();
- checkNewLine(b,"Malformed chunk footer encountered (byte 0)");
- state = State.FOOTER_TWO;
- chunkSize = 0;
- break;
- }
- case FOOTER_TWO:
- {
- final byte b = in.readByte();
- checkHash(b,"Malformed chunk footer encountered (byte 1)");
- state = State.FOOTER_THREE;
- break;
- }
- case FOOTER_THREE:
- {
- final byte b = in.readByte();
-
- // In this state, either header-of-new-chunk or message-end is expected
- // Depends on the next character
-
- extractNewChunkOrMessageEnd(b);
-
- break;
- }
- case FOOTER_FOUR:
- {
- final byte b = in.readByte();
- checkNewLine(b,"Malformed chunk footer encountered (byte 3)");
- state = State.HEADER_ONE;
- out.add(chunk);
- chunk = null;
- break;
- }
- }
- }
-
- in.discardReadBytes();
- }
-
- private void extractNewChunkOrMessageEnd(final byte b) {
- if (isHeaderLengthFirst(b)) {
- // Extract header length#1 from new chunk
- chunkSize = processHeaderLengthFirst(b);
- // Proceed with next chunk processing
- state = State.HEADER_LENGTH_OTHER;
- } else if (b == '#') {
- state = State.FOOTER_FOUR;
- } else {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte) '#', (byte) '1', (byte) '9');
- throw new IllegalStateException("Malformed chunk footer encountered (byte 2)");
- }
- }
-
- private void initChunk() {
- chunk = Unpooled.compositeBuffer();
- }
-
- private void aggregateChunks(final ByteBuf newChunk) {
- chunk.addComponent(chunk.numComponents(), newChunk);
-
- // Update writer index, addComponent does not update it
- chunk.writerIndex(chunk.writerIndex() + newChunk.readableBytes());
- }
-
- private static int processHeaderLengthFirst(final byte b) {
- if (!isHeaderLengthFirst(b)) {
- LOG.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9');
- throw new IllegalStateException("Invalid chunk size encountered (byte 0)");
- }
-
- return b - '0';
- }
-
- private static boolean isHeaderLengthFirst(final byte b) {
- return b >= '1' && b <= '9';
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.handler.codec.DelimiterBasedFrameDecoder;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-
-public class NetconfEOMAggregator extends DelimiterBasedFrameDecoder {
-
- public static final ByteBuf DELIMITER = Unpooled.wrappedBuffer(NetconfMessageConstants.END_OF_MESSAGE);
-
- public NetconfEOMAggregator() {
- super(Integer.MAX_VALUE, DELIMITER);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import org.openexi.proc.HeaderOptionsOutputType;
-import org.openexi.proc.common.EXIOptions;
-import org.openexi.proc.common.EXIOptionsException;
-import org.openexi.proc.common.GrammarOptions;
-import org.openexi.proc.grammars.GrammarCache;
-import org.openexi.sax.EXIReader;
-import org.openexi.sax.Transmogrifier;
-import org.openexi.sax.TransmogrifierException;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-public final class NetconfEXICodec {
- /**
- * NETCONF is XML environment, so the use of EXI cookie is not really needed. Adding it
- * decreases efficiency of encoding by adding human-readable 4 bytes "EXI$" to the head
- * of the stream. This is really useful, so let's output it now.
- */
- private static final boolean OUTPUT_EXI_COOKIE = true;
- /**
- * OpenEXI does not allow us to directly prevent resolution of external entities. In order
- * to prevent XXE attacks, we reuse a single no-op entity resolver.
- */
- private static final EntityResolver ENTITY_RESOLVER = new EntityResolver() {
- @Override
- public InputSource resolveEntity(final String publicId, final String systemId) {
- return new InputSource();
- }
- };
-
- /**
- * Since we have a limited number of options we can have, instantiating a weak cache
- * will allow us to reuse instances where possible.
- */
- private static final LoadingCache<Short, GrammarCache> GRAMMAR_CACHES = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Short, GrammarCache>() {
- @Override
- public GrammarCache load(final Short key) {
- return new GrammarCache(key);
- }
- });
-
- /**
- * Grammar cache acts as a template and is duplicated by the Transmogrifier and the Reader
- * before use. It is safe to reuse a single instance.
- */
- private final GrammarCache exiGrammarCache;
- private final EXIOptions exiOptions;
-
- public NetconfEXICodec(final EXIOptions exiOptions) {
- this.exiOptions = Preconditions.checkNotNull(exiOptions);
- this.exiGrammarCache = createGrammarCache(exiOptions);
- }
-
- private static GrammarCache createGrammarCache(final EXIOptions exiOptions) {
- short go = GrammarOptions.DEFAULT_OPTIONS;
- if (exiOptions.getPreserveComments()) {
- go = GrammarOptions.addCM(go);
- }
- if (exiOptions.getPreserveDTD()) {
- go = GrammarOptions.addDTD(go);
- }
- if (exiOptions.getPreserveNS()) {
- go = GrammarOptions.addNS(go);
- }
- if (exiOptions.getPreservePIs()) {
- go = GrammarOptions.addPI(go);
- }
-
- return GRAMMAR_CACHES.getUnchecked(go);
- }
-
- EXIReader getReader() throws EXIOptionsException {
- final EXIReader r = new EXIReader();
- r.setPreserveLexicalValues(exiOptions.getPreserveLexicalValues());
- r.setGrammarCache(exiGrammarCache);
- r.setEntityResolver(ENTITY_RESOLVER);
- return r;
- }
-
- Transmogrifier getTransmogrifier() throws EXIOptionsException, TransmogrifierException {
- final Transmogrifier transmogrifier = new Transmogrifier();
- transmogrifier.setAlignmentType(exiOptions.getAlignmentType());
- transmogrifier.setBlockSize(exiOptions.getBlockSize());
- transmogrifier.setGrammarCache(exiGrammarCache);
- transmogrifier.setOutputCookie(OUTPUT_EXI_COOKIE);
- transmogrifier.setOutputOptions(HeaderOptionsOutputType.all);
- transmogrifier.setResolveExternalGeneralEntities(false);
- return transmogrifier;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.openexi.proc.common.EXIOptionsException;
-import org.openexi.sax.EXIReader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfEXIToMessageDecoder.class);
- private static final SAXTransformerFactory FACTORY = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
- /**
- * This class is not marked as shared, so it can be attached to only a single channel,
- * which means that {@link #decode(ChannelHandlerContext, ByteBuf, List)}
- * cannot be invoked concurrently. Hence we can reuse the reader.
- */
- private final EXIReader reader;
-
- private NetconfEXIToMessageDecoder(final EXIReader reader) {
- this.reader = Preconditions.checkNotNull(reader);
- }
-
- public static NetconfEXIToMessageDecoder create(final NetconfEXICodec codec) throws EXIOptionsException {
- return new NetconfEXIToMessageDecoder(codec.getReader());
- }
-
- @Override
- protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws EXIOptionsException, IOException, SAXException, TransformerConfigurationException {
- /*
- * Note that we could loop here and process all the messages, but we can't do that.
- * The reason is <stop-exi> operation, which has the contract of immediately stopping
- * the use of EXI, which means the next message needs to be decoded not by us, but rather
- * by the XML decoder.
- */
-
- // If empty Byte buffer is passed to r.parse, EOFException is thrown
- if (!in.isReadable()) {
- LOG.debug("No more content in incoming buffer.");
- return;
- }
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
- }
-
- final TransformerHandler handler = FACTORY.newTransformerHandler();
- reader.setContentHandler(handler);
-
- final DOMResult domResult = new DOMResult();
- handler.setResult(domResult);
-
- try (final InputStream is = new ByteBufInputStream(in)) {
- // Performs internal reset before doing anything
- reader.parse(new InputSource(is));
- }
-
- out.add(new NetconfMessage((Document) domResult.getNode()));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import java.io.IOException;
-import javax.xml.transform.TransformerException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-
-/**
- * Customized NetconfMessageToXMLEncoder that serializes additional header with
- * session metadata along with
- * {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage}
- * . Used by netconf clients to send information about the user, ip address,
- * protocol etc.
- * <p/>
- * Hello message with header example:
- * <p/>
- *
- * <pre>
- * {@code
- * [tomas;10.0.0.0/10000;tcp;1000;1000;;/home/tomas;;]
- * <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- * <capabilities>
- * <capability>urn:ietf:params:netconf:base:1.0</capability>
- * </capabilities>
- * </hello>
- * }
- * </pre>
- */
-public final class NetconfHelloMessageToXMLEncoder extends NetconfMessageToXMLEncoder {
- @Override
- @VisibleForTesting
- public void encode(ChannelHandlerContext ctx, NetconfMessage msg, ByteBuf out) throws IOException, TransformerException {
- Preconditions.checkState(msg instanceof NetconfHelloMessage, "Netconf message of type %s expected, was %s",
- NetconfHelloMessage.class, msg.getClass());
- Optional<NetconfHelloMessageAdditionalHeader> headerOptional = ((NetconfHelloMessage) msg)
- .getAdditionalHeader();
-
- // If additional header present, serialize it along with netconf hello message
- if (headerOptional.isPresent()) {
- out.writeBytes(headerOptional.get().toFormattedString().getBytes(Charsets.UTF_8));
- }
-
- super.encode(ctx, msg, out);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufOutputStream;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.io.IOException;
-import java.io.OutputStream;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.openexi.proc.common.EXIOptionsException;
-import org.openexi.sax.Transmogrifier;
-import org.openexi.sax.TransmogrifierException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.ContentHandler;
-
-public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder<NetconfMessage> {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToEXIEncoder.class);
- /**
- * This class is not marked as shared, so it can be attached to only a single channel,
- * which means that {@link #encode(ChannelHandlerContext, NetconfMessage, ByteBuf)}
- * cannot be invoked concurrently. Hence we can reuse the transmogrifier.
- */
- private final Transmogrifier transmogrifier;
-
- private NetconfMessageToEXIEncoder(final Transmogrifier transmogrifier) {
- this.transmogrifier = Preconditions.checkNotNull(transmogrifier);
- }
-
- public static NetconfMessageToEXIEncoder create(final NetconfEXICodec codec) throws EXIOptionsException, TransmogrifierException {
- return new NetconfMessageToEXIEncoder(codec.getTransmogrifier());
- }
-
- @Override
- protected void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws EXIOptionsException, IOException, TransformerException, TransmogrifierException {
- LOG.trace("Sent to encode : {}", msg);
-
- try (final OutputStream os = new ByteBufOutputStream(out)) {
- transmogrifier.setOutputStream(os);
- final ContentHandler handler = transmogrifier.getSAXTransmogrifier();
- final Transformer transformer = ThreadLocalTransformers.getDefaultTransformer();
- transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(handler));
- } finally {
- // Make sure we do not retain any reference to state by removing
- // the output stream reference and resetting internal state.
- transmogrifier.setOutputStream(null);
- transmogrifier.getSAXTransmogrifier();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufOutputStream;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Comment;
-
-public class NetconfMessageToXMLEncoder extends MessageToByteEncoder<NetconfMessage> {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToXMLEncoder.class);
-
- private final Optional<String> clientId;
-
- public NetconfMessageToXMLEncoder() {
- this(Optional.<String>absent());
- }
-
- public NetconfMessageToXMLEncoder(final Optional<String> clientId) {
- this.clientId = clientId;
- }
-
- @Override
- @VisibleForTesting
- public void encode(final ChannelHandlerContext ctx, final NetconfMessage msg, final ByteBuf out) throws IOException, TransformerException {
- LOG.trace("Sent to encode : {}", msg);
-
- if (clientId.isPresent()) {
- Comment comment = msg.getDocument().createComment("clientId:" + clientId.get());
- msg.getDocument().appendChild(comment);
- }
-
- try (OutputStream os = new ByteBufOutputStream(out)) {
- // Wrap OutputStreamWriter with BufferedWriter as suggested in javadoc for OutputStreamWriter
-
- // Using custom BufferedWriter that does not provide newLine method as performance improvement
- // see javadoc for org.opendaylight.controller.netconf.nettyutil.handler.BufferedWriter
- StreamResult result = new StreamResult(new org.opendaylight.controller.netconf.nettyutil.handler.BufferedWriter(new OutputStreamWriter(os)));
- DOMSource source = new DOMSource(msg.getDocument());
- ThreadLocalTransformers.getPrettyTransformer().transform(source, result);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-/**
- * Customized NetconfXMLToMessageDecoder that reads additional header with
- * session metadata from
- * {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage}
- *
- *
- * This handler should be replaced in pipeline by regular message handler as last step of negotiation.
- * It serves as a message barrier and halts all non-hello netconf messages.
- * Netconf messages after hello should be processed once the negotiation succeeded.
- *
- */
-public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToHelloMessageDecoder.class);
-
- private static final List<byte[]> POSSIBLE_ENDS = ImmutableList.of(
- new byte[] { ']', '\n' },
- new byte[] { ']', '\r', '\n' });
- private static final List<byte[]> POSSIBLE_STARTS = ImmutableList.of(
- new byte[] { '[' },
- new byte[] { '\r', '\n', '[' },
- new byte[] { '\n', '[' });
-
- // State variables do not have to by synchronized
- // Netty uses always the same (1) thread per pipeline
- // We use instance of this per pipeline
- private final List<NetconfMessage> nonHelloMessages = Lists.newArrayList();
- private boolean helloReceived = false;
-
- @Override
- @VisibleForTesting
- public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IOException, SAXException, NetconfDocumentedException {
- if (in.readableBytes() == 0) {
- LOG.debug("No more content in incoming buffer.");
- return;
- }
-
- in.markReaderIndex();
- try {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
- }
-
- byte[] bytes = new byte[in.readableBytes()];
- in.readBytes(bytes);
-
- logMessage(bytes);
-
- // Extract bytes containing header with additional metadata
- String additionalHeader = null;
- if (startsWithAdditionalHeader(bytes)) {
- // Auth information containing username, ip address... extracted for monitoring
- int endOfAuthHeader = getAdditionalHeaderEndIndex(bytes);
- if (endOfAuthHeader > -1) {
- byte[] additionalHeaderBytes = Arrays.copyOfRange(bytes, 0, endOfAuthHeader);
- additionalHeader = additionalHeaderToString(additionalHeaderBytes);
- bytes = Arrays.copyOfRange(bytes, endOfAuthHeader, bytes.length);
- }
- }
-
- Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes));
-
- final NetconfMessage message = getNetconfMessage(additionalHeader, doc);
- if (message instanceof NetconfHelloMessage) {
- Preconditions.checkState(helloReceived == false,
- "Multiple hello messages received, unexpected hello: %s", message);
- out.add(message);
- helloReceived = true;
- // Non hello message, suspend the message and insert into cache
- } else {
- Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s", message);
- LOG.debug("Netconf message received during negotiation, caching {}", message);
- nonHelloMessages.add(message);
- }
- } finally {
- in.discardReadBytes();
- }
- }
-
- private static NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc) throws NetconfDocumentedException {
- NetconfMessage msg = new NetconfMessage(doc);
- if(NetconfHelloMessage.isHelloMessage(msg)) {
- if (additionalHeader != null) {
- return new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader));
- } else {
- return new NetconfHelloMessage(doc);
- }
- }
-
- return msg;
- }
-
- private static int getAdditionalHeaderEndIndex(final byte[] bytes) {
- for (byte[] possibleEnd : POSSIBLE_ENDS) {
- int idx = findByteSequence(bytes, possibleEnd);
-
- if (idx != -1) {
- return idx + possibleEnd.length;
- }
- }
-
- return -1;
- }
-
- private static int findByteSequence(final byte[] bytes, final byte[] sequence) {
- if (bytes.length < sequence.length) {
- throw new IllegalArgumentException("Sequence to be found is longer than the given byte array.");
- }
- if (bytes.length == sequence.length) {
- if (Arrays.equals(bytes, sequence)) {
- return 0;
- } else {
- return -1;
- }
- }
- int j = 0;
- for (int i = 0; i < bytes.length; i++) {
- if (bytes[i] == sequence[j]) {
- j++;
- if (j == sequence.length) {
- return i - j + 1;
- }
- } else {
- j = 0;
- }
- }
- return -1;
- }
-
- private static void logMessage(final byte[] bytes) {
- if (LOG.isDebugEnabled()) {
- String s = Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
- LOG.debug("Parsing message \n{}", s);
- }
- }
-
- private static boolean startsWithAdditionalHeader(final byte[] bytes) {
- for (byte[] possibleStart : POSSIBLE_STARTS) {
- int i = 0;
- for (byte b : possibleStart) {
- if(bytes[i++] != b) {
- break;
- }
-
- if(i == possibleStart.length) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- private static String additionalHeaderToString(final byte[] bytes) {
- return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString();
- }
-
- /**
- * @return Collection of NetconfMessages that were not hello, but were received during negotiation
- */
- public Iterable<NetconfMessage> getPostHelloNetconfMessages() {
- return nonHelloMessages;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-import io.netty.buffer.ByteBufUtil;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import java.io.IOException;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.SAXException;
-
-public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class);
-
- @Override
- public void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out) throws IOException, SAXException {
- if (in.isReadable()) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in));
- }
-
- /* According to the XML 1.0 specifications, when there is an XML declaration
- * at the beginning of an XML document, it is invalid to have
- * white spaces before that declaration (reminder: a XML declaration looks like:
- * <?xml version="1.0" encoding="UTF-8"?>). In contrast, when there is no XML declaration,
- * it is valid to have white spaces at the beginning of the document.
- *
- * When they send a NETCONF message, several NETCONF servers start with a new line (either
- * LF or CRLF), presumably to improve readability in interactive sessions with a human being.
- * Some NETCONF servers send an XML declaration, some others do not.
- *
- * If a server starts a NETCONF message with white spaces and follows with an XML
- * declaration, XmlUtil.readXmlToDocument() will fail because this is invalid XML.
- * But in the spirit of the "NETCONF over SSH" RFC 4742 and to improve interoperability, we want
- * to accept those messages.
- *
- * To do this, the following code strips the leading bytes before the start of the XML messages.
- */
-
- // Skip all leading whitespaces by moving the reader index to the first non whitespace character
- while (in.isReadable()) {
- if (!isWhitespace(in.readByte())) {
- // return reader index to the first non whitespace character
- in.readerIndex(in.readerIndex() - 1);
- break;
- }
- }
-
- // Warn about leading whitespaces
- if (in.readerIndex() != 0 && LOG.isWarnEnabled()) {
- final byte[] strippedBytes = new byte[in.readerIndex()];
- in.getBytes(0, strippedBytes, 0, in.readerIndex());
- LOG.warn("XML message with unwanted leading bytes detected. Discarded the {} leading byte(s): '{}'",
- in.readerIndex(), ByteBufUtil.hexDump(Unpooled.wrappedBuffer(strippedBytes)));
- }
- }
- if (in.isReadable()) {
- out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in))));
- } else {
- LOG.debug("No more content in incoming buffer.");
- }
- }
-
- /**
- * Check whether a byte is whitespace/control character. Considered whitespace characters: <br/>
- * SPACE, \t, \n, \v, \r, \f
- *
- * @param b byte to check
- * @return true if the byte is a whitespace/control character
- */
- private static boolean isWhitespace(final byte b) {
- return b <= 0x0d && b >= 0x09 || b == 0x20;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-
-/**
- * Utility class for cached thread-local transformers. This class exists mostly for use by handlers.
- */
-final class ThreadLocalTransformers {
- private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
-
- private static final ThreadLocal<Transformer> DEFAULT_TRANSFORMER = new ThreadLocal<Transformer>() {
- @Override
- protected Transformer initialValue() {
- try {
- return FACTORY.newTransformer();
- } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
- throw new IllegalStateException("Unexpected error while instantiating a Transformer", e);
- }
- };
-
- @Override
- public void set(final Transformer value) {
- throw new UnsupportedOperationException();
- };
- };
-
- private static final ThreadLocal<Transformer> PRETTY_TRANSFORMER = new ThreadLocal<Transformer>() {
- @Override
- protected Transformer initialValue() {
- final Transformer ret;
-
- try {
- ret = FACTORY.newTransformer();
- } catch (TransformerConfigurationException | TransformerFactoryConfigurationError e) {
- throw new IllegalStateException("Unexpected error while instantiating a Transformer", e);
- }
-
- ret.setOutputProperty(OutputKeys.INDENT, "yes");
- ret.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
- return ret;
- };
-
- @Override
- public void set(final Transformer value) {
- throw new UnsupportedOperationException();
- };
- };
-
- private ThreadLocalTransformers() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- /**
- * Get the transformer with default configuration.
- *
- * @return A transformer with default configuration based on the default implementation.
- */
- public static Transformer getDefaultTransformer() {
- return DEFAULT_TRANSFORMER.get();
- }
-
- /**
- * Get the transformer with default configuration, but with automatic indentation
- * and the XML declaration removed.
- *
- * @return A transformer with human-friendly configuration.
- */
- public static Transformer getPrettyTransformer() {
- return PRETTY_TRANSFORMER.get();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler.exi;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.EXIOptions;
-import org.openexi.proc.common.EXIOptionsException;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public final class EXIParameters {
- private static final String EXI_PARAMETER_ALIGNMENT = "alignment";
- static final String EXI_PARAMETER_BYTE_ALIGNED = "byte-aligned";
- static final String EXI_PARAMETER_BIT_PACKED = "bit-packed";
- static final String EXI_PARAMETER_COMPRESSED = "compressed";
- static final String EXI_PARAMETER_PRE_COMPRESSION = "pre-compression";
-
- private static final String EXI_PARAMETER_FIDELITY = "fidelity";
- private static final String EXI_FIDELITY_DTD = "dtd";
- private static final String EXI_FIDELITY_LEXICAL_VALUES = "lexical-values";
- private static final String EXI_FIDELITY_COMMENTS = "comments";
- private static final String EXI_FIDELITY_PIS = "pis";
- private static final String EXI_FIDELITY_PREFIXES = "prefixes";
-
- private final EXIOptions options;
-
- private EXIParameters(final EXIOptions options) {
- this.options = Preconditions.checkNotNull(options);
- }
-
-
- public static EXIParameters fromXmlElement(final XmlElement root) throws EXIOptionsException {
- final EXIOptions options = new EXIOptions();
-
- options.setAlignmentType(AlignmentType.bitPacked);
-
- final NodeList alignmentElements = root.getElementsByTagName(EXI_PARAMETER_ALIGNMENT);
- if (alignmentElements.getLength() > 0) {
- final Element alignmentElement = (Element) alignmentElements.item(0);
- final String alignmentTextContent = alignmentElement.getTextContent().trim();
-
- switch (alignmentTextContent) {
- case EXI_PARAMETER_BIT_PACKED:
- options.setAlignmentType(AlignmentType.bitPacked);
- break;
- case EXI_PARAMETER_BYTE_ALIGNED:
- options.setAlignmentType(AlignmentType.byteAligned);
- break;
- case EXI_PARAMETER_COMPRESSED:
- options.setAlignmentType(AlignmentType.compress);
- break;
- case EXI_PARAMETER_PRE_COMPRESSION:
- options.setAlignmentType(AlignmentType.preCompress);
- break;
- }
- }
-
- if (root.getElementsByTagName(EXI_PARAMETER_FIDELITY).getLength() > 0) {
- if (root.getElementsByTagName(EXI_FIDELITY_DTD).getLength() > 0) {
- options.setPreserveDTD(true);
- }
- if (root.getElementsByTagName(EXI_FIDELITY_LEXICAL_VALUES).getLength() > 0) {
- options.setPreserveLexicalValues(true);
- }
- if (root.getElementsByTagName(EXI_FIDELITY_COMMENTS).getLength() > 0) {
- options.setPreserveComments(true);
- }
- if (root.getElementsByTagName(EXI_FIDELITY_PIS).getLength() > 0) {
- options.setPreservePIs(true);
- }
- if (root.getElementsByTagName(EXI_FIDELITY_PREFIXES).getLength() > 0) {
- options.setPreserveNS(true);
- }
- }
- return new EXIParameters(options);
- }
-
- public final EXIOptions getOptions() {
- return options;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.exi;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.openexi.proc.common.EXIOptions;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Start-exi netconf message.
- */
-public final class NetconfStartExiMessage extends NetconfMessage {
-
- public static final String START_EXI = "start-exi";
- public static final String ALIGNMENT_KEY = "alignment";
- public static final String FIDELITY_KEY = "fidelity";
- public static final String COMMENTS_KEY = "comments";
- public static final String DTD_KEY = "dtd";
- public static final String LEXICAL_VALUES_KEY = "lexical-values";
- public static final String PIS_KEY = "pis";
- public static final String PREFIXES_KEY = "prefixes";
-
- private NetconfStartExiMessage(final Document doc) {
- super(doc);
- }
-
- public static NetconfStartExiMessage create(final EXIOptions exiOptions, final String messageId) {
- final Document doc = XmlUtil.newDocument();
- final Element rpcElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.RPC_KEY);
- rpcElement.setAttributeNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.MESSAGE_ID, messageId);
-
- // TODO draft http://tools.ietf.org/html/draft-varga-netconf-exi-capability-02#section-3.5.1 has no namespace for start-exi element in xml
- final Element startExiElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
- START_EXI);
-
- addAlignment(exiOptions, doc, startExiElement);
- addFidelity(exiOptions, doc, startExiElement);
-
- rpcElement.appendChild(startExiElement);
-
- doc.appendChild(rpcElement);
- return new NetconfStartExiMessage(doc);
- }
-
- private static void addFidelity(final EXIOptions exiOptions, final Document doc, final Element startExiElement) {
- final List<Element> fidelityElements = Lists.newArrayList();
- createFidelityElement(doc, fidelityElements, exiOptions.getPreserveComments(), COMMENTS_KEY);
- createFidelityElement(doc, fidelityElements, exiOptions.getPreserveDTD(), DTD_KEY);
- createFidelityElement(doc, fidelityElements, exiOptions.getPreserveLexicalValues(), LEXICAL_VALUES_KEY);
- createFidelityElement(doc, fidelityElements, exiOptions.getPreservePIs(), PIS_KEY);
- createFidelityElement(doc, fidelityElements, exiOptions.getPreserveNS(), PREFIXES_KEY);
-
- if (fidelityElements.isEmpty() == false) {
- final Element fidelityElement = doc.createElementNS(
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0, FIDELITY_KEY);
- for (final Element element : fidelityElements) {
- fidelityElement.appendChild(element);
- }
- startExiElement.appendChild(fidelityElement);
- }
- }
-
- private static void addAlignment(final EXIOptions exiOptions, final Document doc, final Element startExiElement) {
- final Element alignmentElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
- ALIGNMENT_KEY);
-
- String alignmentString = EXIParameters.EXI_PARAMETER_BIT_PACKED;
- switch (exiOptions.getAlignmentType()) {
- case byteAligned: {
- alignmentString = EXIParameters.EXI_PARAMETER_BYTE_ALIGNED;
- break;
- }
- case bitPacked: {
- alignmentString = EXIParameters.EXI_PARAMETER_BIT_PACKED;
- break;
- }
- case compress: {
- alignmentString = EXIParameters.EXI_PARAMETER_COMPRESSED;
- break;
- }
- case preCompress: {
- alignmentString = EXIParameters.EXI_PARAMETER_PRE_COMPRESSION;
- break;
- }
- }
-
- alignmentElement.setTextContent(alignmentString);
- startExiElement.appendChild(alignmentElement);
- }
-
- private static void createFidelityElement(final Document doc, final List<Element> fidelityElements, final boolean fidelity, final String fidelityName) {
-
- if (fidelity) {
- fidelityElements.add(doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0,
- fidelityName));
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication;
-
-import java.io.IOException;
-import org.apache.sshd.ClientSession;
-
-/**
- * Class providing authentication facility to SSH handler.
- */
-public abstract class AuthenticationHandler {
-
- public abstract String getUsername();
-
- public abstract org.apache.sshd.client.future.AuthFuture authenticate(final ClientSession session) throws IOException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication;
-
-import java.io.IOException;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.client.future.AuthFuture;
-
-/**
- * Class Providing username/password authentication option to
- * {@link org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler}
- */
-public class LoginPassword extends AuthenticationHandler {
- private final String username;
- private final String password;
-
- public LoginPassword(String username, String password) {
- this.username = username;
- this.password = password;
- }
-
- @Override
- public String getUsername() {
- return username;
- }
-
- @Override
- public AuthFuture authenticate(final ClientSession session) throws IOException {
- session.addPasswordIdentity(password);
- return session.auth();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
-
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelOutboundHandlerAdapter;
-import io.netty.channel.ChannelPromise;
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.util.HashMap;
-import org.apache.sshd.ClientChannel;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
-import org.apache.sshd.client.future.AuthFuture;
-import org.apache.sshd.client.future.ConnectFuture;
-import org.apache.sshd.client.future.OpenFuture;
-import org.apache.sshd.common.future.CloseFuture;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Netty SSH handler class. Acts as interface between Netty and SSH library.
- */
-public class AsyncSshHandler extends ChannelOutboundHandlerAdapter {
-
- private static final Logger LOG = LoggerFactory.getLogger(AsyncSshHandler.class);
- public static final String SUBSYSTEM = "netconf";
-
- public static final SshClient DEFAULT_CLIENT = SshClient.setUpDefaultClient();
-
- public static final int SSH_DEFAULT_NIO_WORKERS = 8;
-
- // Disable default timeouts from mina sshd
- private static final long DEFAULT_TIMEOUT = -1L;
-
- static {
- DEFAULT_CLIENT.setProperties(new HashMap<String, String>(){
- {
- put(SshClient.AUTH_TIMEOUT, Long.toString(DEFAULT_TIMEOUT));
- put(SshClient.IDLE_TIMEOUT, Long.toString(DEFAULT_TIMEOUT));
- }
- });
- // TODO make configurable, or somehow reuse netty threadpool
- DEFAULT_CLIENT.setNioWorkers(SSH_DEFAULT_NIO_WORKERS);
- DEFAULT_CLIENT.start();
- }
-
- private final AuthenticationHandler authenticationHandler;
- private final SshClient sshClient;
-
- private AsyncSshHandlerReader sshReadAsyncListener;
- private AsyncSshHandlerWriter sshWriteAsyncHandler;
-
- private ClientChannel channel;
- private ClientSession session;
- private ChannelPromise connectPromise;
-
-
- public static AsyncSshHandler createForNetconfSubsystem(final AuthenticationHandler authenticationHandler) throws IOException {
- return new AsyncSshHandler(authenticationHandler, DEFAULT_CLIENT);
- }
-
- /**
- *
- * @param authenticationHandler
- * @param sshClient started SshClient
- * @throws IOException
- */
- public AsyncSshHandler(final AuthenticationHandler authenticationHandler, final SshClient sshClient) throws IOException {
- this.authenticationHandler = Preconditions.checkNotNull(authenticationHandler);
- this.sshClient = Preconditions.checkNotNull(sshClient);
- // Start just in case
- sshClient.start();
- }
-
- private void startSsh(final ChannelHandlerContext ctx, final SocketAddress address) {
- LOG.debug("Starting SSH to {} on channel: {}", address, ctx.channel());
-
- final ConnectFuture sshConnectionFuture = sshClient.connect(authenticationHandler.getUsername(), address);
- sshConnectionFuture.addListener(new SshFutureListener<ConnectFuture>() {
- @Override
- public void operationComplete(final ConnectFuture future) {
- if (future.isConnected()) {
- handleSshSessionCreated(future, ctx);
- } else {
- handleSshSetupFailure(ctx, future.getException());
- }
- }
- });
- }
-
- private synchronized void handleSshSessionCreated(final ConnectFuture future, final ChannelHandlerContext ctx) {
- try {
- LOG.trace("SSH session created on channel: {}", ctx.channel());
-
- session = future.getSession();
- final AuthFuture authenticateFuture = authenticationHandler.authenticate(session);
- authenticateFuture.addListener(new SshFutureListener<AuthFuture>() {
- @Override
- public void operationComplete(final AuthFuture future) {
- if (future.isSuccess()) {
- handleSshAuthenticated(session, ctx);
- } else {
- // Exception does not have to be set in the future, add simple exception in such case
- final Throwable exception = future.getException() == null ?
- new IllegalStateException("Authentication failed") :
- future.getException();
- handleSshSetupFailure(ctx, exception);
- }
- }
- });
- } catch (final IOException e) {
- handleSshSetupFailure(ctx, e);
- }
- }
-
- private synchronized void handleSshAuthenticated(final ClientSession session, final ChannelHandlerContext ctx) {
- try {
- LOG.debug("SSH session authenticated on channel: {}, server version: {}", ctx.channel(), session.getServerVersion());
-
- channel = session.createSubsystemChannel(SUBSYSTEM);
- channel.setStreaming(ClientChannel.Streaming.Async);
- channel.open().addListener(new SshFutureListener<OpenFuture>() {
- @Override
- public void operationComplete(final OpenFuture future) {
- if(future.isOpened()) {
- handleSshChanelOpened(ctx);
- } else {
- handleSshSetupFailure(ctx, future.getException());
- }
- }
- });
-
-
- } catch (final IOException e) {
- handleSshSetupFailure(ctx, e);
- }
- }
-
- private synchronized void handleSshChanelOpened(final ChannelHandlerContext ctx) {
- LOG.trace("SSH subsystem channel opened successfully on channel: {}", ctx.channel());
-
- connectPromise.setSuccess();
-
- // TODO we should also read from error stream and at least log from that
-
- sshReadAsyncListener = new AsyncSshHandlerReader(new AutoCloseable() {
- @Override
- public void close() throws Exception {
- AsyncSshHandler.this.disconnect(ctx, ctx.newPromise());
- }
- }, new AsyncSshHandlerReader.ReadMsgHandler() {
- @Override
- public void onMessageRead(final ByteBuf msg) {
- ctx.fireChannelRead(msg);
- }
- }, channel.toString(), channel.getAsyncOut());
-
- // if readAsyncListener receives immediate close, it will close this handler and closing this handler sets channel variable to null
- if(channel != null) {
- sshWriteAsyncHandler = new AsyncSshHandlerWriter(channel.getAsyncIn());
- ctx.fireChannelActive();
- }
- }
-
- private synchronized void handleSshSetupFailure(final ChannelHandlerContext ctx, final Throwable e) {
- LOG.warn("Unable to setup SSH connection on channel: {}", ctx.channel(), e);
- disconnect(ctx, ctx.newPromise());
-
- // If the promise is not yet done, we have failed with initial connect and set connectPromise to failure
- if(!connectPromise.isDone()) {
- connectPromise.setFailure(e);
- }
- }
-
- @Override
- public synchronized void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
- sshWriteAsyncHandler.write(ctx, msg, promise);
- }
-
- @Override
- public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) throws Exception {
- LOG.debug("SSH session connecting on channel {}. promise: {} ", ctx.channel(), connectPromise);
- this.connectPromise = promise;
- startSsh(ctx, remoteAddress);
- }
-
- @Override
- public void close(final ChannelHandlerContext ctx, final ChannelPromise promise) throws Exception {
- disconnect(ctx, promise);
- }
-
- @Override
- public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) {
- LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}", ctx.channel(), connectPromise);
-
- // If we have already succeeded and the session was dropped after, we need to fire inactive to notify reconnect logic
- if(connectPromise.isSuccess()) {
- ctx.fireChannelInactive();
- }
-
- if(sshWriteAsyncHandler != null) {
- sshWriteAsyncHandler.close();
- }
-
- if(sshReadAsyncListener != null) {
- sshReadAsyncListener.close();
- }
-
- if(session!= null && !session.isClosed() && !session.isClosing()) {
- session.close(false).addListener(new SshFutureListener<CloseFuture>() {
- @Override
- public void operationComplete(final CloseFuture future) {
- if (future.isClosed() == false) {
- session.close(true);
- }
- session = null;
- }
- });
- }
-
- // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs to cleanup its resources
- // e.g. Socket that it tries to open in its constructor (https://bugs.opendaylight.org/show_bug.cgi?id=2430)
- // TODO better solution would be to implement custom ChannelFactory + Channel that will use mina SSH lib internally: port this to custom channel implementation
- try {
- // Disconnect has to be closed after inactive channel event was fired, because it interferes with it
- super.disconnect(ctx, ctx.newPromise());
- } catch (final Exception e) {
- LOG.warn("Unable to cleanup all resources for channel: {}. Ignoring.", ctx.channel(), e);
- }
-
- channel = null;
- promise.setSuccess();
- LOG.debug("SSH session closed on channel: {}", ctx.channel());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoReadFuture;
-import org.apache.sshd.common.util.Buffer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Listener on async input stream from SSH session.
- * This listeners schedules reads in a loop until the session is closed or read fails.
- */
-public final class AsyncSshHandlerReader implements SshFutureListener<IoReadFuture>, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(AsyncSshHandlerReader.class);
-
- private static final int BUFFER_SIZE = 8192;
-
- private final AutoCloseable connectionClosedCallback;
- private final ReadMsgHandler readHandler;
-
- private final String channelId;
- private IoInputStream asyncOut;
- private Buffer buf;
- private IoReadFuture currentReadFuture;
-
- public AsyncSshHandlerReader(final AutoCloseable connectionClosedCallback, final ReadMsgHandler readHandler, final String channelId, final IoInputStream asyncOut) {
- this.connectionClosedCallback = connectionClosedCallback;
- this.readHandler = readHandler;
- this.channelId = channelId;
- this.asyncOut = asyncOut;
- buf = new Buffer(BUFFER_SIZE);
- asyncOut.read(buf).addListener(this);
- }
-
- @Override
- public synchronized void operationComplete(final IoReadFuture future) {
- if(future.getException() != null) {
- if(asyncOut.isClosed() || asyncOut.isClosing()) {
- // Ssh dropped
- LOG.debug("Ssh session dropped on channel: {}", channelId, future.getException());
- } else {
- LOG.warn("Exception while reading from SSH remote on channel {}", channelId, future.getException());
- }
- invokeDisconnect();
- return;
- }
-
- if (future.getRead() > 0) {
- final ByteBuf msg = Unpooled.wrappedBuffer(buf.array(), 0, future.getRead());
- if(LOG.isTraceEnabled()) {
- LOG.trace("Reading message on channel: {}, message: {}", channelId, AsyncSshHandlerWriter.byteBufToString(msg));
- }
- readHandler.onMessageRead(msg);
-
- // Schedule next read
- buf = new Buffer(BUFFER_SIZE);
- currentReadFuture = asyncOut.read(buf);
- currentReadFuture.addListener(this);
- }
- }
-
- private void invokeDisconnect() {
- try {
- connectionClosedCallback.close();
- } catch (final Exception e) {
- // This should not happen
- throw new IllegalStateException(e);
- }
- }
-
- @Override
- public synchronized void close() {
- // Remove self as listener on close to prevent reading from closed input
- if(currentReadFuture != null) {
- currentReadFuture.removeListener(this);
- currentReadFuture = null;
- }
-
- asyncOut = null;
- }
-
- public interface ReadMsgHandler {
-
- void onMessageRead(ByteBuf msg);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.Queue;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoOutputStream;
-import org.apache.sshd.common.io.IoWriteFuture;
-import org.apache.sshd.common.io.WritePendingException;
-import org.apache.sshd.common.util.Buffer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Async Ssh writer. Takes messages(byte arrays) and sends them encrypted to remote server.
- * Also handles pending writes by caching requests until pending state is over.
- */
-public final class AsyncSshHandlerWriter implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory
- .getLogger(AsyncSshHandlerWriter.class);
-
- // public static final int MAX_PENDING_WRITES = 1000;
- // TODO implement Limiting mechanism for pending writes
- // But there is a possible issue with limiting:
- // 1. What to do when queue is full ? Immediate Fail for every request ?
- // 2. At this level we might be dealing with Chunks of messages(not whole messages) and unexpected behavior might occur
- // when we send/queue 1 chunk and fail the other chunks
-
- private volatile IoOutputStream asyncIn;
-
- // Order has to be preserved for queued writes
- private final Deque<PendingWriteRequest> pending = new LinkedList<>();
-
- public AsyncSshHandlerWriter(final IoOutputStream asyncIn) {
- this.asyncIn = asyncIn;
- }
-
- public void write(final ChannelHandlerContext ctx,
- final Object msg, final ChannelPromise promise) {
- if (asyncIn == null) {
- promise.setFailure(new IllegalStateException("Channel closed"));
- return;
- }
- // synchronized block due to deadlock that happens on ssh window resize
- // writes and pending writes would lock the underlyinch channel session
- // window resize write would try to write the message on an already locked channelSession
- // while the pending write was in progress from the write callback
- synchronized (asyncIn) {
- // TODO check for isClosed, isClosing might be performed by mina SSH internally and is not required here
- // If we are closed/closing, set immediate fail
- if (asyncIn.isClosed() || asyncIn.isClosing()) {
- promise.setFailure(new IllegalStateException("Channel closed"));
- } else {
- final ByteBuf byteBufMsg = (ByteBuf) msg;
- if (pending.isEmpty() == false) {
- queueRequest(ctx, byteBufMsg, promise);
- return;
- }
-
- writeWithPendingDetection(ctx, promise, byteBufMsg, false);
- }
- }
- }
-
- //sending message with pending
- //if resending message not succesfull, then attribute wasPending is true
- private void writeWithPendingDetection(final ChannelHandlerContext ctx, final ChannelPromise promise, final ByteBuf byteBufMsg, final boolean wasPending) {
- try {
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Writing request on channel: {}, message: {}", ctx.channel(), byteBufToString(byteBufMsg));
- }
- asyncIn.write(toBuffer(byteBufMsg)).addListener(new SshFutureListener<IoWriteFuture>() {
-
- @Override
- public void operationComplete(final IoWriteFuture future) {
- // synchronized block due to deadlock that happens on ssh window resize
- // writes and pending writes would lock the underlyinch channel session
- // window resize write would try to write the message on an already locked channelSession,
- // while the pending write was in progress from the write callback
- synchronized (asyncIn) {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Ssh write request finished on channel: {} with result: {}: and ex:{}, message: {}",
- ctx.channel(), future.isWritten(), future.getException(), byteBufToString(byteBufMsg));
- }
-
- // Notify success or failure
- if (future.isWritten()) {
- promise.setSuccess();
- } else {
- LOG.warn("Ssh write request failed on channel: {} for message: {}", ctx.channel(), byteBufToString(byteBufMsg), future.getException());
- promise.setFailure(future.getException());
- }
-
- // Not needed anymore, release
- byteBufMsg.release();
-
- //rescheduling message from queue after successfully sent
- if (wasPending) {
- byteBufMsg.resetReaderIndex();
- pending.remove();
- }
- }
-
- // Check pending queue and schedule next
- // At this time we are guaranteed that we are not in pending state anymore so the next request should succeed
- writePendingIfAny();
- }
- });
-
- } catch (final WritePendingException e) {
-
- if(wasPending == false){
- queueRequest(ctx, byteBufMsg, promise);
- }
- }
- }
-
- private void writePendingIfAny() {
- synchronized (asyncIn) {
- if (pending.peek() == null) {
- return;
- }
-
- final PendingWriteRequest pendingWrite = pending.peek();
- final ByteBuf msg = pendingWrite.msg;
- if (LOG.isTraceEnabled()) {
- LOG.trace("Writing pending request on channel: {}, message: {}", pendingWrite.ctx.channel(), byteBufToString(msg));
- }
-
- writeWithPendingDetection(pendingWrite.ctx, pendingWrite.promise, msg, true);
- }
- }
-
- public static String byteBufToString(final ByteBuf msg) {
- final String s = msg.toString(Charsets.UTF_8);
- msg.resetReaderIndex();
- return s;
- }
-
- private void queueRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
-// try {
- LOG.debug("Write pending on channel: {}, queueing, current queue size: {}", ctx.channel(), pending.size());
- if (LOG.isTraceEnabled()) {
- LOG.trace("Queueing request due to pending: {}", byteBufToString(msg));
- }
- new PendingWriteRequest(ctx, msg, promise).pend(pending);
-// } catch (final Exception ex) {
-// LOG.warn("Unable to queue write request on channel: {}. Setting fail for the request: {}", ctx.channel(), ex, byteBufToString(msg));
-// msg.release();
-// promise.setFailure(ex);
-// }
- }
-
- @Override
- public void close() {
- asyncIn = null;
- }
-
- private static Buffer toBuffer(final ByteBuf msg) {
- // TODO Buffer vs ByteBuf translate, Can we handle that better ?
- msg.resetReaderIndex();
- final byte[] temp = new byte[msg.readableBytes()];
- msg.readBytes(temp, 0, msg.readableBytes());
- return new Buffer(temp);
- }
-
- private static final class PendingWriteRequest {
- private final ChannelHandlerContext ctx;
- private final ByteBuf msg;
- private final ChannelPromise promise;
-
- public PendingWriteRequest(final ChannelHandlerContext ctx, final ByteBuf msg, final ChannelPromise promise) {
- this.ctx = ctx;
- // Reset reader index, last write (failed) attempt moved index to the end
- msg.resetReaderIndex();
- this.msg = msg;
- this.promise = promise;
- }
-
- public void pend(final Queue<PendingWriteRequest> pending) {
- // Preconditions.checkState(pending.size() < MAX_PENDING_WRITES,
- // "Too much pending writes(%s) on channel: %s, remote window is not getting read or is too small",
- // pending.size(), ctx.channel());
- Preconditions.checkState(pending.offer(this), "Cannot pend another request write (pending count: %s) on channel: %s",
- pending.size(), ctx.channel());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import io.netty.util.concurrent.Promise;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-
-public class AbstractChannelInitializerTest {
-
- @Mock
- private Channel channel;
- @Mock
- private ChannelPipeline pipeline;
- @Mock
- private Promise<NetconfSession> sessionPromise;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(pipeline).when(channel).pipeline();
- doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
- }
-
- @Test
- public void testInit() throws Exception {
- final TestingInitializer testingInitializer = new TestingInitializer();
- testingInitializer.initialize(channel, sessionPromise);
- verify(pipeline, times(4)).addLast(anyString(), any(ChannelHandler.class));
- }
-
- private static final class TestingInitializer extends AbstractChannelInitializer<NetconfSession> {
-
- @Override
- protected void initializeSessionNegotiator(final Channel ch, final Promise<NetconfSession> promise) {
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import com.google.common.base.Optional;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelPipeline;
-import io.netty.handler.codec.ByteToMessageDecoder;
-import io.netty.handler.codec.MessageToByteEncoder;
-import java.util.Collections;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.api.NetconfSessionListener;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.nettyutil.handler.exi.NetconfStartExiMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.openexi.proc.common.EXIOptions;
-
-public class AbstractNetconfSessionTest {
-
- @Mock
- private NetconfSessionListener<NetconfSession> listener;
- @Mock
- private Channel channel;
- @Mock
- private ChannelPipeline pipeline;
- private NetconfHelloMessage clientHello;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doNothing().when(listener).onMessage(any(NetconfSession.class), any(NetconfMessage.class));
- doNothing().when(listener).onSessionUp(any(NetconfSession.class));
- doNothing().when(listener).onSessionDown(any(NetconfSession.class), any(Exception.class));
- doNothing().when(listener).onSessionTerminated(any(NetconfSession.class), any(NetconfTerminationReason.class));
-
- doReturn(mock(ChannelFuture.class)).when(channel).writeAndFlush(any(NetconfMessage.class));
- doReturn(pipeline).when(channel).pipeline();
- doReturn("mockChannel").when(channel).toString();
- doReturn(mock(ChannelFuture.class)).when(channel).close();
-
- doReturn(null).when(pipeline).replace(anyString(), anyString(), any(ChannelHandler.class));
-
- clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(), Optional.<NetconfHelloMessageAdditionalHeader>absent());
- }
-
- @Test
- public void testHandleMessage() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- testingNetconfSession.handleMessage(clientHello);
- verify(listener).onMessage(testingNetconfSession, clientHello);
- }
-
- @Test
- public void testSessionUp() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- testingNetconfSession.sessionUp();
- verify(listener).onSessionUp(testingNetconfSession);
- assertEquals(1L, testingNetconfSession.getSessionId());
- }
-
- @Test
- public void testClose() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- testingNetconfSession.sessionUp();
- testingNetconfSession.close();
- verify(channel).close();
- verify(listener).onSessionTerminated(any(NetconfSession.class), any(NetconfTerminationReason.class));
- }
-
- @Test
- public void testReplaceHandlers() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- final ChannelHandler mock = mock(ChannelHandler.class);
- doReturn("handler").when(mock).toString();
-
- testingNetconfSession.replaceMessageDecoder(mock);
- verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, mock);
- testingNetconfSession.replaceMessageEncoder(mock);
- verify(pipeline).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
- testingNetconfSession.replaceMessageEncoderAfterNextMessage(mock);
- verifyNoMoreInteractions(pipeline);
-
- testingNetconfSession.sendMessage(clientHello);
- verify(pipeline, times(2)).replace(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, mock);
- }
-
- @Test
- public void testStartExi() throws Exception {
- TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- testingNetconfSession = spy(testingNetconfSession);
-
- testingNetconfSession.startExiCommunication(NetconfStartExiMessage.create(new EXIOptions(), "4"));
- verify(testingNetconfSession).addExiHandlers(any(ByteToMessageDecoder.class), any(MessageToByteEncoder.class));
- }
-
- @Test
- public void testEndOfInput() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- testingNetconfSession.endOfInput();
- verifyZeroInteractions(listener);
- testingNetconfSession.sessionUp();
- testingNetconfSession.endOfInput();
- verify(listener).onSessionDown(any(NetconfSession.class), any(Exception.class));
- }
-
- @Test
- public void testSendMessage() throws Exception {
- final TestingNetconfSession testingNetconfSession = new TestingNetconfSession(listener, channel, 1L);
- final NetconfHelloMessage clientHello = NetconfHelloMessage.createClientHello(Collections.<String>emptySet(), Optional.<NetconfHelloMessageAdditionalHeader>absent());
- testingNetconfSession.sendMessage(clientHello);
- verify(channel).writeAndFlush(clientHello);
- }
-
- private static class TestingNetconfSession extends AbstractNetconfSession<NetconfSession, NetconfSessionListener<NetconfSession>> {
-
- protected TestingNetconfSession(final NetconfSessionListener<NetconfSession> sessionListener, final Channel channel, final long sessionId) {
- super(sessionListener, channel, sessionId);
- }
-
- @Override
- protected NetconfSession thisInstance() {
- return this;
- }
-
- @Override
- protected void addExiHandlers(final ByteToMessageDecoder decoder, final MessageToByteEncoder<NetconfMessage> encoder) {}
-
- @Override
- public void stopExiCommunication() {}
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import com.google.common.base.Charsets;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import java.nio.ByteBuffer;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-public class ChunkedFramingMechanismEncoderTest {
-
- private int chunkSize;
- @Mock
- private ChannelHandlerContext ctx;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- chunkSize = 256;
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testIllegalSize() throws Exception {
- new ChunkedFramingMechanismEncoder(10);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testIllegalSizeMax() throws Exception {
- new ChunkedFramingMechanismEncoder(Integer.MAX_VALUE);
- }
-
- @Test
- public void testEncode() throws Exception {
- final ChunkedFramingMechanismEncoder encoder = new ChunkedFramingMechanismEncoder(chunkSize);
- final int lastChunkSize = 20;
- final ByteBuf src = Unpooled.wrappedBuffer(getByteArray(chunkSize * 4 + lastChunkSize));
- final ByteBuf destination = Unpooled.buffer();
- encoder.encode(ctx, src, destination);
-
- assertEquals(1077, destination.readableBytes());
-
- byte[] buf = new byte[destination.readableBytes()];
- destination.readBytes(buf);
- String s = Charsets.US_ASCII.decode(ByteBuffer.wrap(buf)).toString();
-
- assertTrue(s.startsWith("\n#256\na"));
- assertTrue(s.endsWith("\n#20\naaaaaaaaaaaaaaaaaaaa\n##\n"));
- }
-
- private static byte[] getByteArray(final int size) {
- final byte[] bytes = new byte[size];
- for (int i = 0; i < size; i++) {
- bytes[i] = 'a';
- }
- return bytes;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants;
-
-public class EOMFramingMechanismEncoderTest {
-
- @Test
- public void testEncode() throws Exception {
- final byte[] content = new byte[50];
- final ByteBuf source = Unpooled.wrappedBuffer(content);
- final ByteBuf destination = Unpooled.buffer();
- new EOMFramingMechanismEncoder().encode(null, source, destination);
-
- assertEquals(Unpooled.wrappedBuffer(source.array(), NetconfMessageConstants.END_OF_MESSAGE), destination);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import org.hamcrest.CoreMatchers;
-import org.hamcrest.MatcherAssert;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.util.messages.FramingMechanism;
-
-public class FramingMechanismHandlerFactoryTest {
-
- @Test
- public void testCreate() throws Exception {
- MatcherAssert.assertThat(FramingMechanismHandlerFactory
- .createHandler(FramingMechanism.CHUNK), CoreMatchers
- .instanceOf(ChunkedFramingMechanismEncoder.class));
- MatcherAssert.assertThat(FramingMechanismHandlerFactory
- .createHandler(FramingMechanism.EOM), CoreMatchers
- .instanceOf(EOMFramingMechanismEncoder.class));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.Lists;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import java.util.List;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class NetconfChunkAggregatorTest {
-
- private static final String CHUNKED_MESSAGE = "\n#4\n" +
- "<rpc" +
- "\n#18\n" +
- " message-id=\"102\"\n" +
- "\n#79\n" +
- " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <close-session/>\n" +
- "</rpc>" +
- "\n##\n";
-
- public static final String EXPECTED_MESSAGE = "<rpc message-id=\"102\"\n" +
- " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <close-session/>\n" +
- "</rpc>";
-
- private static final String CHUNKED_MESSAGE_ONE = "\n#101\n" + EXPECTED_MESSAGE + "\n##\n";
-
- private static NetconfChunkAggregator agr;
-
- @BeforeClass
- public static void setUp() throws Exception {
- agr = new NetconfChunkAggregator();
- }
-
- @Test
- public void testMultipleChunks() throws Exception {
- final List<Object> output = Lists.newArrayList();
- final ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE.getBytes(Charsets.UTF_8));
- agr.decode(null, input, output);
-
- assertEquals(1, output.size());
- final ByteBuf chunk = (ByteBuf) output.get(0);
-
- assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
- }
-
- @Test
- public void testOneChunks() throws Exception {
- final List<Object> output = Lists.newArrayList();
- final ByteBuf input = Unpooled.copiedBuffer(CHUNKED_MESSAGE_ONE.getBytes(Charsets.UTF_8));
- agr.decode(null, input, output);
-
- assertEquals(1, output.size());
- final ByteBuf chunk = (ByteBuf) output.get(0);
-
- assertEquals(EXPECTED_MESSAGE, chunk.toString(Charsets.UTF_8));
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.collect.Lists;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.openexi.proc.common.EXIOptions;
-import org.openexi.proc.common.EXIOptionsException;
-import org.openexi.sax.Transmogrifier;
-import org.openexi.sax.TransmogrifierException;
-import org.xml.sax.InputSource;
-
-public class NetconfEXIHandlersTest {
-
- private final String msgAsString = "<netconf-message/>";
- private NetconfMessageToEXIEncoder netconfMessageToEXIEncoder;
- private NetconfEXIToMessageDecoder netconfEXIToMessageDecoder;
- private NetconfMessage msg;
- private byte[] msgAsExi;
-
- @Before
- public void setUp() throws Exception {
- final NetconfEXICodec codec = new NetconfEXICodec(new EXIOptions());
- netconfMessageToEXIEncoder = NetconfMessageToEXIEncoder.create(codec);
- netconfEXIToMessageDecoder = NetconfEXIToMessageDecoder.create(codec);
-
- msg = new NetconfMessage(XmlUtil.readXmlToDocument(msgAsString));
- this.msgAsExi = msgToExi(msgAsString, codec);
- }
-
- private static byte[] msgToExi(final String msgAsString, final NetconfEXICodec codec) throws EXIOptionsException, TransmogrifierException, IOException {
- final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- final Transmogrifier transmogrifier = codec.getTransmogrifier();
- transmogrifier.setOutputStream(byteArrayOutputStream);
- transmogrifier.encode(new InputSource(new ByteArrayInputStream(msgAsString.getBytes())));
- return byteArrayOutputStream.toByteArray();
- }
-
- @Test
- public void testEncodeDecode() throws Exception {
- final ByteBuf buffer = Unpooled.buffer();
- netconfMessageToEXIEncoder.encode(null, msg, buffer);
- final int exiLength = msgAsExi.length;
- // array from buffer is cca 256 n length, compare only subarray
- assertArrayEquals(msgAsExi, Arrays.copyOfRange(buffer.array(), 0, exiLength));
-
- // assert all other bytes in buffer be 0
- for (int i = exiLength; i < buffer.array().length; i++) {
- assertEquals((byte)0, buffer.array()[i]);
- }
-
- final List<Object> out = Lists.newArrayList();
- netconfEXIToMessageDecoder.decode(null, buffer, out);
-
- XMLUnit.compareXML(msg.getDocument(), ((NetconfMessage) out.get(0)).getDocument());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertThat;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-
-public class NetconfHelloMessageToXMLEncoderTest {
-
- @Mock
- private ChannelHandlerContext ctx;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testEncode() throws Exception {
- final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"),
- NetconfHelloMessageAdditionalHeader.fromString("[tomas;10.0.0.0:10000;tcp;client;]"));
- final ByteBuf destination = Unpooled.buffer();
- new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
-
- final String encoded = new String(destination.array());
- assertThat(encoded, containsString("[tomas;10.0.0.0:10000;tcp;client;]"));
- assertThat(encoded, containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
- }
-
- @Test
- public void testEncodeNoHeader() throws Exception {
- final NetconfMessage msg = new NetconfHelloMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
- final ByteBuf destination = Unpooled.buffer();
- new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, destination);
-
- final String encoded = new String(destination.array());
- assertThat(encoded, not(containsString("[tomas;10.0.0.0:10000;tcp;client;]")));
- assertThat(encoded, containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testEncodeNotHello() throws Exception {
- final NetconfMessage msg = new NetconfMessage(XmlUtil.readXmlToDocument("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>"));
- new NetconfHelloMessageToXMLEncoder().encode(ctx, msg, null);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.io.Files;
-import io.netty.buffer.Unpooled;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Test;
-
-public class NetconfMessageFactoryTest {
- @Test
- public void testAuth() throws Exception {
- NetconfXMLToHelloMessageDecoder parser = new NetconfXMLToHelloMessageDecoder();
- File authHelloFile = new File(getClass().getResource("/netconfMessages/client_hello_with_auth.xml").getFile());
-
- final List<Object> out = new ArrayList<>();
- parser.decode(null, Unpooled.wrappedBuffer(Files.toByteArray(authHelloFile)), out);
- assertEquals(1, out.size());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import java.util.List;
-import org.hamcrest.CoreMatchers;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage;
-
-public class NetconfXMLToHelloMessageDecoderTest {
-
- @Test
- public void testDecodeWithHeader() throws Exception {
- final ByteBuf src = Unpooled.wrappedBuffer(String.format("%s\n%s",
- "[tomas;10.0.0.0:10000;tcp;client;]", "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>").getBytes());
- final List<Object> out = Lists.newArrayList();
- new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
-
- assertEquals(1, out.size());
- assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
- final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
- assertTrue(hello.getAdditionalHeader().isPresent());
- assertEquals("[tomas;10.0.0.0:10000;tcp;client;]" + System.lineSeparator(), hello.getAdditionalHeader().get().toFormattedString());
- assertThat(XmlUtil.toString(hello.getDocument()), CoreMatchers.containsString("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\""));
- }
-
- @Test
- public void testDecodeNoHeader() throws Exception {
- final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final List<Object> out = Lists.newArrayList();
- new NetconfXMLToHelloMessageDecoder().decode(null, src, out);
-
- assertEquals(1, out.size());
- assertThat(out.get(0), CoreMatchers.instanceOf(NetconfHelloMessage.class));
- final NetconfHelloMessage hello = (NetconfHelloMessage) out.get(0);
- assertFalse(hello.getAdditionalHeader().isPresent());
- }
-
- @Test
- public void testDecodeCaching() throws Exception {
- final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final ByteBuf msg2 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final ByteBuf src = Unpooled.wrappedBuffer("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final List<Object> out = Lists.newArrayList();
- final NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
- decoder.decode(null, src, out);
- decoder.decode(null, msg1, out);
- decoder.decode(null, msg2, out);
-
- assertEquals(1, out.size());
-
- assertEquals(2, Iterables.size(decoder.getPostHelloNetconfMessages()));
- }
-
- @Test(expected = IllegalStateException.class)
- public void testDecodeNotHelloReceived() throws Exception {
- final ByteBuf msg1 = Unpooled.wrappedBuffer("<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"/>".getBytes());
- final List<Object> out = Lists.newArrayList();
- NetconfXMLToHelloMessageDecoder decoder = new NetconfXMLToHelloMessageDecoder();
- decoder.decode(null, msg1, out);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler;
-
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.collect.Lists;
-import io.netty.buffer.Unpooled;
-import java.util.ArrayList;
-import org.junit.Test;
-import org.xml.sax.SAXParseException;
-
-public class NetconfXMLToMessageDecoderTest {
-
- @Test
- public void testDecodeNoMoreContent() throws Exception {
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.buffer(), out);
- assertEquals(0, out.size());
- }
-
- @Test
- public void testDecode() throws Exception {
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("<msg/>".getBytes()), out);
- assertEquals(1, out.size());
- }
-
- @Test
- public void testDecodeWithLeadingLFAndXmlDecl() throws Exception {
- /* Test that we accept XML documents with a line feed (0x0a) before the
- * XML declaration in the XML prologue.
- * A leading LF is the case reported in BUG-2838.
- */
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
- assertEquals(1, out.size());
- }
-
- @Test
- public void testDecodeWithLeadingCRLFAndXmlDecl() throws Exception {
- /* Test that we accept XML documents with both a carriage return and
- * line feed (0x0d 0x0a) before the XML declaration in the XML prologue.
- * Leading CRLF can be seen with some Cisco routers
- * (eg CSR1000V running IOS 15.4(1)S)
- */
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\r\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes()), out);
- assertEquals(1, out.size());
- }
-
- @Test(expected=SAXParseException.class)
- public void testDecodeGibberish() throws Exception {
- /* Test that we reject inputs where we cannot find the xml start '<' character */
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\r\n?xml version>".getBytes()), out);
- assertEquals(1, out.size());
- }
-
- @Test
- public void testDecodeOnlyWhitespaces() throws Exception {
- /* Test that we handle properly a bunch of whitespaces.
- */
- final ArrayList<Object> out = Lists.newArrayList();
- new NetconfXMLToMessageDecoder().decode(null, Unpooled.wrappedBuffer("\r\n".getBytes()), out);
- assertEquals(0, out.size());
- }
-
- @Test
- public void testDecodeWithAllWhitespaces() throws Exception {
- /* Test that every whitespace we want to skip is actually skipped.
- */
-
- final ArrayList<Object> out = Lists.newArrayList();
- byte whitespaces[] = {' ', '\t', '\n', '\r', '\f', 0x0b /* vertical tab */};
- new NetconfXMLToMessageDecoder().decode(
- null,
- Unpooled.copiedBuffer(
- Unpooled.wrappedBuffer(whitespaces),
- Unpooled.wrappedBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?><msg/>".getBytes())),
- out);
- assertEquals(1, out.size());
- }
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.exi;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.Arrays;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.EXIOptions;
-
-@RunWith(Parameterized.class)
-public class EXIParametersTest {
-
- @Parameterized.Parameters
- public static Iterable<Object[]> data() throws Exception {
- final String noChangeXml =
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>bit-packed</alignment>\n" +
- "</start-exi>\n";
-
-
- final String fullOptionsXml =
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>byte-aligned</alignment>\n" +
- "<fidelity>\n" +
- "<comments/>\n" +
- "<dtd/>\n" +
- "<lexical-values/>\n" +
- "<pis/>\n" +
- "<prefixes/>\n" +
- "</fidelity>\n" +
- "</start-exi>\n";
-
- final EXIOptions fullOptions = new EXIOptions();
- fullOptions.setAlignmentType(AlignmentType.byteAligned);
- fullOptions.setPreserveLexicalValues(true);
- fullOptions.setPreserveDTD(true);
- fullOptions.setPreserveComments(true);
- fullOptions.setPreserveNS(true);
- fullOptions.setPreservePIs(true);
-
- return Arrays.asList(new Object[][]{
- {noChangeXml, new EXIOptions()},
- {fullOptionsXml, fullOptions},
- });
- }
-
- private final String sourceXml;
- private final EXIOptions exiOptions;
-
- public EXIParametersTest(final String sourceXml, final EXIOptions exiOptions) {
- this.sourceXml = sourceXml;
- this.exiOptions = exiOptions;
- }
-
- @Test
- public void testFromXmlElement() throws Exception {
- final EXIParameters opts =
- EXIParameters.fromXmlElement(
- XmlElement.fromDomElement(
- XmlUtil.readXmlToElement(sourceXml)));
-
-
- assertEquals(opts.getOptions().getAlignmentType(), exiOptions.getAlignmentType());
- assertEquals(opts.getOptions().getPreserveComments(), exiOptions.getPreserveComments());
- assertEquals(opts.getOptions().getPreserveLexicalValues(), exiOptions.getPreserveLexicalValues());
- assertEquals(opts.getOptions().getPreserveNS(), exiOptions.getPreserveNS());
- assertEquals(opts.getOptions().getPreserveDTD(), exiOptions.getPreserveDTD());
- assertEquals(opts.getOptions().getPreserveNS(), exiOptions.getPreserveNS());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.exi;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Arrays;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.EXIOptions;
-
-@RunWith(Parameterized.class)
-public class NetconfStartExiMessageTest {
-
- @Parameterized.Parameters
- public static Iterable<Object[]> data() throws Exception {
- final String noChangeXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>bit-packed</alignment>\n" +
- "</start-exi>\n" +
- "</rpc>";
-
-
- final String fullOptionsXml = "<rpc xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:message-id=\"id\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<start-exi xmlns=\"urn:ietf:params:xml:ns:netconf:exi:1.0\">\n" +
- "<alignment>byte-aligned</alignment>\n" +
- "<fidelity>\n" +
- "<comments/>\n" +
- "<dtd/>\n" +
- "<lexical-values/>\n" +
- "<pis/>\n" +
- "<prefixes/>\n" +
- "</fidelity>\n" +
- "</start-exi>\n" +
- "</rpc>";
-
- final EXIOptions fullOptions = new EXIOptions();
- fullOptions.setAlignmentType(AlignmentType.byteAligned);
- fullOptions.setPreserveLexicalValues(true);
- fullOptions.setPreserveDTD(true);
- fullOptions.setPreserveComments(true);
- fullOptions.setPreserveNS(true);
- fullOptions.setPreservePIs(true);
-
- return Arrays.asList(new Object[][]{
- {noChangeXml, new EXIOptions()},
- {fullOptionsXml, fullOptions},
- });
- }
-
- private final String controlXml;
- private final EXIOptions exiOptions;
-
- public NetconfStartExiMessageTest(final String controlXml, final EXIOptions exiOptions) {
- this.controlXml = controlXml;
- this.exiOptions = exiOptions;
- }
-
- @Test
- public void testCreate() throws Exception {
- final NetconfStartExiMessage startExiMessage = NetconfStartExiMessage.create(exiOptions, "id");
-
- XMLUnit.setIgnoreWhitespace(true);
- XMLUnit.setIgnoreAttributeOrder(true);
- final Diff diff = XMLUnit.compareXML(XMLUnit.buildControlDocument(controlXml), startExiMessage.getDocument());
- assertTrue(diff.toString(), diff.similar());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.client.future.AuthFuture;
-import org.junit.Test;
-
-public class LoginPasswordTest {
-
- @Test
- public void testLoginPassword() throws Exception {
- final LoginPassword loginPassword = new LoginPassword("user", "pwd");
- assertEquals("user", loginPassword.getUsername());
-
- final ClientSession session = mock(ClientSession.class);
- doNothing().when(session).addPasswordIdentity("pwd");
- doReturn(mock(AuthFuture.class)).when(session).auth();
- loginPassword.authenticate(session);
-
- verify(session).addPasswordIdentity("pwd");
- verify(session).auth();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-import io.netty.channel.DefaultChannelPromise;
-import java.io.IOException;
-import java.net.SocketAddress;
-import org.apache.sshd.ClientChannel;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
-import org.apache.sshd.client.channel.ChannelSubsystem;
-import org.apache.sshd.client.future.AuthFuture;
-import org.apache.sshd.client.future.ConnectFuture;
-import org.apache.sshd.client.future.OpenFuture;
-import org.apache.sshd.common.future.CloseFuture;
-import org.apache.sshd.common.future.SshFuture;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoOutputStream;
-import org.apache.sshd.common.io.IoReadFuture;
-import org.apache.sshd.common.io.IoWriteFuture;
-import org.apache.sshd.common.util.Buffer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
-
-public class AsyncSshHandlerTest {
-
- @Mock
- private SshClient sshClient;
- @Mock
- private AuthenticationHandler authHandler;
- @Mock
- private ChannelHandlerContext ctx;
- @Mock
- private Channel channel;
- @Mock
- private SocketAddress remoteAddress;
- @Mock
- private SocketAddress localAddress;
-
- private AsyncSshHandler asyncSshHandler;
-
- private SshFutureListener<ConnectFuture> sshConnectListener;
- private SshFutureListener<AuthFuture> sshAuthListener;
- private SshFutureListener<OpenFuture> sshChannelOpenListener;
-
- private ChannelPromise promise;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- stubAuth();
- stubSshClient();
- stubChannel();
- stubCtx();
- stubRemoteAddress();
-
- promise = getMockedPromise();
-
- asyncSshHandler = new AsyncSshHandler(authHandler, sshClient);
- }
-
- @After
- public void tearDown() throws Exception {
- sshConnectListener = null;
- sshAuthListener = null;
- sshChannelOpenListener = null;
- promise = null;
- asyncSshHandler.close(ctx, getMockedPromise());
- }
-
- private void stubAuth() throws IOException {
- doReturn("usr").when(authHandler).getUsername();
-
- final AuthFuture authFuture = mock(AuthFuture.class);
- Futures.addCallback(stubAddListener(authFuture), new SuccessFutureListener<AuthFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<AuthFuture> result) {
- sshAuthListener = result;
- }
- });
- doReturn(authFuture).when(authHandler).authenticate(any(ClientSession.class));
- }
-
- @SuppressWarnings("unchecked")
- private static <T extends SshFuture<T>> ListenableFuture<SshFutureListener<T>> stubAddListener(final T future) {
- final SettableFuture<SshFutureListener<T>> listenerSettableFuture = SettableFuture.create();
-
- doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocation) throws Throwable {
- listenerSettableFuture.set((SshFutureListener<T>) invocation.getArguments()[0]);
- return null;
- }
- }).when(future).addListener(any(SshFutureListener.class));
-
- return listenerSettableFuture;
- }
-
- private void stubRemoteAddress() {
- doReturn("remote").when(remoteAddress).toString();
- }
-
- private void stubCtx() {
- doReturn(channel).when(ctx).channel();
- doReturn(ctx).when(ctx).fireChannelActive();
- doReturn(ctx).when(ctx).fireChannelInactive();
- doReturn(ctx).when(ctx).fireChannelRead(anyObject());
- doReturn(mock(ChannelFuture.class)).when(ctx).disconnect(any(ChannelPromise.class));
- doReturn(getMockedPromise()).when(ctx).newPromise();
- }
-
- private void stubChannel() {
- doReturn("channel").when(channel).toString();
- }
-
- private void stubSshClient() {
- doNothing().when(sshClient).start();
- final ConnectFuture connectFuture = mock(ConnectFuture.class);
- Futures.addCallback(stubAddListener(connectFuture), new SuccessFutureListener<ConnectFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<ConnectFuture> result) {
- sshConnectListener = result;
- }
- });
- doReturn(connectFuture).when(sshClient).connect("usr", remoteAddress);
- }
-
- @Test
- public void testConnectSuccess() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- verify(subsystemChannel).setStreaming(ClientChannel.Streaming.Async);
-
- verify(promise).setSuccess();
- verify(ctx).fireChannelActive();
- }
-
- @Test
- public void testRead() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- verify(ctx).fireChannelRead(any(ByteBuf.class));
- }
-
- @Test
- public void testReadClosed() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoReadFuture mockedReadFuture = asyncOut.read(null);
-
- Futures.addCallback(stubAddListener(mockedReadFuture), new SuccessFutureListener<IoReadFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<IoReadFuture> result) {
- doReturn(new IllegalStateException()).when(mockedReadFuture).getException();
- doReturn(mockedReadFuture).when(mockedReadFuture).removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
- doReturn(true).when(asyncOut).isClosing();
- doReturn(true).when(asyncOut).isClosed();
- result.operationComplete(mockedReadFuture);
- }
- });
-
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- verify(ctx).fireChannelInactive();
- }
-
- @Test
- public void testReadFail() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoReadFuture mockedReadFuture = asyncOut.read(null);
-
- Futures.addCallback(stubAddListener(mockedReadFuture), new SuccessFutureListener<IoReadFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<IoReadFuture> result) {
- doReturn(new IllegalStateException()).when(mockedReadFuture).getException();
- doReturn(mockedReadFuture).when(mockedReadFuture).removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
- result.operationComplete(mockedReadFuture);
- }
- });
-
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- verify(ctx).fireChannelInactive();
- }
-
- @Test
- public void testWrite() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- final ChannelPromise writePromise = getMockedPromise();
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0, 1, 2, 3, 4, 5}), writePromise);
-
- verify(writePromise).setSuccess();
- }
-
- @Test
- public void testWriteClosed() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
-
- final IoWriteFuture ioWriteFuture = asyncIn.write(null);
-
- Futures.addCallback(stubAddListener(ioWriteFuture), new SuccessFutureListener<IoWriteFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<IoWriteFuture> result) {
- doReturn(false).when(ioWriteFuture).isWritten();
- doReturn(new IllegalStateException()).when(ioWriteFuture).getException();
- doReturn(true).when(asyncIn).isClosing();
- doReturn(true).when(asyncIn).isClosed();
- result.operationComplete(ioWriteFuture);
- }
- });
-
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- final ChannelPromise writePromise = getMockedPromise();
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0,1,2,3,4,5}), writePromise);
-
- verify(writePromise).setFailure(any(Throwable.class));
- }
-
- @Test
- public void testWritePendingOne() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final IoWriteFuture ioWriteFuture = asyncIn.write(null);
-
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- final ChannelPromise firstWritePromise = getMockedPromise();
-
- // intercept listener for first write, so we can invoke successful write later thus simulate pending of the first write
- final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture = stubAddListener(ioWriteFuture);
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0,1,2,3,4,5}), firstWritePromise);
- final SshFutureListener<IoWriteFuture> firstWriteListener = firstWriteListenerFuture.get();
- // intercept second listener, this is the listener for pending write for the pending write to know when pending state ended
- final ListenableFuture<SshFutureListener<IoWriteFuture>> pendingListener = stubAddListener(ioWriteFuture);
-
- final ChannelPromise secondWritePromise = getMockedPromise();
- // now make write throw pending exception
- doThrow(org.apache.sshd.common.io.WritePendingException.class).when(asyncIn).write(any(Buffer.class));
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0, 1, 2, 3, 4, 5}), secondWritePromise);
-
- doReturn(ioWriteFuture).when(asyncIn).write(any(Buffer.class));
-
- verifyZeroInteractions(firstWritePromise, secondWritePromise);
-
- // make first write stop pending
- firstWriteListener.operationComplete(ioWriteFuture);
-
- // notify listener for second write that pending has ended
- pendingListener.get().operationComplete(ioWriteFuture);
-
- // verify both write promises successful
- verify(firstWritePromise).setSuccess();
- verify(secondWritePromise).setSuccess();
- }
-
- @Ignore("Pending queue is not limited")
- @Test
- public void testWritePendingMax() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final IoWriteFuture ioWriteFuture = asyncIn.write(null);
-
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- final ChannelPromise firstWritePromise = getMockedPromise();
-
- // intercept listener for first write, so we can invoke successful write later thus simulate pending of the first write
- final ListenableFuture<SshFutureListener<IoWriteFuture>> firstWriteListenerFuture = stubAddListener(ioWriteFuture);
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0,1,2,3,4,5}), firstWritePromise);
-
- final ChannelPromise secondWritePromise = getMockedPromise();
- // now make write throw pending exception
- doThrow(org.apache.sshd.common.io.WritePendingException.class).when(asyncIn).write(any(Buffer.class));
- for (int i = 0; i < 1001; i++) {
- asyncSshHandler.write(ctx, Unpooled.copiedBuffer(new byte[]{0, 1, 2, 3, 4, 5}), secondWritePromise);
- }
-
- verify(secondWritePromise, times(1)).setFailure(any(Throwable.class));
- }
-
- @Test
- public void testDisconnect() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
- sshAuthListener.operationComplete(getSuccessAuthFuture());
- sshChannelOpenListener.operationComplete(getSuccessOpenFuture());
-
- final ChannelPromise disconnectPromise = getMockedPromise();
- asyncSshHandler.disconnect(ctx, disconnectPromise);
-
- verify(sshSession).close(anyBoolean());
- verify(disconnectPromise).setSuccess();
- verify(ctx).fireChannelInactive();
- }
-
- private static OpenFuture getSuccessOpenFuture() {
- final OpenFuture failedOpenFuture = mock(OpenFuture.class);
- doReturn(true).when(failedOpenFuture).isOpened();
- return failedOpenFuture;
- }
-
- private static AuthFuture getSuccessAuthFuture() {
- final AuthFuture authFuture = mock(AuthFuture.class);
- doReturn(true).when(authFuture).isSuccess();
- return authFuture;
- }
-
- private static ConnectFuture getSuccessConnectFuture(final ClientSession sshSession) {
- final ConnectFuture connectFuture = mock(ConnectFuture.class);
- doReturn(true).when(connectFuture).isConnected();
-
- doReturn(sshSession).when(connectFuture).getSession();
- return connectFuture;
- }
-
- private static ClientSession getMockedSshSession(final ChannelSubsystem subsystemChannel) throws IOException {
- final ClientSession sshSession = mock(ClientSession.class);
-
- doReturn("sshSession").when(sshSession).toString();
- doReturn("serverVersion").when(sshSession).getServerVersion();
- doReturn(false).when(sshSession).isClosed();
- doReturn(false).when(sshSession).isClosing();
- final CloseFuture closeFuture = mock(CloseFuture.class);
- Futures.addCallback(stubAddListener(closeFuture), new SuccessFutureListener<CloseFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<CloseFuture> result) {
- doReturn(true).when(closeFuture).isClosed();
- result.operationComplete(closeFuture);
- }
- });
- doReturn(closeFuture).when(sshSession).close(false);
-
- doReturn(subsystemChannel).when(sshSession).createSubsystemChannel(anyString());
-
- return sshSession;
- }
-
- private ChannelSubsystem getMockedSubsystemChannel(final IoInputStream asyncOut, final IoOutputStream asyncIn) throws IOException {
- final ChannelSubsystem subsystemChannel = mock(ChannelSubsystem.class);
- doReturn("subsystemChannel").when(subsystemChannel).toString();
-
- doNothing().when(subsystemChannel).setStreaming(any(ClientChannel.Streaming.class));
- final OpenFuture openFuture = mock(OpenFuture.class);
-
- Futures.addCallback(stubAddListener(openFuture), new SuccessFutureListener<OpenFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<OpenFuture> result) {
- sshChannelOpenListener = result;
- }
- });
-
- doReturn(asyncOut).when(subsystemChannel).getAsyncOut();
-
- doReturn(openFuture).when(subsystemChannel).open();
- doReturn(asyncIn).when(subsystemChannel).getAsyncIn();
- return subsystemChannel;
- }
-
- private static IoOutputStream getMockedIoOutputStream() {
- final IoOutputStream mock = mock(IoOutputStream.class);
- final IoWriteFuture ioWriteFuture = mock(IoWriteFuture.class);
- doReturn(ioWriteFuture).when(ioWriteFuture).addListener(Matchers.<SshFutureListener<IoWriteFuture>>any());
- doReturn(true).when(ioWriteFuture).isWritten();
-
- Futures.addCallback(stubAddListener(ioWriteFuture), new SuccessFutureListener<IoWriteFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<IoWriteFuture> result) {
- result.operationComplete(ioWriteFuture);
- }
- });
-
- doReturn(ioWriteFuture).when(mock).write(any(Buffer.class));
- doReturn(false).when(mock).isClosed();
- doReturn(false).when(mock).isClosing();
- return mock;
- }
-
- private static IoInputStream getMockedIoInputStream() {
- final IoInputStream mock = mock(IoInputStream.class);
- final IoReadFuture ioReadFuture = mock(IoReadFuture.class);
- doReturn(null).when(ioReadFuture).getException();
- doReturn(ioReadFuture).when(ioReadFuture).removeListener(Matchers.<SshFutureListener<IoReadFuture>>any());
- doReturn(5).when(ioReadFuture).getRead();
- doReturn(new Buffer(new byte[]{0, 1, 2, 3, 4})).when(ioReadFuture).getBuffer();
- doReturn(ioReadFuture).when(ioReadFuture).addListener(Matchers.<SshFutureListener<IoReadFuture>>any());
-
- // Always success for read
- Futures.addCallback(stubAddListener(ioReadFuture), new SuccessFutureListener<IoReadFuture>() {
- @Override
- public void onSuccess(final SshFutureListener<IoReadFuture> result) {
- result.operationComplete(ioReadFuture);
- }
- });
-
- doReturn(ioReadFuture).when(mock).read(any(Buffer.class));
- doReturn(false).when(mock).isClosed();
- doReturn(false).when(mock).isClosing();
- return mock;
- }
-
- @Test
- public void testConnectFailOpenChannel() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final IoInputStream asyncOut = getMockedIoInputStream();
- final IoOutputStream asyncIn = getMockedIoOutputStream();
- final ChannelSubsystem subsystemChannel = getMockedSubsystemChannel(asyncOut, asyncIn);
- final ClientSession sshSession = getMockedSshSession(subsystemChannel);
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
-
- sshAuthListener.operationComplete(getSuccessAuthFuture());
-
- verify(subsystemChannel).setStreaming(ClientChannel.Streaming.Async);
-
- sshChannelOpenListener.operationComplete(getFailedOpenFuture());
- verify(promise).setFailure(any(Throwable.class));
- }
-
- @Test
- public void testConnectFailAuth() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final ClientSession sshSession = mock(ClientSession.class);
- doReturn(true).when(sshSession).isClosed();
- final ConnectFuture connectFuture = getSuccessConnectFuture(sshSession);
-
- sshConnectListener.operationComplete(connectFuture);
-
- final AuthFuture authFuture = getFailedAuthFuture();
-
- sshAuthListener.operationComplete(authFuture);
- verify(promise).setFailure(any(Throwable.class));
- }
-
- private static AuthFuture getFailedAuthFuture() {
- final AuthFuture authFuture = mock(AuthFuture.class);
- doReturn(false).when(authFuture).isSuccess();
- doReturn(new IllegalStateException()).when(authFuture).getException();
- return authFuture;
- }
-
- private static OpenFuture getFailedOpenFuture() {
- final OpenFuture authFuture = mock(OpenFuture.class);
- doReturn(false).when(authFuture).isOpened();
- doReturn(new IllegalStateException()).when(authFuture).getException();
- return authFuture;
- }
-
- @Test
- public void testConnectFail() throws Exception {
- asyncSshHandler.connect(ctx, remoteAddress, localAddress, promise);
-
- final ConnectFuture connectFuture = getFailedConnectFuture();
- sshConnectListener.operationComplete(connectFuture);
- verify(promise).setFailure(any(Throwable.class));
- }
-
- private static ConnectFuture getFailedConnectFuture() {
- final ConnectFuture connectFuture = mock(ConnectFuture.class);
- doReturn(false).when(connectFuture).isConnected();
- doReturn(new IllegalStateException()).when(connectFuture).getException();
- return connectFuture;
- }
-
- private ChannelPromise getMockedPromise() {
- return spy(new DefaultChannelPromise(channel));
- }
-
- private static abstract class SuccessFutureListener<T extends SshFuture<T>> implements FutureCallback<SshFutureListener<T>> {
-
- @Override
- public abstract void onSuccess(final SshFutureListener<T> result);
-
- @Override
- public void onFailure(final Throwable t) {
- throw new RuntimeException(t);
- }
- }
-}
+++ /dev/null
-[tomas;10.0.0.0/10000;tcp;1000;1000;;/home/tomas;;]
-<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <capabilities>
- <capability>urn:ietf:params:netconf:base:1.0</capability>
- </capabilities>
-</hello>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>netconf-subsystem</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <artifactId>netconf-notifications-api</artifactId>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-notifications</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-
-
-/**
- * Listener for base netconf notifications defined in https://tools.ietf.org/html/rfc6470.
- * This listener uses generated classes from yang model defined in RFC6470.
- * It alleviates the provisioning of base netconf notifications from the code.
- */
-public interface BaseNetconfNotificationListener {
-
- /**
- * Callback used to notify about a change in used capabilities
- */
- void onCapabilityChanged(final NetconfCapabilityChange capabilityChange);
-
- // TODO add other base notifications
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-/**
- * Registration for base notification publisher. This registration allows for publishing of base netconf notifications using generated classes
- */
-public interface BaseNotificationPublisherRegistration extends NotificationRegistration, BaseNetconfNotificationListener {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-import com.google.common.base.Preconditions;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Special kind of netconf message that contains a timestamp.
- */
-public final class NetconfNotification extends NetconfMessage {
-
- public static final String NOTIFICATION = "notification";
- public static final String NOTIFICATION_NAMESPACE = "urn:ietf:params:netconf:capability:notification:1.0";
- public static final String RFC3339_DATE_FORMAT_BLUEPRINT = "yyyy-MM-dd'T'HH:mm:ssXXX";
- public static final String EVENT_TIME = "eventTime";
-
- /**
- * Create new notification and capture the timestamp in the constructor
- */
- public NetconfNotification(final Document notificationContent) {
- this(notificationContent, new Date());
- }
-
- /**
- * Create new notification with provided timestamp
- */
- public NetconfNotification(final Document notificationContent, final Date eventTime) {
- super(wrapNotification(notificationContent, eventTime));
- }
-
- private static Document wrapNotification(final Document notificationContent, final Date eventTime) {
- Preconditions.checkNotNull(notificationContent);
- Preconditions.checkNotNull(eventTime);
-
- final Element baseNotification = notificationContent.getDocumentElement();
- final Element entireNotification = notificationContent.createElementNS(NOTIFICATION_NAMESPACE, NOTIFICATION);
- entireNotification.appendChild(baseNotification);
-
- final Element eventTimeElement = notificationContent.createElementNS(NOTIFICATION_NAMESPACE, EVENT_TIME);
- eventTimeElement.setTextContent(getSerializedEventTime(eventTime));
- entireNotification.appendChild(eventTimeElement);
-
- notificationContent.appendChild(entireNotification);
- return notificationContent;
- }
-
- private static String getSerializedEventTime(final Date eventTime) {
- // SimpleDateFormat is not threadsafe, cannot be in a constant
- return new SimpleDateFormat(RFC3339_DATE_FORMAT_BLUEPRINT).format(eventTime);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-
-/**
- * Collector of all notifications. Base or generic
- */
-public interface NetconfNotificationCollector {
-
- /**
- * Add notification publisher for a particular stream
- *
- * Implementations should allow for multiple publishers of a single stream
- * and its up to implementations to decide how to merge metadata (e.g. description)
- * for the same stream when providing information about available stream
- *
- */
- NotificationPublisherRegistration registerNotificationPublisher(Stream stream);
-
- /**
- * Register base notification publisher
- */
- BaseNotificationPublisherRegistration registerBaseNotificationPublisher();
-
- /**
- * Users of the registry have an option to get notification each time new notification stream gets registered
- * This allows for a push model in addition to pull model for retrieving information about available streams.
- *
- * The listener should receive callbacks for each stream available prior to the registration when its registered
- */
- NotificationRegistration registerStreamListener(NetconfNotificationStreamListener listener);
-
- /**
- * Simple listener that receives notifications about changes in stream availability
- */
- public interface NetconfNotificationStreamListener {
-
- /**
- * Stream becomes available in the collector (first publisher is registered)
- */
- void onStreamRegistered(Stream stream);
-
- /**
- * Stream is not available anymore in the collector (last publisher is unregistered)
- */
- void onStreamUnregistered(StreamNameType stream);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-
-/**
- * Generic listener for netconf notifications
- */
-public interface NetconfNotificationListener {
-
- /**
- * Callback used to notify the listener about any new notification
- */
- void onNotification(StreamNameType stream, NetconfNotification notification);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-
-/**
- *
- */
-public interface NetconfNotificationRegistry {
-
- /**
- * Add listener for a certain notification type
- */
- NotificationListenerRegistration registerNotificationListener(StreamNameType stream, NetconfNotificationListener listener);
-
- /**
- * Check stream availability
- */
- boolean isStreamAvailable(StreamNameType streamNameType);
-
- /**
- * Get all the streams available
- */
- Streams getNotificationPublishers();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-/**
- * Manages the registration of a single listener
- */
-public interface NotificationListenerRegistration extends NotificationRegistration {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-/**
- * Registration for notification publisher. This registration allows for publishing any netconf notifications
- */
-public interface NotificationPublisherRegistration extends NetconfNotificationListener, NotificationRegistration {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications;
-
-/**
- * Generic registration, used as a base for other registration types
- */
-public interface NotificationRegistration extends AutoCloseable {
-
- // Overriden close does not throw any kind of checked exception
-
- /**
- * Close the registration.
- */
- @Override
- void close();
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <parent>
- <artifactId>netconf-subsystem</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <artifactId>netconf-notifications-impl</artifactId>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-generator-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-data-codec</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.notifications.impl.osgi.Activator</Bundle-Activator>
- <Export-Package>org.opendaylight.controller.netconf.notifications.impl.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.HashMultiset;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multiset;
-import com.google.common.collect.Sets;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationListener;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
-import org.opendaylight.controller.netconf.notifications.NotificationPublisherRegistration;
-import org.opendaylight.controller.netconf.notifications.NotificationRegistration;
-import org.opendaylight.controller.netconf.notifications.impl.ops.NotificationsTransformUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.StreamsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@ThreadSafe
-public class NetconfNotificationManager implements NetconfNotificationCollector, NetconfNotificationRegistry, NetconfNotificationListener, AutoCloseable {
-
- public static final StreamNameType BASE_STREAM_NAME = new StreamNameType("NETCONF");
- public static final Stream BASE_NETCONF_STREAM;
-
- static {
- BASE_NETCONF_STREAM = new StreamBuilder()
- .setName(BASE_STREAM_NAME)
- .setKey(new StreamKey(BASE_STREAM_NAME))
- .setReplaySupport(false)
- .setDescription("Default Event Stream")
- .build();
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNotificationManager.class);
-
- // TODO excessive synchronization provides thread safety but is most likely not optimal (combination of concurrent collections might improve performance)
- // And also calling callbacks from a synchronized block is dangerous since the listeners/publishers can block the whole notification processing
-
- @GuardedBy("this")
- private final Multimap<StreamNameType, GenericNotificationListenerReg> notificationListeners = HashMultimap.create();
-
- @GuardedBy("this")
- private final Set<NetconfNotificationStreamListener> streamListeners = Sets.newHashSet();
-
- @GuardedBy("this")
- private final Map<StreamNameType, Stream> streamMetadata = Maps.newHashMap();
-
- @GuardedBy("this")
- private final Multiset<StreamNameType> availableStreams = HashMultiset.create();
-
- @GuardedBy("this")
- private final Set<GenericNotificationPublisherReg> notificationPublishers = Sets.newHashSet();
-
- @Override
- public synchronized void onNotification(final StreamNameType stream, final NetconfNotification notification) {
- LOG.debug("Notification of type {} detected", stream);
- if (LOG.isTraceEnabled()) {
- LOG.debug("Notification of type {} detected: {}", stream, notification);
- }
-
- for (final GenericNotificationListenerReg listenerReg : notificationListeners.get(BASE_STREAM_NAME)) {
- listenerReg.getListener().onNotification(BASE_STREAM_NAME, notification);
- }
- }
-
- @Override
- public synchronized NotificationListenerRegistration registerNotificationListener(final StreamNameType stream, final NetconfNotificationListener listener) {
- Preconditions.checkNotNull(stream);
- Preconditions.checkNotNull(listener);
-
- LOG.trace("Notification listener registered for stream: {}", stream);
-
- final GenericNotificationListenerReg genericNotificationListenerReg = new GenericNotificationListenerReg(listener) {
- @Override
- public void close() {
- synchronized (NetconfNotificationManager.this) {
- LOG.trace("Notification listener unregistered for stream: {}", stream);
- super.close();
- }
- }
- };
-
- notificationListeners.put(BASE_STREAM_NAME, genericNotificationListenerReg);
- return genericNotificationListenerReg;
- }
-
- @Override
- public synchronized Streams getNotificationPublishers() {
- return new StreamsBuilder().setStream(Lists.newArrayList(streamMetadata.values())).build();
- }
-
- @Override
- public synchronized boolean isStreamAvailable(final StreamNameType streamNameType) {
- return availableStreams.contains(streamNameType);
- }
-
- @Override
- public synchronized NotificationRegistration registerStreamListener(final NetconfNotificationStreamListener listener) {
- streamListeners.add(listener);
-
- // Notify about all already available
- for (final Stream availableStream : streamMetadata.values()) {
- listener.onStreamRegistered(availableStream);
- }
-
- return new NotificationRegistration() {
- @Override
- public void close() {
- synchronized (NetconfNotificationManager.this) {
- streamListeners.remove(listener);
- }
- }
- };
- }
-
- @Override
- public synchronized void close() {
- // Unregister all listeners
- for (final GenericNotificationListenerReg genericNotificationListenerReg : notificationListeners.values()) {
- genericNotificationListenerReg.close();
- }
- notificationListeners.clear();
-
- // Unregister all publishers
- for (final GenericNotificationPublisherReg notificationPublisher : notificationPublishers) {
- notificationPublisher.close();
- }
- notificationPublishers.clear();
-
- // Clear stream Listeners
- streamListeners.clear();
- }
-
- @Override
- public synchronized NotificationPublisherRegistration registerNotificationPublisher(final Stream stream) {
- Preconditions.checkNotNull(stream);
- final StreamNameType streamName = stream.getName();
-
- LOG.debug("Notification publisher registered for stream: {}", streamName);
- if (LOG.isTraceEnabled()) {
- LOG.trace("Notification publisher registered for stream: {}", stream);
- }
-
- if (streamMetadata.containsKey(streamName)) {
- LOG.warn("Notification stream {} already registered as: {}. Will be reused", streamName, streamMetadata.get(streamName));
- } else {
- streamMetadata.put(streamName, stream);
- }
-
- availableStreams.add(streamName);
-
- final GenericNotificationPublisherReg genericNotificationPublisherReg = new GenericNotificationPublisherReg(this, streamName) {
- @Override
- public void close() {
- synchronized (NetconfNotificationManager.this) {
- super.close();
- }
- }
- };
-
- notificationPublishers.add(genericNotificationPublisherReg);
-
- notifyStreamAdded(stream);
- return genericNotificationPublisherReg;
- }
-
- private void unregisterNotificationPublisher(final StreamNameType streamName, final GenericNotificationPublisherReg genericNotificationPublisherReg) {
- availableStreams.remove(streamName);
- notificationPublishers.remove(genericNotificationPublisherReg);
-
- LOG.debug("Notification publisher unregistered for stream: {}", streamName);
-
- // Notify stream listeners if all publishers are gone and also clear metadata for stream
- if (!isStreamAvailable(streamName)) {
- LOG.debug("Notification stream: {} became unavailable", streamName);
- streamMetadata.remove(streamName);
- notifyStreamRemoved(streamName);
- }
- }
-
- private synchronized void notifyStreamAdded(final Stream stream) {
- for (final NetconfNotificationStreamListener streamListener : streamListeners) {
- streamListener.onStreamRegistered(stream);
- }
- }
-
- private synchronized void notifyStreamRemoved(final StreamNameType stream) {
- for (final NetconfNotificationStreamListener streamListener : streamListeners) {
- streamListener.onStreamUnregistered(stream);
- }
- }
-
- @Override
- public BaseNotificationPublisherRegistration registerBaseNotificationPublisher() {
- final NotificationPublisherRegistration notificationPublisherRegistration = registerNotificationPublisher(BASE_NETCONF_STREAM);
- return new BaseNotificationPublisherReg(notificationPublisherRegistration);
- }
-
- private static class GenericNotificationPublisherReg implements NotificationPublisherRegistration {
- private NetconfNotificationManager baseListener;
- private final StreamNameType registeredStream;
-
- public GenericNotificationPublisherReg(final NetconfNotificationManager baseListener, final StreamNameType registeredStream) {
- this.baseListener = baseListener;
- this.registeredStream = registeredStream;
- }
-
- @Override
- public void close() {
- baseListener.unregisterNotificationPublisher(registeredStream, this);
- baseListener = null;
- }
-
- @Override
- public void onNotification(final StreamNameType stream, final NetconfNotification notification) {
- Preconditions.checkState(baseListener != null, "Already closed");
- Preconditions.checkArgument(stream.equals(registeredStream));
- baseListener.onNotification(stream, notification);
- }
- }
-
- private static class BaseNotificationPublisherReg implements BaseNotificationPublisherRegistration {
-
- private final NotificationPublisherRegistration baseRegistration;
-
- public BaseNotificationPublisherReg(final NotificationPublisherRegistration baseRegistration) {
- this.baseRegistration = baseRegistration;
- }
-
- @Override
- public void close() {
- baseRegistration.close();
- }
-
- private static NetconfNotification serializeNotification(final NetconfCapabilityChange capabilityChange) {
- return NotificationsTransformUtil.transform(capabilityChange);
- }
-
- @Override
- public void onCapabilityChanged(final NetconfCapabilityChange capabilityChange) {
- baseRegistration.onNotification(BASE_STREAM_NAME, serializeNotification(capabilityChange));
-// baseRegistration.onNotification(BASE_STREAM_NAME, serializeNotification(computeDiff(removed, added)));
- }
- }
-
- private class GenericNotificationListenerReg implements NotificationListenerRegistration {
- private final NetconfNotificationListener listener;
-
- public GenericNotificationListenerReg(final NetconfNotificationListener listener) {
- this.listener = listener;
- }
-
- public NetconfNotificationListener getListener() {
- return listener;
- }
-
- @Override
- public void close() {
- notificationListeners.remove(BASE_STREAM_NAME, this);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.SessionAwareNetconfOperation;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationListener;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
-import org.opendaylight.controller.netconf.notifications.impl.NetconfNotificationManager;
-import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Create subscription listens for create subscription requests and registers notification listeners into notification registry.
- * Received notifications are sent to the client right away
- */
-public class CreateSubscription extends AbstractLastNetconfOperation implements SessionAwareNetconfOperation, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(CreateSubscription.class);
-
- static final String CREATE_SUBSCRIPTION = "create-subscription";
-
- private final NetconfNotificationRegistry notifications;
- private final List<NotificationListenerRegistration> subscriptions = Lists.newArrayList();
- private NetconfSession netconfSession;
-
- public CreateSubscription(final String netconfSessionIdForReporting, final NetconfNotificationRegistry notifications) {
- super(netconfSessionIdForReporting);
- this.notifications = notifications;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- operationElement.checkName(CREATE_SUBSCRIPTION);
- operationElement.checkNamespace(CreateSubscriptionInput.QNAME.getNamespace().toString());
- // FIXME reimplement using CODEC_REGISTRY and parse everything into generated class instance
- // Waiting ofr https://git.opendaylight.org/gerrit/#/c/13763/
-
- // FIXME filter could be supported same way as netconf server filters get and get-config results
- final Optional<XmlElement> filter = operationElement.getOnlyChildElementWithSameNamespaceOptionally("filter");
- Preconditions.checkArgument(filter.isPresent() == false, "Filter element not yet supported");
-
- // Replay not supported
- final Optional<XmlElement> startTime = operationElement.getOnlyChildElementWithSameNamespaceOptionally("startTime");
- Preconditions.checkArgument(startTime.isPresent() == false, "StartTime element not yet supported");
-
- // Stop time not supported
- final Optional<XmlElement> stopTime = operationElement.getOnlyChildElementWithSameNamespaceOptionally("stopTime");
- Preconditions.checkArgument(stopTime.isPresent() == false, "StopTime element not yet supported");
-
- final StreamNameType streamNameType = parseStreamIfPresent(operationElement);
-
- Preconditions.checkNotNull(netconfSession);
- // Premature streams are allowed (meaning listener can register even if no provider is available yet)
- if(notifications.isStreamAvailable(streamNameType) == false) {
- LOG.warn("Registering premature stream {}. No publisher available yet for session {}", streamNameType, getNetconfSessionIdForReporting());
- }
-
- final NotificationListenerRegistration notificationListenerRegistration =
- notifications.registerNotificationListener(streamNameType, new NotificationSubscription(netconfSession));
- subscriptions.add(notificationListenerRegistration);
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- private static StreamNameType parseStreamIfPresent(final XmlElement operationElement) throws DocumentedException {
- final Optional<XmlElement> stream = operationElement.getOnlyChildElementWithSameNamespaceOptionally("stream");
- return stream.isPresent() ? new StreamNameType(stream.get().getTextContent()) : NetconfNotificationManager.BASE_STREAM_NAME;
- }
-
- @Override
- protected String getOperationName() {
- return CREATE_SUBSCRIPTION;
- }
-
- @Override
- protected String getOperationNamespace() {
- return CreateSubscriptionInput.QNAME.getNamespace().toString();
- }
-
- @Override
- public void setSession(final NetconfSession session) {
- this.netconfSession = session;
- }
-
- @Override
- public void close() {
- netconfSession = null;
- // Unregister from notification streams
- for (final NotificationListenerRegistration subscription : subscriptions) {
- subscription.close();
- }
- }
-
- private static class NotificationSubscription implements NetconfNotificationListener {
- private final NetconfSession currentSession;
-
- public NotificationSubscription(final NetconfSession currentSession) {
- this.currentSession = currentSession;
- }
-
- @Override
- public void onNotification(final StreamNameType stream, final NetconfNotification notification) {
- currentSession.sendMessage(notification);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.Netconf;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.NetconfBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * Serialize the subtree for netconf notifications into the response of get rpc.
- * This operation just adds its subtree into the common response of get rpc.
- */
-public class Get extends AbstractNetconfOperation implements AutoCloseable {
-
- private static final String GET = "get";
- private static final InstanceIdentifier<Netconf> NETCONF_SUBTREE_INSTANCE_IDENTIFIER = InstanceIdentifier.builder(Netconf.class).build();
-
- private final NetconfNotificationRegistry notificationRegistry;
-
- public Get(final String netconfSessionIdForReporting, final NetconfNotificationRegistry notificationRegistry) {
- super(netconfSessionIdForReporting);
- Preconditions.checkNotNull(notificationRegistry);
- this.notificationRegistry = notificationRegistry;
- }
-
- @Override
- protected String getOperationName() {
- return GET;
- }
-
- @Override
- public Document handle(final Document requestMessage, final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- final Document partialResponse = subsequentOperation.execute(requestMessage);
- final Streams availableStreams = notificationRegistry.getNotificationPublishers();
- if(availableStreams.getStream().isEmpty() == false) {
- serializeStreamsSubtree(partialResponse, availableStreams);
- }
- return partialResponse;
- }
-
- static void serializeStreamsSubtree(final Document partialResponse, final Streams availableStreams) throws DocumentedException {
- final Netconf netconfSubtree = new NetconfBuilder().setStreams(availableStreams).build();
- final NormalizedNode<?, ?> normalized = toNormalized(netconfSubtree);
-
- final DOMResult result = new DOMResult(getPlaceholder(partialResponse));
-
- try {
- NotificationsTransformUtil.writeNormalizedNode(normalized, result, SchemaPath.ROOT);
- } catch (final XMLStreamException | IOException e) {
- throw new IllegalStateException("Unable to serialize " + netconfSubtree, e);
- }
- }
-
- private static Element getPlaceholder(final Document innerResult)
- throws DocumentedException {
- final XmlElement rootElement = XmlElement.fromDomElementWithExpected(
- innerResult.getDocumentElement(), XmlMappingConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
- }
-
- private static NormalizedNode<?, ?> toNormalized(final Netconf netconfSubtree) {
- return NotificationsTransformUtil.CODEC_REGISTRY.toNormalizedNode(NETCONF_SUBTREE_INSTANCE_IDENTIFIER, netconfSubtree).getValue();
- }
-
- @Override
- protected Element handle(final Document document, final XmlElement message, final NetconfOperationChainedExecution subsequentOperation)
- throws DocumentedException {
- throw new UnsupportedOperationException("Never gets called");
- }
-
- @Override
- protected HandlingPriority getHandlingPriority() {
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(2);
- }
-
- @Override
- public void close() throws Exception {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Iterables;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Date;
-import javassist.ClassPool;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-public final class NotificationsTransformUtil {
-
- private static final Logger LOG = LoggerFactory.getLogger(NotificationsTransformUtil.class);
-
- private NotificationsTransformUtil() {}
-
- static final SchemaContext NOTIFICATIONS_SCHEMA_CTX;
- static final BindingNormalizedNodeCodecRegistry CODEC_REGISTRY;
- static final XMLOutputFactory XML_FACTORY;
- static final RpcDefinition CREATE_SUBSCRIPTION_RPC;
-
- static final SchemaPath CAPABILITY_CHANGE_SCHEMA_PATH = SchemaPath.create(true, NetconfCapabilityChange.QNAME);
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
-
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(Collections.singletonList($YangModuleInfoImpl.getInstance()));
- moduleInfoBackedContext.addModuleInfos(Collections.singletonList(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.$YangModuleInfoImpl.getInstance()));
- final Optional<SchemaContext> schemaContextOptional = moduleInfoBackedContext.tryToCreateSchemaContext();
- Preconditions.checkState(schemaContextOptional.isPresent());
- NOTIFICATIONS_SCHEMA_CTX = schemaContextOptional.get();
-
- CREATE_SUBSCRIPTION_RPC = Preconditions.checkNotNull(findCreateSubscriptionRpc());
-
- Preconditions.checkNotNull(CREATE_SUBSCRIPTION_RPC);
-
- final JavassistUtils javassist = JavassistUtils.forClassPool(ClassPool.getDefault());
- CODEC_REGISTRY = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(javassist));
- CODEC_REGISTRY.onBindingRuntimeContextUpdated(BindingRuntimeContext.create(moduleInfoBackedContext, NOTIFICATIONS_SCHEMA_CTX));
- }
-
- private static RpcDefinition findCreateSubscriptionRpc() {
- return Iterables.getFirst(Collections2.filter(NOTIFICATIONS_SCHEMA_CTX.getOperations(), new Predicate<RpcDefinition>() {
- @Override
- public boolean apply(final RpcDefinition input) {
- return input.getQName().getLocalName().equals(CreateSubscription.CREATE_SUBSCRIPTION);
- }
- }), null);
- }
-
- /**
- * Transform base notification for capabilities into NetconfNotification
- */
- public static NetconfNotification transform(final NetconfCapabilityChange capabilityChange) {
- return transform(capabilityChange, Optional.<Date>absent());
- }
-
- public static NetconfNotification transform(final NetconfCapabilityChange capabilityChange, final Date eventTime) {
- return transform(capabilityChange, Optional.fromNullable(eventTime));
- }
-
- private static NetconfNotification transform(final NetconfCapabilityChange capabilityChange, final Optional<Date> eventTime) {
- final ContainerNode containerNode = CODEC_REGISTRY.toNormalizedNodeNotification(capabilityChange);
- final DOMResult result = new DOMResult(XmlUtil.newDocument());
- try {
- writeNormalizedNode(containerNode, result, CAPABILITY_CHANGE_SCHEMA_PATH);
- } catch (final XMLStreamException| IOException e) {
- throw new IllegalStateException("Unable to serialize " + capabilityChange, e);
- }
- final Document node = (Document) result.getNode();
- return eventTime.isPresent() ?
- new NetconfNotification(node, eventTime.get()):
- new NetconfNotification(node);
- }
-
- static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath) throws IOException, XMLStreamException {
- NormalizedNodeWriter normalizedNodeWriter = null;
- NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
- XMLStreamWriter writer = null;
- try {
- writer = XML_FACTORY.createXMLStreamWriter(result);
- normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, NOTIFICATIONS_SCHEMA_CTX, schemaPath);
- normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
-
- normalizedNodeWriter.write(normalized);
-
- normalizedNodeWriter.flush();
- } finally {
- try {
- if(normalizedNodeWriter != null) {
- normalizedNodeWriter.close();
- }
- if(normalizedNodeStreamWriter != null) {
- normalizedNodeStreamWriter.close();
- }
- if(writer != null) {
- writer.close();
- }
- } catch (final Exception e) {
- LOG.warn("Unable to close resource properly", e);
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.osgi;
-
-import com.google.common.collect.Sets;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Set;
-import org.opendaylight.controller.config.util.capability.BasicCapability;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.api.util.NetconfConstants;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
-import org.opendaylight.controller.netconf.notifications.impl.NetconfNotificationManager;
-import org.opendaylight.controller.netconf.notifications.impl.ops.CreateSubscription;
-import org.opendaylight.controller.netconf.notifications.impl.ops.Get;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Activator implements BundleActivator {
-
- private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
-
- private ServiceRegistration<NetconfNotificationCollector> netconfNotificationCollectorServiceRegistration;
- private ServiceRegistration<NetconfOperationServiceFactory> operationaServiceRegistration;
- private NetconfNotificationManager netconfNotificationManager;
-
- @Override
- public void start(final BundleContext context) throws Exception {
- netconfNotificationManager = new NetconfNotificationManager();
- netconfNotificationCollectorServiceRegistration = context.registerService(NetconfNotificationCollector.class, netconfNotificationManager, new Hashtable<String, Object>());
-
- final NetconfOperationServiceFactory netconfOperationServiceFactory = new NetconfOperationServiceFactory() {
-
- private final Set<Capability> capabilities = Collections.<Capability>singleton(new BasicCapability(NetconfNotification.NOTIFICATION_NAMESPACE));
-
- @Override
- public Set<Capability> getCapabilities() {
- return capabilities;
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- listener.onCapabilitiesChanged(capabilities, Collections.<Capability>emptySet());
- return new AutoCloseable() {
- @Override
- public void close() {
- listener.onCapabilitiesChanged(Collections.<Capability>emptySet(), capabilities);
- }
- };
- }
-
- @Override
- public NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return new NetconfOperationService() {
-
- private final CreateSubscription createSubscription = new CreateSubscription(netconfSessionIdForReporting, netconfNotificationManager);
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- return Sets.<NetconfOperation>newHashSet(
- new Get(netconfSessionIdForReporting, netconfNotificationManager),
- createSubscription);
- }
-
- @Override
- public void close() {
- createSubscription.close();
- }
- };
- }
- };
-
- final Dictionary<String, String> properties = new Hashtable<>();
- properties.put(NetconfConstants.SERVICE_NAME, NetconfConstants.NETCONF_MONITORING);
- operationaServiceRegistration = context.registerService(NetconfOperationServiceFactory.class, netconfOperationServiceFactory, properties);
- }
-
- @Override
- public void stop(final BundleContext context) throws Exception {
- if(netconfNotificationCollectorServiceRegistration != null) {
- netconfNotificationCollectorServiceRegistration.unregister();
- netconfNotificationCollectorServiceRegistration = null;
- }
- if (netconfNotificationManager != null) {
- netconfNotificationManager.close();
- }
- if (operationaServiceRegistration != null) {
- operationaServiceRegistration.unregister();
- operationaServiceRegistration = null;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.notifications.BaseNotificationPublisherRegistration;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationCollector;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationListener;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
-
-public class NetconfNotificationManagerTest {
-
- @Mock
- private NetconfNotificationRegistry notificationRegistry;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testNotificationListeners() throws Exception {
- final NetconfNotificationManager netconfNotificationManager = new NetconfNotificationManager();
- final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
- netconfNotificationManager.registerBaseNotificationPublisher();
-
- final NetconfCapabilityChangeBuilder capabilityChangedBuilder = new NetconfCapabilityChangeBuilder();
-
- final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
- doNothing().when(listener).onNotification(any(StreamNameType.class), any(NetconfNotification.class));
- final NotificationListenerRegistration notificationListenerRegistration = netconfNotificationManager.registerNotificationListener(NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener);
- final NetconfCapabilityChange notification = capabilityChangedBuilder.build();
- baseNotificationPublisherRegistration.onCapabilityChanged(notification);
-
- verify(listener).onNotification(any(StreamNameType.class), any(NetconfNotification.class));
-
- notificationListenerRegistration.close();
-
- baseNotificationPublisherRegistration.onCapabilityChanged(notification);
- verifyNoMoreInteractions(listener);
- }
-
- @Test
- public void testClose() throws Exception {
- final NetconfNotificationManager netconfNotificationManager = new NetconfNotificationManager();
-
- final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration = netconfNotificationManager.registerBaseNotificationPublisher();
-
- final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
- doNothing().when(listener).onNotification(any(StreamNameType.class), any(NetconfNotification.class));
-
- netconfNotificationManager.registerNotificationListener(NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener);
-
- final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener =
- mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
- doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
- doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
- netconfNotificationManager.registerStreamListener(streamListener);
-
- verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
-
- netconfNotificationManager.close();
-
- verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_NETCONF_STREAM.getName());
-
- try {
- baseNotificationPublisherRegistration.onCapabilityChanged(new NetconfCapabilityChangeBuilder().build());
- } catch (final IllegalStateException e) {
- // Exception should be thrown after manager is closed
- return;
- }
-
- fail("Publishing into a closed manager should fail");
- }
-
- @Test
- public void testStreamListeners() throws Exception {
- final NetconfNotificationManager netconfNotificationManager = new NetconfNotificationManager();
-
- final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener = mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
- doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
- doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
-
- netconfNotificationManager.registerStreamListener(streamListener);
-
- final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
- netconfNotificationManager.registerBaseNotificationPublisher();
-
- verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
-
-
- baseNotificationPublisherRegistration.close();
-
- verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_STREAM_NAME);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationListener;
-import org.opendaylight.controller.netconf.notifications.NetconfNotificationRegistry;
-import org.opendaylight.controller.netconf.notifications.NotificationListenerRegistration;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.w3c.dom.Element;
-
-public class CreateSubscriptionTest {
-
- private static final String CREATE_SUBSCRIPTION_XML = "<create-subscription\n" +
- "xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\" xmlns:netconf=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<stream>TESTSTREAM</stream>" +
- "</create-subscription>";
-
- @Mock
- private NetconfNotificationRegistry notificationRegistry;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(true).when(notificationRegistry).isStreamAvailable(any(StreamNameType.class));
- doReturn(mock(NotificationListenerRegistration.class)).when(notificationRegistry).registerNotificationListener(any(StreamNameType.class), any(NetconfNotificationListener.class));
- }
-
- @Test
- public void testHandleWithNoSubsequentOperations() throws Exception {
- final CreateSubscription createSubscription = new CreateSubscription("id", notificationRegistry);
- createSubscription.setSession(mock(NetconfSession.class));
-
- final Element e = XmlUtil.readXmlToElement(CREATE_SUBSCRIPTION_XML);
-
- final XmlElement operationElement = XmlElement.fromDomElement(e);
- final Element element = createSubscription.handleWithNoSubsequentOperations(XmlUtil.newDocument(), operationElement);
-
- Assert.assertThat(XmlUtil.toString(element), CoreMatchers.containsString("ok"));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.Streams;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.StreamsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamKey;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public class GetTest {
-
- @Test
- public void testSerializeStreamsSubtree() throws Exception {
- final StreamsBuilder streamsBuilder = new StreamsBuilder();
- final StreamBuilder streamBuilder = new StreamBuilder();
- final StreamNameType base = new StreamNameType("base");
- streamBuilder.setName(base);
- streamBuilder.setKey(new StreamKey(base));
- streamBuilder.setDescription("description");
- streamBuilder.setReplaySupport(false);
- streamsBuilder.setStream(Lists.newArrayList(streamBuilder.build()));
- final Streams streams = streamsBuilder.build();
-
- final Document response = getBlankResponse();
- Get.serializeStreamsSubtree(response, streams);
- NotificationsTransformUtilTest.compareXml(XmlUtil.toString(response),
- "<rpc-reply message-id=\"101\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<data>\n" +
- "<netconf xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">\n" +
- "<streams>\n" +
- "<stream>\n" +
- "<name>base</name>\n" +
- "<description>description</description>\n" +
- "<replaySupport>false</replaySupport>\n" +
- "</stream>\n" +
- "</streams>\n" +
- "</netconf>\n" +
- "</data>\n" +
- "</rpc-reply>\n");
- }
-
- private static Document getBlankResponse() throws IOException, SAXException {
-
- return XmlUtil.readXmlToDocument("<rpc-reply message-id=\"101\"\n" +
- "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<data>\n" +
- "</data>\n" +
- "</rpc-reply>");
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.notifications.impl.ops;
-
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import org.custommonkey.xmlunit.DetailedDiff;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
-import org.xml.sax.SAXException;
-
-public class NotificationsTransformUtilTest {
-
- private static final Date DATE = new Date();
- private static final String innerNotification = "<netconf-capability-change xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-notifications\">" +
- "<deleted-capability>uri4</deleted-capability>" +
- "<deleted-capability>uri3</deleted-capability>" +
- "<added-capability>uri1</added-capability>" +
- "</netconf-capability-change>";
-
- private static final String expectedNotification = "<notification xmlns=\"urn:ietf:params:netconf:capability:notification:1.0\">" +
- innerNotification +
- "<eventTime>" + new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT).format(DATE) + "</eventTime>" +
- "</notification>";
-
- @Test
- public void testTransform() throws Exception {
- final NetconfCapabilityChangeBuilder netconfCapabilityChangeBuilder = new NetconfCapabilityChangeBuilder();
-
- netconfCapabilityChangeBuilder.setAddedCapability(Lists.newArrayList(new Uri("uri1"), new Uri("uri1")));
- netconfCapabilityChangeBuilder.setDeletedCapability(Lists.newArrayList(new Uri("uri4"), new Uri("uri3")));
-
- final NetconfCapabilityChange capabilityChange = netconfCapabilityChangeBuilder.build();
- final NetconfNotification transform = NotificationsTransformUtil.transform(capabilityChange, DATE);
-
- final String serialized = XmlUtil.toString(transform.getDocument());
-
- compareXml(expectedNotification, serialized);
- }
-
- static void compareXml(final String expected, final String actual) throws SAXException, IOException {
- XMLUnit.setIgnoreWhitespace(true);
- final Diff diff = new Diff(expected, actual);
- final DetailedDiff detailedDiff = new DetailedDiff(diff);
- detailedDiff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
- assertTrue(detailedDiff.toString(), detailedDiff.similar());
- }
-
- @Test
- public void testTransformFromDOM() throws Exception {
- final NetconfNotification netconfNotification = new NetconfNotification(XmlUtil.readXmlToDocument(innerNotification), DATE);
-
- XMLUnit.setIgnoreWhitespace(true);
- compareXml(expectedNotification, netconfNotification.toString());
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-ssh</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-auth</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-config-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk15on</artifactId>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sshd</groupId>
- <artifactId>sshd-core</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.ssh.osgi.NetconfSSHActivator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-package org.opendaylight.controller.config.yang.netconf.northbound.ssh;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.local.LocalAddress;
-import io.netty.util.concurrent.GenericFutureListener;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.concurrent.Executors;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.controller.netconf.api.NetconfServerDispatcher;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfNorthboundSshModule extends org.opendaylight.controller.config.yang.netconf.northbound.ssh.AbstractNetconfNorthboundSshModule {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundSshModule.class);
-
- public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfNorthboundSshModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final org.opendaylight.controller.config.yang.netconf.northbound.ssh.NetconfNorthboundSshModule oldModule, final java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final NetconfServerDispatcher dispatch = getDispatcherDependency();
-
- final LocalAddress localAddress = new LocalAddress(getPort().toString());
- final ChannelFuture localServer = dispatch.createLocalServer(localAddress);
-
- final SshProxyServer sshProxyServer = new SshProxyServer(Executors.newScheduledThreadPool(1), getWorkerThreadGroupDependency(), getEventExecutorDependency());
-
- final InetSocketAddress bindingAddress = getInetAddress();
- final SshProxyServerConfigurationBuilder sshProxyServerConfigurationBuilder = new SshProxyServerConfigurationBuilder();
- sshProxyServerConfigurationBuilder.setBindingAddress(bindingAddress);
- sshProxyServerConfigurationBuilder.setLocalAddress(localAddress);
- sshProxyServerConfigurationBuilder.setAuthenticator(new UserAuthenticator(getUsername(), getPassword()));
- sshProxyServerConfigurationBuilder.setIdleTimeout(Integer.MAX_VALUE);
- sshProxyServerConfigurationBuilder.setKeyPairProvider(new PEMGeneratorHostKeyProvider());
-
- localServer.addListener(new GenericFutureListener<ChannelFuture>() {
-
- @Override
- public void operationComplete(final ChannelFuture future) {
- if(future.isDone() && !future.isCancelled()) {
- try {
- sshProxyServer.bind(sshProxyServerConfigurationBuilder.createSshProxyServerConfiguration());
- LOG.info("Netconf SSH endpoint started successfully at {}", bindingAddress);
- } catch (final IOException e) {
- throw new RuntimeException("Unable to start SSH netconf server", e);
- }
- } else {
- LOG.warn("Unable to start SSH netconf server at {}", bindingAddress, future.cause());
- throw new RuntimeException("Unable to start SSH netconf server", future.cause());
- }
- }
- });
-
- return new NetconfServerCloseable(localServer, sshProxyServer);
- }
-
- private InetSocketAddress getInetAddress() {
- try {
- final InetAddress inetAd = InetAddress.getByName(getBindingAddress().getIpv4Address() == null ? getBindingAddress().getIpv6Address().getValue() : getBindingAddress().getIpv4Address().getValue());
- return new InetSocketAddress(inetAd, getPort().getValue());
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + getBindingAddress(), e);
- }
- }
-
- private static final class NetconfServerCloseable implements AutoCloseable {
- private final ChannelFuture localServer;
- private final SshProxyServer sshProxyServer;
-
- public NetconfServerCloseable(final ChannelFuture localServer, final SshProxyServer sshProxyServer) {
- this.localServer = localServer;
- this.sshProxyServer = sshProxyServer;
- }
-
- @Override
- public void close() throws Exception {
- sshProxyServer.close();
-
- if(localServer.isDone()) {
- localServer.channel().close();
- } else {
- localServer.cancel(true);
- }
- }
- }
-
-
- private static final class UserAuthenticator implements PasswordAuthenticator {
-
- private final String username;
- private final String password;
-
- public UserAuthenticator(final String username, final String password) {
- this.username = username;
- this.password = password;
- }
-
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- // FIXME use aaa stuff here instead
- return this.username.equals(username) && this.password.equals(password);
- }
- }
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-northbound-ssh yang module local name: netconf-northbound-ssh
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Mon Feb 09 14:09:07 CET 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.netconf.northbound.ssh;
-public class NetconfNorthboundSshModuleFactory extends org.opendaylight.controller.config.yang.netconf.northbound.ssh.AbstractNetconfNorthboundSshModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh;
-
-import com.google.common.base.Preconditions;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import io.netty.util.concurrent.GenericFutureListener;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoOutputStream;
-import org.apache.sshd.server.AsyncCommand;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.Environment;
-import org.apache.sshd.server.ExitCallback;
-import org.apache.sshd.server.SessionAware;
-import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This command handles all netconf related rpc and forwards to delegate server.
- * Uses netty to make a local connection to delegate server.
- *
- * Command is Apache Mina SSH terminology for objects handling ssh data.
- */
-public class RemoteNetconfCommand implements AsyncCommand, SessionAware {
-
- private static final Logger LOG = LoggerFactory.getLogger(RemoteNetconfCommand.class);
-
- private final EventLoopGroup clientEventGroup;
- private final LocalAddress localAddress;
-
- private IoInputStream in;
- private IoOutputStream out;
- private ExitCallback callback;
- private NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
-
- private Channel clientChannel;
- private ChannelFuture clientChannelFuture;
-
- public RemoteNetconfCommand(final EventLoopGroup clientEventGroup, final LocalAddress localAddress) {
- this.clientEventGroup = clientEventGroup;
- this.localAddress = localAddress;
- }
-
- @Override
- public void setIoInputStream(final IoInputStream in) {
- this.in = in;
- }
-
- @Override
- public void setIoOutputStream(final IoOutputStream out) {
- this.out = out;
- }
-
- @Override
- public void setIoErrorStream(final IoOutputStream err) {
- // TODO do we want to use error stream in some way ?
- }
-
- @Override
- public void setInputStream(final InputStream in) {
- throw new UnsupportedOperationException("Synchronous IO is unsupported");
- }
-
- @Override
- public void setOutputStream(final OutputStream out) {
- throw new UnsupportedOperationException("Synchronous IO is unsupported");
-
- }
-
- @Override
- public void setErrorStream(final OutputStream err) {
- throw new UnsupportedOperationException("Synchronous IO is unsupported");
-
- }
-
- @Override
- public void setExitCallback(final ExitCallback callback) {
- this.callback = callback;
- }
-
- @Override
- public void start(final Environment env) throws IOException {
- LOG.trace("Establishing internal connection to netconf server for client: {}", getClientAddress());
-
- final Bootstrap clientBootstrap = new Bootstrap();
- clientBootstrap.group(clientEventGroup).channel(LocalChannel.class);
-
- clientBootstrap
- .handler(new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(final LocalChannel ch) throws Exception {
- ch.pipeline().addLast(new SshProxyClientHandler(in, out, netconfHelloMessageAdditionalHeader, callback));
- }
- });
- clientChannelFuture = clientBootstrap.connect(localAddress);
- clientChannelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
-
- @Override
- public void operationComplete(final ChannelFuture future) throws Exception {
- if(future.isSuccess()) {
- clientChannel = clientChannelFuture.channel();
- } else {
- LOG.warn("Unable to establish internal connection to netconf server for client: {}", getClientAddress());
- Preconditions.checkNotNull(callback, "Exit callback must be set");
- callback.onExit(1, "Unable to establish internal connection to netconf server for client: "+ getClientAddress());
- }
- }
- });
- }
-
- @Override
- public void destroy() {
- LOG.trace("Releasing internal connection to netconf server for client: {} on channel: {}",
- getClientAddress(), clientChannel);
-
- clientChannelFuture.cancel(true);
- if(clientChannel != null) {
- clientChannel.close().addListener(new GenericFutureListener<ChannelFuture>() {
-
- @Override
- public void operationComplete(final ChannelFuture future) throws Exception {
- if (future.isSuccess() == false) {
- LOG.warn("Unable to release internal connection to netconf server on channel: {}", clientChannel);
- }
- }
- });
- }
- }
-
- private String getClientAddress() {
- return netconfHelloMessageAdditionalHeader.getAddress();
- }
-
- @Override
- public void setSession(final ServerSession session) {
- final SocketAddress remoteAddress = session.getIoSession().getRemoteAddress();
- String hostName = "";
- String port = "";
- if(remoteAddress instanceof InetSocketAddress) {
- hostName = ((InetSocketAddress) remoteAddress).getAddress().getHostAddress();
- port = Integer.toString(((InetSocketAddress) remoteAddress).getPort());
- }
- netconfHelloMessageAdditionalHeader = new NetconfHelloMessageAdditionalHeader(
- session.getUsername(), hostName, port, "ssh", "client");
- }
-
- public static class NetconfCommandFactory implements NamedFactory<Command> {
-
- public static final String NETCONF = "netconf";
-
- private final EventLoopGroup clientBootstrap;
- private final LocalAddress localAddress;
-
- public NetconfCommandFactory(final EventLoopGroup clientBootstrap, final LocalAddress localAddress) {
-
- this.clientBootstrap = clientBootstrap;
- this.localAddress = localAddress;
- }
-
- @Override
- public String getName() {
- return NETCONF;
- }
-
- @Override
- public RemoteNetconfCommand create() {
- return new RemoteNetconfCommand(clientBootstrap, localAddress);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoOutputStream;
-import org.apache.sshd.server.ExitCallback;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerReader;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerWriter;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Netty handler that reads SSH from remote client and writes to delegate server and reads from delegate server and writes to remote client
- */
-final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {
-
- private static final Logger LOG = LoggerFactory.getLogger(SshProxyClientHandler.class);
-
- private final IoInputStream in;
- private final IoOutputStream out;
-
- private AsyncSshHandlerReader asyncSshHandlerReader;
- private AsyncSshHandlerWriter asyncSshHandlerWriter;
-
- private final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
- private final ExitCallback callback;
-
- public SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
- final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
- final ExitCallback callback) {
- this.in = in;
- this.out = out;
- this.netconfHelloMessageAdditionalHeader = netconfHelloMessageAdditionalHeader;
- this.callback = callback;
- }
-
- @Override
- public void channelActive(final ChannelHandlerContext ctx) throws Exception {
- writeAdditionalHeader(ctx);
-
- asyncSshHandlerWriter = new AsyncSshHandlerWriter(out);
- asyncSshHandlerReader = new AsyncSshHandlerReader(new AutoCloseable() {
- @Override
- public void close() throws Exception {
- // Close both sessions (delegate server and remote client)
- ctx.fireChannelInactive();
- ctx.disconnect();
- ctx.close();
- asyncSshHandlerReader.close();
- asyncSshHandlerWriter.close();
- }
- }, new AsyncSshHandlerReader.ReadMsgHandler() {
- @Override
- public void onMessageRead(final ByteBuf msg) {
- if(LOG.isTraceEnabled()) {
- LOG.trace("Forwarding message for client: {} on channel: {}, message: {}",
- netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(), AsyncSshHandlerWriter.byteBufToString(msg));
- }
- // Just forward to delegate
- ctx.writeAndFlush(msg);
- }
- }, "ssh" + netconfHelloMessageAdditionalHeader.getAddress(), in);
-
-
- super.channelActive(ctx);
- }
-
- private void writeAdditionalHeader(final ChannelHandlerContext ctx) {
- ctx.writeAndFlush(Unpooled.copiedBuffer(netconfHelloMessageAdditionalHeader.toFormattedString().getBytes()));
- }
-
- @Override
- public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
- asyncSshHandlerWriter.write(ctx, msg, ctx.newPromise());
- }
-
- @Override
- public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
- LOG.debug("Internal connection to netconf server was dropped for client: {} on channel: ",
- netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel());
- callback.onExit(1, "Internal connection to netconf server was dropped for client: " +
- netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
- super.channelInactive(ctx);
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh;
-
-import com.google.common.collect.Lists;
-import io.netty.channel.EventLoopGroup;
-import java.io.IOException;
-import java.nio.channels.AsynchronousChannelGroup;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import org.apache.sshd.SshServer;
-import org.apache.sshd.common.Cipher;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.RuntimeSshException;
-import org.apache.sshd.common.cipher.ARCFOUR128;
-import org.apache.sshd.common.cipher.ARCFOUR256;
-import org.apache.sshd.common.io.IoAcceptor;
-import org.apache.sshd.common.io.IoConnector;
-import org.apache.sshd.common.io.IoHandler;
-import org.apache.sshd.common.io.IoServiceFactory;
-import org.apache.sshd.common.io.IoServiceFactoryFactory;
-import org.apache.sshd.common.io.nio2.Nio2Acceptor;
-import org.apache.sshd.common.io.nio2.Nio2Connector;
-import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
-import org.apache.sshd.common.util.CloseableUtils;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.ServerFactoryManager;
-
-/**
- * Proxy SSH server that just delegates decrypted content to a delegate server within same VM.
- * Implemented using Apache Mina SSH lib.
- */
-public class SshProxyServer implements AutoCloseable {
-
- private static final ARCFOUR128.Factory DEFAULT_ARCFOUR128_FACTORY = new ARCFOUR128.Factory();
- private static final ARCFOUR256.Factory DEFAULT_ARCFOUR256_FACTORY = new ARCFOUR256.Factory();
- private final SshServer sshServer;
- private final ScheduledExecutorService minaTimerExecutor;
- private final EventLoopGroup clientGroup;
- private final IoServiceFactoryFactory nioServiceWithPoolFactoryFactory;
-
- public SshProxyServer(final ScheduledExecutorService minaTimerExecutor, final EventLoopGroup clientGroup, final ExecutorService nioExecutor) {
- this.minaTimerExecutor = minaTimerExecutor;
- this.clientGroup = clientGroup;
- this.nioServiceWithPoolFactoryFactory = new NioServiceWithPoolFactory.NioServiceWithPoolFactoryFactory(nioExecutor);
- this.sshServer = SshServer.setUpDefaultServer();
- }
-
- public void bind(final SshProxyServerConfiguration sshProxyServerConfiguration) throws IOException {
- sshServer.setHost(sshProxyServerConfiguration.getBindingAddress().getHostString());
- sshServer.setPort(sshProxyServerConfiguration.getBindingAddress().getPort());
-
- //remove rc4 ciphers
- final List<NamedFactory<Cipher>> cipherFactories = sshServer.getCipherFactories();
- for (Iterator<NamedFactory<Cipher>> i = cipherFactories.iterator(); i.hasNext(); ) {
- final NamedFactory<Cipher> factory = i.next();
- if (factory.getName().contains(DEFAULT_ARCFOUR128_FACTORY.getName())
- || factory.getName().contains(DEFAULT_ARCFOUR256_FACTORY.getName())) {
- i.remove();
- }
- }
- sshServer.setPasswordAuthenticator(sshProxyServerConfiguration.getAuthenticator());
- sshServer.setKeyPairProvider(sshProxyServerConfiguration.getKeyPairProvider());
-
- sshServer.setIoServiceFactoryFactory(nioServiceWithPoolFactoryFactory);
- sshServer.setScheduledExecutorService(minaTimerExecutor);
- sshServer.setProperties(getProperties(sshProxyServerConfiguration));
-
- final RemoteNetconfCommand.NetconfCommandFactory netconfCommandFactory =
- new RemoteNetconfCommand.NetconfCommandFactory(clientGroup, sshProxyServerConfiguration.getLocalAddress());
- sshServer.setSubsystemFactories(Lists.<NamedFactory<Command>>newArrayList(netconfCommandFactory));
- sshServer.start();
- }
-
- private static Map<String, String> getProperties(final SshProxyServerConfiguration sshProxyServerConfiguration) {
- return new HashMap<String, String>()
- {
- {
- put(ServerFactoryManager.IDLE_TIMEOUT, String.valueOf(sshProxyServerConfiguration.getIdleTimeout()));
- // TODO make auth timeout configurable on its own
- put(ServerFactoryManager.AUTH_TIMEOUT, String.valueOf(sshProxyServerConfiguration.getIdleTimeout()));
- }
- };
- }
-
- @Override
- public void close() {
- try {
- sshServer.stop(true);
- } catch (final InterruptedException e) {
- throw new RuntimeException("Interrupted while stopping sshServer", e);
- } finally {
- sshServer.close(true);
- }
- }
-
- /**
- * Based on Nio2ServiceFactory with one addition: injectable executor
- */
- private static final class NioServiceWithPoolFactory extends CloseableUtils.AbstractCloseable implements IoServiceFactory {
-
- private final FactoryManager manager;
- private final AsynchronousChannelGroup group;
-
- public NioServiceWithPoolFactory(final FactoryManager manager, final ExecutorService executor) {
- this.manager = manager;
- try {
- group = AsynchronousChannelGroup.withThreadPool(executor);
- } catch (final IOException e) {
- throw new RuntimeSshException(e);
- }
- }
-
- public IoConnector createConnector(final IoHandler handler) {
- return new Nio2Connector(manager, handler, group);
- }
-
- public IoAcceptor createAcceptor(final IoHandler handler) {
- return new Nio2Acceptor(manager, handler, group);
- }
-
- @Override
- protected void doCloseImmediately() {
- try {
- group.shutdownNow();
- group.awaitTermination(5, TimeUnit.SECONDS);
- } catch (final Exception e) {
- log.debug("Exception caught while closing channel group", e);
- } finally {
- super.doCloseImmediately();
- }
- }
-
- private static final class NioServiceWithPoolFactoryFactory extends Nio2ServiceFactoryFactory {
-
- private final ExecutorService nioExecutor;
-
- private NioServiceWithPoolFactoryFactory(final ExecutorService nioExecutor) {
- this.nioExecutor = nioExecutor;
- }
-
- @Override
- public IoServiceFactory create(final FactoryManager manager) {
- return new NioServiceWithPoolFactory(manager, nioExecutor);
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-import org.apache.sshd.common.KeyPairProvider;
-import org.apache.sshd.server.PasswordAuthenticator;
-
-public final class SshProxyServerConfiguration {
- private final InetSocketAddress bindingAddress;
- private final LocalAddress localAddress;
- private final PasswordAuthenticator authenticator;
- private final KeyPairProvider keyPairProvider;
- private final int idleTimeout;
-
- SshProxyServerConfiguration(final InetSocketAddress bindingAddress, final LocalAddress localAddress, final PasswordAuthenticator authenticator, final KeyPairProvider keyPairProvider, final int idleTimeout) {
- this.bindingAddress = Preconditions.checkNotNull(bindingAddress);
- this.localAddress = Preconditions.checkNotNull(localAddress);
- this.authenticator = Preconditions.checkNotNull(authenticator);
- this.keyPairProvider = Preconditions.checkNotNull(keyPairProvider);
- // Idle timeout cannot be disabled in the sshd by using =< 0 value
- Preconditions.checkArgument(idleTimeout > 0, "Idle timeout has to be > 0");
- this.idleTimeout = idleTimeout;
- }
-
- public InetSocketAddress getBindingAddress() {
- return bindingAddress;
- }
-
- public LocalAddress getLocalAddress() {
- return localAddress;
- }
-
- public PasswordAuthenticator getAuthenticator() {
- return authenticator;
- }
-
- public KeyPairProvider getKeyPairProvider() {
- return keyPairProvider;
- }
-
- public int getIdleTimeout() {
- return idleTimeout;
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh;
-
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-import org.apache.sshd.common.KeyPairProvider;
-import org.apache.sshd.server.PasswordAuthenticator;
-
-public final class SshProxyServerConfigurationBuilder {
- private InetSocketAddress bindingAddress;
- private LocalAddress localAddress;
- private PasswordAuthenticator authenticator;
- private KeyPairProvider keyPairProvider;
- private int idleTimeout;
-
- public SshProxyServerConfigurationBuilder setBindingAddress(final InetSocketAddress bindingAddress) {
- this.bindingAddress = bindingAddress;
- return this;
- }
-
- public SshProxyServerConfigurationBuilder setLocalAddress(final LocalAddress localAddress) {
- this.localAddress = localAddress;
- return this;
- }
-
- public SshProxyServerConfigurationBuilder setAuthenticator(final PasswordAuthenticator authenticator) {
- this.authenticator = authenticator;
- return this;
- }
-
- public SshProxyServerConfigurationBuilder setKeyPairProvider(final KeyPairProvider keyPairProvider) {
- this.keyPairProvider = keyPairProvider;
- return this;
- }
-
- public SshProxyServerConfigurationBuilder setIdleTimeout(final int idleTimeout) {
- this.idleTimeout = idleTimeout;
- return this;
- }
-
- public SshProxyServerConfiguration createSshProxyServerConfiguration() {
- return new SshProxyServerConfiguration(bindingAddress, localAddress, authenticator, keyPairProvider, idleTimeout);
- }
-
- public static SshProxyServerConfigurationBuilder create() {
- return new SshProxyServerConfigurationBuilder();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.ssh.osgi;
-
-import com.google.common.base.Preconditions;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.controller.netconf.auth.AuthConstants;
-import org.opendaylight.controller.netconf.auth.AuthProvider;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class AuthProviderTracker implements ServiceTrackerCustomizer<AuthProvider, AuthProvider>, PasswordAuthenticator {
- private static final Logger LOG = LoggerFactory.getLogger(AuthProviderTracker.class);
-
- private final BundleContext bundleContext;
-
- private Integer maxPreference;
- private final ServiceTracker<AuthProvider, AuthProvider> listenerTracker;
- private AuthProvider authProvider;
-
- public AuthProviderTracker(final BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- listenerTracker = new ServiceTracker<>(bundleContext, AuthProvider.class, this);
- listenerTracker.open();
- }
-
- @Override
- public AuthProvider addingService(final ServiceReference<AuthProvider> reference) {
- LOG.trace("Service {} added", reference);
- final AuthProvider authService = bundleContext.getService(reference);
- final Integer newServicePreference = getPreference(reference);
- if(isBetter(newServicePreference)) {
- maxPreference = newServicePreference;
- this.authProvider = authService;
- }
- return authService;
- }
-
- private static Integer getPreference(final ServiceReference<AuthProvider> reference) {
- final Object preferenceProperty = reference.getProperty(AuthConstants.SERVICE_PREFERENCE_KEY);
- return preferenceProperty == null ? Integer.MIN_VALUE : Integer.valueOf(preferenceProperty.toString());
- }
-
- private boolean isBetter(final Integer newServicePreference) {
- Preconditions.checkNotNull(newServicePreference);
- if(maxPreference == null) {
- return true;
- }
-
- return newServicePreference > maxPreference;
- }
-
- @Override
- public void modifiedService(final ServiceReference<AuthProvider> reference, final AuthProvider service) {
- final AuthProvider authService = bundleContext.getService(reference);
- final Integer newServicePreference = getPreference(reference);
- if(isBetter(newServicePreference)) {
- LOG.trace("Replacing modified service {} in netconf SSH.", reference);
- this.authProvider = authService;
- }
- }
-
- @Override
- public void removedService(final ServiceReference<AuthProvider> reference, final AuthProvider service) {
- LOG.trace("Removing service {} from netconf SSH. {}", reference,
- " SSH won't authenticate users until AuthProvider service will be started.");
- maxPreference = null;
- this.authProvider = null;
- }
-
- public void stop() {
- listenerTracker.close();
- // sshThread should finish normally since sshServer.close stops processing
- }
-
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- if (authProvider == null) {
- LOG.warn("AuthProvider is missing, failing authentication");
- return false;
- }
- return authProvider.authenticated(username, password);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.ssh.osgi;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Strings;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import org.apache.sshd.common.util.ThreadUtils;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.InfixProp;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfSSHActivator implements BundleActivator {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfSSHActivator.class);
-
- private static final java.lang.String ALGORITHM = "RSA";
- private static final int KEY_SIZE = 4096;
- public static final int POOL_SIZE = 8;
- private static final int DEFAULT_IDLE_TIMEOUT = Integer.MAX_VALUE;
-
- private ScheduledExecutorService minaTimerExecutor;
- private NioEventLoopGroup clientGroup;
- private ExecutorService nioExecutor;
- private AuthProviderTracker authProviderTracker;
-
- private SshProxyServer server;
-
- @Override
- public void start(final BundleContext bundleContext) throws IOException {
- minaTimerExecutor = Executors.newScheduledThreadPool(POOL_SIZE, new ThreadFactory() {
- @Override
- public Thread newThread(final Runnable r) {
- return new Thread(r, "netconf-ssh-server-mina-timers");
- }
- });
- clientGroup = new NioEventLoopGroup();
- nioExecutor = ThreadUtils.newFixedThreadPool("netconf-ssh-server-nio-group", POOL_SIZE);
- server = startSSHServer(bundleContext);
- }
-
- @Override
- public void stop(final BundleContext context) throws IOException {
- if (server != null) {
- server.close();
- }
-
- if(authProviderTracker != null) {
- authProviderTracker.stop();
- }
-
- if(nioExecutor!=null) {
- nioExecutor.shutdownNow();
- }
-
- if(clientGroup != null) {
- clientGroup.shutdownGracefully();
- }
-
- if(minaTimerExecutor != null) {
- minaTimerExecutor.shutdownNow();
- }
- }
-
- private SshProxyServer startSSHServer(final BundleContext bundleContext) throws IOException {
- final Optional<InetSocketAddress> maybeSshSocketAddress = NetconfConfigUtil.extractNetconfServerAddress(bundleContext, InfixProp.ssh);
-
- if (!maybeSshSocketAddress.isPresent()) {
- LOG.trace("SSH bridge not configured");
- return null;
- }
-
- final InetSocketAddress sshSocketAddress = maybeSshSocketAddress.get();
- LOG.trace("Starting netconf SSH bridge at {}", sshSocketAddress);
-
- final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
-
- authProviderTracker = new AuthProviderTracker(bundleContext);
-
- final String path = NetconfConfigUtil.getPrivateKeyPath(bundleContext);
-
- checkState(!Strings.isNullOrEmpty(path), "Path to ssh private key is blank. Reconfigure %s",
- NetconfConfigUtil.getPrivateKeyKey());
-
- final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerExecutor, clientGroup, nioExecutor);
- sshProxyServer.bind(
- new SshProxyServerConfigurationBuilder()
- .setBindingAddress(sshSocketAddress)
- .setLocalAddress(localAddress)
- .setAuthenticator(authProviderTracker)
- .setKeyPairProvider(new PEMGeneratorHostKeyProvider(path, ALGORITHM, KEY_SIZE))
- .setIdleTimeout(DEFAULT_IDLE_TIMEOUT)
- .createSshProxyServerConfiguration());
- return sshProxyServer;
- }
-
-}
+++ /dev/null
-module netconf-northbound-ssh {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:ssh";
- prefix "nni";
-
- import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
- import netconf-northbound { prefix nn; revision-date 2015-01-14; }
- import config { prefix config; revision-date 2013-04-05; }
- import threadpool {prefix th;}
- import netty {prefix netty;}
- import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
-
- organization "Cisco Systems, Inc.";
-
- description
- "This module contains the base YANG definitions for
- a default implementation of netconf northbound server";
-
- revision "2015-01-14" {
- description
- "Initial revision.";
- }
-
- identity netconf-northbound-ssh {
- base config:module-type;
- config:java-name-prefix NetconfNorthboundSsh;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-northbound-ssh {
- when "/config:modules/config:module/config:type = 'netconf-northbound-ssh'";
-
- leaf port {
- type inet:port-number;
- default 2830;
- }
-
- leaf binding-address {
- type inet:ip-address;
- default "0.0.0.0";
- }
-
- container processing-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity th:scheduled-threadpool;
- }
- }
-
- description "Required by the mina-ssh library used in SSH endpoint";
- }
-
- container event-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity netty:netty-event-executor;
- }
- }
- }
-
- container worker-thread-group {
- uses config:service-ref {
- refine type {
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- container dispatcher {
- uses config:service-ref {
- refine type {
- config:required-identity nn:netconf-server-dispatcher;
- }
- }
- }
-
- // FIXME use auth provider from aaa instead
- leaf username {
- description "Specifies username credential";
- type string;
- }
-
- leaf password {
- description "Specifies password credential";
- type string;
- }
-
-
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import io.netty.channel.nio.NioEventLoopGroup;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Sends one message when a connection is open and echoes back any received
- * data to the server. Simply put, the echo client initiates the ping-pong
- * traffic between the echo client and server by sending the first message to
- * the server.
- */
-public class EchoClient extends Thread {
- private static final Logger LOG = LoggerFactory.getLogger(EchoClient.class);
-
-
- private final ChannelInitializer<LocalChannel> channelInitializer;
-
-
- public EchoClient(final ChannelHandler clientHandler) {
- channelInitializer = new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(LocalChannel ch) throws Exception {
- ch.pipeline().addLast(clientHandler);
- }
- };
- }
-
- public EchoClient(ChannelInitializer<LocalChannel> channelInitializer) {
- this.channelInitializer = channelInitializer;
- }
-
- @Override
- public void run() {
- // Configure the client.
- EventLoopGroup group = new NioEventLoopGroup();
- try {
- Bootstrap b = new Bootstrap();
-
- b.group(group)
- .channel(LocalChannel.class)
- .handler(channelInitializer);
-
- // Start the client.
- LocalAddress localAddress = new LocalAddress("foo");
- ChannelFuture f = b.connect(localAddress).sync();
-
- // Wait until the connection is closed.
- f.channel().closeFuture().sync();
- } catch (Exception e) {
- LOG.error("Error in client", e);
- throw new RuntimeException("Error in client", e);
- } finally {
- // Shut down the event loop to terminate all threads.
- LOG.info("Client is shutting down");
- group.shutdownGracefully();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.base.Charsets;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Handler implementation for the echo client. It initiates the ping-pong
- * traffic between the echo client and server by sending the first message to
- * the server.
- */
-public class EchoClientHandler extends ChannelInboundHandlerAdapter implements ChannelFutureListener {
- private static final Logger LOG = LoggerFactory.getLogger(EchoClientHandler.class);
-
- private ChannelHandlerContext ctx;
- private final StringBuilder fromServer = new StringBuilder();
-
- public static enum State {CONNECTING, CONNECTED, FAILED_TO_CONNECT, CONNECTION_CLOSED}
-
-
- private State state = State.CONNECTING;
-
- @Override
- public synchronized void channelActive(ChannelHandlerContext ctx) {
- checkState(this.ctx == null);
- LOG.info("channelActive");
- this.ctx = ctx;
- state = State.CONNECTED;
- }
-
- @Override
- public synchronized void channelInactive(ChannelHandlerContext ctx) throws Exception {
- state = State.CONNECTION_CLOSED;
- }
-
- @Override
- public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- ByteBuf bb = (ByteBuf) msg;
- String string = bb.toString(Charsets.UTF_8);
- fromServer.append(string);
- LOG.info(">{}", string);
- bb.release();
- }
-
- @Override
- public synchronized void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream.", cause);
- checkState(this.ctx.equals(ctx));
- ctx.close();
- this.ctx = null;
- }
-
- public synchronized void write(String message) {
- ByteBuf byteBuf = Unpooled.copiedBuffer(message.getBytes());
- ctx.writeAndFlush(byteBuf);
- }
-
- public synchronized boolean isConnected() {
- return state == State.CONNECTED;
- }
-
- public synchronized String read() {
- return fromServer.toString();
- }
-
- @Override
- public synchronized void operationComplete(ChannelFuture future) throws Exception {
- checkState(state == State.CONNECTING);
- if (future.isSuccess()) {
- LOG.trace("Successfully connected, state will be switched in channelActive");
- } else {
- state = State.FAILED_TO_CONNECT;
- }
- }
-
- public State getState() {
- return state;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import io.netty.channel.local.LocalServerChannel;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Echoes back any received data from a client.
- */
-public class EchoServer implements Runnable {
- private static final Logger LOG = LoggerFactory.getLogger(EchoServer.class);
-
- public void run() {
- // Configure the server.
- EventLoopGroup bossGroup = new NioEventLoopGroup(1);
- EventLoopGroup workerGroup = new NioEventLoopGroup();
- try {
- ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup)
- .channel(LocalServerChannel.class)
- .option(ChannelOption.SO_BACKLOG, 100)
- .handler(new LoggingHandler(LogLevel.INFO))
- .childHandler(new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(LocalChannel ch) throws Exception {
- ch.pipeline().addLast(new EchoServerHandler());
- }
- });
-
- // Start the server.
- LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
- ChannelFuture f = b.bind(localAddress).sync();
-
- // Wait until the server socket is closed.
- f.channel().closeFuture().sync();
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- // Shut down all event loops to terminate all threads.
- bossGroup.shutdownGracefully();
- workerGroup.shutdownGracefully();
- }
- }
-
- public static void main(String[] args) throws Exception {
- new Thread(new EchoServer()).start();
- Thread.sleep(1000);
- EchoClientHandler clientHandler = new EchoClientHandler();
- EchoClient echoClient = new EchoClient(clientHandler);
- new Thread(echoClient).start();
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- do {
- String message = reader.readLine();
- if (message == null || "exit".equalsIgnoreCase(message)) {
- break;
- }
- LOG.debug("Got '{}'", message);
- clientHandler.write(message);
- } while (true);
- System.exit(0);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Splitter;
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Handler implementation for the echo server.
- */
-@Sharable
-public class EchoServerHandler extends ChannelInboundHandlerAdapter {
-
- private static final Logger LOG = LoggerFactory.getLogger(EchoServerHandler.class);
- private String fromLastNewLine = "";
- private final Splitter splitter = Splitter.onPattern("\r?\n");
- @Override
- public void channelActive(ChannelHandlerContext ctx) throws Exception {
- LOG.debug("sleep start");
- Thread.sleep(1000);
- LOG.debug("sleep done");
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
- ByteBuf byteBuf = (ByteBuf) msg;
- String message = byteBuf.toString(Charsets.UTF_8);
- LOG.info("writing back '{}'", message);
- ctx.write(msg);
- fromLastNewLine += message;
- for (String line : splitter.split(fromLastNewLine)) {
- if ("quit".equals(line)) {
- LOG.info("closing server ctx");
- ctx.flush();
- ctx.close();
- break;
- }
- fromLastNewLine = line; // last line should be preserved
- }
-
- // do not release byteBuf as it is handled back
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- LOG.debug("flushing");
- ctx.flush();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-
-public class ProxyServer implements Runnable {
- private final ProxyHandlerFactory proxyHandlerFactory;
-
- public ProxyServer(ProxyHandlerFactory proxyHandlerFactory) {
- this.proxyHandlerFactory = proxyHandlerFactory;
- }
-
- public void run() {
- // Configure the server.
- final EventLoopGroup bossGroup = new NioEventLoopGroup();
- EventLoopGroup workerGroup = new NioEventLoopGroup();
- try {
- final LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress();
- ServerBootstrap serverBootstrap = new ServerBootstrap();
- serverBootstrap.group(bossGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .option(ChannelOption.SO_BACKLOG, 100)
- .handler(new LoggingHandler(LogLevel.INFO))
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- ch.pipeline().addLast(proxyHandlerFactory.create(bossGroup, localAddress));
- }
- });
-
- // Start the server.
- InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8080);
- ChannelFuture f = serverBootstrap.bind(address).sync();
-
- // Wait until the server socket is closed.
- f.channel().closeFuture().sync();
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- // Shut down all event loops to terminate all threads.
- bossGroup.shutdownGracefully();
- workerGroup.shutdownGracefully();
- }
- }
- public static interface ProxyHandlerFactory {
- ChannelHandler create(EventLoopGroup bossGroup, LocalAddress localAddress);
- }
-
- public static void main(String[] args) {
- ProxyHandlerFactory proxyHandlerFactory = new ProxyHandlerFactory() {
- @Override
- public ChannelHandler create(EventLoopGroup bossGroup, LocalAddress localAddress) {
- return new ProxyServerHandler(bossGroup, localAddress);
- }
- };
- start(proxyHandlerFactory);
- }
-
- public static void start(ProxyHandlerFactory proxyHandlerFactory) {
- new Thread(new EchoServer()).start();
- new Thread(new ProxyServer(proxyHandlerFactory)).start();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import com.google.common.base.Charsets;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProxyServerHandler extends ChannelInboundHandlerAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProxyServerHandler.class);
- private final Bootstrap clientBootstrap;
- private final LocalAddress localAddress;
-
-
- private Channel clientChannel;
-
- public ProxyServerHandler(EventLoopGroup bossGroup, LocalAddress localAddress) {
- clientBootstrap = new Bootstrap();
- clientBootstrap.group(bossGroup).channel(LocalChannel.class);
- this.localAddress = localAddress;
- }
-
- @Override
- public void channelActive(ChannelHandlerContext remoteCtx) {
- final ProxyClientHandler clientHandler = new ProxyClientHandler(remoteCtx);
- clientBootstrap.handler(new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(LocalChannel ch) throws Exception {
- ch.pipeline().addLast(clientHandler);
- }
- });
- ChannelFuture clientChannelFuture = clientBootstrap.connect(localAddress).awaitUninterruptibly();
- clientChannel = clientChannelFuture.channel();
- clientChannel.writeAndFlush(Unpooled.copiedBuffer("connected\n".getBytes()));
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) {
- LOG.info("channelInactive - closing client connection");
- clientChannel.close();
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, final Object msg) {
- LOG.debug("Writing to client {}", msg);
- clientChannel.write(msg);
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- LOG.debug("flushing");
- clientChannel.flush();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream.", cause);
- ctx.close();
- }
-}
-
-class ProxyClientHandler extends ChannelInboundHandlerAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
-
- private final ChannelHandlerContext remoteCtx;
-
-
- public ProxyClientHandler(ChannelHandlerContext remoteCtx) {
- this.remoteCtx = remoteCtx;
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) {
- LOG.info("client active");
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- ByteBuf bb = (ByteBuf) msg;
- LOG.info(">{}", bb.toString(Charsets.UTF_8));
- remoteCtx.write(msg);
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- LOG.debug("Flushing server ctx");
- remoteCtx.flush();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream", cause);
- ctx.close();
- }
-
- // called both when local or remote connection dies
- @Override
- public void channelInactive(ChannelHandlerContext ctx) {
- LOG.debug("channelInactive() called, closing remote client ctx");
- remoteCtx.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.netty;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.base.Stopwatch;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.util.HashedWheelTimer;
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.nio.file.Files;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.netty.EchoClientHandler.State;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SSHTest {
- private static final Logger LOG = LoggerFactory.getLogger(SSHTest.class);
- public static final String AHOJ = "ahoj\n";
-
- private static EventLoopGroup nettyGroup;
- private static HashedWheelTimer hashedWheelTimer;
- private static ExecutorService nioExec;
- private static ScheduledExecutorService minaTimerEx;
-
- @BeforeClass
- public static void setUp() throws Exception {
- hashedWheelTimer = new HashedWheelTimer();
- nettyGroup = new NioEventLoopGroup();
- nioExec = Executors.newFixedThreadPool(1);
- minaTimerEx = Executors.newScheduledThreadPool(1);
- }
-
- @AfterClass
- public static void tearDown() throws Exception {
- hashedWheelTimer.stop();
- nettyGroup.shutdownGracefully().await(5, TimeUnit.SECONDS);
- minaTimerEx.shutdownNow();
- nioExec.shutdownNow();
- }
-
- @Test
- public void test() throws Exception {
- File sshKeyPair = Files.createTempFile("sshKeyPair", ".pem").toFile();
- sshKeyPair.deleteOnExit();
- new Thread(new EchoServer(), "EchoServer").start();
-
- final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
- final SshProxyServer sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec);
- sshProxyServer.bind(
- new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- return true;
- }
- }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
-
- final EchoClientHandler echoClientHandler = connectClient(addr);
-
- Stopwatch stopwatch = Stopwatch.createStarted();
- while(echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
- Thread.sleep(500);
- }
- assertTrue(echoClientHandler.isConnected());
- LOG.info("connected, writing to client");
- echoClientHandler.write(AHOJ);
-
- // check that server sent back the same string
- stopwatch = stopwatch.reset().start();
- while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
- Thread.sleep(500);
- }
-
- try {
- final String read = echoClientHandler.read();
- assertTrue(read + " should end with " + AHOJ, read.endsWith(AHOJ));
- } finally {
- LOG.info("Closing socket");
- sshProxyServer.close();
- }
- }
-
- public EchoClientHandler connectClient(final InetSocketAddress address) {
- final EchoClientHandler echoClientHandler = new EchoClientHandler();
- final ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<NioSocketChannel>() {
- @Override
- public void initChannel(final NioSocketChannel ch) throws Exception {
- ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(new LoginPassword("a", "a")));
- ch.pipeline().addLast(echoClientHandler);
- }
- };
- final Bootstrap b = new Bootstrap();
-
- b.group(nettyGroup)
- .channel(NioSocketChannel.class)
- .handler(channelInitializer);
-
- // Start the client.
- b.connect(address).addListener(echoClientHandler);
- return echoClientHandler;
- }
-
- @Test
- public void testClientWithoutServer() throws Exception {
- final InetSocketAddress address = new InetSocketAddress(12345);
- final EchoClientHandler echoClientHandler = connectClient(address);
- final Stopwatch stopwatch = Stopwatch.createStarted();
- while(echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
- Thread.sleep(100);
- }
- assertFalse(echoClientHandler.isConnected());
- assertEquals(State.FAILED_TO_CONNECT, echoClientHandler.getState());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.ssh.authentication;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import java.io.File;
-import java.net.InetSocketAddress;
-import java.nio.file.Files;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
-import org.apache.sshd.client.future.AuthFuture;
-import org.apache.sshd.client.future.ConnectFuture;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public class SSHServerTest {
-
- private static final String USER = "netconf";
- private static final String PASSWORD = "netconf";
- private static final String HOST = "127.0.0.1";
- private static final int PORT = 1830;
- private static final Logger LOG = LoggerFactory.getLogger(SSHServerTest.class);
-
- private File sshKeyPair;
- private SshProxyServer server;
-
- @Mock
- private BundleContext mockedContext;
- private final ExecutorService nioExec = Executors.newFixedThreadPool(1);
- private final EventLoopGroup clientGroup = new NioEventLoopGroup();
- private final ScheduledExecutorService minaTimerEx = Executors.newScheduledThreadPool(1);
-
- @Before
- public void setUp() throws Exception {
- sshKeyPair = Files.createTempFile("sshKeyPair", ".pem").toFile();
- sshKeyPair.deleteOnExit();
-
- MockitoAnnotations.initMocks(this);
- doReturn(null).when(mockedContext).createFilter(anyString());
- doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
- doReturn(new ServiceReference[0]).when(mockedContext).getServiceReferences(anyString(), anyString());
-
- LOG.info("Creating SSH server");
-
- final InetSocketAddress addr = InetSocketAddress.createUnresolved(HOST, PORT);
- server = new SshProxyServer(minaTimerEx, clientGroup, nioExec);
- server.bind(
- new SshProxyServerConfigurationBuilder().setBindingAddress(addr).setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress()).setAuthenticator(new PasswordAuthenticator() {
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- return true;
- }
- }).setKeyPairProvider(new PEMGeneratorHostKeyProvider(sshKeyPair.toPath().toAbsolutePath().toString())).setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
- LOG.info("SSH server started on {}", PORT);
- }
-
- @Test
- public void connect() throws Exception {
- final SshClient sshClient = SshClient.setUpDefaultClient();
- sshClient.start();
- try {
- final ConnectFuture connect = sshClient.connect(USER, HOST, PORT);
- connect.await(30, TimeUnit.SECONDS);
- org.junit.Assert.assertTrue(connect.isConnected());
- final ClientSession session = connect.getSession();
- session.addPasswordIdentity(PASSWORD);
- final AuthFuture auth = session.auth();
- auth.await(30, TimeUnit.SECONDS);
- org.junit.Assert.assertTrue(auth.isSuccess());
- } finally {
- sshClient.close(true);
- server.close();
- clientGroup.shutdownGracefully().await();
- minaTimerEx.shutdownNow();
- nioExec.shutdownNow();
- }
- }
-
-}
+++ /dev/null
------BEGIN RSA PRIVATE KEY-----
-MIIEogIBAAKCAQEAuC9hbEacpewvylI0mwFwjy3Wou2hpr/ncN9BBiFDSaG5yW2k
-3Oy+SCAcFCL+ZKWb6cc6Ch4gUeCwyEHRojZguuhliKtak9YQf6qbvpPLe00842Lx
-iqNAGurMpzizCDsGFq8ChaAkBZQI3TvcHuPoSUWSMJ+K8xHpRyUdVr6g2yEjezKJ
-sTXBtWaeCCh6YUafFujuDJk7fvYcPW7Je5KRBBStIKvxcMW0zB+7eq04deTHwGbJ
-gGjKWilQ72hsDDP3Hbp5CJMAYg1r4GlCmFx3KyHRGztgWgNgaD7nNpKCkTLjtmA6
-b4x7TA+jrzZ6Af2z5TMrI4dv5w1SrxHaZ+ziLQIDAQABAoIBAHTndeGgq/rQf8De
-Do+4CTaHtK0zQSAyu/azbXUzlZ7drKuCEVs8VMY4wzmwwGEnkF+A2YDkgEUX5X0l
-8aYQ97KKoS9u+43MGCrAIhyDeGrpqlT1TzRcy+qJz53v6gq2U/X/3QztiQ+VV078
-mIluxNgE9XYxPaNsYfGLSCTv1+9c8y/hjGVX2kwFK+u4ut0ZZETggNa8UxfaHVDS
-fIJQX9Gm3J3GSUV30fDGMBIUW6ESLc2L8b7u8Mp9TRP39ZeQSuEUjBe8MYKv0Rel
-oEpjZvcnniMTpFbLpndBYn7/AoIiEBvtCN8faVTuRRcvvLcsRm09IctzKQYnMh6M
-6PLKV+ECgYEA8HFRYaKHUzxpzE/fyon82GQbzqFFY0/bbWrfWICMfNbIgshJUie6
-FmH5iUFMfeqaT7v557HFM0GB9FeIeSbvd88YmiBAcRopZ3DfMkDH+DT73yJ+/TKG
-2nrQtdhyuTIs4bwHqeS2BBJYs7PK9R2rratF3l34Tf7mjlvyOgygHdUCgYEAxBo2
-8hEBlAVNcNb1hTYUxe1w1B6675/mFlmw98Xmj9dRYfICXNhahs8tX3/lsBEd+vBu
-fI0oyHaff8m5bPgGzD1ZMybfeROujNrgxaKVk7Ef0FDRRCop4bm18OroFlFAt9l8
-wMp++ToACbdvQvL/mjWMPYlIxhB/YxHswICZZvkCgYAexxKYwdo6sGAGlC7cWT9x
-X5cjowcjyEQZRHXkeUgCbufpvcOM7aLnXJE5nY8yCwbHsBM0MlBA2GDPKylAANjk
-aDEJAZneIHAuWodngl1Wi0m2bU7+ECqs6s2uiU9eH2sZVh1RBQK7kLGkBx6ys6KX
-L3ZZGYRAT6GplWFzRsx0JQKBgCeVlxPD5QqpC1nEumi6YvUVGdpnnZpzL3HBhxxs
-wT612wKnZFyze4qM1X7ahVXGDsQxtkvD/sCAWW/lG13orw6ZL6FIroF1PJ3ILOkY
-CZN3hJF7TtKwpCWhZB2OfWzL2AGEkE8mUP0j/Q/5DCd6f6f0OSvOw3bfq6cm3iB5
-lP2ZAoGAXsRN5TZTX4AQ2xTlrDQ8A5XgcvyWQpJOmEXMTyHV7VaJVzmNWFVAvndK
-5UIq8ALDwB2t7vjmMUW6euvIwqtXiop7G79UOb3e3NhzeyWFGQyBLqCRznGaXQTT
-dlFy73xhukZMhFnj006bjKCYvOPnwuGl3+0fuWil5Rq3jOuY5c8=
------END RSA PRIVATE KEY-----
+++ /dev/null
-<configuration>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="error">
- <appender-ref ref="STDOUT" />
- </root>
- <logger name="org.opendaylight.controller.netconf" level="TRACE"/>
-</configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../</relativePath>
- </parent>
- <artifactId>netconf-tcp</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.netconf.tcp.osgi.NetconfTCPActivator</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-package org.opendaylight.controller.config.yang.netconf.northbound.tcp;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.util.concurrent.GenericFutureListener;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import org.opendaylight.controller.netconf.api.NetconfServerDispatcher;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfNorthboundTcpModule extends org.opendaylight.controller.config.yang.netconf.northbound.tcp.AbstractNetconfNorthboundTcpModule {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundTcpModule.class);
-
-
- public NetconfNorthboundTcpModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfNorthboundTcpModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.netconf.northbound.tcp.NetconfNorthboundTcpModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final NetconfServerDispatcher dispatch = getDispatcherDependency();
- final ChannelFuture tcpServer = dispatch.createServer(getInetAddress());
-
- tcpServer.addListener(new GenericFutureListener<ChannelFuture>() {
- @Override
- public void operationComplete(ChannelFuture future) throws Exception {
- if (future.isDone() && future.isSuccess()) {
- LOG.info("Netconf TCP endpoint started successfully at {}", getInetAddress());
- } else {
- LOG.warn("Unable to start TCP netconf server at {}", getInetAddress(), future.cause());
- throw new RuntimeException("Unable to start TCP netconf server", future.cause());
- }
- }
- });
-
- return new NetconfServerCloseable(tcpServer);
- }
-
- private InetSocketAddress getInetAddress() {
- try {
- final InetAddress inetAd = InetAddress.getByName(getBindingAddress().getIpv4Address() == null ? getBindingAddress().getIpv6Address().getValue() : getBindingAddress().getIpv4Address().getValue());
- return new InetSocketAddress(inetAd, getPort().getValue());
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unable to bind netconf endpoint to address " + getBindingAddress(), e);
- }
- }
-
- private static final class NetconfServerCloseable implements AutoCloseable {
- private final ChannelFuture localServer;
-
- public NetconfServerCloseable(final ChannelFuture localServer) {
- this.localServer = localServer;
- }
-
- @Override
- public void close() throws Exception {
- if(localServer.isDone()) {
- localServer.channel().close();
- } else {
- localServer.cancel(true);
- }
- }
- }
-
-}
+++ /dev/null
-/*
-* Generated file
-*
-* Generated from: yang module name: netconf-northbound-tcp yang module local name: netconf-northbound-tcp
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Thu Apr 23 16:34:55 CEST 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.netconf.northbound.tcp;
-public class NetconfNorthboundTcpModuleFactory extends org.opendaylight.controller.config.yang.netconf.northbound.tcp.AbstractNetconfNorthboundTcpModuleFactory {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.tcp.netty;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-import java.net.InetSocketAddress;
-
-public class ProxyServer implements AutoCloseable {
- private final EventLoopGroup bossGroup = new NioEventLoopGroup();
- private final EventLoopGroup workerGroup = new NioEventLoopGroup();
- private final ChannelFuture channelFuture;
-
- public ProxyServer(InetSocketAddress address, final LocalAddress localAddress) {
- // Configure the server.
- final Bootstrap clientBootstrap = new Bootstrap();
- clientBootstrap.group(bossGroup).channel(LocalChannel.class);
-
- ServerBootstrap serverBootstrap = new ServerBootstrap();
- serverBootstrap.group(bossGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .handler(new LoggingHandler(LogLevel.DEBUG))
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- ch.pipeline().addLast(new ProxyServerHandler(clientBootstrap, localAddress));
- }
- });
-
- // Start the server.
- channelFuture = serverBootstrap.bind(address).syncUninterruptibly();
- }
-
- @Override
- public void close() {
- channelFuture.channel().close();
- bossGroup.shutdownGracefully();
- workerGroup.shutdownGracefully();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.tcp.netty;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.local.LocalChannel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ProxyServerHandler extends ChannelInboundHandlerAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProxyServerHandler.class);
- private final Bootstrap clientBootstrap;
- private final LocalAddress localAddress;
-
- private Channel clientChannel;
-
- public ProxyServerHandler(Bootstrap clientBootstrap, LocalAddress localAddress) {
- this.clientBootstrap = clientBootstrap;
- this.localAddress = localAddress;
- }
-
- @Override
- public void channelActive(ChannelHandlerContext remoteCtx) {
- final ProxyClientHandler clientHandler = new ProxyClientHandler(remoteCtx);
- clientBootstrap.handler(new ChannelInitializer<LocalChannel>() {
- @Override
- public void initChannel(LocalChannel ch) throws Exception {
- ch.pipeline().addLast(clientHandler);
- }
- });
- ChannelFuture clientChannelFuture = clientBootstrap.connect(localAddress).awaitUninterruptibly();
- clientChannel = clientChannelFuture.channel();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) {
- LOG.trace("channelInactive - closing client channel");
- clientChannel.close();
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, final Object msg) {
- LOG.trace("Writing to client channel");
- clientChannel.write(msg);
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- LOG.trace("Flushing client channel");
- clientChannel.flush();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream.", cause);
- ctx.close();
- }
-}
-
-class ProxyClientHandler extends ChannelInboundHandlerAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
-
- private final ChannelHandlerContext remoteCtx;
- private ChannelHandlerContext localCtx;
-
- public ProxyClientHandler(ChannelHandlerContext remoteCtx) {
- this.remoteCtx = remoteCtx;
- }
-
- @Override
- public void channelActive(ChannelHandlerContext ctx) {
- checkState(this.localCtx == null);
- LOG.trace("Client channel active");
- this.localCtx = ctx;
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg) {
- LOG.trace("Forwarding message");
- remoteCtx.write(msg);
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- LOG.trace("Flushing remote ctx");
- remoteCtx.flush();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- // Close the connection when an exception is raised.
- LOG.warn("Unexpected exception from downstream", cause);
- checkState(this.localCtx.equals(ctx));
- ctx.close();
- }
-
- // called both when local or remote connection dies
- @Override
- public void channelInactive(ChannelHandlerContext ctx) {
- LOG.trace("channelInactive() called, closing remote client ctx");
- remoteCtx.close();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.tcp.osgi;
-
-import com.google.common.base.Optional;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.netconf.tcp.netty.ProxyServer;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
-import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.InfixProp;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Opens TCP port specified in config.ini, creates bridge between this port and local netconf server.
- */
-public class NetconfTCPActivator implements BundleActivator {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfTCPActivator.class);
- private ProxyServer proxyServer;
-
- @Override
- public void start(BundleContext context) {
- final Optional<InetSocketAddress> maybeAddress = NetconfConfigUtil.extractNetconfServerAddress(context, InfixProp.tcp);
- if (maybeAddress.isPresent() == false) {
- LOG.debug("Netconf tcp server is not configured to start");
- return;
- }
- InetSocketAddress address = maybeAddress.get();
- if (address.getAddress().isAnyLocalAddress()) {
- LOG.warn("Unprotected netconf TCP address is configured to ANY local address. This is a security risk. Consider changing {} to 127.0.0.1",
- NetconfConfigUtil.getNetconfServerAddressKey(InfixProp.tcp));
- }
- LOG.info("Starting TCP netconf server at {}", address);
- proxyServer = new ProxyServer(address, NetconfConfigUtil.getNetconfLocalAddress());
- }
-
- @Override
- public void stop(BundleContext context) {
- if (proxyServer != null) {
- proxyServer.close();
- }
- }
-}
+++ /dev/null
-module netconf-northbound-tcp {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netconf:northbound:tcp";
- prefix "nni";
-
- import netconf-northbound-mapper { prefix nnm; revision-date 2015-01-14; }
- import netconf-northbound { prefix nn; revision-date 2015-01-14; }
- import config { prefix config; revision-date 2013-04-05; }
- import threadpool {prefix th;}
- import netty {prefix netty;}
- import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
-
- organization "Cisco Systems, Inc.";
-
- description
- "This module contains the base YANG definitions for
- a default implementation of netconf northbound tcp server";
-
- revision "2015-04-23" {
- description
- "Initial revision.";
- }
-
- identity netconf-northbound-tcp {
- base config:module-type;
- config:java-name-prefix NetconfNorthboundTcp;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case netconf-northbound-tcp {
- when "/config:modules/config:module/config:type = 'netconf-northbound-tcp'";
-
- leaf port {
- type inet:port-number;
- default 2831;
- }
-
- leaf binding-address {
- type inet:ip-address;
- default "0.0.0.0";
- }
-
- container dispatcher {
- uses config:service-ref {
- refine type {
- config:required-identity nn:netconf-server-dispatcher;
- }
- }
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-util</artifactId>
- <packaging>bundle</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <!-- compile dependencies -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager-facade-xml</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-handler</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.controller.netconf.util.*</Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>test-jar</goal>
- </goals>
- <phase>package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util;
-
-public class CloseableUtil {
-
- public static void closeAll(Iterable<? extends AutoCloseable> autoCloseables) throws Exception {
- Exception lastException = null;
- for (AutoCloseable autoCloseable : autoCloseables) {
- try {
- autoCloseable.close();
- } catch (Exception e) {
- if (lastException == null) {
- lastException = e;
- } else {
- lastException.addSuppressed(e);
- }
- }
- }
- if (lastException != null) {
- throw lastException;
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-public final class NetconfUtil {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfUtil.class);
-
- private NetconfUtil() {}
-
- public static Document checkIsMessageOk(Document response) throws DocumentedException {
- XmlElement element = XmlElement.fromDomDocument(response);
- Preconditions.checkState(element.getName().equals(XmlMappingConstants.RPC_REPLY_KEY));
- element = element.getOnlyChildElement();
- if (element.getName().equals(XmlNetconfConstants.OK)) {
- return response;
- }
- LOG.warn("Can not load last configuration. Operation failed.");
- throw new IllegalStateException("Can not load last configuration. Operation failed: "
- + XmlUtil.toString(response));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util;
-
-import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Iterables;
-import java.io.Closeable;
-import java.io.Flushable;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamAttributeWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-//TODO this does not extend NormalizedNodeWriter from yangtools due to api freeze, make this inherit common methods to avoid code duplication
-//TODO move this to yangtools, since this is in netconf-util due to api freeze in lithium
-public class OrderedNormalizedNodeWriter implements Closeable, Flushable{
-
- private final SchemaContext schemaContext;
- private final SchemaNode root;
- private final NormalizedNodeStreamWriter writer;
-
- public OrderedNormalizedNodeWriter(NormalizedNodeStreamWriter writer, SchemaContext schemaContext, SchemaPath path) {
- this.writer = writer;
- this.schemaContext = schemaContext;
- this.root = findParentSchemaOnPath(schemaContext, path);
- }
-
- public OrderedNormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
- if (root == schemaContext) {
- return write(node, schemaContext.getDataChildByName(node.getNodeType()));
- }
-
- return write(node, root);
- }
-
- public OrderedNormalizedNodeWriter write(final Collection<DataContainerChild<?,?>> nodes) throws IOException {
- if (writeChildren(nodes, root, false)) {
- return this;
- }
-
- throw new IllegalStateException("It wasn't possible to serialize nodes " + nodes);
-
- }
-
- private OrderedNormalizedNodeWriter write(NormalizedNode<?, ?> node, SchemaNode dataSchemaNode) throws IOException {
- if (node == null) {
- return this;
- }
-
- if (wasProcessedAsCompositeNode(node, dataSchemaNode)) {
- return this;
- }
-
- if (wasProcessAsSimpleNode(node)) {
- return this;
- }
-
- throw new IllegalStateException("It wasn't possible to serialize node " + node);
- }
-
- private void write(List<NormalizedNode<?, ?>> nodes, SchemaNode dataSchemaNode) throws IOException {
- for (NormalizedNode<?, ?> node : nodes) {
- write(node, dataSchemaNode);
- }
- }
-
- private OrderedNormalizedNodeWriter writeLeaf(final NormalizedNode<?, ?> node) throws IOException {
- if (wasProcessAsSimpleNode(node)) {
- return this;
- }
-
- throw new IllegalStateException("It wasn't possible to serialize node " + node);
- }
-
- private boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children, SchemaNode parentSchemaNode, boolean endParent) throws IOException {
- //Augmentations cannot be gotten with node.getChild so create our own structure with augmentations resolved
- ArrayListMultimap<QName, NormalizedNode<?, ?>> qNameToNodes = ArrayListMultimap.create();
- for (NormalizedNode<?, ?> child : children) {
- if (child instanceof AugmentationNode) {
- qNameToNodes.putAll(resolveAugmentations(child));
- } else {
- qNameToNodes.put(child.getNodeType(), child);
- }
- }
-
- if (parentSchemaNode instanceof DataNodeContainer) {
- if (parentSchemaNode instanceof ListSchemaNode && qNameToNodes.containsKey(parentSchemaNode.getQName())) {
- write(qNameToNodes.get(parentSchemaNode.getQName()), parentSchemaNode);
- } else {
- for (DataSchemaNode schemaNode : ((DataNodeContainer) parentSchemaNode).getChildNodes()) {
- write(qNameToNodes.get(schemaNode.getQName()), schemaNode);
- }
- }
- } else if(parentSchemaNode instanceof ChoiceSchemaNode) {
- for (ChoiceCaseNode ccNode : ((ChoiceSchemaNode) parentSchemaNode).getCases()) {
- for (DataSchemaNode dsn : ccNode.getChildNodes()) {
- if (qNameToNodes.containsKey(dsn.getQName())) {
- write(qNameToNodes.get(dsn.getQName()), dsn);
- }
- }
- }
- } else {
- for (NormalizedNode<?, ?> child : children) {
- writeLeaf(child);
- }
- }
- if (endParent) {
- writer.endNode();
- }
- return true;
- }
-
- private ArrayListMultimap<QName, NormalizedNode<?, ?>> resolveAugmentations(NormalizedNode<?, ?> child) {
- final ArrayListMultimap<QName, NormalizedNode<?, ?>> resolvedAugs = ArrayListMultimap.create();
- for (NormalizedNode<?, ?> node : ((AugmentationNode) child).getValue()) {
- if (node instanceof AugmentationNode) {
- resolvedAugs.putAll(resolveAugmentations(node));
- } else {
- resolvedAugs.put(node.getNodeType(), node);
- }
- }
- return resolvedAugs;
- }
-
- private boolean writeMapEntryNode(final MapEntryNode node, final SchemaNode dataSchemaNode) throws IOException {
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer)
- .startMapEntryNode(node.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(node.getValue()), node.getAttributes());
- } else {
- writer.startMapEntryNode(node.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(node.getValue()));
- }
- return writeChildren(node.getValue(), dataSchemaNode, true);
- }
-
- private boolean wasProcessAsSimpleNode(final NormalizedNode<?, ?> node) throws IOException {
- if (node instanceof LeafSetEntryNode) {
- final LeafSetEntryNode<?> nodeAsLeafList = (LeafSetEntryNode<?>)node;
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).leafSetEntryNode(nodeAsLeafList.getValue(), nodeAsLeafList.getAttributes());
- } else {
- writer.leafSetEntryNode(nodeAsLeafList.getValue());
- }
- return true;
- } else if (node instanceof LeafNode) {
- final LeafNode<?> nodeAsLeaf = (LeafNode<?>)node;
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue(), nodeAsLeaf.getAttributes());
- } else {
- writer.leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue());
- }
- return true;
- } else if (node instanceof AnyXmlNode) {
- final AnyXmlNode anyXmlNode = (AnyXmlNode)node;
- writer.anyxmlNode(anyXmlNode.getIdentifier(), anyXmlNode.getValue());
- return true;
- }
-
- return false;
- }
-
- private boolean wasProcessedAsCompositeNode(final NormalizedNode<?, ?> node, SchemaNode dataSchemaNode) throws IOException {
- if (node instanceof ContainerNode) {
- final ContainerNode n = (ContainerNode) node;
- if(writer instanceof NormalizedNodeStreamAttributeWriter) {
- ((NormalizedNodeStreamAttributeWriter) writer).startContainerNode(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()), n.getAttributes());
- } else {
- writer.startContainerNode(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- }
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof MapEntryNode) {
- return writeMapEntryNode((MapEntryNode) node, dataSchemaNode);
- }
- if (node instanceof UnkeyedListEntryNode) {
- final UnkeyedListEntryNode n = (UnkeyedListEntryNode) node;
- writer.startUnkeyedListItem(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof ChoiceNode) {
- final ChoiceNode n = (ChoiceNode) node;
- writer.startChoiceNode(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof AugmentationNode) {
- final AugmentationNode n = (AugmentationNode) node;
- writer.startAugmentationNode(n.getIdentifier());
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof UnkeyedListNode) {
- final UnkeyedListNode n = (UnkeyedListNode) node;
- writer.startUnkeyedList(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof OrderedMapNode) {
- final OrderedMapNode n = (OrderedMapNode) node;
- writer.startOrderedMapNode(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof MapNode) {
- final MapNode n = (MapNode) node;
- writer.startMapNode(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
- if (node instanceof LeafSetNode) {
- //covers also OrderedLeafSetNode for which doesn't exist start* method
- final LeafSetNode<?> n = (LeafSetNode<?>) node;
- writer.startLeafSet(n.getIdentifier(), OrderedNormalizedNodeWriter.childSizeHint(n.getValue()));
- return writeChildren(n.getValue(), dataSchemaNode, true);
- }
-
- return false;
- }
-
- private static final int childSizeHint(final Iterable<?> children) {
- return (children instanceof Collection) ? ((Collection<?>) children).size() : UNKNOWN_SIZE;
- }
-
- //TODO similar code is already present in schemaTracker, unify this when this writer is moved back to yangtools
- private SchemaNode findParentSchemaOnPath(SchemaContext schemaContext, SchemaPath path) {
- SchemaNode current = Preconditions.checkNotNull(schemaContext);
- for (final QName qname : path.getPathFromRoot()) {
- SchemaNode child;
- if(current instanceof DataNodeContainer) {
- child = ((DataNodeContainer) current).getDataChildByName(qname);
-
- if (child == null && current instanceof SchemaContext) {
- child = tryFindGroupings((SchemaContext) current, qname).orNull();
- }
-
- if(child == null && current instanceof SchemaContext) {
- child = tryFindNotification((SchemaContext) current, qname)
- .or(tryFindRpc(((SchemaContext) current), qname)).orNull();
- }
- } else if (current instanceof ChoiceSchemaNode) {
- child = ((ChoiceSchemaNode) current).getCaseNodeByName(qname);
- } else if (current instanceof RpcDefinition) {
- switch (qname.getLocalName()) {
- case "input":
- child = ((RpcDefinition) current).getInput();
- break;
- case "output":
- child = ((RpcDefinition) current).getOutput();
- break;
- default:
- child = null;
- break;
- }
- } else {
- throw new IllegalArgumentException(String.format("Schema node %s does not allow children.", current));
- }
- current = child;
- }
- return current;
- }
-
- //TODO this method is already present in schemaTracker, unify this when this writer is moved back to yangtools
- private Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
- return Optional.<SchemaNode> fromNullable(Iterables.find(ctx.getGroupings(), new SchemaNodePredicate(qname), null));
- }
-
- //TODO this method is already present in schemaTracker, unify this when this writer is moved back to yangtools
- private Optional<SchemaNode> tryFindRpc(final SchemaContext ctx, final QName qname) {
- return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getOperations(), new SchemaNodePredicate(qname), null));
- }
-
- //TODO this method is already present in schemaTracker, unify this when this writer is moved back to yangtools
- private Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
- return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getNotifications(), new SchemaNodePredicate(qname), null));
- }
-
- @Override
- public void flush() throws IOException {
- writer.flush();
- }
-
- @Override
- public void close() throws IOException {
- writer.flush();
- writer.close();
- }
-
- //TODO this class is already present in schemaTracker, unify this when this writer is moved back to yangtools
- private static final class SchemaNodePredicate implements Predicate<SchemaNode> {
- private final QName qname;
-
- public SchemaNodePredicate(final QName qname) {
- this.qname = qname;
- }
-
- @Override
- public boolean apply(final SchemaNode input) {
- return input.getQName().equals(qname);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util.mapping;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperation {
-
- protected AbstractLastNetconfOperation(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handle(Document document, XmlElement operationElement,
- NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- if (!subsequentOperation.isExecutionTermination()){
- throw new DocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation),
- DocumentedException.ErrorType.application,
- DocumentedException.ErrorTag.malformed_message,
- DocumentedException.ErrorSeverity.error);
- }
-
- return handleWithNoSubsequentOperations(document, operationElement);
- }
-
- @Override
- protected HandlingPriority getHandlingPriority() {
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
- }
-
- protected abstract Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.mapping;
-
-import com.google.common.base.Optional;
-import java.util.Map;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-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.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-public abstract class AbstractNetconfOperation implements NetconfOperation {
- private final String netconfSessionIdForReporting;
-
- protected AbstractNetconfOperation(final String netconfSessionIdForReporting) {
- this.netconfSessionIdForReporting = netconfSessionIdForReporting;
- }
-
- public final String getNetconfSessionIdForReporting() {
- return netconfSessionIdForReporting;
- }
-
- @Override
- public HandlingPriority canHandle(final Document message) throws DocumentedException {
- OperationNameAndNamespace operationNameAndNamespace = null;
- operationNameAndNamespace = new OperationNameAndNamespace(message);
- return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace());
- }
-
- public static final class OperationNameAndNamespace {
- private final String operationName, namespace;
- private final XmlElement operationElement;
-
- public OperationNameAndNamespace(final Document message) throws DocumentedException {
- XmlElement requestElement = null;
- requestElement = getRequestElementWithCheck(message);
- operationElement = requestElement.getOnlyChildElement();
- operationName = operationElement.getName();
- namespace = operationElement.getNamespace();
- }
-
- public String getOperationName() {
- return operationName;
- }
-
- public String getNamespace() {
- return namespace;
- }
-
- public XmlElement getOperationElement() {
- return operationElement;
- }
- }
-
- protected static XmlElement getRequestElementWithCheck(final Document message) throws DocumentedException {
- return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
- }
-
- protected HandlingPriority canHandle(final String operationName, final String operationNamespace) {
- return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
- ? getHandlingPriority()
- : HandlingPriority.CANNOT_HANDLE;
- }
-
- protected HandlingPriority getHandlingPriority() {
- return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
- }
-
- protected String getOperationNamespace() {
- return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
- }
-
- protected abstract String getOperationName();
-
- @Override
- public Document handle(final Document requestMessage,
- final NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
-
- XmlElement requestElement = getRequestElementWithCheck(requestMessage);
-
- Document document = XmlUtil.newDocument();
-
- XmlElement operationElement = requestElement.getOnlyChildElement();
- Map<String, Attr> attributes = requestElement.getAttributes();
-
- Element response = handle(document, operationElement, subsequentOperation);
- Element rpcReply = XmlUtil.createElement(document, XmlMappingConstants.RPC_REPLY_KEY, Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
-
- if(XmlElement.fromDomElement(response).hasNamespace()) {
- rpcReply.appendChild(response);
- } else {
- Element responseNS = XmlUtil.createElement(document, response.getNodeName(), Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
- NodeList list = response.getChildNodes();
- while(list.getLength()!=0) {
- responseNS.appendChild(list.item(0));
- }
- rpcReply.appendChild(responseNS);
- }
-
- for (Attr attribute : attributes.values()) {
- rpcReply.setAttributeNode((Attr) document.importNode(attribute, true));
- }
- document.appendChild(rpcReply);
- return document;
- }
-
- protected abstract Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
- throws DocumentedException;
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer(getClass().getName());
- try {
- sb.append("{name=").append(getOperationName());
- } catch(UnsupportedOperationException e) {
- // no problem
- }
- sb.append(", namespace=").append(getOperationNamespace());
- sb.append(", session=").append(netconfSessionIdForReporting);
- sb.append('}');
- return sb.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util.mapping;
-
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public abstract class AbstractSingletonNetconfOperation extends AbstractLastNetconfOperation {
-
- protected AbstractSingletonNetconfOperation(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handle(Document document, XmlElement operationElement,
- NetconfOperationChainedExecution subsequentOperation) throws DocumentedException {
- return handleWithNoSubsequentOperations(document, operationElement);
- }
-
- @Override
- protected HandlingPriority getHandlingPriority() {
- return HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-/**
- * Known NETCONF framing mechanisms.
- */
-public enum FramingMechanism {
- /**
- * @see <a href="http://tools.ietf.org/html/rfc6242#section-4.2">Chunked
- * framing mechanism</a>
- */
- CHUNK,
- /**
- * @see <a
- * href="http://tools.ietf.org/html/rfc6242#section-4.3">End-of-message
- * framing mechanism</a>
- */
- EOM
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import java.util.Set;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-/**
- * NetconfMessage that can carry additional header with session metadata. See {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader}
- */
-public final class NetconfHelloMessage extends NetconfMessage {
-
- public static final String HELLO_TAG = "hello";
-
- private final NetconfHelloMessageAdditionalHeader additionalHeader;
-
- public NetconfHelloMessage(Document doc, NetconfHelloMessageAdditionalHeader additionalHeader) throws NetconfDocumentedException {
- super(doc);
- checkHelloMessage(doc);
- this.additionalHeader = additionalHeader;
- }
-
- public NetconfHelloMessage(Document doc) throws NetconfDocumentedException {
- this(doc, null);
- }
-
- public Optional<NetconfHelloMessageAdditionalHeader> getAdditionalHeader() {
- return additionalHeader== null ? Optional.<NetconfHelloMessageAdditionalHeader>absent() : Optional.of(additionalHeader);
- }
-
- private static void checkHelloMessage(Document doc) {
- Preconditions.checkArgument(isHelloMessage(doc),
- "Hello message invalid format, should contain %s tag from namespace %s, but is: %s", HELLO_TAG,
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlUtil.toString(doc));
- }
-
- public static NetconfHelloMessage createClientHello(Iterable<String> capabilities,
- Optional<NetconfHelloMessageAdditionalHeader> additionalHeaderOptional) throws NetconfDocumentedException {
- Document doc = createHelloMessageDoc(capabilities);
- return additionalHeaderOptional.isPresent() ? new NetconfHelloMessage(doc, additionalHeaderOptional.get())
- : new NetconfHelloMessage(doc);
- }
-
- private static Document createHelloMessageDoc(Iterable<String> capabilities) {
- Document doc = XmlUtil.newDocument();
- Element helloElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- HELLO_TAG);
- Element capabilitiesElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.CAPABILITIES);
-
- for (String capability : Sets.newHashSet(capabilities)) {
- Element capElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.CAPABILITY);
- capElement.setTextContent(capability);
- capabilitiesElement.appendChild(capElement);
- }
-
- helloElement.appendChild(capabilitiesElement);
-
- doc.appendChild(helloElement);
- return doc;
- }
-
- public static NetconfHelloMessage createServerHello(Set<String> capabilities, long sessionId) throws NetconfDocumentedException {
- Document doc = createHelloMessageDoc(capabilities);
- Element sessionIdElement = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
- XmlNetconfConstants.SESSION_ID);
- sessionIdElement.setTextContent(Long.toString(sessionId));
- doc.getDocumentElement().appendChild(sessionIdElement);
- return new NetconfHelloMessage(doc);
- }
-
- public static boolean isHelloMessage(final NetconfMessage msg) {
- Document document = msg.getDocument();
- return isHelloMessage(document);
- }
-
- private static boolean isHelloMessage(final Document document) {
- XmlElement element = XmlElement.fromDomElement(document.getDocumentElement());
- try {
- // accept even if hello has no namespace
- return element.getName().equals(HELLO_TAG) &&
- (!element.hasNamespace() || element.getNamespace().equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
- } catch (DocumentedException e) {
- // Cannot happen, since we check for hasNamespace
- throw new IllegalStateException(e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Preconditions;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Additional header can be used with hello message to carry information about
- * session's connection. Provided information can be reported via netconf
- * monitoring.
- * <pre>
- * It has PATTERN "[username; host-address:port; transport; session-identifier;]"
- * username - name of account on a remote
- * host-address - client's IP address
- * port - port number
- * transport - tcp, ssh
- * session-identifier - persister, client
- * Session-identifier is optional, others mandatory.
- * </pre>
- * This header is inserted in front of a netconf hello message followed by a newline.
- */
-public class NetconfHelloMessageAdditionalHeader {
-
- private static final String SC = ";";
-
- private final String userName;
- private final String hostAddress;
- private final String port;
- private final String transport;
- private final String sessionIdentifier;
-
- public NetconfHelloMessageAdditionalHeader(String userName, String hostAddress, String port, String transport, String sessionIdentifier) {
- this.userName = userName;
- this.hostAddress = hostAddress;
- this.port = port;
- this.transport = transport;
- this.sessionIdentifier = sessionIdentifier;
- }
-
- public String getUserName() {
- return userName;
- }
-
- public String getAddress() {
- return hostAddress;
- }
-
- public String getPort() {
- return port;
- }
-
- public String getTransport() {
- return transport;
- }
-
- public String getSessionIdentifier() {
- return sessionIdentifier;
- }
-
- /**
- * Format additional header into a string suitable as a prefix for netconf hello message
- */
- public String toFormattedString() {
- Preconditions.checkNotNull(userName);
- Preconditions.checkNotNull(hostAddress);
- Preconditions.checkNotNull(port);
- Preconditions.checkNotNull(transport);
- Preconditions.checkNotNull(sessionIdentifier);
- return "[" + userName + SC + hostAddress + ":" + port + SC + transport + SC + sessionIdentifier + SC + "]"
- + System.lineSeparator();
- }
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer("NetconfHelloMessageAdditionalHeader{");
- sb.append("userName='").append(userName).append('\'');
- sb.append(", hostAddress='").append(hostAddress).append('\'');
- sb.append(", port='").append(port).append('\'');
- sb.append(", transport='").append(transport).append('\'');
- sb.append(", sessionIdentifier='").append(sessionIdentifier).append('\'');
- sb.append('}');
- return sb.toString();
- }
-
- // TODO IPv6
- private static final Pattern PATTERN = Pattern
- .compile("\\[(?<username>[^;]+);(?<address>[0-9\\.]+)[:/](?<port>[0-9]+);(?<transport>[a-z]+)[^\\]]+\\]");
- private static final Pattern CUSTOM_HEADER_PATTERN = Pattern
- .compile("\\[(?<username>[^;]+);(?<address>[0-9\\.]+)[:/](?<port>[0-9]+);(?<transport>[a-z]+);(?<sessionIdentifier>[a-z]+)[^\\]]+\\]");
-
- /**
- * Parse additional header from a formatted string
- */
- public static NetconfHelloMessageAdditionalHeader fromString(String additionalHeader) {
- String additionalHeaderTrimmed = additionalHeader.trim();
- Matcher matcher = PATTERN.matcher(additionalHeaderTrimmed);
- Matcher matcher2 = CUSTOM_HEADER_PATTERN.matcher(additionalHeaderTrimmed);
- Preconditions.checkArgument(matcher.matches(), "Additional header in wrong format %s, expected %s",
- additionalHeaderTrimmed, PATTERN);
-
- String username = matcher.group("username");
- String address = matcher.group("address");
- String port = matcher.group("port");
- String transport = matcher.group("transport");
- String sessionIdentifier = "client";
- if (matcher2.matches()) {
- sessionIdentifier = matcher2.group("sessionIdentifier");
- }
- return new NetconfHelloMessageAdditionalHeader(username, address, port, transport, sessionIdentifier);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Charsets;
-
-public final class NetconfMessageConstants {
-
- private NetconfMessageConstants(){}
- /**
- * The NETCONF 1.0 old-style message separator. This is framing mechanism
- * is used by default.
- */
- public static final byte[] END_OF_MESSAGE = "]]>]]>".getBytes(Charsets.UTF_8);
-
- // bytes
-
- public static final int MIN_HEADER_LENGTH = 4;
-
- // bytes
-
- public static final int MAX_HEADER_LENGTH = 13;
-
- public static final byte[] START_OF_CHUNK = "\n#".getBytes(Charsets.UTF_8);
- public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import java.nio.ByteBuffer;
-
-/**
- * Netconf message header is used only when chunked framing mechanism is
- * supported. The header consists of only the length field.
- */
-@Deprecated
-public final class NetconfMessageHeader {
- // \n#<length>\n
- private static final byte[] HEADER_START = new byte[] { (byte) 0x0a, (byte) 0x23 };
- private static final byte HEADER_END = (byte) 0x0a;
- private final long length;
-
- public NetconfMessageHeader(final long length) {
- Preconditions.checkArgument(length < Integer.MAX_VALUE && length > 0);
- this.length = length;
- }
-
- public byte[] toBytes() {
- return toBytes(this.length);
- }
-
- // FIXME: improve precision to long
- public int getLength() {
- return (int) this.length;
- }
-
- public static NetconfMessageHeader fromBytes(final byte[] bytes) {
- // the length is variable therefore bytes between headerBegin and
- // headerEnd mark the length
- // the length should be only numbers and therefore easily parsed with
- // ASCII
- long length = Long.parseLong(Charsets.US_ASCII.decode(
- ByteBuffer.wrap(bytes, HEADER_START.length, bytes.length - HEADER_START.length - 1)).toString());
-
- return new NetconfMessageHeader(length);
- }
-
- public static byte[] toBytes(final long length) {
- final byte[] l = String.valueOf(length).getBytes(Charsets.US_ASCII);
- final byte[] h = new byte[HEADER_START.length + l.length + 1];
- System.arraycopy(HEADER_START, 0, h, 0, HEADER_START.length);
- System.arraycopy(l, 0, h, HEADER_START.length, l.length);
- System.arraycopy(new byte[] { HEADER_END }, 0, h, HEADER_START.length + l.length, 1);
- return h;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.Collections2;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-public final class NetconfMessageUtil {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageUtil.class);
-
- private NetconfMessageUtil() {}
-
- public static boolean isOKMessage(NetconfMessage message) throws NetconfDocumentedException {
- return isOKMessage(message.getDocument());
- }
-
- public static boolean isOKMessage(Document document) throws NetconfDocumentedException {
- return isOKMessage(XmlElement.fromDomDocument(document));
- }
-
- public static boolean isOKMessage(XmlElement xmlElement) throws NetconfDocumentedException {
- if(xmlElement.getChildElements().size() != 1) {
- return false;
- }
- try {
- return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.OK);
- } catch (DocumentedException e) {
- throw new NetconfDocumentedException(e);
- }
- }
-
- public static boolean isErrorMessage(NetconfMessage message) throws NetconfDocumentedException {
- return isErrorMessage(message.getDocument());
- }
-
- public static boolean isErrorMessage(Document document) throws NetconfDocumentedException {
- return isErrorMessage(XmlElement.fromDomDocument(document));
- }
-
- public static boolean isErrorMessage(XmlElement xmlElement) throws NetconfDocumentedException {
- if(xmlElement.getChildElements().size() != 1) {
- return false;
- }
- try {
- return xmlElement.getOnlyChildElement().getName().equals(DocumentedException.RPC_ERROR);
- } catch (DocumentedException e) {
- throw new NetconfDocumentedException(e);
- }
- }
-
- public static Collection<String> extractCapabilitiesFromHello(Document doc) throws NetconfDocumentedException {
- XmlElement responseElement = XmlElement.fromDomDocument(doc);
- // Extract child element <capabilities> from <hello> with or without(fallback) the same namespace
- Optional<XmlElement> capabilitiesElement = responseElement
- .getOnlyChildElementWithSameNamespaceOptionally(XmlNetconfConstants.CAPABILITIES)
- .or(responseElement
- .getOnlyChildElementOptionally(XmlNetconfConstants.CAPABILITIES));
-
- List<XmlElement> caps = capabilitiesElement.get().getChildElements(XmlNetconfConstants.CAPABILITY);
- return Collections2.transform(caps, new Function<XmlElement, String>() {
-
- @Override
- public String apply(@Nonnull XmlElement input) {
- // Trim possible leading/tailing whitespace
- try {
- return input.getTextContent().trim();
- } catch (DocumentedException e) {
- LOG.trace("Error fetching input text content",e);
- return null;
- }
- }
- });
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-
-public final class SendErrorExceptionUtil {
- private static final Logger LOG = LoggerFactory.getLogger(SendErrorExceptionUtil.class);
-
- private SendErrorExceptionUtil() {}
-
- public static void sendErrorMessage(final NetconfSession session,
- final DocumentedException sendErrorException) {
- LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
- final Document errorDocument = createDocument(sendErrorException);
- ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
- }
-
- public static void sendErrorMessage(final Channel channel, final DocumentedException sendErrorException) {
- LOG.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
- final Document errorDocument = createDocument(sendErrorException);
- ChannelFuture f = channel.writeAndFlush(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
- }
-
- public static void sendErrorMessage(final NetconfSession session, final DocumentedException sendErrorException,
- final NetconfMessage incommingMessage) {
- final Document errorDocument = createDocument(sendErrorException);
- if (LOG.isTraceEnabled()) {
- LOG.trace("Sending error {}", XmlUtil.toString(errorDocument));
- }
-
- tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
- ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument));
- f.addListener(new SendErrorVerifyingListener(sendErrorException));
- }
-
- private static void tryToCopyAttributes(final Document incommingDocument, final Document errorDocument,
- final DocumentedException sendErrorException) {
- try {
- final Element incommingRpc = incommingDocument.getDocumentElement();
- Preconditions.checkState(incommingRpc.getTagName().equals(XmlNetconfConstants.RPC_KEY), "Missing %s element",
- XmlNetconfConstants.RPC_KEY);
-
- final Element rpcReply = errorDocument.getDocumentElement();
- Preconditions.checkState(rpcReply.getTagName().equals(XmlMappingConstants.RPC_REPLY_KEY), "Missing %s element",
- XmlMappingConstants.RPC_REPLY_KEY);
-
- final NamedNodeMap incomingAttributes = incommingRpc.getAttributes();
- for (int i = 0; i < incomingAttributes.getLength(); i++) {
- final Attr attr = (Attr) incomingAttributes.item(i);
- // skip namespace
- if (attr.getNodeName().equals(XmlUtil.XMLNS_ATTRIBUTE_KEY)) {
- continue;
- }
- rpcReply.setAttributeNode((Attr) errorDocument.importNode(attr, true));
- }
- } catch (final Exception e) {
- LOG.warn("Unable to copy incomming attributes to {}, returned rpc-error might be invalid for client",
- sendErrorException, e);
- }
- }
-
- private static Document createDocument(final DocumentedException sendErrorException) {
- return sendErrorException.toXMLDocument();
- }
-
- /**
- * Checks if netconf error was sent successfully.
- */
- private static final class SendErrorVerifyingListener implements ChannelFutureListener {
- private final DocumentedException sendErrorException;
-
- public SendErrorVerifyingListener(final DocumentedException sendErrorException) {
- this.sendErrorException = sendErrorException;
- }
-
- @Override
- public void operationComplete(final ChannelFuture channelFuture) throws Exception {
- Preconditions.checkState(channelFuture.isSuccess(), "Unable to send exception %s", sendErrorException,
- channelFuture.cause());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.osgi;
-
-import com.google.common.base.Optional;
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-import java.util.concurrent.TimeUnit;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfConfigUtil {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfConfigUtil.class);
-
- private static final String PREFIX_PROP = "netconf.";
-
- private NetconfConfigUtil() {
- }
-
- public enum InfixProp {
- tcp, ssh
- }
-
- private static final String PORT_SUFFIX_PROP = ".port";
- private static final String ADDRESS_SUFFIX_PROP = ".address";
- private static final String PRIVATE_KEY_PATH_PROP = ".pk.path";
-
- private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis";
- public static final long DEFAULT_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30);
- private static final LocalAddress netconfLocalAddress = new LocalAddress("netconf");
-
- public static LocalAddress getNetconfLocalAddress() {
- return netconfLocalAddress;
- }
-
- public static long extractTimeoutMillis(final BundleContext bundleContext) {
- final String key = PREFIX_PROP + CONNECTION_TIMEOUT_MILLIS_PROP;
- final String timeoutString = bundleContext.getProperty(key);
- if (timeoutString == null || timeoutString.length() == 0) {
- return DEFAULT_TIMEOUT_MILLIS;
- }
- try {
- return Long.parseLong(timeoutString);
- } catch (final NumberFormatException e) {
- LOG.warn("Cannot parse {} property: {}, using defaults", key, timeoutString, e);
- return DEFAULT_TIMEOUT_MILLIS;
- }
- }
-
- public static String getPrivateKeyPath(final BundleContext context) {
- return getPropertyValue(context, getPrivateKeyKey());
- }
-
- public static String getPrivateKeyKey() {
- return PREFIX_PROP + InfixProp.ssh + PRIVATE_KEY_PATH_PROP;
- }
-
- private static String getPropertyValue(final BundleContext context, final String propertyName) {
- final String propertyValue = context.getProperty(propertyName);
- if (propertyValue == null) {
- throw new IllegalStateException("Cannot find initial property with name '" + propertyName + "'");
- }
- return propertyValue;
- }
-
- public static String getNetconfServerAddressKey(InfixProp infixProp) {
- return PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP;
- }
-
- /**
- * @param context from which properties are being read.
- * @param infixProp either tcp or ssh
- * @return value if address and port are present and valid, Optional.absent otherwise.
- * @throws IllegalStateException if address or port are invalid, or configuration is missing
- */
- public static Optional<InetSocketAddress> extractNetconfServerAddress(final BundleContext context,
- final InfixProp infixProp) {
-
- final Optional<String> address = getProperty(context, getNetconfServerAddressKey(infixProp));
- final Optional<String> port = getProperty(context, PREFIX_PROP + infixProp + PORT_SUFFIX_PROP);
-
- if (address.isPresent() && port.isPresent()) {
- try {
- return Optional.of(parseAddress(address, port));
- } catch (final RuntimeException e) {
- LOG.warn("Unable to parse {} netconf address from {}:{}, fallback to default",
- infixProp, address, port, e);
- }
- }
- return Optional.absent();
- }
-
- private static InetSocketAddress parseAddress(final Optional<String> address, final Optional<String> port) {
- final int portNumber = Integer.valueOf(port.get());
- return new InetSocketAddress(address.get(), portNumber);
- }
-
- private static Optional<String> getProperty(final BundleContext context, final String propKey) {
- String value = context.getProperty(propKey);
- if (value != null && value.isEmpty()) {
- value = null;
- }
- return Optional.fromNullable(value);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-import javax.xml.namespace.NamespaceContext;
-
-// http://www.ibm.com/developerworks/library/x-nmspccontext/
-public class HardcodedNamespaceResolver implements NamespaceContext {
- private final Map<String/* prefix */, String/* namespace */> prefixesToNamespaces;
-
- public HardcodedNamespaceResolver(String prefix, String namespace) {
- this(ImmutableMap.of(prefix, namespace));
- }
-
- public HardcodedNamespaceResolver(Map<String, String> prefixesToNamespaces) {
- this.prefixesToNamespaces = Collections.unmodifiableMap(prefixesToNamespaces);
- }
-
- /**
- * This method returns the uri for all prefixes needed. Wherever possible it
- * uses XMLConstants.
- *
- * @param prefix
- * @return uri
- */
- @Override
- public String getNamespaceURI(String prefix) {
- if (prefixesToNamespaces.containsKey(prefix)) {
- return prefixesToNamespaces.get(prefix);
- } else {
- throw new IllegalStateException("Prefix mapping not found for " + prefix);
- }
- }
-
- @Override
- public String getPrefix(String namespaceURI) {
- // Not needed in this context.
- return null;
- }
-
- @Override
- public Iterator<?> getPrefixes(String namespaceURI) {
- // Not needed in this context.
- return null;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-
-public final class XMLNetconfUtil {
- private static final XPathFactory FACTORY = XPathFactory.newInstance();
- private static final NamespaceContext NS_CONTEXT = new HardcodedNamespaceResolver("netconf",
- XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-
- private XMLNetconfUtil() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- public static XPathExpression compileXPath(final String xPath) {
- final XPath xpath = FACTORY.newXPath();
- xpath.setNamespaceContext(NS_CONTEXT);
- try {
- return xpath.compile(xPath);
- } catch (final XPathExpressionException e) {
- throw new IllegalStateException("Error while compiling xpath expression " + xPath, e);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.xml.transform.Source;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.Validator;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public final class XmlNetconfValidator {
-
- private static final Schema SCHEMA;
-
- private XmlNetconfValidator() {}
-
- static {
- final InputStream xmlSchema = XmlNetconfValidator.class.getResourceAsStream("/xml.xsd");
- Preconditions.checkNotNull(xmlSchema, "Cannot find xml.xsd");
-
- final InputStream rfc4714Schema = XmlNetconfValidator.class.getResourceAsStream("/rfc4741.xsd");
- Preconditions.checkNotNull(rfc4714Schema, "Cannot find rfc4741.xsd");
- SCHEMA = XmlUtil.loadSchema(xmlSchema, rfc4714Schema);
- }
-
- public static void validate(Document inputDocument) throws SAXException, IOException {
- final Validator validator = SCHEMA.newValidator();
- final Source source = new DOMSource(inputDocument);
- validator.validate(source);
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <rpc-error>
- <error-type>*** transport/rpc/protocol/application</error-type>
- <error-tag>*** RFC 4741 Appendix A. NETCONF Error List</error-tag>
- <error-severity>*** error/warning</error-severity>
-
- <!--
- <error-info>
- <bad-attribute>message-id</bad-attribute>
- <bad-element>rpc</bad-element>
- </error-info>
- -->
-
- </rpc-error>
-</rpc-reply>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
- targetNamespace="urn:ietf:params:xml:ns:netconf:base:1.0"
- elementFormDefault="qualified"
- attributeFormDefault="unqualified"
- xml:lang="en">
- <!--
- import standard XML definitions
- -->
- <xs:import namespace="http://www.w3.org/XML/1998/namespace"
- schemaLocation="http://www.w3.org/2001/xml.xsd">
-
- <xs:annotation>
- <xs:documentation>
- This import accesses the xml: attribute groups for the
- xml:lang as declared on the error-message element.
- </xs:documentation>
- </xs:annotation>
- </xs:import>
- <!--
- message-id attribute
- -->
- <xs:simpleType name="messageIdType">
- <xs:restriction base="xs:string">
- <xs:maxLength value="4095"/>
- </xs:restriction>
- </xs:simpleType>
- <!--
- Types used for session-id
- -->
- <xs:simpleType name="SessionId">
- <xs:restriction base="xs:unsignedInt">
- <xs:minInclusive value="1"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="SessionIdOrZero">
- <xs:restriction base="xs:unsignedInt"/>
- </xs:simpleType>
- <!--
- <rpc> element
- -->
- <xs:complexType name="rpcType">
- <xs:sequence>
- <xs:element ref="rpcOperation"/>
-
-
- </xs:sequence>
- <xs:attribute name="message-id" type="messageIdType"
- use="required"/>
- <!--
- Arbitrary attributes can be supplied with <rpc> element.
- -->
- <xs:anyAttribute processContents="lax"/>
- </xs:complexType>
- <xs:element name="rpc" type="rpcType"/>
- <!--
- data types and elements used to construct rpc-errors
- -->
- <xs:simpleType name="ErrorType">
- <xs:restriction base="xs:string">
- <xs:enumeration value="transport"/>
- <xs:enumeration value="rpc"/>
- <xs:enumeration value="protocol"/>
- <xs:enumeration value="application"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="ErrorTag">
- <xs:restriction base="xs:string">
- <xs:enumeration value="in-use"/>
- <xs:enumeration value="invalid-value"/>
- <xs:enumeration value="too-big"/>
- <xs:enumeration value="missing-attribute"/>
- <xs:enumeration value="bad-attribute"/>
- <xs:enumeration value="unknown-attribute"/>
- <xs:enumeration value="missing-element"/>
- <xs:enumeration value="bad-element"/>
- <xs:enumeration value="unknown-element"/>
- <xs:enumeration value="unknown-namespace"/>
- <xs:enumeration value="access-denied"/>
- <xs:enumeration value="lock-denied"/>
- <xs:enumeration value="resource-denied"/>
- <xs:enumeration value="rollback-failed"/>
- <xs:enumeration value="data-exists"/>
- <xs:enumeration value="data-missing"/>
- <xs:enumeration value="operation-not-supported"/>
- <xs:enumeration value="operation-failed"/>
- <xs:enumeration value="partial-operation"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:simpleType name="ErrorSeverity">
- <xs:restriction base="xs:string">
- <xs:enumeration value="error"/>
- <xs:enumeration value="warning"/>
- </xs:restriction>
-
-
- </xs:simpleType>
- <xs:complexType name="errorInfoType">
- <xs:sequence>
- <xs:choice>
- <xs:element name="session-id" type="SessionIdOrZero"/>
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:sequence>
- <xs:element name="bad-attribute" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- <xs:element name="bad-element" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- <xs:element name="ok-element" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- <xs:element name="err-element" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- <xs:element name="noop-element" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- <xs:element name="bad-namespace" type="xs:QName"
- minOccurs="0" maxOccurs="1"/>
- </xs:sequence>
- </xs:sequence>
- </xs:choice>
- <!-- elements from any other namespace are also allowed
- to follow the NETCONF elements -->
- <xs:any namespace="##other"
- minOccurs="0" maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:complexType>
- <xs:complexType name="rpcErrorType">
- <xs:sequence>
- <xs:element name="error-type" type="ErrorType"/>
- <xs:element name="error-tag" type="ErrorTag"/>
- <xs:element name="error-severity" type="ErrorSeverity"/>
- <xs:element name="error-app-tag" type="xs:string"
- minOccurs="0"/>
- <xs:element name="error-path" type="xs:string" minOccurs="0"/>
- <xs:element name="error-message" minOccurs="0">
- <xs:complexType>
- <xs:simpleContent>
- <xs:extension base="xs:string">
- <xs:attribute ref="xml:lang" use="optional"/>
- </xs:extension>
- </xs:simpleContent>
- </xs:complexType>
- </xs:element>
- <xs:element name="error-info" type="errorInfoType"
- minOccurs="0"/>
- </xs:sequence>
-
-
- </xs:complexType>
- <!--
- <rpc-reply> element
- -->
- <xs:complexType name="rpcReplyType">
- <xs:choice>
- <xs:element name="ok"/>
- <xs:group ref="rpcResponse"/>
- </xs:choice>
- <xs:attribute name="message-id" type="messageIdType"
- use="optional"/>
- <!--
- Any attributes supplied with <rpc> element must be returned
- on <rpc-reply>.
- -->
- <xs:anyAttribute processContents="lax"/>
- </xs:complexType>
- <xs:group name="rpcResponse">
- <xs:sequence>
- <xs:element name="rpc-error" type="rpcErrorType"
- minOccurs="0" maxOccurs="unbounded"/>
- <xs:element name="data" type="dataInlineType" minOccurs="0"/>
- </xs:sequence>
- </xs:group>
- <xs:element name="rpc-reply" type="rpcReplyType"/>
- <!--
- Type for <test-option> parameter to <edit-config>
- -->
- <xs:simpleType name="testOptionType">
- <xs:restriction base="xs:string">
- <xs:enumeration value="test-then-set"/>
- <xs:enumeration value="set"/>
- </xs:restriction>
- </xs:simpleType>
- <!--
- Type for <error-option> parameter to <edit-config>
- -->
- <xs:simpleType name="errorOptionType">
- <xs:restriction base="xs:string">
- <xs:annotation>
- <xs:documentation>
- Use of the rollback-on-error value requires
- the :rollback-on-error capability.
- </xs:documentation>
- </xs:annotation>
- <xs:enumeration value="stop-on-error"/>
- <xs:enumeration value="continue-on-error"/>
- <xs:enumeration value="rollback-on-error"/>
-
-
- </xs:restriction>
- </xs:simpleType>
- <!--
- rpcOperationType: used as a base type for all
- NETCONF operations
- -->
- <xs:complexType name="rpcOperationType"/>
- <xs:element name="rpcOperation"
- type="rpcOperationType" abstract="true"/>
- <!--
- Type for <config> element
- -->
- <xs:complexType name="configInlineType">
- <xs:complexContent>
- <xs:extension base="xs:anyType"/>
- </xs:complexContent>
- </xs:complexType>
- <!--
- Type for <data> element
- -->
- <xs:complexType name="dataInlineType">
- <xs:complexContent>
- <xs:extension base="xs:anyType"/>
- </xs:complexContent>
- </xs:complexType>
- <!--
- Type for <filter> element
- -->
- <xs:simpleType name="FilterType">
- <xs:restriction base="xs:string">
- <xs:annotation>
- <xs:documentation>
- Use of the xpath value requires the :xpath capability.
- </xs:documentation>
- </xs:annotation>
- <xs:enumeration value="subtree"/>
- <xs:enumeration value="xpath"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:complexType name="filterInlineType">
- <xs:complexContent>
- <xs:extension base="xs:anyType">
- <xs:attribute name="type"
- type="FilterType" default="subtree"/>
- <!-- if type="xpath", the xpath expression
- appears in the select element -->
- <xs:attribute name="select"/>
- </xs:extension>
-
-
- </xs:complexContent>
- </xs:complexType>
- <!--
- configuration datastore names
- -->
- <xs:annotation>
- <xs:documentation>
- The startup datastore can be used only if the :startup
- capability is advertised. The candidate datastore can
- be used only if the :candidate datastore is advertised.
- </xs:documentation>
- </xs:annotation>
- <xs:complexType name="configNameType"/>
- <xs:element name="config-name"
- type="configNameType" abstract="true"/>
- <xs:element name="startup" type="configNameType"
- substitutionGroup="config-name"/>
- <xs:element name="candidate" type="configNameType"
- substitutionGroup="config-name"/>
- <xs:element name="running" type="configNameType"
- substitutionGroup="config-name"/>
- <!--
- operation attribute used in <edit-config>
- -->
- <xs:simpleType name="editOperationType">
- <xs:restriction base="xs:string">
- <xs:enumeration value="merge"/>
- <xs:enumeration value="replace"/>
- <xs:enumeration value="create"/>
- <xs:enumeration value="delete"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:attribute name="operation"
- type="editOperationType" default="merge"/>
- <!--
- <default-operation> element
- -->
- <xs:simpleType name="defaultOperationType">
- <xs:restriction base="xs:string">
- <xs:enumeration value="merge"/>
- <xs:enumeration value="replace"/>
- <xs:enumeration value="none"/>
- </xs:restriction>
- </xs:simpleType>
- <!--
- <url> element
- -->
- <xs:complexType name="configURIType">
-
-
- <xs:annotation>
- <xs:documentation>
- Use of the url element requires the :url capability.
- </xs:documentation>
- </xs:annotation>
- <xs:simpleContent>
- <xs:extension base="xs:anyURI"/>
- </xs:simpleContent>
- </xs:complexType>
- <!--
- Type for <source> element (except <get-config>)
- -->
- <xs:complexType name="rpcOperationSourceType">
- <xs:choice>
- <xs:element name="config" type="configInlineType"/>
- <xs:element ref="config-name"/>
- <xs:element name="url" type="configURIType"/>
- </xs:choice>
- </xs:complexType>
- <!--
- Type for <source> element in <get-config>
- -->
- <xs:complexType name="getConfigSourceType">
- <xs:choice>
- <xs:element ref="config-name"/>
- <xs:element name="url" type="configURIType"/>
- </xs:choice>
- </xs:complexType>
- <!--
- Type for <target> element
- -->
- <xs:complexType name="rpcOperationTargetType">
- <xs:choice>
- <xs:element ref="config-name"/>
- <xs:element name="url" type="configURIType"/>
- </xs:choice>
- </xs:complexType>
- <!--
- <get-config> operation
- -->
- <xs:complexType name="getConfigType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="source"
- type="getConfigSourceType"/>
- <xs:element name="filter"
- type="filterInlineType" minOccurs="0"/>
-
-
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="get-config" type="getConfigType"
- substitutionGroup="rpcOperation"/>
- <!--
- <edit-config> operation
- -->
- <xs:complexType name="editConfigType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:annotation>
- <xs:documentation>
- Use of the test-option element requires the
- :validate capability. Use of the url element
- requires the :url capability.
- </xs:documentation>
- </xs:annotation>
- <xs:element name="target"
- type="rpcOperationTargetType"/>
- <xs:element name="default-operation"
- type="defaultOperationType"
- minOccurs="0"/>
- <xs:element name="test-option"
- type="testOptionType"
- minOccurs="0"/>
- <xs:element name="error-option"
- type="errorOptionType"
- minOccurs="0"/>
- <xs:choice>
- <xs:element name="config"
- type="configInlineType"/>
- <xs:element name="url"
- type="configURIType"/>
- </xs:choice>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="edit-config" type="editConfigType"
- substitutionGroup="rpcOperation"/>
- <!--
- <copy-config> operation
- -->
- <xs:complexType name="copyConfigType">
- <xs:complexContent>
-
-
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="target" type="rpcOperationTargetType"/>
- <xs:element name="source" type="rpcOperationSourceType"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="copy-config" type="copyConfigType"
- substitutionGroup="rpcOperation"/>
- <!--
- <delete-config> operation
- -->
- <xs:complexType name="deleteConfigType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="target" type="rpcOperationTargetType"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="delete-config" type="deleteConfigType"
- substitutionGroup="rpcOperation"/>
- <!--
- <get> operation
- -->
- <xs:complexType name="getType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="filter"
- type="filterInlineType" minOccurs="0"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="get" type="getType"
- substitutionGroup="rpcOperation"/>
- <!--
- <lock> operation
- -->
- <xs:complexType name="lockType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="target"
- type="rpcOperationTargetType"/>
-
-
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="lock" type="lockType"
- substitutionGroup="rpcOperation"/>
- <!--
- <unlock> operation
- -->
- <xs:complexType name="unlockType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="target" type="rpcOperationTargetType"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="unlock" type="unlockType"
- substitutionGroup="rpcOperation"/>
- <!--
- <operations> operation
- -->
- <xs:complexType name="validateType">
- <xs:annotation>
- <xs:documentation>
- The validate operation requires the :validate capability.
- </xs:documentation>
- </xs:annotation>
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="source" type="rpcOperationSourceType"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="validate" type="validateType"
- substitutionGroup="rpcOperation"/>
- <!--
- <commit> operation
- -->
- <xs:simpleType name="confirmTimeoutType">
- <xs:restriction base="xs:unsignedInt">
- <xs:minInclusive value="1"/>
- </xs:restriction>
- </xs:simpleType>
- <xs:complexType name="commitType">
-
-
- <xs:annotation>
- <xs:documentation>
- The commit operation requires the :candidate capability.
- </xs:documentation>
- </xs:annotation>
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:annotation>
- <xs:documentation>
- Use of the confirmed and confirm-timeout elements
- requires the :confirmed-commit capability.
- </xs:documentation>
- </xs:annotation>
- <xs:element name="confirmed" minOccurs="0"/>
- <xs:element name="confirm-timeout"
- type="confirmTimeoutType"
- minOccurs="0"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="commit" type="commitType"
- substitutionGroup="rpcOperation"/>
- <!--
- <discard-changes> operation
- -->
- <xs:complexType name="discardChangesType">
- <xs:annotation>
- <xs:documentation>
- The discard-changes operation requires the
- :candidate capability.
- </xs:documentation>
- </xs:annotation>
- <xs:complexContent>
- <xs:extension base="rpcOperationType"/>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="discard-changes"
- type="discardChangesType"
- substitutionGroup="rpcOperation"/>
- <!--
- <close-session> operation
- -->
- <xs:complexType name="closeSessionType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType"/>
- </xs:complexContent>
-
-
- </xs:complexType>
- <xs:element name="close-session" type="closeSessionType"
- substitutionGroup="rpcOperation"/>
- <!--
- <kill-session> operation
- -->
- <xs:complexType name="killSessionType">
- <xs:complexContent>
- <xs:extension base="rpcOperationType">
- <xs:sequence>
- <xs:element name="session-id"
- type="SessionId" minOccurs="1"/>
- </xs:sequence>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
- <xs:element name="kill-session" type="killSessionType"
- substitutionGroup="rpcOperation"/>
- <!--
- <hello> element
- -->
- <xs:element name="hello">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="capabilities">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="capability" type="xs:anyURI"
- maxOccurs="unbounded"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
- <xs:element name="session-id"
- type="SessionId" minOccurs="0"/>
- </xs:sequence>
- </xs:complexType>
- </xs:element>
-</xs:schema>
+++ /dev/null
-<?xml version='1.0'?>
-<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
-<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"
- xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns="http://www.w3.org/1999/xhtml"
- xml:lang="en">
-
- <xs:annotation>
- <xs:documentation>
- <div>
- <h1>About the XML namespace</h1>
-
- <div class="bodytext">
- <p>
- This schema document describes the XML namespace, in a form
- suitable for import by other schema documents.
- </p>
- <p>
- See
- <a href="http://www.w3.org/XML/1998/namespace.html">
- http://www.w3.org/XML/1998/namespace.html
- </a>
- and
- <a href="http://www.w3.org/TR/REC-xml">
- http://www.w3.org/TR/REC-xml
- </a>
- for information
- about this namespace.
- </p>
- <p>
- Note that local names in this namespace are intended to be
- defined only by the World Wide Web Consortium or its subgroups.
- The names currently defined in this namespace are listed below.
- They should not be used with conflicting semantics by any Working
- Group, specification, or document instance.
- </p>
- <p>
- See further below in this document for more information about
- <a
- href="#usage">how to refer to this schema document from your own
- XSD schema documents
- </a>
- and about<a href="#nsversioning">the
- namespace-versioning policy governing this schema document</a>.
- </p>
- </div>
- </div>
- </xs:documentation>
- </xs:annotation>
-
- <xs:attribute name="lang">
- <xs:annotation>
- <xs:documentation>
- <div>
-
- <h3>lang (as an attribute name)</h3>
- <p>
- denotes an attribute whose value
- is a language code for the natural language of the content of
- any element; its value is inherited. This name is reserved
- by virtue of its definition in the XML specification.
- </p>
-
- </div>
- <div>
- <h4>Notes</h4>
- <p>
- Attempting to install the relevant ISO 2- and 3-letter
- codes as the enumerated possible values is probably never
- going to be a realistic possibility.
- </p>
- <p>
- See BCP 47 at
- <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
- http://www.rfc-editor.org/rfc/bcp/bcp47.txt
- </a>
- and the IANA language subtag registry at
- <a href="http://www.iana.org/assignments/language-subtag-registry">
- http://www.iana.org/assignments/language-subtag-registry
- </a>
- for further information.
- </p>
- <p>
- The union allows for the 'un-declaration' of xml:lang with
- the empty string.
- </p>
- </div>
- </xs:documentation>
- </xs:annotation>
- <xs:simpleType>
- <xs:union memberTypes="xs:language">
- <xs:simpleType>
- <xs:restriction base="xs:string">
- <xs:enumeration value=""/>
- </xs:restriction>
- </xs:simpleType>
- </xs:union>
- </xs:simpleType>
- </xs:attribute>
-
- <xs:attribute name="space">
- <xs:annotation>
- <xs:documentation>
- <div>
-
- <h3>space (as an attribute name)</h3>
- <p>
- denotes an attribute whose
- value is a keyword indicating what whitespace processing
- discipline is intended for the content of the element; its
- value is inherited. This name is reserved by virtue of its
- definition in the XML specification.
- </p>
-
- </div>
- </xs:documentation>
- </xs:annotation>
- <xs:simpleType>
- <xs:restriction base="xs:NCName">
- <xs:enumeration value="default"/>
- <xs:enumeration value="preserve"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
-
- <xs:attribute name="base" type="xs:anyURI">
- <xs:annotation>
- <xs:documentation>
- <div>
-
- <h3>base (as an attribute name)</h3>
- <p>
- denotes an attribute whose value
- provides a URI to be used as the base for interpreting any
- relative URIs in the scope of the element on which it
- appears; its value is inherited. This name is reserved
- by virtue of its definition in the XML Base specification.
- </p>
-
- <p>
- See
- <a
- href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/
- </a>
- for information about this attribute.
- </p>
- </div>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- <xs:attribute name="id" type="xs:ID">
- <xs:annotation>
- <xs:documentation>
- <div>
-
- <h3>id (as an attribute name)</h3>
- <p>
- denotes an attribute whose value
- should be interpreted as if declared to be of type ID.
- This name is reserved by virtue of its definition in the
- xml:id specification.
- </p>
-
- <p>
- See
- <a
- href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/
- </a>
- for information about this attribute.
- </p>
- </div>
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
-
- <xs:attributeGroup name="specialAttrs">
- <xs:attribute ref="xml:base"/>
- <xs:attribute ref="xml:lang"/>
- <xs:attribute ref="xml:space"/>
- <xs:attribute ref="xml:id"/>
- </xs:attributeGroup>
-
- <xs:annotation>
- <xs:documentation>
- <div>
-
- <h3>Father (in any context at all)</h3>
-
- <div class="bodytext">
- <p>
- denotes Jon Bosak, the chair of
- the original XML Working Group. This name is reserved by
- the following decision of the W3C XML Plenary and
- XML Coordination groups:
- </p>
- <blockquote>
- <p>
- In appreciation for his vision, leadership and
- dedication the W3C XML Plenary on this 10th day of
- February, 2000, reserves for Jon Bosak in perpetuity
- the XML name "xml:Father".
- </p>
- </blockquote>
- </div>
- </div>
- </xs:documentation>
- </xs:annotation>
-
- <xs:annotation>
- <xs:documentation>
- <div xml:id="usage" id="usage">
- <h2>
- <a name="usage">About this schema document</a>
- </h2>
-
- <div class="bodytext">
- <p>
- This schema defines attributes and an attribute group suitable
- for use by schemas wishing to allow<code>xml:base</code>,
- <code>xml:lang</code>,
- <code>xml:space</code>
- or
- <code>xml:id</code>
- attributes on elements they define.
- </p>
- <p>
- To enable this, such a schema must import this schema for
- the XML namespace, e.g. as follows:
- </p>
- <pre>
- <schema . . .>
- . . .
- <import namespace="http://www.w3.org/XML/1998/namespace"
- schemaLocation="http://www.w3.org/2001/xml.xsd"/>
- </pre>
- <p>
- or
- </p>
- <pre>
- <import namespace="http://www.w3.org/XML/1998/namespace"
- schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
- </pre>
- <p>
- Subsequently, qualified reference to any of the attributes or the
- group defined below will have the desired effect, e.g.
- </p>
- <pre>
- <type . . .>
- . . .
- <attributeGroup ref="xml:specialAttrs"/>
- </pre>
- <p>
- will define a type which will schema-validate an instance element
- with any of those attributes.
- </p>
- </div>
- </div>
- </xs:documentation>
- </xs:annotation>
-
- <xs:annotation>
- <xs:documentation>
- <div id="nsversioning" xml:id="nsversioning">
- <h2>
- <a name="nsversioning">Versioning policy for this schema document</a>
- </h2>
- <div class="bodytext">
- <p>
- In keeping with the XML Schema WG's standard versioning
- policy, this schema document will persist at
- <a href="http://www.w3.org/2009/01/xml.xsd">
- http://www.w3.org/2009/01/xml.xsd</a>.
- </p>
- <p>
- At the date of issue it can also be found at
- <a href="http://www.w3.org/2001/xml.xsd">
- http://www.w3.org/2001/xml.xsd</a>.
- </p>
- <p>
- The schema document at that URI may however change in the future,
- in order to remain compatible with the latest version of XML
- Schema itself, or with the XML namespace itself. In other words,
- if the XML Schema or XML namespaces change, the version of this
- document at
- <a href="http://www.w3.org/2001/xml.xsd">
- http://www.w3.org/2001/xml.xsd
- </a>
- will change accordingly; the version at
- <a href="http://www.w3.org/2009/01/xml.xsd">
- http://www.w3.org/2009/01/xml.xsd
- </a>
- will not change.
- </p>
- <p>
- Previous dated (and unchanging) versions of this schema
- document are at:
- </p>
- <ul>
- <li>
- <a href="http://www.w3.org/2009/01/xml.xsd">
- http://www.w3.org/2009/01/xml.xsd
- </a>
- </li>
- <li>
- <a href="http://www.w3.org/2007/08/xml.xsd">
- http://www.w3.org/2007/08/xml.xsd
- </a>
- </li>
- <li>
- <a href="http://www.w3.org/2004/10/xml.xsd">
- http://www.w3.org/2004/10/xml.xsd
- </a>
- </li>
- <li>
- <a href="http://www.w3.org/2001/03/xml.xsd">
- http://www.w3.org/2001/03/xml.xsd
- </a>
- </li>
- </ul>
- </div>
- </div>
- </xs:documentation>
- </xs:annotation>
-
-</xs:schema>
-
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.collect.Lists;
-import org.junit.Test;
-
-public class CloseableUtilTest {
-
- @Test
- public void testCloseAllFail() throws Exception {
- final AutoCloseable failingCloseable = new AutoCloseable() {
- @Override
- public void close() throws Exception {
- throw new RuntimeException("testing failing close");
- }
- };
-
- try {
- CloseableUtil.closeAll(Lists.newArrayList(failingCloseable, failingCloseable));
- fail("Exception with suppressed should be thrown");
- } catch (final RuntimeException e) {
- assertEquals(1, e.getSuppressed().length);
- }
- }
-
- @Test
- public void testCloseAll() throws Exception {
- final AutoCloseable failingCloseable = mock(AutoCloseable.class);
- doNothing().when(failingCloseable).close();
- CloseableUtil.closeAll(Lists.newArrayList(failingCloseable, failingCloseable));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-
-public class NetconfUtilTest {
-
- @Test
- public void testConflictingVersionDetection() throws Exception {
- Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
- try{
- NetconfUtil.checkIsMessageOk(document);
- fail();
- }catch(IllegalStateException e){
- assertThat(e.getMessage(), containsString("Optimistic lock failed. Expected parent version 21, was 18"));
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class AbstractLastNetconfOperationTest {
- class LastNetconfOperationImplTest extends AbstractLastNetconfOperation {
-
- boolean handleWithNoSubsequentOperationsRun;
-
- protected LastNetconfOperationImplTest(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- handleWithNoSubsequentOperationsRun = false;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
- handleWithNoSubsequentOperationsRun = true;
- return null;
- }
-
- @Override
- protected String getOperationName() {
- return "";
- }
- }
-
- LastNetconfOperationImplTest netconfOperation;
-
- @Before
- public void setUp() throws Exception {
- netconfOperation = new LastNetconfOperationImplTest("");
- }
-
- @Test
- public void testNetconfOperation() throws Exception {
- netconfOperation.handleWithNoSubsequentOperations(null, null);
- assertTrue(netconfOperation.handleWithNoSubsequentOperationsRun);
- assertEquals(HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY, netconfOperation.getHandlingPriority());
- }
-
- @Test(expected = DocumentedException.class)
- public void testHandle() throws Exception {
- NetconfOperationChainedExecution operation = mock(NetconfOperationChainedExecution.class);
- doReturn("").when(operation).toString();
-
- doReturn(false).when(operation).isExecutionTermination();
- netconfOperation.handle(null, null, operation);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.io.IOException;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-public class AbstractNetconfOperationTest {
-
- class NetconfOperationImpl extends AbstractNetconfOperation {
-
- public boolean handleRun;
-
- protected NetconfOperationImpl(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- this.handleRun = false;
- }
-
- @Override
- protected String getOperationName() {
- return null;
- }
-
- @Override
- protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation) throws DocumentedException{
- this.handleRun = true;
- try {
- return XmlUtil.readXmlToElement("<element/>");
- } catch (SAXException | IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- private NetconfOperationImpl netconfOperation;
- private NetconfOperationChainedExecution operation;
-
- @Before
- public void setUp() throws Exception {
- netconfOperation = new NetconfOperationImpl("str");
- operation = mock(NetconfOperationChainedExecution.class);
- }
-
- @Test
- public void testAbstractNetconfOperation() throws Exception {
- Document helloMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/edit_config.xml");
- assertEquals(netconfOperation.getNetconfSessionIdForReporting(), "str");
- assertNotNull(netconfOperation.canHandle(helloMessage));
- assertEquals(netconfOperation.getHandlingPriority(), HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY);
-
- netconfOperation.handle(helloMessage, operation);
- assertTrue(netconfOperation.handleRun);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.mapping;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class AbstractSingletonNetconfOperationTest {
- class SingletonNCOperationImpl extends AbstractSingletonNetconfOperation {
-
- protected SingletonNCOperationImpl(String netconfSessionIdForReporting) {
- super(netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws DocumentedException{
- return null;
- }
-
- @Override
- protected String getOperationName() {
- return null;
- }
- }
-
- @Test
- public void testAbstractSingletonNetconfOperation() throws Exception {
- SingletonNCOperationImpl operation = new SingletonNCOperationImpl("");
- assertEquals(operation.getHandlingPriority(), HandlingPriority.HANDLE_WITH_MAX_PRIORITY);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class NetconfHelloMessageAdditionalHeaderTest {
-
-
- private String customHeader = "[user;1.1.1.1:40;tcp;client;]";
- private NetconfHelloMessageAdditionalHeader header;
-
- @Before
- public void setUp() throws Exception {
- header = new NetconfHelloMessageAdditionalHeader("user", "1.1.1.1", "40", "tcp", "client");
- }
-
- @Test
- public void testGetters() throws Exception {
- assertEquals(header.getAddress(), "1.1.1.1");
- assertEquals(header.getUserName(), "user");
- assertEquals(header.getPort(), "40");
- assertEquals(header.getTransport(), "tcp");
- assertEquals(header.getSessionIdentifier(), "client");
- }
-
- @Test
- public void testStaticConstructor() throws Exception {
- NetconfHelloMessageAdditionalHeader h = NetconfHelloMessageAdditionalHeader.fromString(customHeader);
- assertEquals(h.toString(), header.toString());
- assertEquals(h.toFormattedString(), header.toFormattedString());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.base.Optional;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.internal.util.collections.Sets;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-
-public class NetconfHelloMessageTest {
-
- Set<String> caps;
-
- @Before
- public void setUp() {
- caps = Sets.newSet("cap1");
- }
-
- @Test
- public void testConstructor() throws NetconfDocumentedException {
- NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("name","host","1","transp","id");
- NetconfHelloMessage message = NetconfHelloMessage.createClientHello(caps, Optional.of(additionalHeader));
- assertTrue(NetconfHelloMessage.isHelloMessage(message));
- assertEquals(Optional.of(additionalHeader), message.getAdditionalHeader());
-
- NetconfHelloMessage serverMessage = NetconfHelloMessage.createServerHello(caps, 100L);
- assertTrue(NetconfHelloMessage.isHelloMessage(serverMessage));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.base.Charsets;
-import org.junit.Test;
-
-@Deprecated
-public class NetconfMessageHeaderTest {
- @Test
- public void testGet() throws Exception {
- NetconfMessageHeader header = new NetconfMessageHeader(10);
- assertEquals(header.getLength(), 10);
-
- byte[] expectedValue = "\n#10\n".getBytes(Charsets.US_ASCII);
- assertArrayEquals(expectedValue, header.toBytes());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Collection;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.w3c.dom.Document;
-
-public class NetconfMessageUtilTest {
- @Test
- public void testNetconfMessageUtil() throws Exception {
- Document okMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc-reply_ok.xml");
- assertTrue(NetconfMessageUtil.isOKMessage(new NetconfMessage(okMessage)));
- assertFalse(NetconfMessageUtil.isErrorMessage(new NetconfMessage(okMessage)));
-
- Document errorMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/communicationError/testClientSendsRpcReply_expectedResponse.xml");
- assertTrue(NetconfMessageUtil.isErrorMessage(new NetconfMessage(errorMessage)));
- assertFalse(NetconfMessageUtil.isOKMessage(new NetconfMessage(errorMessage)));
-
- Document helloMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/client_hello.xml");
- Collection<String> caps = NetconfMessageUtil.extractCapabilitiesFromHello(new NetconfMessage(helloMessage).getDocument());
- assertTrue(caps.contains("urn:ietf:params:netconf:base:1.0"));
- assertTrue(caps.contains("urn:ietf:params:netconf:base:1.1"));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.messages;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.util.concurrent.GenericFutureListener;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfSession;
-import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
-import org.w3c.dom.Document;
-
-public class SendErrorExceptionUtilTest {
-
- NetconfSession netconfSession;
- ChannelFuture channelFuture;
- Channel channel;
- private DocumentedException exception;
-
- @Before
- public void setUp() throws Exception {
- netconfSession = mock(NetconfSession.class);
- channelFuture = mock(ChannelFuture.class);
- channel = mock(Channel.class);
- doReturn(channelFuture).when(netconfSession).sendMessage(any(NetconfMessage.class));
- doReturn(channelFuture).when(channelFuture).addListener(any(GenericFutureListener.class));
- doReturn(channelFuture).when(channel).writeAndFlush(any(NetconfMessage.class));
- exception = new DocumentedException("err");
- }
-
- @Test
- public void testSendErrorMessage1() throws Exception {
- SendErrorExceptionUtil.sendErrorMessage(netconfSession, exception);
- verify(channelFuture, times(1)).addListener(any(GenericFutureListener.class));
- verify(netconfSession, times(1)).sendMessage(any(NetconfMessage.class));
- }
-
- @Test
- public void testSendErrorMessage2() throws Exception {
- SendErrorExceptionUtil.sendErrorMessage(channel, exception);
- verify(channelFuture, times(1)).addListener(any(GenericFutureListener.class));
- }
-
- @Test
- public void testSendErrorMessage3() throws Exception {
- Document helloMessage = XmlFileLoader.xmlFileToDocument("netconfMessages/rpc.xml");
- SendErrorExceptionUtil.sendErrorMessage(netconfSession, exception, new NetconfMessage(helloMessage));
- verify(channelFuture, times(1)).addListener(any(GenericFutureListener.class));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.osgi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import com.google.common.base.Optional;
-import io.netty.channel.local.LocalAddress;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-public class NetconfConfigUtilTest {
-
- private BundleContext bundleContext;
-
- @Before
- public void setUp() throws Exception {
- bundleContext = mock(BundleContext.class);
- }
-
- @Test
- public void testNetconfConfigUtil() throws Exception {
- assertEquals(NetconfConfigUtil.getNetconfLocalAddress(), new LocalAddress("netconf"));
-
- doReturn("").when(bundleContext).getProperty("netconf.connectionTimeoutMillis");
- assertEquals(NetconfConfigUtil.extractTimeoutMillis(bundleContext), NetconfConfigUtil.DEFAULT_TIMEOUT_MILLIS);
-
- doReturn("a").when(bundleContext).getProperty("netconf.connectionTimeoutMillis");
- assertEquals(NetconfConfigUtil.extractTimeoutMillis(bundleContext), NetconfConfigUtil.DEFAULT_TIMEOUT_MILLIS);
- }
-
- @Test
- public void testgetPrivateKeyKey() throws Exception {
- assertEquals(NetconfConfigUtil.getPrivateKeyKey(), "netconf.ssh.pk.path");
- }
-
- @Test
- public void testgetNetconfServerAddressKey() throws Exception {
- NetconfConfigUtil.InfixProp prop = NetconfConfigUtil.InfixProp.tcp;
- assertEquals(NetconfConfigUtil.getNetconfServerAddressKey(prop), "netconf.tcp.address");
- }
-
- @Test
- public void testExtractNetconfServerAddress() throws Exception {
- NetconfConfigUtil.InfixProp prop = NetconfConfigUtil.InfixProp.tcp;
- doReturn("").when(bundleContext).getProperty(anyString());
- assertEquals(NetconfConfigUtil.extractNetconfServerAddress(bundleContext, prop), Optional.absent());
- }
-
- @Test
- public void testExtractNetconfServerAddress2() throws Exception {
- NetconfConfigUtil.InfixProp prop = NetconfConfigUtil.InfixProp.tcp;
- doReturn("1.1.1.1").when(bundleContext).getProperty("netconf.tcp.address");
- doReturn("20").when(bundleContext).getProperty("netconf.tcp.port");
- Optional<InetSocketAddress> inetSocketAddressOptional = NetconfConfigUtil.extractNetconfServerAddress(bundleContext, prop);
- assertTrue(inetSocketAddressOptional.isPresent());
- assertEquals(inetSocketAddressOptional.get(), new InetSocketAddress("1.1.1.1", 20));
- }
-
- @Test
- public void testGetPrivateKeyPath() throws Exception {
- doReturn("path").when(bundleContext).getProperty("netconf.ssh.pk.path");
- assertEquals(NetconfConfigUtil.getPrivateKeyPath(bundleContext), "path");
- }
-
- @Test(expected = IllegalStateException.class)
- public void testGetPrivateKeyPath2() throws Exception {
- doReturn(null).when(bundleContext).getProperty("netconf.ssh.pk.path");
- assertEquals(NetconfConfigUtil.getPrivateKeyPath(bundleContext), "path");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.test;
-
-import org.custommonkey.xmlunit.ElementNameAndTextQualifier;
-import org.custommonkey.xmlunit.ElementQualifier;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Custom xmlunit qualifier that doesn't care about order when deeper in the recursion
- * defaults to comparing element name and text content
- */
-public class NetconfXmlUnitRecursiveQualifier implements ElementQualifier {
-
- private final ElementQualifier qualifier;
-
- public NetconfXmlUnitRecursiveQualifier() {
- this.qualifier = new ElementNameAndTextQualifier();
- }
-
- public NetconfXmlUnitRecursiveQualifier(final ElementQualifier qualifier) {
- this.qualifier = qualifier;
- }
-
- @Override
- public boolean qualifyForComparison(Element currentControl,
- Element currentTest) {
- return compareNodes(currentControl, currentTest);
- }
-
- private boolean compareNodes(Node currentControl, Node currentTest) {
- try {
-
- if (!qualifier.qualifyForComparison((Element) currentControl,
- (Element) currentTest)) {
- return false;
- }
-
- NodeList controlNodes;
- NodeList testNodes;
-
- if (currentControl.hasChildNodes() && currentTest.hasChildNodes()) {
- controlNodes = currentControl.getChildNodes();
- testNodes = currentTest.getChildNodes();
- } else {
- return !(currentControl.hasChildNodes() || currentTest.hasChildNodes());
- }
-
- return (countNodesWithoutConsecutiveTextNodes(controlNodes) == countNodesWithoutConsecutiveTextNodes(testNodes))
- && checkChildren(controlNodes, testNodes);
-
- } catch (Exception e) {
- return false;
- }
- }
-
- private boolean checkChildren(NodeList controlNodes, NodeList testNodes) {
- for (int i = 0; i < controlNodes.getLength(); i++) {
- boolean matchFound = false;
- for (int j = 0; j < testNodes.getLength(); j++) {
- Node controlNode = controlNodes.item(i);
- Node testNode = testNodes.item(j);
-
- if (controlNode.getNodeType() != testNode.getNodeType()) {
- continue;
- }
-
- if (controlNode.getNodeType() == Node.TEXT_NODE) {
- if (concatenateText(controlNode).equals(concatenateText(testNode))) {
- matchFound = true;
- break;
- }
-
- } else if (compareNodes(controlNode, testNode)) {
- matchFound = true;
- break;
- }
- }
- if (!matchFound) {
- return false;
- }
- }
-
- return true;
- }
-
- private static String concatenateText(Node textNode) {
- StringBuilder builder = new StringBuilder();
- Node next = textNode;
-
- do {
- if (next.getNodeValue() != null) {
- builder.append(next.getNodeValue().trim());
- next = next.getNextSibling();
- }
- } while (next != null && next.getNodeType() == Node.TEXT_NODE);
-
- return builder.toString();
- }
-
- private static int countNodesWithoutConsecutiveTextNodes(NodeList l) {
- int count = 0;
- boolean lastNodeWasText = false;
- final int length = l.getLength();
- for (int i = 0; i < length; i++) {
- Node n = l.item(i);
- if (!lastNodeWasText || n.getNodeType() != Node.TEXT_NODE) {
- count++;
- }
- lastNodeWasText = n.getNodeType() == Node.TEXT_NODE;
- }
- return count;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.test;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.io.ByteSource;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.xml.parsers.ParserConfigurationException;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-public class XmlFileLoader {
-
- public static NetconfMessage xmlFileToNetconfMessage(final String fileName) throws IOException, SAXException,
- ParserConfigurationException {
- return new NetconfMessage(xmlFileToDocument(fileName));
- }
-
- public static Element xmlFileToElement(final String fileName) throws IOException, SAXException,
- ParserConfigurationException {
- return xmlFileToDocument(fileName).getDocumentElement();
- }
-
- public static String xmlFileToString(final String fileName) throws IOException, SAXException,
- ParserConfigurationException {
- return XmlUtil.toString(xmlFileToDocument(fileName));
- }
-
- public static Document xmlFileToDocument(final String fileName) throws IOException, SAXException,
- ParserConfigurationException {
- try (InputStream resourceAsStream = XmlFileLoader.class.getClassLoader().getResourceAsStream(fileName)) {
- Preconditions.checkNotNull(resourceAsStream, fileName);
- final Document doc = XmlUtil.readXmlToDocument(resourceAsStream);
- return doc;
- }
- }
-
- public static String fileToString(final String fileName) throws IOException {
- try (InputStream resourceAsStream = XmlFileLoader.class.getClassLoader().getResourceAsStream(fileName)) {
- Preconditions.checkNotNull(resourceAsStream);
- return new ByteSource() {
- @Override
- public InputStream openStream() {
- return resourceAsStream;
- }
- }.asCharSource(Charsets.UTF_8).read();
-
- }
- }
-
- public static InputStream getResourceAsStream(final String fileName) {
- return XmlFileLoader.class.getClassLoader().getResourceAsStream(fileName);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.test;
-
-import static org.custommonkey.xmlunit.XMLAssert.assertNodeTestPasses;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.custommonkey.xmlunit.AbstractNodeTester;
-import org.custommonkey.xmlunit.NodeTest;
-import org.custommonkey.xmlunit.NodeTestException;
-import org.custommonkey.xmlunit.NodeTester;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
-public class XmlUnitUtil {
-
- private XmlUnitUtil() {}
-
- public static void assertContainsElementWithText(final Document doc, final String textToFind) throws NodeTestException {
- NodeTest nt = new NodeTest(doc);
- NodeTester tester = new AbstractNodeTester() {
-
- boolean textFound = false;
-
- @Override
- public void testText(Text text) throws NodeTestException {
- if(!textFound) {
- if (text.getData().equalsIgnoreCase(textToFind)) {
- textFound = true;
- }
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertTrue(textFound);
- }
- };
- assertNodeTestPasses(nt, tester, new short[]{Node.TEXT_NODE}, true);
- }
-
- public static void assertContainsElement(final Document doc, final Element testElement) throws NodeTestException {
- NodeTest nt = new NodeTest(doc);
- NodeTester tester = new AbstractNodeTester() {
-
- private boolean elementFound = false;
-
- @Override
- public void testElement(Element element) throws NodeTestException {
- if (!elementFound) {
- if(element.isEqualNode(testElement)) {
- elementFound = true;
- }
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertTrue(elementFound);
- }
- };
- assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true);
- }
-
- public static void assertContainsElementWithName(final Document doc, final String elementName) throws NodeTestException {
- NodeTest nt = new NodeTest(doc);
- NodeTester tester = new AbstractNodeTester() {
-
- private boolean elementFound = false;
-
- @Override
- public void testElement(Element element) throws NodeTestException {
- if (!elementFound) {
- if (element.getNodeName() != null && element.getNodeName().equals(elementName)) {
- elementFound = true;
- }
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertTrue(XmlUtil.toString(doc), elementFound);
- }
- };
- assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true);
- }
-
- public static void assertElementsCount(final Document doc, final String elementName, final int expectedCount) {
- NodeTest nt = new NodeTest(doc);
- NodeTester tester = new AbstractNodeTester() {
-
- private int elementFound = 0;
-
- @Override
- public void testElement(Element element) throws NodeTestException {
- if (element.getNodeName() != null && element.getNodeName().equals(elementName)) {
- elementFound++;
- }
- }
-
- @Override
- public void noMoreNodes(NodeTest forTest) throws NodeTestException {
- assertEquals(expectedCount, elementFound);
- }
- };
- assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-
-public class HardcodedNamespaceResolverTest {
-
- @Test
- public void testResolver() throws Exception {
- final HardcodedNamespaceResolver hardcodedNamespaceResolver = new HardcodedNamespaceResolver("prefix", "namespace");
-
- assertEquals("namespace", hardcodedNamespaceResolver.getNamespaceURI("prefix"));
- try{
- hardcodedNamespaceResolver.getNamespaceURI("unknown");
- fail("Unknown namespace lookup should fail");
- } catch(IllegalStateException e) {}
-
- assertNull(hardcodedNamespaceResolver.getPrefix("any"));
- assertNull(hardcodedNamespaceResolver.getPrefixes("any"));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.util.xml;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.w3c.dom.Element;
-
-public class XMLNetconfUtilTest {
-
- @Test
- public void testXPath() throws Exception {
- final XPathExpression correctXPath = XMLNetconfUtil.compileXPath("/top/innerText");
- try {
- XMLNetconfUtil.compileXPath("!@(*&$!");
- fail("Incorrect xpath should fail");
- } catch (IllegalStateException e) {}
- final Object value = XmlUtil.evaluateXPath(correctXPath, XmlUtil.readXmlToDocument("<top><innerText>value</innerText></top>"), XPathConstants.NODE);
- assertEquals("value", ((Element) value).getTextContent());
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <capabilities>
- <capability>urn:ietf:params:netconf:base:1.0</capability>
- <capability>urn:ietf:params:netconf:base:1.1</capability>
- </capabilities>
-</hello>
+++ /dev/null
-<rpc message-id="103" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <close-session/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="1" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <close-session xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <commit></commit>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <rpc-error>
- <error-type>protocol</error-type>
- <error-tag>unknown-element</error-tag>
- <error-severity>error</error-severity>
- <error-info>
- <bad-element>rpc-reply</bad-element>
- </error-info>
- </rpc-error>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc-reply message-id="*** replaced by message id ***"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <ok/>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <rpc-error>
- <error-type>rpc</error-type>
- <error-tag>missing-attribute</error-tag>
- <error-severity>error</error-severity>
- <error-info>
- <bad-attribute>message-id</bad-attribute>
- <bad-element>rpc</bad-element>
- </error-info>
- </rpc-error>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="persister_commit">
- <rpc-error>
- <error-type>application</error-type>
- <error-tag>operation-failed</error-tag>
- <error-severity>error</error-severity>
-
-
-
- <error-info>
- <error>org.opendaylight.controller.config.api.ConflictingVersionException: Optimistic lock failed. Expected parent version 21, was 18</error>
- </error-info>
- </rpc-error>
-</rpc-reply>
+++ /dev/null
-<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-config>
- <source>
- <running/>
- </source>
- <filter type="xpath" select="/top/jmxbean[objectName='org.opendaylight.controller:type=ConfigRegistry']"/>
- </get-config>
-</rpc>
+++ /dev/null
-<rpc-reply message-id="101"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <data>
- <jmxbean
- objectName="org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean">
- <ExportedInterfaces>
- <Entries>
- <Entry>testing-threadpool</Entry>
- <Entry>modifiable-threadpool</Entry>
- </Entries>
- </ExportedInterfaces>
- <ImplementationName>fixed</ImplementationName>
- <ThreadCount>10</ThreadCount>
- <TriggerNewInstanceCreation>false</TriggerNewInstanceCreation>
- </jmxbean>
- <jmxbean
- objectName="org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean">
- <ExportedInterfaces>
- <Entries>
- <Entry>testing-threadpool</Entry>
- <Entry>modifiable-threadpool</Entry>
- </Entries>
- </ExportedInterfaces>
- <ImplementationName>fixed</ImplementationName>
- <ThreadCount>10</ThreadCount>
- <TriggerNewInstanceCreation>false</TriggerNewInstanceCreation>
- </jmxbean>
- </data>
-</rpc-reply>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <discard-changes></discard-changes>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="101" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>instance-from-code_dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>instance-from-code</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
-
- <from-grouping>
- <enum-in-grouping>version1</enum-in-grouping>
- </from-grouping>
- <sleep-factor>
- 2.58
- </sleep-factor>
-
- <extended>
- 10
- </extended>
-
- <extended-twice>
- 20
- </extended-twice>
-
- <extended-enum>
- two
- </extended-enum>
-
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>YmluYXJ5</binaryLeaf>
-
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">configAttributeType</type>
- <dto_d xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep_user</name>
- </testing-dep>
-
- <testing-deps>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep_user</name>
- </testing-deps>
- <testing-deps>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep_user_two</name>
- </testing-deps>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-short>4</simple-short>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep_user_two</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep_user</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_user_two</name>
- <provider>/config/modules/module[name='impl-dep']/instance[name='dep2']
- </provider>
- </instance>
- <instance>
- <name>user_to_instance_from_code</name>
- <provider>
- /modules/module[type='impl-netconf'][name='instance-from-code']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>instance-from-code_dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep_user_another</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- test-only
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>instance-from-code_dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep_user_another_test1</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_user_another_test2</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" id="a" message-id="101" xmlnx="a:b:c:d">
- <data>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
- </data>
-</rpc-reply>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-identity-test
- </type>
- <name>id-test</name>
- <identities>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</safi>
- </identities>
- <identities>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</afi>
- <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</safi>
- </identities>
- <identities-container>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity2</afi>
- </identities-container>
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>none</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-identity-test
- </type>
- <name>id-test</name>
- <identities xc:operation="replace">
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</safi>
- </identities>
- <identities-container xc:operation="replace">
- <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:test:types">prefix:test-identity1</afi>
- </identities-container>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <default-operation>merge</default-operation>
- <test-option>set</test-option>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <name>d1</name>
- <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
- </module>
- <module>
- <name>d2</name>
- <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
- </module>
- <module>
- <name>parent</name>
- <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
-
- <multiple-dependencies xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-deps>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_d1</name>
- </testing-deps>
- <testing-deps>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_d2</name>
- </testing-deps>
- </multiple-dependencies>
-
- </module>
-
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_d1</name>
- <provider>/modules/module[type='multiple-dependencies'][name='d1']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_d2</name>
- <provider>/modules/module[type='multiple-dependencies'][name='d2']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <default-operation>merge</default-operation>
- <test-option>set</test-option>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <name>d3</name>
- <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
- </module>
- <module>
- <name>parent</name>
- <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:multiple-dependencies</type>
- <multiple-dependencies xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-deps>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_d3</name>
- </testing-deps>
- </multiple-dependencies>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_d3</name>
- <provider>/modules/module[type='multiple-dependencies'][name='d3']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <default-operation>merge</default-operation>
- <test-option>set</test-option>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="merge">
- <name>threadfactory-naming-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- th-java:threadfactory-naming
- </type>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefixDefinedInXML
- </name-prefix>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory</type>
- <instance>
- <name>user_to_instance_from_code</name>
- <provider>
- /modules/module[type='threadfactory-naming'][name='threadfactory-naming-instance']</provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <default-operation>merge</default-operation>
- <test-option>set</test-option>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="merge">
- <name>impl-dep-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:test:impl">th-java:impl-dep
- </type>
- </module>
- </modules>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>none</default-operation>
- <error-option>stop-on-error</error-option>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <name>instance-from-code_dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>instance-from-code</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>8ad1</binaryLeaf>
- <dto_d>
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- </impl-netconf>
- </module>
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test3</name>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>none</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="remove">
- <name>instance-from-code_dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="remove">
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="remove">
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="remove">
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>instance-from-code</name>
- </module>
-
- <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="remove">
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- </module>
- </modules>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- test-then-set
- </test-option>
- <default-operation>none</default-operation>
- <config>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <name>ref_dep_user_another</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- test-then-set
- </test-option>
- <default-operation>none</default-operation>
- <config>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance xmlns:a="urn:ietf:params:xml:ns:netconf:base:1.0" a:operation="delete">
- <name>i_dont_exist</name>
- <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>replace</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
- </modules>
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"/>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>replace</default-operation>
- <config xmlns="top:level:namespace">
- <modules>
- <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl" operation="remove">
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">impl-dep</type>
- <name>dep</name>
- </module>
- <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl" operation="remove">
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">impl-dep</type>
- <name>dep2</name>
- </module>
- </modules>
- <services/>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <config xmlns="top:level:namespace">
- <modules>
- <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl"
- operation="replace">
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">impl-dep</type>
- <name>dep</name>
- </module>
- </modules>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <default-operation>replace</default-operation>
- <config xmlns="top:level:namespace">
- <modules operation="replace">
- <module xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl" operation="merge">
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">impl-dep</type>
- <name>dep</name>
- </module>
- </modules>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>instance-from-code</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <ip xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">127.1.2.3</ip>
- <union-test-attr xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">randomStringForUnion</union-test-attr>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc message-id="1"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <config/>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <source>
- <running/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <get-config>
- <source>
- <candidate/>
- </source>
- </get-config>
-</rpc>
+++ /dev/null
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
- <identifier>threadpool-api</identifier>
- </get-schema>
-</rpc>
+++ /dev/null
-<rpc message-id="2"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
- <identifier>threadpool-api</identifier>
- <version>2010-09-24</version>
- <format
- xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">ncm:yang
- </format>
- </get-schema>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <capabilities>
- <capability>urn:ietf:params:netconf:base:1.0</capability>
- </capabilities>
- <session-id>666</session-id>
-</hello>
+++ /dev/null
-<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.1">
- <capabilities>
- <capability>urn:ietf:params:netconf:base:1.0</capability>
- </capabilities>
-</hello>
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="101"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <lock>
- <target>
- <candidate/>
- </target>
- </lock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rpc message-id="6"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <target>
- <candidate/>
- </target>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="merge">
- <name>threadfactory-naming-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- th-java:threadfactory-naming
- </type>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefixDefinedInXML
- </name-prefix>
- </module>
- </modules>
-
- <mountpoints>
- <mountpoint>
- <id>localhost:12002</id>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="merge">
- <name>threadfactory-naming-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- th-java:threadfactory-naming
- </type>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefixDefinedInXML
- </name-prefix>
- </module>
- </modules>
- </config>
- </mountpoint>
- <mountpoint>
- <id>localhost:12003</id>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="replace">
- <name>threadfactory-naming-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- th-java:threadfactory-naming
- </type>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefixDefinedInXML
- </name-prefix>
- </module>
- </modules>
- </config>
- </mountpoint>
- </mountpoints>
- </config>
-
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mount>
- <mountpoint-id>
- localhost:12002
- </mountpoint-id>
- </mount>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <mount>
- <mountpoint-id>
- localhost:12003
- </mountpoint-id>
- </mount>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unmount>
- <mountpoint-id>
- localhost:12002
- </mountpoint-id>
- </unmount>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>test1</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>8545649856</binaryLeaf>
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">configAttributeType</type>
- <dto_d>
- <simple-int1>444</simple-int1>
- <simple-int2 xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl2">4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_2</name>
- <provider>/modules/module[type='impl-dep'][name='dep2']
- </provider>
- </instance>
- <instance>
- <name>ref_test1</name>
- <provider>
- /modules/module[type='impl-netconf'][name='test1']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl
- </type>
-
- <name>testimpl</name>
- <simpleInt>1</simpleInt>
- <simpleInt xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">2</simpleInt>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>test1</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <simple-long-2 xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">44</simple-long-2>
- <binaryLeaf></binaryLeaf>
- <type xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">configAttributeType</type>
- <dto_d xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_2</name>
- <provider>/modules/module[type='impl-dep'][name='dep2']
- </provider>
- </instance>
- <instance>
- <name>ref_test1</name>
- <provider>
- /modules/module[type='impl-netconf'][name='test1']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl
- </type>
-
- <name>test1</name>
- <allow-user>1</allow-user>
- <allow-user xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">2</allow-user>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>test1</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>8545649856</binaryLeaf>
- <dto_d xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_2</name>
- <provider>/modules/module[type='impl-dep'][name='dep2']
- </provider>
- </instance>
- <instance>
- <name>ref_test1</name>
- <provider>
- /modules/module[type='impl-netconf'][name='test1']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" message-id="a">
- <ok/>
-</rpc-reply>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <no-arg xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <context-instance>/modules/module[type='impl-netconf' and name='instance-from-code']</context-instance>
- <arg1>
- testarg1
- </arg1>
- </no-arg>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <noArgInner xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <context-instance>
- /modules/module[name='instance-from-code'][type='impl-netconf']/inner-running-data-additional[key='1']
- </context-instance>
- </noArgInner>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <noArgInnerInner
- xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <context-instance>
- /modules/module[type='impl-netconf'][name='test2']/inner-running-data[key='2']/inner-inner-running-data[key='3']
- </context-instance>
-
- <arg1>
- 456
- </arg1>
- <arg2>
- true
- </arg2>
-
- </noArgInnerInner>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <leaf-list-output
- xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <context-instance>
- /modules/module[type='impl-netconf'][name='instance-from-code']/inner-running-data[key='0']/inner-inner-running-data[key='1']
- </context-instance>
- </leaf-list-output>
-</rpc>
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" a="64" message-id="a">
-<start-exi xmlns="urn:ietf:params:xml:ns:netconf:exi:1.0">
-<alignment>pre-compression</alignment>
-<fidelity>
-<dtd/>
-<lexical-values/>
-</fidelity>
-</start-exi>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <stop-exi xmlns="urn:ietf:params:xml:ns:netconf:exi:1.0"/>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module
- xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
- nc:operation="merge">
- <name>threadfactory-naming-instance</name>
- <type
- xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- th-java:threadfactory-naming
- </type>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
- prefixDefinedInXML
- </name-prefix>
- </module>
- </modules>
- </config>
- </edit-config>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<rpc message-id="101"
- xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <unlock>
- <target>
- <candidate/>
- </target>
- </unlock>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- <unknownAttribute>error</unknownAttribute>
- </module>
-
-
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/config/modules/module[name='impl-dep']/instance[name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- </modules>
-
- <unknownAttribute>error</unknownAttribute>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- </modules>
-
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <unknownAttribute>error</unknownAttribute>
- l
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- </modules>
-
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- l
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <unknownAttribute>error</unknownAttribute>
-
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- </modules>
-
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- l
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
-
- <instance>
- <name>ref_dep</name>
- <unknownAttribute>error</unknownAttribute>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <unknownAttribute>error</unknownAttribute>
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
-
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>test1</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>8545649856</binaryLeaf>
- <dto_d>
- <unknownAttribute>error</unknownAttribute>
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_2</name>
- <provider>/modules/module[type='impl-dep'][name='dep2']
- </provider>
- </instance>
- <instance>
- <name>ref_test1</name>
- <provider>
- /modules/module[type='impl-netconf'][name='test1']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <edit-config>
- <target>
- <candidate/>
- </target>
- <test-option>
- set
- </test-option>
- <default-operation>merge</default-operation>
- <config>
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <module>
- <name>dep</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <name>dep2</name>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-dep
- </type>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
-
- <name>test1</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <simple-long-2>44</simple-long-2>
- <binaryLeaf>8545649856</binaryLeaf>
- <dto_d>
- <simple-int1>444</simple-int1>
- <simple-int2>4444</simple-int2>
- <simple-int3>454</simple-int3>
- <complex-dto-bInner>
- <simple-int3>44</simple-int3>
- <deep>
- <simple-int3>4</simple-int3>
- </deep>
- <simple-list>4</simple-list>
- </complex-dto-bInner>
- <simple-list>4</simple-list>
- </dto_d>
- <simpleInt>44</simpleInt>
- <simple-test>545</simple-test>
- <simple-long>454545</simple-long>
- <simpleBoolean>false</simpleBoolean>
- <dto-c>
- <dto-a-inner>
- <dto-a-inner-inner>
- <simple-arg>456</simple-arg>
- </dto-a-inner-inner>
- <simple-arg>44</simple-arg>
- </dto-a-inner>
- </dto-c>
- <simple-short>4</simple-short>
- <simple-BigInteger>999</simple-BigInteger>
- <simple-byte>4</simple-byte>
- <peers>
- <port>port1</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- </peers>
- <peers>
- <port>port23</port>
- <simple-int3>456</simple-int3>
- <core-size>44</core-size>
- <unknownAttribute>error</unknownAttribute>
- </peers>
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
-
- <module>
- <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- test-impl:impl-netconf
- </type>
- <name>test2</name>
- <impl-netconf xmlns="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
- <testing-dep>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <name>ref_dep</name>
- </testing-dep>
- </impl-netconf>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
- <instance>
- <name>ref_dep</name>
- <provider>/modules/module[type='impl-dep'][name='dep']
- </provider>
- </instance>
- <instance>
- <name>ref_dep_2</name>
- <provider>/modules/module[type='impl-dep'][name='dep2']
- </provider>
- </instance>
- <instance>
- <name>ref_test1</name>
- <provider>
- /modules/module[type='impl-netconf'][name='test1']
- </provider>
- </instance>
- </service>
- </services>
- </config>
- </edit-config>
-</rpc>
+++ /dev/null
-<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
- <validate>
- <source>
- <candidate/>
- </source>
- </validate>
-</rpc>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.opendaylight</artifactId>
- <version>1.6.0-SNAPSHOT</version>
- <relativePath>../commons/opendaylight</relativePath>
- </parent>
- <artifactId>netconf-subsystem</artifactId>
-
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <properties>
- <netconf.version>0.4.0-SNAPSHOT</netconf.version>
- <config.netconf.client.configfile>01-netconf.xml</config.netconf.client.configfile>
- <config.netconf.mdsal.configfile>08-mdsal-netconf.xml</config.netconf.mdsal.configfile>
- <config.netconf.connector.configfile>99-netconf-connector.xml</config.netconf.connector.configfile>
- <sonar.exclusions>**/org/opendaylight/controller/netconf/cli/**, **/org/opendaylight/controller/netconf/test/tool/**</sonar.exclusions>
- </properties>
-
- <modules>
- <module>netconf-artifacts</module>
-
- <module>netconf-api</module>
- <module>netconf-config</module>
- <module>netconf-impl</module>
- <module>config-netconf-connector</module>
- <module>mdsal-netconf-connector</module>
- <module>mdsal-netconf-monitoring</module>
- <module>netconf-util</module>
- <module>netconf-netty-util</module>
- <module>netconf-mapping-api</module>
- <module>netconf-client</module>
- <module>netconf-config-dispatcher</module>
- <module>netconf-ssh</module>
- <module>netconf-tcp</module>
- <module>netconf-monitoring</module>
- <module>netconf-connector-config</module>
- <module>netconf-mdsal-config</module>
- <module>netconf-auth</module>
- <module>netconf-notifications-impl</module>
- <module>netconf-notifications-api</module>
- <module>sal-netconf-connector</module>
- <module>messagebus-netconf</module>
- <module>features</module>
- <module>models</module>
- <module>tools</module>
- </modules>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-artifacts</artifactId>
- <version>${project.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>features-netconf-connector</artifactId>
- <version>${project.version}</version>
- <classifier>features</classifier>
- <type>xml</type>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- </dependencyManagement>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>config</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-jmx-generator-plugin</artifactId>
- <version>${config.version}</version>
- </dependency>
- </dependencies>
- </plugin>
- </plugins>
-
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <failsOnError>false</failsOnError>
- <failOnViolation>true</failOnViolation>
- <configLocation>checkstyle-logging.xml</configLocation>
- <consoleOutput>true</consoleOutput>
- <includeTestSourceDirectory>true</includeTestSourceDirectory>
- <sourceDirectory>${project.basedir}</sourceDirectory>
- <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang</includes>
- <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java</excludes>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>checkstyle-logging</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- <profiles>
- <profile>
- <id>integrationtests</id>
- <activation>
- <activeByDefault>false</activeByDefault>
- </activation>
- <modules>
- <module>netconf-it</module>
- </modules>
- </profile>
- </profiles>
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>sal-netconf-connector</artifactId>
-
- <packaging>bundle</packaging>
-
- <!-- Preserve version from mdsal -->
- <version>${mdsal.version}</version>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-config-dispatcher</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-connector-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-notifications</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-notifications-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-threadgroup-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-generator-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-topology</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-parser-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-manager</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-netconf-connector</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-persister-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-util</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>logback-config</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- <type>test-jar</type>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
-
-import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkCondition;
-import static org.opendaylight.controller.config.api.JmxAttributeValidationException.checkNotNull;
-
-import com.google.common.base.Optional;
-import io.netty.util.concurrent.EventExecutor;
-import java.math.BigDecimal;
-import java.net.InetSocketAddress;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import org.opendaylight.controller.config.api.JmxAttributeValidationException;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.controller.sal.connect.netconf.NetconfStateSchemas;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.sal.KeepaliveSalFacade;
-import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceSalFacade;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.TimedReconnectStrategy;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- */
-public final class NetconfConnectorModule extends org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModule
-{
- private static final Logger LOG = LoggerFactory.getLogger(NetconfConnectorModule.class);
-
- private BundleContext bundleContext;
- private Optional<NetconfSessionPreferences> userCapabilities;
- private SchemaSourceRegistry schemaRegistry;
- private SchemaContextFactory schemaContextFactory;
-
- public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public NetconfConnectorModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, final NetconfConnectorModule oldModule, final java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- protected void customValidation() {
- checkNotNull(getAddress(), addressJmxAttribute);
- checkCondition(isHostAddressPresent(getAddress()), "Host address not present in " + getAddress(), addressJmxAttribute);
- checkNotNull(getPort(), portJmxAttribute);
- checkNotNull(getDomRegistry(), portJmxAttribute);
- checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
-
- checkNotNull(getConnectionTimeoutMillis(), connectionTimeoutMillisJmxAttribute);
- checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", connectionTimeoutMillisJmxAttribute);
-
- checkNotNull(getConnectionTimeoutMillis(), defaultRequestTimeoutMillisJmxAttribute);
- checkCondition(getConnectionTimeoutMillis() > 0, "must be > 0", defaultRequestTimeoutMillisJmxAttribute);
-
- checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
- checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
-
- checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
- checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
- checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
-
- // Check username + password in case of ssh
- if(getTcpOnly() == false) {
- checkNotNull(getUsername(), usernameJmxAttribute);
- checkNotNull(getPassword(), passwordJmxAttribute);
- }
-
- userCapabilities = getUserCapabilities();
-
- if(getKeepaliveExecutor() == null) {
- LOG.warn("Keepalive executor missing. Using default instance for now, the configuration needs to be updated");
-
- // Instantiate the default executor, now we know its necessary
- if(DEFAULT_KEEPALIVE_EXECUTOR == null) {
- DEFAULT_KEEPALIVE_EXECUTOR = Executors.newScheduledThreadPool(2, new ThreadFactory() {
- @Override
- public Thread newThread(final Runnable r) {
- final Thread thread = new Thread(r);
- thread.setName("netconf-southound-keepalives-" + thread.getId());
- thread.setDaemon(true);
- return thread;
- }
- });
- }
- }
- }
-
- private boolean isHostAddressPresent(final Host address) {
- return address.getDomainName() != null ||
- address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
- }
-
- @Deprecated
- private static ScheduledExecutorService DEFAULT_KEEPALIVE_EXECUTOR;
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- final RemoteDeviceId id = new RemoteDeviceId(getIdentifier(), getSocketAddress());
-
- final ExecutorService globalProcessingExecutor = getProcessingExecutorDependency().getExecutor();
-
- final Broker domBroker = getDomRegistryDependency();
- final BindingAwareBroker bindingBroker = getBindingRegistryDependency();
-
- RemoteDeviceHandler<NetconfSessionPreferences> salFacade
- = new NetconfDeviceSalFacade(id, domBroker, bindingBroker, getDefaultRequestTimeoutMillis());
-
- final Long keepaliveDelay = getKeepaliveDelay();
- if(shouldSendKeepalive()) {
- // Keepalive executor is optional for now and a default instance is supported
- final ScheduledExecutorService executor = getKeepaliveExecutor() == null ?
- DEFAULT_KEEPALIVE_EXECUTOR : getKeepaliveExecutorDependency().getExecutor();
- salFacade = new KeepaliveSalFacade(id, salFacade, executor, keepaliveDelay);
- }
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO =
- new NetconfDevice.SchemaResourcesDTO(schemaRegistry, schemaContextFactory, new NetconfStateSchemas.NetconfStateSchemasResolverImpl());
-
- final NetconfDevice device =
- new NetconfDevice(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, getReconnectOnChangedSchema());
-
- final NetconfDeviceCommunicator listener = userCapabilities.isPresent() ?
- new NetconfDeviceCommunicator(id, device, userCapabilities.get()) : new NetconfDeviceCommunicator(id, device);
-
- if(shouldSendKeepalive()) {
- ((KeepaliveSalFacade) salFacade).setListener(listener);
- }
-
- final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(listener);
- final NetconfClientDispatcher dispatcher = getClientDispatcherDependency();
-
- listener.initializeRemoteConnection(dispatcher, clientConfig);
-
- return new SalConnectorCloseable(listener, salFacade);
- }
-
- private boolean shouldSendKeepalive() {
- return getKeepaliveDelay() > 0;
- }
-
- private Optional<NetconfSessionPreferences> getUserCapabilities() {
- if(getYangModuleCapabilities() == null) {
- return Optional.absent();
- }
-
- final List<String> capabilities = getYangModuleCapabilities().getCapability();
- if(capabilities == null || capabilities.isEmpty()) {
- return Optional.absent();
- }
-
- final NetconfSessionPreferences parsedOverrideCapabilities = NetconfSessionPreferences.fromStrings(capabilities);
- JmxAttributeValidationException.checkCondition(
- parsedOverrideCapabilities.getNonModuleCaps().isEmpty(),
- "Capabilities to override can only contain module based capabilities, non-module capabilities will be retrieved from the device," +
- " configured non-module capabilities: " + parsedOverrideCapabilities.getNonModuleCaps(),
- yangModuleCapabilitiesJmxAttribute);
-
- return Optional.of(parsedOverrideCapabilities);
- }
-
- public NetconfReconnectingClientConfiguration getClientConfig(final NetconfDeviceCommunicator listener) {
- final InetSocketAddress socketAddress = getSocketAddress();
- final long clientConnectionTimeoutMillis = getConnectionTimeoutMillis();
-
- final ReconnectStrategyFactory sf = new TimedReconnectStrategyFactory(
- getEventExecutorDependency(), getMaxConnectionAttempts(), getBetweenAttemptsTimeoutMillis(), getSleepFactor());
- final ReconnectStrategy strategy = sf.createReconnectStrategy();
-
- return NetconfReconnectingClientConfigurationBuilder.create()
- .withAddress(socketAddress)
- .withConnectionTimeoutMillis(clientConnectionTimeoutMillis)
- .withReconnectStrategy(strategy)
- .withAuthHandler(new LoginPassword(getUsername(), getPassword()))
- .withProtocol(getTcpOnly() ?
- NetconfClientConfiguration.NetconfClientProtocol.TCP :
- NetconfClientConfiguration.NetconfClientProtocol.SSH)
- .withConnectStrategyFactory(sf)
- .withSessionListener(listener)
- .build();
- }
-
- private static final class SalConnectorCloseable implements AutoCloseable {
- private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
- private final NetconfDeviceCommunicator listener;
-
- public SalConnectorCloseable(final NetconfDeviceCommunicator listener,
- final RemoteDeviceHandler<NetconfSessionPreferences> salFacade) {
- this.listener = listener;
- this.salFacade = salFacade;
- }
-
- @Override
- public void close() {
- listener.close();
- salFacade.close();
- }
- }
-
- private static final class TimedReconnectStrategyFactory implements ReconnectStrategyFactory {
- private final Long connectionAttempts;
- private final EventExecutor executor;
- private final double sleepFactor;
- private final int minSleep;
-
- TimedReconnectStrategyFactory(final EventExecutor executor, final Long maxConnectionAttempts, final int minSleep, final BigDecimal sleepFactor) {
- if (maxConnectionAttempts != null && maxConnectionAttempts > 0) {
- connectionAttempts = maxConnectionAttempts;
- } else {
- LOG.trace("Setting {} on {} to infinity", maxConnectionAttemptsJmxAttribute, this);
- connectionAttempts = null;
- }
-
- this.sleepFactor = sleepFactor.doubleValue();
- this.executor = executor;
- this.minSleep = minSleep;
- }
-
- @Override
- public ReconnectStrategy createReconnectStrategy() {
- final Long maxSleep = null;
- final Long deadline = null;
-
- return new TimedReconnectStrategy(executor, minSleep,
- minSleep, sleepFactor, maxSleep, connectionAttempts, deadline);
- }
- }
-
- private InetSocketAddress getSocketAddress() {
- if(getAddress().getDomainName() != null) {
- return new InetSocketAddress(getAddress().getDomainName().getValue(), getPort().getValue());
- } else {
- final IpAddress ipAddress = getAddress().getIpAddress();
- final String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue();
- return new InetSocketAddress(ip, getPort().getValue());
- }
- }
-
- public void setSchemaRegistry(final SchemaSourceRegistry schemaRegistry) {
- this.schemaRegistry = schemaRegistry;
- }
-
- public void setSchemaContextFactory(final SchemaContextFactory schemaContextFactory) {
- this.schemaContextFactory = schemaContextFactory;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yang.md.sal.connector.netconf;
-
-import java.io.File;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
-import org.osgi.framework.BundleContext;
-
-/**
-*
-*/
-public class NetconfConnectorModuleFactory extends
- org.opendaylight.controller.config.yang.md.sal.connector.netconf.AbstractNetconfConnectorModuleFactory {
-
- // TODO this should be injected
- // Netconf devices have separated schema registry + factory from controller
- private final SharedSchemaRepository repository = new SharedSchemaRepository(NAME);
- private final SchemaContextFactory schemaContextFactory
- = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
-
- public NetconfConnectorModuleFactory() {
- // Start cache and Text to AST transformer
- final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File("cache/schema"));
- repository.registerSchemaSourceListener(cache);
- repository.registerSchemaSourceListener(TextToASTTransformer.create(repository, repository));
- }
-
- @Override
- public Module createModule(final String instanceName, final DependencyResolver dependencyResolver,
- final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
- final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
- old, bundleContext);
-
- module.setSchemaRegistry(repository);
- module.setSchemaContextFactory(schemaContextFactory);
- return module;
- }
-
- @Override
- public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
- final NetconfConnectorModule module = (NetconfConnectorModule) super.createModule(instanceName, dependencyResolver,
- bundleContext);
- module.setSchemaRegistry(repository);
- module.setSchemaContextFactory(schemaContextFactory);
- return module;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.api;
-
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public interface MessageTransformer<M> {
-
- DOMNotification toNotification(M message);
-
- M toRpcRequest(SchemaPath rpc, NormalizedNode<?, ?> node);
-
- DOMRpcResult toRpcResult(M message, SchemaPath rpc);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.api;
-
-/**
- *
- */
-public interface RemoteDevice<PREF, M, LISTENER extends RemoteDeviceCommunicator<M>> {
-
- void onRemoteSessionUp(PREF remoteSessionCapabilities, LISTENER listener);
-
- void onRemoteSessionDown();
-
- void onRemoteSessionFailed(Throwable throwable);
-
- void onNotification(M notification);
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.api;
-
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public interface RemoteDeviceCommunicator<M> extends AutoCloseable {
-
- ListenableFuture<RpcResult<M>> sendRequest(M message, QName rpc);
-
- void close();
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.api;
-
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public interface RemoteDeviceHandler<PREF> extends AutoCloseable {
-
- void onDeviceConnected(SchemaContext remoteSchemaContext,
- PREF netconfSessionPreferences, DOMRpcService deviceRpc);
-
- void onDeviceDisconnected();
-
- void onDeviceFailed(Throwable throwable);
-
- void onNotification(DOMNotification domNotification);
-
- void close();
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.api;
-
-import java.io.InputStream;
-import java.util.Collection;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
-
-public interface SchemaContextProviderFactory {
-
- SchemaContextProvider createContextProvider(Collection<QName> capabilities, SchemaSourceProvider<InputStream> sourceProvider);
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/**
- * General API for remote connectors e.g. netconf connector
- *
- * TODO extract into separate bundle when another connector is implemented e.g. restconf connector
- */
-package org.opendaylight.controller.sal.connect.api;
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.api.MessageTransformer;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.controller.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
-import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This is a mediator between NetconfDeviceCommunicator and NetconfDeviceSalFacade
- */
-public final class NetconfDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDevice.class);
-
- /**
- * Initial schema context contains schemas for netconf monitoring and netconf notifications
- */
- public static final SchemaContext INIT_SCHEMA_CTX;
-
- static {
- try {
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(
- Lists.newArrayList(
- $YangModuleInfoImpl.getInstance(),
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.$YangModuleInfoImpl.getInstance(),
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl.getInstance()));
- INIT_SCHEMA_CTX = moduleInfoBackedContext.tryToCreateSchemaContext().get();
- } catch (final RuntimeException e) {
- LOG.error("Unable to prepare schema context for netconf initialization", e);
- throw new ExceptionInInitializerError(e);
- }
- }
-
- public static final Function<QName, SourceIdentifier> QNAME_TO_SOURCE_ID_FUNCTION = new Function<QName, SourceIdentifier>() {
- @Override
- public SourceIdentifier apply(final QName input) {
- return new SourceIdentifier(input.getLocalName(), Optional.fromNullable(input.getFormattedRevision()));
- }
- };
-
- private final RemoteDeviceId id;
- private final boolean reconnectOnSchemasChange;
-
- private final SchemaContextFactory schemaContextFactory;
- private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
- private final ListeningExecutorService processingExecutor;
- private final SchemaSourceRegistry schemaRegistry;
- private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
- private final NotificationHandler notificationHandler;
- private final List<SchemaSourceRegistration<? extends SchemaSourceRepresentation>> sourceRegistrations = Lists.newArrayList();
-
- // Message transformer is constructed once the schemas are available
- private MessageTransformer<NetconfMessage> messageTransformer;
-
- public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ExecutorService globalProcessingExecutor) {
- this(schemaResourcesDTO, id, salFacade, globalProcessingExecutor, false);
- }
-
- /**
- * Create rpc implementation capable of handling RPC for monitoring and notifications even before the schemas of remote device are downloaded
- */
- static NetconfDeviceRpc getRpcForInitialization(final NetconfDeviceCommunicator listener) {
- return new NetconfDeviceRpc(INIT_SCHEMA_CTX, listener, new NetconfMessageTransformer(INIT_SCHEMA_CTX, false));
- }
-
-
- // FIXME reduce parameters
- public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
- this.id = id;
- this.reconnectOnSchemasChange = reconnectOnSchemasChange;
- this.schemaRegistry = schemaResourcesDTO.getSchemaRegistry();
- this.schemaContextFactory = schemaResourcesDTO.getSchemaContextFactory();
- this.salFacade = salFacade;
- this.stateSchemasResolver = schemaResourcesDTO.getStateSchemasResolver();
- this.processingExecutor = MoreExecutors.listeningDecorator(globalProcessingExecutor);
- this.notificationHandler = new NotificationHandler(salFacade, id);
- }
-
- @Override
- public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities,
- final NetconfDeviceCommunicator listener) {
- // SchemaContext setup has to be performed in a dedicated thread since
- // we are in a netty thread in this method
- // Yang models are being downloaded in this method and it would cause a
- // deadlock if we used the netty thread
- // http://netty.io/wiki/thread-model.html
- LOG.debug("{}: Session to remote device established with {}", id, remoteSessionCapabilities);
-
- final NetconfDeviceRpc initRpc = getRpcForInitialization(listener);
- final DeviceSourcesResolver task = new DeviceSourcesResolver(remoteSessionCapabilities, id, stateSchemasResolver, initRpc);
- final ListenableFuture<DeviceSources> sourceResolverFuture = processingExecutor.submit(task);
-
- if (shouldListenOnSchemaChange(remoteSessionCapabilities)) {
- registerToBaseNetconfStream(initRpc, listener);
- }
-
- final FutureCallback<DeviceSources> resolvedSourceCallback = new FutureCallback<DeviceSources>() {
- @Override
- public void onSuccess(final DeviceSources result) {
- addProvidedSourcesToSchemaRegistry(initRpc, result);
- setUpSchema(result);
- }
-
- private void setUpSchema(final DeviceSources result) {
- processingExecutor.submit(new RecursiveSchemaSetup(result, remoteSessionCapabilities, listener));
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.warn("{}: Unexpected error resolving device sources: {}", id, t);
- handleSalInitializationFailure(t, listener);
- }
- };
-
- Futures.addCallback(sourceResolverFuture, resolvedSourceCallback);
- }
-
- private void registerToBaseNetconfStream(final NetconfDeviceRpc deviceRpc, final NetconfDeviceCommunicator listener) {
- // TODO check whether the model describing create subscription is present in schema
- // Perhaps add a default schema context to support create-subscription if the model was not provided (same as what we do for base netconf operations in transformer)
- final CheckedFuture<DOMRpcResult, DOMRpcException> rpcResultListenableFuture =
- deviceRpc.invokeRpc(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME), NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_CONTENT);
-
- final NotificationHandler.NotificationFilter filter = new NotificationHandler.NotificationFilter() {
- @Override
- public Optional<DOMNotification> filterNotification(final DOMNotification notification) {
- if (isCapabilityChanged(notification)) {
- LOG.info("{}: Schemas change detected, reconnecting", id);
- // Only disconnect is enough, the reconnecting nature of the connector will take care of reconnecting
- listener.disconnect();
- return Optional.absent();
- }
- return Optional.of(notification);
- }
-
- private boolean isCapabilityChanged(final DOMNotification notification) {
- return notification.getBody().getNodeType().equals(NetconfCapabilityChange.QNAME);
- }
- };
-
- Futures.addCallback(rpcResultListenableFuture, new FutureCallback<DOMRpcResult>() {
- @Override
- public void onSuccess(final DOMRpcResult domRpcResult) {
- notificationHandler.addNotificationFilter(filter);
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.warn("Unable to subscribe to base notification stream. Schemas will not be reloaded on the fly", t);
- }
- });
- }
-
- private boolean shouldListenOnSchemaChange(final NetconfSessionPreferences remoteSessionCapabilities) {
- return remoteSessionCapabilities.isNotificationsSupported() && reconnectOnSchemasChange;
- }
-
- @VisibleForTesting
- void handleSalInitializationSuccess(final SchemaContext result, final NetconfSessionPreferences remoteSessionCapabilities, final DOMRpcService deviceRpc) {
- messageTransformer = new NetconfMessageTransformer(result, true);
-
- updateTransformer(messageTransformer);
- // salFacade.onDeviceConnected has to be called before the notification handler is initialized
- salFacade.onDeviceConnected(result, remoteSessionCapabilities, deviceRpc);
- notificationHandler.onRemoteSchemaUp(messageTransformer);
-
- LOG.info("{}: Netconf connector initialized successfully", id);
- }
-
- private void handleSalInitializationFailure(final Throwable t, final RemoteDeviceCommunicator<NetconfMessage> listener) {
- LOG.error("{}: Initialization in sal failed, disconnecting from device", id, t);
- listener.close();
- onRemoteSessionDown();
- resetMessageTransformer();
- }
-
- /**
- * Set the transformer to null as is in initial state
- */
- private void resetMessageTransformer() {
- updateTransformer(null);
- }
-
- private void updateTransformer(final MessageTransformer<NetconfMessage> transformer) {
- messageTransformer = transformer;
- }
-
- private void addProvidedSourcesToSchemaRegistry(final NetconfDeviceRpc deviceRpc, final DeviceSources deviceSources) {
- final NetconfRemoteSchemaYangSourceProvider yangProvider = new NetconfRemoteSchemaYangSourceProvider(id, deviceRpc);
- for (final SourceIdentifier sourceId : deviceSources.getProvidedSources()) {
- sourceRegistrations.add(schemaRegistry.registerSchemaSource(yangProvider,
- PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
- }
- }
-
- @Override
- public void onRemoteSessionDown() {
- notificationHandler.onRemoteSchemaDown();
-
- salFacade.onDeviceDisconnected();
- for (final SchemaSourceRegistration<? extends SchemaSourceRepresentation> sourceRegistration : sourceRegistrations) {
- sourceRegistration.close();
- }
- resetMessageTransformer();
- }
-
- @Override
- public void onRemoteSessionFailed(final Throwable throwable) {
- salFacade.onDeviceFailed(throwable);
- }
-
- @Override
- public void onNotification(final NetconfMessage notification) {
- notificationHandler.handleNotification(notification);
- }
-
- /**
- * Just a transfer object containing schema related dependencies. Injected in constructor.
- */
- public static class SchemaResourcesDTO {
- private final SchemaSourceRegistry schemaRegistry;
- private final SchemaContextFactory schemaContextFactory;
- private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
-
- public SchemaResourcesDTO(final SchemaSourceRegistry schemaRegistry, final SchemaContextFactory schemaContextFactory, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
- this.schemaRegistry = Preconditions.checkNotNull(schemaRegistry);
- this.schemaContextFactory = Preconditions.checkNotNull(schemaContextFactory);
- this.stateSchemasResolver = Preconditions.checkNotNull(stateSchemasResolver);
- }
-
- public SchemaSourceRegistry getSchemaRegistry() {
- return schemaRegistry;
- }
-
- public SchemaContextFactory getSchemaContextFactory() {
- return schemaContextFactory;
- }
-
- public NetconfStateSchemas.NetconfStateSchemasResolver getStateSchemasResolver() {
- return stateSchemasResolver;
- }
- }
-
- /**
- * Schema building callable.
- */
- private static class DeviceSourcesResolver implements Callable<DeviceSources> {
-
- private final NetconfDeviceRpc deviceRpc;
- private final NetconfSessionPreferences remoteSessionCapabilities;
- private final RemoteDeviceId id;
- private final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver;
-
- DeviceSourcesResolver(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities,
- final RemoteDeviceId id, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver) {
- this.deviceRpc = deviceRpc;
- this.remoteSessionCapabilities = remoteSessionCapabilities;
- this.id = id;
- this.stateSchemasResolver = stateSchemasResolver;
- }
-
- public DeviceSourcesResolver(final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id, final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver, final NetconfDeviceRpc rpcForMonitoring) {
- this(rpcForMonitoring, remoteSessionCapabilities, id, stateSchemasResolver);
- }
-
- @Override
- public DeviceSources call() throws Exception {
- final NetconfStateSchemas availableSchemas = stateSchemasResolver.resolve(deviceRpc, remoteSessionCapabilities, id);
- LOG.debug("{}: Schemas exposed by ietf-netconf-monitoring: {}", id, availableSchemas.getAvailableYangSchemasQNames());
-
- final Set<QName> requiredSources = Sets.newHashSet(remoteSessionCapabilities.getModuleBasedCaps());
- final Set<QName> providedSources = availableSchemas.getAvailableYangSchemasQNames();
-
- final Set<QName> requiredSourcesNotProvided = Sets.difference(requiredSources, providedSources);
- if (!requiredSourcesNotProvided.isEmpty()) {
- LOG.warn("{}: Netconf device does not provide all yang models reported in hello message capabilities, required but not provided: {}",
- id, requiredSourcesNotProvided);
- LOG.warn("{}: Attempting to build schema context from required sources", id);
- }
-
- // Here all the sources reported in netconf monitoring are merged with those reported in hello.
- // It is necessary to perform this since submodules are not mentioned in hello but still required.
- // This clashes with the option of a user to specify supported yang models manually in configuration for netconf-connector
- // and as a result one is not able to fully override yang models of a device. It is only possible to add additional models.
- final Set<QName> providedSourcesNotRequired = Sets.difference(providedSources, requiredSources);
- if (!providedSourcesNotRequired.isEmpty()) {
- LOG.warn("{}: Netconf device provides additional yang models not reported in hello message capabilities: {}",
- id, providedSourcesNotRequired);
- LOG.warn("{}: Adding provided but not required sources as required to prevent failures", id);
- LOG.debug("{}: Netconf device reported in hello: {}", id, requiredSources);
- requiredSources.addAll(providedSourcesNotRequired);
- }
-
- return new DeviceSources(requiredSources, providedSources);
- }
- }
-
- /**
- * Contains RequiredSources - sources from capabilities.
- */
- private static final class DeviceSources {
- private final Set<QName> requiredSources;
- private final Set<QName> providedSources;
-
- public DeviceSources(final Set<QName> requiredSources, final Set<QName> providedSources) {
- this.requiredSources = requiredSources;
- this.providedSources = providedSources;
- }
-
- public Set<QName> getRequiredSourcesQName() {
- return requiredSources;
- }
-
- public Set<QName> getProvidedSourcesQName() {
- return providedSources;
- }
-
- public Collection<SourceIdentifier> getRequiredSources() {
- return Collections2.transform(requiredSources, QNAME_TO_SOURCE_ID_FUNCTION);
- }
-
- public Collection<SourceIdentifier> getProvidedSources() {
- return Collections2.transform(providedSources, QNAME_TO_SOURCE_ID_FUNCTION);
- }
-
- }
-
- /**
- * Schema builder that tries to build schema context from provided sources or biggest subset of it.
- */
- private final class RecursiveSchemaSetup implements Runnable {
- private final DeviceSources deviceSources;
- private final NetconfSessionPreferences remoteSessionCapabilities;
- private final RemoteDeviceCommunicator<NetconfMessage> listener;
- private final NetconfDeviceCapabilities capabilities;
-
- public RecursiveSchemaSetup(final DeviceSources deviceSources, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceCommunicator<NetconfMessage> listener) {
- this.deviceSources = deviceSources;
- this.remoteSessionCapabilities = remoteSessionCapabilities;
- this.listener = listener;
- this.capabilities = remoteSessionCapabilities.getNetconfDeviceCapabilities();
- }
-
- @Override
- public void run() {
- setUpSchema(deviceSources.getRequiredSources());
- }
-
- /**
- * Recursively build schema context, in case of success or final failure notify device
- */
- // FIXME reimplement without recursion
- private void setUpSchema(final Collection<SourceIdentifier> requiredSources) {
- LOG.trace("{}: Trying to build schema context from {}", id, requiredSources);
-
- // If no more sources, fail
- if(requiredSources.isEmpty()) {
- final IllegalStateException cause = new IllegalStateException(id + ": No more sources for schema context");
- handleSalInitializationFailure(cause, listener);
- salFacade.onDeviceFailed(cause);
- return;
- }
-
- final CheckedFuture<SchemaContext, SchemaResolutionException> schemaBuilderFuture = schemaContextFactory.createSchemaContext(requiredSources);
-
- final FutureCallback<SchemaContext> RecursiveSchemaBuilderCallback = new FutureCallback<SchemaContext>() {
-
- @Override
- public void onSuccess(final SchemaContext result) {
- LOG.debug("{}: Schema context built successfully from {}", id, requiredSources);
- final Collection<QName> filteredQNames = Sets.difference(deviceSources.getProvidedSourcesQName(), capabilities.getUnresolvedCapabilites().keySet());
- capabilities.addCapabilities(filteredQNames);
- capabilities.addNonModuleBasedCapabilities(remoteSessionCapabilities.getNonModuleCaps());
- handleSalInitializationSuccess(result, remoteSessionCapabilities, getDeviceSpecificRpc(result));
- }
-
- @Override
- public void onFailure(final Throwable t) {
- // In case source missing, try without it
- if (t instanceof MissingSchemaSourceException) {
- final SourceIdentifier missingSource = ((MissingSchemaSourceException) t).getSourceId();
- LOG.warn("{}: Unable to build schema context, missing source {}, will reattempt without it", id, missingSource);
- capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(Sets.newHashSet(missingSource)), UnavailableCapability.FailureReason.MissingSource);
- setUpSchema(stripMissingSource(requiredSources, missingSource));
-
- // In case resolution error, try only with resolved sources
- } else if (t instanceof SchemaResolutionException) {
- // TODO check for infinite loop
- final SchemaResolutionException resolutionException = (SchemaResolutionException) t;
- final Set<SourceIdentifier> unresolvedSources = resolutionException.getUnsatisfiedImports().keySet();
- capabilities.addUnresolvedCapabilities(getQNameFromSourceIdentifiers(unresolvedSources), UnavailableCapability.FailureReason.UnableToResolve);
- LOG.warn("{}: Unable to build schema context, unsatisfied imports {}, will reattempt with resolved only", id, resolutionException.getUnsatisfiedImports());
- setUpSchema(resolutionException.getResolvedSources());
- // unknown error, fail
- } else {
- handleSalInitializationFailure(t, listener);
- }
- }
- };
-
- Futures.addCallback(schemaBuilderFuture, RecursiveSchemaBuilderCallback);
- }
-
- private NetconfDeviceRpc getDeviceSpecificRpc(final SchemaContext result) {
- return new NetconfDeviceRpc(result, listener, new NetconfMessageTransformer(result, true));
- }
-
- private Collection<SourceIdentifier> stripMissingSource(final Collection<SourceIdentifier> requiredSources, final SourceIdentifier sIdToRemove) {
- final LinkedList<SourceIdentifier> sourceIdentifiers = Lists.newLinkedList(requiredSources);
- final boolean removed = sourceIdentifiers.remove(sIdToRemove);
- Preconditions.checkState(removed, "{}: Trying to remove {} from {} failed", id, sIdToRemove, requiredSources);
- return sourceIdentifiers;
- }
-
- private Collection<QName> getQNameFromSourceIdentifiers(final Collection<SourceIdentifier> identifiers) {
- final Collection<QName> qNames = Collections2.transform(identifiers, new Function<SourceIdentifier, QName>() {
- @Override
- public QName apply(final SourceIdentifier sourceIdentifier) {
- return getQNameFromSourceIdentifier(sourceIdentifier);
- }
- });
-
- if (qNames.isEmpty()) {
- LOG.debug("{}: Unable to map any source identfiers to a capability reported by device : {}", id, identifiers);
- }
- return qNames;
- }
-
- private QName getQNameFromSourceIdentifier(final SourceIdentifier identifier) {
- // Required sources are all required and provided merged in DeviceSourcesResolver
- for (final QName qname : deviceSources.getRequiredSourcesQName()) {
- if(qname.getLocalName().equals(identifier.getName()) == false) {
- continue;
- }
-
- if(identifier.getRevision().equals(SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION) &&
- qname.getRevision() == null) {
- return qname;
- }
-
- if (qname.getFormattedRevision().equals(identifier.getRevision())) {
- return qname;
- }
- }
- throw new IllegalArgumentException("Unable to map identifier to a devices reported capability: " + identifier + " Available: " + deviceSources.getRequiredSourcesQName());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Sets;
-import java.net.URI;
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Holds QNames for all yang modules reported by ietf-netconf-monitoring/state/schemas
- */
-public final class NetconfStateSchemas {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfStateSchemas.class);
-
- /**
- * Factory for NetconfStateSchemas
- */
- public interface NetconfStateSchemasResolver {
- NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id);
- }
-
- /**
- * Default implementation resolving schemas QNames from netconf-state
- */
- public static final class NetconfStateSchemasResolverImpl implements NetconfStateSchemasResolver {
-
- @Override
- public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
- return NetconfStateSchemas.create(deviceRpc, remoteSessionCapabilities, id);
- }
- }
-
- public static final NetconfStateSchemas EMPTY = new NetconfStateSchemas(Collections.<RemoteYangSchema>emptySet());
-
- private static final YangInstanceIdentifier STATE_SCHEMAS_IDENTIFIER =
- YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).build();
-
- private static final ContainerNode GET_SCHEMAS_RPC;
- static {
- final DataContainerChild<?, ?> filter = NetconfMessageTransformUtil.toFilterStructure(STATE_SCHEMAS_IDENTIFIER, NetconfDevice.INIT_SCHEMA_CTX);
- GET_SCHEMAS_RPC
- = Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_GET_QNAME)).withChild(filter).build();
- }
-
- private final Set<RemoteYangSchema> availableYangSchemas;
-
- public NetconfStateSchemas(final Set<RemoteYangSchema> availableYangSchemas) {
- this.availableYangSchemas = availableYangSchemas;
- }
-
- public Set<RemoteYangSchema> getAvailableYangSchemas() {
- return availableYangSchemas;
- }
-
- public Set<QName> getAvailableYangSchemasQNames() {
- return Sets.newHashSet(Collections2.transform(getAvailableYangSchemas(), new Function<RemoteYangSchema, QName>() {
- @Override
- public QName apply(final RemoteYangSchema input) {
- return input.getQName();
- }
- }));
- }
-
- /**
- * Issue get request to remote device and parse response to find all schemas under netconf-state/schemas
- */
- private static NetconfStateSchemas create(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
- if(remoteSessionCapabilities.isMonitoringSupported() == false) {
- LOG.warn("{}: Netconf monitoring not supported on device, cannot detect provided schemas", id);
- return EMPTY;
- }
-
- final DOMRpcResult schemasNodeResult;
- try {
- schemasNodeResult = deviceRpc.invokeRpc(toPath(NETCONF_GET_QNAME), GET_SCHEMAS_RPC).get();
- } catch (final InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(id + ": Interrupted while waiting for response to " + STATE_SCHEMAS_IDENTIFIER, e);
- } catch (final ExecutionException e) {
- LOG.warn("{}: Unable to detect available schemas, get to {} failed", id, STATE_SCHEMAS_IDENTIFIER, e);
- return EMPTY;
- }
-
- if(schemasNodeResult.getErrors().isEmpty() == false) {
- LOG.warn("{}: Unable to detect available schemas, get to {} failed, {}", id, STATE_SCHEMAS_IDENTIFIER, schemasNodeResult.getErrors());
- return EMPTY;
- }
-
- final Optional<? extends NormalizedNode<?, ?>> schemasNode = findSchemasNode(schemasNodeResult.getResult());
-
- if(schemasNode.isPresent()) {
- Preconditions.checkState(schemasNode.get() instanceof ContainerNode,
- "Expecting container containing schemas, but was %s", schemasNode.get());
- return create(id, ((ContainerNode) schemasNode.get()));
- } else {
- LOG.warn("{}: Unable to detect available schemas, get to {} was empty", id, STATE_SCHEMAS_IDENTIFIER);
- return EMPTY;
- }
- }
-
- private static Optional<? extends NormalizedNode<?, ?>> findSchemasNode(final NormalizedNode<?, ?> result) {
- if(result == null) {
- return Optional.absent();
- }
- final Optional<DataContainerChild<?, ?>> dataNode = ((DataContainerNode<?>) result).getChild(toId(NETCONF_DATA_QNAME));
- if(dataNode.isPresent() == false) {
- return Optional.absent();
- }
-
- final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> nStateNode =
- ((DataContainerNode<?>) dataNode.get()).getChild(toId(NetconfState.QNAME));
- if(nStateNode.isPresent() == false) {
- return Optional.absent();
- }
-
- return ((DataContainerNode<?>) nStateNode.get()).getChild(toId(Schemas.QNAME));
- }
-
- /**
- * Parse response of get(netconf-state/schemas) to find all schemas under netconf-state/schemas
- */
- @VisibleForTesting
- protected static NetconfStateSchemas create(final RemoteDeviceId id, final ContainerNode schemasNode) {
- final Set<RemoteYangSchema> availableYangSchemas = Sets.newHashSet();
-
- final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = schemasNode.getChild(toId(Schema.QNAME));
- Preconditions.checkState(child.isPresent(), "Unable to find list: %s in response: %s", Schema.QNAME.withoutRevision(), schemasNode);
- Preconditions.checkState(child.get() instanceof MapNode, "Unexpected structure for container: %s in response: %s. Expecting a list", Schema.QNAME.withoutRevision(), schemasNode);
-
- for (final MapEntryNode schemaNode : ((MapNode) child.get()).getValue()) {
- final Optional<RemoteYangSchema> fromCompositeNode = RemoteYangSchema.createFromNormalizedNode(id, schemaNode);
- if(fromCompositeNode.isPresent()) {
- availableYangSchemas.add(fromCompositeNode.get());
- }
- }
-
- return new NetconfStateSchemas(availableYangSchemas);
- }
-
- public final static class RemoteYangSchema {
- private final QName qname;
-
- RemoteYangSchema(final QName qname) {
- this.qname = qname;
- }
-
- public QName getQName() {
- return qname;
- }
-
- static Optional<RemoteYangSchema> createFromNormalizedNode(final RemoteDeviceId id, final MapEntryNode schemaNode) {
- Preconditions.checkArgument(schemaNode.getNodeType().equals(Schema.QNAME), "Wrong QName %s", schemaNode.getNodeType());
-
- QName childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_FORMAT;
-
- String formatAsString = getSingleChildNodeValue(schemaNode, childNode).get();
-
- if(formatAsString.equals(Yang.QNAME.toString()) == false) {
- LOG.debug("{}: Ignoring schema due to unsupported format: {}", id, formatAsString);
- return Optional.absent();
- }
-
- childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_LOCATION;
- final Set<String> locationsAsString = getAllChildNodeValues(schemaNode, childNode);
- if(locationsAsString.contains(Schema.Location.Enumeration.NETCONF.toString()) == false) {
- LOG.debug("{}: Ignoring schema due to unsupported location: {}", id, locationsAsString);
- return Optional.absent();
- }
-
- childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE;
- final String namespaceAsString = getSingleChildNodeValue(schemaNode, childNode).get();
-
- childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_VERSION;
- // Revision does not have to be filled
- final Optional<String> revisionAsString = getSingleChildNodeValue(schemaNode, childNode);
-
- childNode = NetconfMessageTransformUtil.IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER;
- final String moduleNameAsString = getSingleChildNodeValue(schemaNode, childNode).get();
-
- final QName moduleQName = revisionAsString.isPresent()
- ? QName.create(namespaceAsString, revisionAsString.get(), moduleNameAsString)
- : QName.create(URI.create(namespaceAsString), null, moduleNameAsString);
-
- return Optional.of(new RemoteYangSchema(moduleQName));
- }
-
- /**
- * Extracts all values of a leaf-list node as a set of strings
- */
- private static Set<String> getAllChildNodeValues(final DataContainerNode<?> schemaNode, final QName childNodeQName) {
- final Set<String> extractedValues = Sets.newHashSet();
- final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = schemaNode.getChild(toId(childNodeQName));
- Preconditions.checkArgument(child.isPresent(), "Child nodes %s not present", childNodeQName);
- Preconditions.checkArgument(child.get() instanceof LeafSetNode<?>, "Child nodes %s not present", childNodeQName);
- for (final LeafSetEntryNode<?> childNode : ((LeafSetNode<?>) child.get()).getValue()) {
- extractedValues.add(getValueOfSimpleNode(childNode).get());
- }
- return extractedValues;
- }
-
- private static Optional<String> getSingleChildNodeValue(final DataContainerNode<?> schemaNode, final QName childNode) {
- final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> node = schemaNode.getChild(toId(childNode));
- Preconditions.checkArgument(node.isPresent(), "Child node %s not present", childNode);
- return getValueOfSimpleNode(node.get());
- }
-
- private static Optional<String> getValueOfSimpleNode(final NormalizedNode<? extends YangInstanceIdentifier.PathArgument, ?> node) {
- final Object value = node.getValue();
- return value == null || Strings.isNullOrEmpty(value.toString()) ? Optional.<String>absent() : Optional.of(value.toString().trim());
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- final RemoteYangSchema that = (RemoteYangSchema) o;
-
- if (!qname.equals(that.qname)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return qname.hashCode();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.util.LinkedList;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.api.MessageTransformer;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Handles incoming notifications. Either caches them(until onRemoteSchemaUp is called) or passes to sal Facade.
- */
-final class NotificationHandler {
-
- private static final Logger LOG = LoggerFactory.getLogger(NotificationHandler.class);
-
- private final RemoteDeviceHandler<?> salFacade;
- private final List<NetconfMessage> queue = new LinkedList<>();
- private final RemoteDeviceId id;
- private boolean passNotifications = false;
-
- private NotificationFilter filter;
- private MessageTransformer<NetconfMessage> messageTransformer;
-
- NotificationHandler(final RemoteDeviceHandler<?> salFacade, final RemoteDeviceId id) {
- this.salFacade = Preconditions.checkNotNull(salFacade);
- this.id = Preconditions.checkNotNull(id);
- }
-
- synchronized void handleNotification(final NetconfMessage notification) {
- if(passNotifications) {
- passNotification(transformNotification(notification));
- } else {
- queueNotification(notification);
- }
- }
-
- /**
- * Forward all cached notifications and pass all notifications from this point directly to sal facade.
- * @param messageTransformer
- */
- synchronized void onRemoteSchemaUp(final MessageTransformer<NetconfMessage> messageTransformer) {
- this.messageTransformer = Preconditions.checkNotNull(messageTransformer);
-
- passNotifications = true;
-
- for (final NetconfMessage cachedNotification : queue) {
- passNotification(transformNotification(cachedNotification));
- }
-
- queue.clear();
- }
-
- private DOMNotification transformNotification(final NetconfMessage cachedNotification) {
- final DOMNotification parsedNotification = messageTransformer.toNotification(cachedNotification);
- Preconditions.checkNotNull(parsedNotification, "%s: Unable to parse received notification: %s", id, cachedNotification);
- return parsedNotification;
- }
-
- private void queueNotification(final NetconfMessage notification) {
- Preconditions.checkState(passNotifications == false);
-
- LOG.debug("{}: Caching notification {}, remote schema not yet fully built", id, notification);
- if(LOG.isTraceEnabled()) {
- LOG.trace("{}: Caching notification {}", id, XmlUtil.toString(notification.getDocument()));
- }
-
- queue.add(notification);
- }
-
- private synchronized void passNotification(final DOMNotification parsedNotification) {
- LOG.debug("{}: Forwarding notification {}", id, parsedNotification);
-
- if(filter == null || filter.filterNotification(parsedNotification).isPresent()) {
- salFacade.onNotification(parsedNotification);
- }
- }
-
- synchronized void addNotificationFilter(final NotificationFilter filter) {
- this.filter = filter;
- }
-
- synchronized void onRemoteSchemaDown() {
- queue.clear();
- passNotifications = false;
- messageTransformer = null;
- }
-
- static interface NotificationFilter {
-
- Optional<DOMNotification> filterNotification(DOMNotification notification);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability.FailureReason;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public final class NetconfDeviceCapabilities {
- private final Map<QName, FailureReason> unresolvedCapabilites;
- private final Set<QName> resolvedCapabilities;
-
- private final Set<String> nonModuleBasedCapabilities;
-
- public NetconfDeviceCapabilities() {
- this.unresolvedCapabilites = new HashMap<>();
- this.resolvedCapabilities = new HashSet<>();
- this.nonModuleBasedCapabilities = new HashSet<>();
- }
-
- public void addUnresolvedCapability(QName source, FailureReason reason) {
- unresolvedCapabilites.put(source, reason);
- }
-
- public void addUnresolvedCapabilities(Collection<QName> capabilities, FailureReason reason) {
- for (QName s : capabilities) {
- unresolvedCapabilites.put(s, reason);
- }
- }
-
- public void addCapabilities(Collection<QName> availableSchemas) {
- resolvedCapabilities.addAll(availableSchemas);
- }
-
- public void addNonModuleBasedCapabilities(Collection<String> nonModuleCapabilities) {
- this.nonModuleBasedCapabilities.addAll(nonModuleCapabilities);
- }
-
- public Set<String> getNonModuleBasedCapabilities() {
- return nonModuleBasedCapabilities;
- }
-
- public Map<QName, FailureReason> getUnresolvedCapabilites() {
- return unresolvedCapabilites;
- }
-
- public Set<QName> getResolvedCapabilities() {
- return resolvedCapabilities;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.FutureListener;
-import io.netty.util.concurrent.GenericFutureListener;
-import java.util.ArrayDeque;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfDeviceCommunicator implements NetconfClientSessionListener, RemoteDeviceCommunicator<NetconfMessage> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceCommunicator.class);
-
- private final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice;
- private final Optional<NetconfSessionPreferences> overrideNetconfCapabilities;
- private final RemoteDeviceId id;
- private final Lock sessionLock = new ReentrantLock();
-
- // TODO implement concurrent message limit
- private final Queue<Request> requests = new ArrayDeque<>();
- private NetconfClientSession session;
- private Future<?> initFuture;
-
- public NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
- final NetconfSessionPreferences NetconfSessionPreferences) {
- this(id, remoteDevice, Optional.of(NetconfSessionPreferences));
- }
-
- public NetconfDeviceCommunicator(final RemoteDeviceId id,
- final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice) {
- this(id, remoteDevice, Optional.<NetconfSessionPreferences>absent());
- }
-
- private NetconfDeviceCommunicator(final RemoteDeviceId id, final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> remoteDevice,
- final Optional<NetconfSessionPreferences> overrideNetconfCapabilities) {
- this.id = id;
- this.remoteDevice = remoteDevice;
- this.overrideNetconfCapabilities = overrideNetconfCapabilities;
- }
-
- @Override
- public void onSessionUp(final NetconfClientSession session) {
- sessionLock.lock();
- try {
- LOG.debug("{}: Session established", id);
- this.session = session;
-
- NetconfSessionPreferences netconfSessionPreferences =
- NetconfSessionPreferences.fromNetconfSession(session);
- LOG.trace("{}: Session advertised capabilities: {}", id,
- netconfSessionPreferences);
-
- if(overrideNetconfCapabilities.isPresent()) {
- netconfSessionPreferences = netconfSessionPreferences.addModuleCaps(overrideNetconfCapabilities.get());
- LOG.debug(
- "{}: Session capabilities overridden, capabilities that will be used: {}",
- id, netconfSessionPreferences);
- }
-
- remoteDevice.onRemoteSessionUp(netconfSessionPreferences, this);
- }
- finally {
- sessionLock.unlock();
- }
- }
-
- public void initializeRemoteConnection(final NetconfClientDispatcher dispatcher, final NetconfClientConfiguration config) {
- // TODO 2313 extract listener from configuration
- if(config instanceof NetconfReconnectingClientConfiguration) {
- initFuture = dispatcher.createReconnectingClient((NetconfReconnectingClientConfiguration) config);
- } else {
- initFuture = dispatcher.createClient(config);
- }
-
-
- initFuture.addListener(new GenericFutureListener<Future<Object>>(){
-
- @Override
- public void operationComplete(Future<Object> future) throws Exception {
- if (!future.isSuccess() && !future.isCancelled()) {
- LOG.debug("{}: Connection failed", id, future.cause());
- NetconfDeviceCommunicator.this.remoteDevice.onRemoteSessionFailed(future.cause());
- }
- }
- });
-
- }
-
- public void disconnect() {
- if(session != null) {
- session.close();
- }
- }
-
- private void tearDown( String reason ) {
- List<UncancellableFuture<RpcResult<NetconfMessage>>> futuresToCancel = Lists.newArrayList();
- sessionLock.lock();
- try {
- if( session != null ) {
- session = null;
-
- /*
- * Walk all requests, check if they have been executing
- * or cancelled and remove them from the queue.
- */
- final Iterator<Request> it = requests.iterator();
- while (it.hasNext()) {
- final Request r = it.next();
- if (r.future.isUncancellable()) {
- futuresToCancel.add( r.future );
- it.remove();
- } else if (r.future.isCancelled()) {
- // This just does some house-cleaning
- it.remove();
- }
- }
-
- remoteDevice.onRemoteSessionDown();
- }
- }
- finally {
- sessionLock.unlock();
- }
-
- // Notify pending request futures outside of the sessionLock to avoid unnecessarily
- // blocking the caller.
- for( UncancellableFuture<RpcResult<NetconfMessage>> future: futuresToCancel ) {
- if( Strings.isNullOrEmpty( reason ) ) {
- future.set( createSessionDownRpcResult() );
- } else {
- future.set( createErrorRpcResult( RpcError.ErrorType.TRANSPORT, reason ) );
- }
- }
- }
-
- private RpcResult<NetconfMessage> createSessionDownRpcResult() {
- return createErrorRpcResult( RpcError.ErrorType.TRANSPORT,
- String.format( "The netconf session to %1$s is disconnected", id.getName() ) );
- }
-
- private RpcResult<NetconfMessage> createErrorRpcResult( RpcError.ErrorType errorType, String message ) {
- return RpcResultBuilder.<NetconfMessage>failed()
- .withError(errorType, NetconfDocumentedException.ErrorTag.operation_failed.getTagValue(), message).build();
- }
-
- @Override
- public void onSessionDown(final NetconfClientSession session, final Exception e) {
- LOG.warn("{}: Session went down", id, e);
- tearDown( null );
- }
-
- @Override
- public void onSessionTerminated(final NetconfClientSession session, final NetconfTerminationReason reason) {
- LOG.warn("{}: Session terminated {}", id, reason);
- tearDown( reason.getErrorMessage() );
- }
-
- @Override
- public void close() {
- // Cancel reconnect if in progress
- if(initFuture != null) {
- initFuture.cancel(false);
- }
- // Disconnect from device
- if(session != null) {
- session.close();
- // tear down not necessary, called indirectly by above close
- }
- }
-
- @Override
- public void onMessage(final NetconfClientSession session, final NetconfMessage message) {
- /*
- * Dispatch between notifications and messages. Messages need to be processed
- * with lock held, notifications do not.
- */
- if (isNotification(message)) {
- processNotification(message);
- } else {
- processMessage(message);
- }
- }
-
- private void processMessage(final NetconfMessage message) {
- Request request = null;
- sessionLock.lock();
-
- try {
- request = requests.peek();
- if (request != null && request.future.isUncancellable()) {
- requests.poll();
- } else {
- request = null;
- LOG.warn("{}: Ignoring unsolicited message {}", id,
- msgToS(message));
- }
- }
- finally {
- sessionLock.unlock();
- }
-
- if( request != null ) {
-
- LOG.debug("{}: Message received {}", id, message);
-
- if(LOG.isTraceEnabled()) {
- LOG.trace( "{}: Matched request: {} to response: {}", id, msgToS( request.request ), msgToS( message ) );
- }
-
- try {
- NetconfMessageTransformUtil.checkValidReply( request.request, message );
- } catch (final NetconfDocumentedException e) {
- LOG.warn(
- "{}: Invalid request-reply match, reply message contains different message-id, request: {}, response: {}",
- id, msgToS(request.request), msgToS(message), e);
-
- request.future.set( RpcResultBuilder.<NetconfMessage>failed()
- .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
-
- //recursively processing message to eventually find matching request
- processMessage(message);
-
- return;
- }
-
- try {
- NetconfMessageTransformUtil.checkSuccessReply(message);
- } catch(final NetconfDocumentedException e) {
- LOG.warn(
- "{}: Error reply from remote device, request: {}, response: {}",
- id, msgToS(request.request), msgToS(message), e);
-
- request.future.set( RpcResultBuilder.<NetconfMessage>failed()
- .withRpcError( NetconfMessageTransformUtil.toRpcError( e ) ).build() );
- return;
- }
-
- request.future.set( RpcResultBuilder.success( message ).build() );
- }
- }
-
- private static String msgToS(final NetconfMessage msg) {
- return XmlUtil.toString(msg.getDocument());
- }
-
- @Override
- public ListenableFuture<RpcResult<NetconfMessage>> sendRequest(final NetconfMessage message, final QName rpc) {
- sessionLock.lock();
- try {
- return sendRequestWithLock( message, rpc );
- } finally {
- sessionLock.unlock();
- }
- }
-
- private ListenableFuture<RpcResult<NetconfMessage>> sendRequestWithLock(
- final NetconfMessage message, final QName rpc) {
- if(LOG.isTraceEnabled()) {
- LOG.trace("{}: Sending message {}", id, msgToS(message));
- }
-
- if (session == null) {
- LOG.warn("{}: Session is disconnected, failing RPC request {}",
- id, message);
- return Futures.immediateFuture( createSessionDownRpcResult() );
- }
-
- final Request req = new Request( new UncancellableFuture<RpcResult<NetconfMessage>>(true),
- message );
- requests.add(req);
-
- session.sendMessage(req.request).addListener(new FutureListener<Void>() {
- @Override
- public void operationComplete(final Future<Void> future) throws Exception {
- if( !future.isSuccess() ) {
- // We expect that a session down will occur at this point
- LOG.debug("{}: Failed to send request {}", id,
- XmlUtil.toString(req.request.getDocument()),
- future.cause());
-
- if( future.cause() != null ) {
- req.future.set( createErrorRpcResult( RpcError.ErrorType.TRANSPORT,
- future.cause().getLocalizedMessage() ) );
- } else {
- req.future.set( createSessionDownRpcResult() ); // assume session is down
- }
- req.future.setException( future.cause() );
- }
- else {
- LOG.trace("Finished sending request {}", req.request);
- }
- }
- });
-
- return req.future;
- }
-
- private void processNotification(final NetconfMessage notification) {
- if(LOG.isTraceEnabled()) {
- LOG.trace("{}: Notification received: {}", id, notification);
- }
-
- remoteDevice.onNotification(notification);
- }
-
- private static boolean isNotification(final NetconfMessage message) {
- final XmlElement xmle = XmlElement.fromDomDocument(message.getDocument());
- return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()) ;
- }
-
- private static final class Request {
- final UncancellableFuture<RpcResult<NetconfMessage>> future;
- final NetconfMessage request;
-
- private Request(final UncancellableFuture<RpcResult<NetconfMessage>> future,
- final NetconfMessage request) {
- this.future = future;
- this.request = request;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import java.net.URI;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfSessionPreferences {
-
- private static final class ParameterMatcher {
- private final Predicate<String> predicate;
- private final int skipLength;
-
- ParameterMatcher(final String name) {
- predicate = new Predicate<String>() {
- @Override
- public boolean apply(final String input) {
- return input.startsWith(name);
- }
- };
-
- this.skipLength = name.length();
- }
-
- private String from(final Iterable<String> params) {
- final Optional<String> o = Iterables.tryFind(params, predicate);
- if (!o.isPresent()) {
- return null;
- }
-
- return o.get().substring(skipLength);
- }
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfSessionPreferences.class);
- private static final ParameterMatcher MODULE_PARAM = new ParameterMatcher("module=");
- private static final ParameterMatcher REVISION_PARAM = new ParameterMatcher("revision=");
- private static final ParameterMatcher BROKEN_REVISON_PARAM = new ParameterMatcher("amp;revision=");
- private static final Splitter AMP_SPLITTER = Splitter.on('&');
- private static final Predicate<String> CONTAINS_REVISION = new Predicate<String>() {
- @Override
- public boolean apply(final String input) {
- return input.contains("revision=");
- }
- };
-
- private final Set<QName> moduleBasedCaps;
- private final Set<String> nonModuleCaps;
-
- private NetconfSessionPreferences(final Set<String> nonModuleCaps, final Set<QName> moduleBasedCaps) {
- this.nonModuleCaps = Preconditions.checkNotNull(nonModuleCaps);
- this.moduleBasedCaps = Preconditions.checkNotNull(moduleBasedCaps);
- }
-
- public Set<QName> getModuleBasedCaps() {
- return moduleBasedCaps;
- }
-
- public Set<String> getNonModuleCaps() {
- return nonModuleCaps;
- }
-
- public boolean containsNonModuleCapability(final String capability) {
- return nonModuleCaps.contains(capability);
- }
-
- public boolean containsModuleCapability(final QName capability) {
- return moduleBasedCaps.contains(capability);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("capabilities", nonModuleCaps)
- .add("moduleBasedCapabilities", moduleBasedCaps)
- .add("rollback", isRollbackSupported())
- .add("monitoring", isMonitoringSupported())
- .add("candidate", isCandidateSupported())
- .add("writableRunning", isRunningWritable())
- .toString();
- }
-
- public boolean isRollbackSupported() {
- return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString());
- }
-
- public boolean isCandidateSupported() {
- return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_CANDIDATE_URI.toString());
- }
-
- public boolean isRunningWritable() {
- return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_RUNNING_WRITABLE_URI.toString());
- }
-
- public boolean isNotificationsSupported() {
- return containsNonModuleCapability(NetconfMessageTransformUtil.NETCONF_NOTIFICATONS_URI.toString())
- || containsModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_NOTIFICATIONS);
- }
-
- public boolean isMonitoringSupported() {
- return containsModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING)
- || containsNonModuleCapability(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
- }
-
- public NetconfSessionPreferences addModuleCaps(final NetconfSessionPreferences netconfSessionModuleCapabilities) {
- final HashSet<QName> mergedCaps = Sets.newHashSetWithExpectedSize(moduleBasedCaps.size() + netconfSessionModuleCapabilities.getModuleBasedCaps().size());
- mergedCaps.addAll(moduleBasedCaps);
- mergedCaps.addAll(netconfSessionModuleCapabilities.getModuleBasedCaps());
- return new NetconfSessionPreferences(getNonModuleCaps(), mergedCaps);
- }
-
- public static NetconfSessionPreferences fromNetconfSession(final NetconfClientSession session) {
- return fromStrings(session.getServerCapabilities());
- }
-
- private static QName cachedQName(final String namespace, final String revision, final String moduleName) {
- return QName.cachedReference(QName.create(namespace, revision, moduleName));
- }
-
- private static QName cachedQName(final String namespace, final String moduleName) {
- return QName.cachedReference(QName.create(URI.create(namespace), null, moduleName).withoutRevision());
- }
-
- public static NetconfSessionPreferences fromStrings(final Collection<String> capabilities) {
- final Set<QName> moduleBasedCaps = new HashSet<>();
- final Set<String> nonModuleCaps = Sets.newHashSet(capabilities);
-
- for (final String capability : capabilities) {
- final int qmark = capability.indexOf('?');
- if (qmark == -1) {
- continue;
- }
-
- final String namespace = capability.substring(0, qmark);
- final Iterable<String> queryParams = AMP_SPLITTER.split(capability.substring(qmark + 1));
- final String moduleName = MODULE_PARAM.from(queryParams);
- if (moduleName == null) {
- continue;
- }
-
- String revision = REVISION_PARAM.from(queryParams);
- if (revision != null) {
- addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
- continue;
- }
-
- /*
- * We have seen devices which mis-escape revision, but the revision may not
- * even be there. First check if there is a substring that matches revision.
- */
- if (Iterables.any(queryParams, CONTAINS_REVISION)) {
-
- LOG.debug("Netconf device was not reporting revision correctly, trying to get amp;revision=");
- revision = BROKEN_REVISON_PARAM.from(queryParams);
- if (revision == null) {
- LOG.warn("Netconf device returned revision incorrectly escaped for {}, ignoring it", capability);
- addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
- } else {
- addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, revision, moduleName));
- }
- continue;
- }
-
- // Fallback, no revision provided for module
- addModuleQName(moduleBasedCaps, nonModuleCaps, capability, cachedQName(namespace, moduleName));
- }
-
- return new NetconfSessionPreferences(ImmutableSet.copyOf(nonModuleCaps), ImmutableSet.copyOf(moduleBasedCaps));
- }
-
-
- private static void addModuleQName(final Set<QName> moduleBasedCaps, final Set<String> nonModuleCaps, final String capability, final QName qName) {
- moduleBasedCaps.add(qName);
- nonModuleCaps.remove(capability);
- }
-
- private NetconfDeviceCapabilities capabilities = new NetconfDeviceCapabilities();
-
- public NetconfDeviceCapabilities getNetconfDeviceCapabilities() {
- return capabilities;
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AbstractFuture;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.GuardedBy;
-
-final class UncancellableFuture<V> extends AbstractFuture<V> {
- @GuardedBy("this")
- private boolean uncancellable = false;
-
- public UncancellableFuture(final boolean uncancellable) {
- this.uncancellable = uncancellable;
- }
-
- public synchronized boolean setUncancellable() {
- if (isCancelled()) {
- return false;
- }
-
- uncancellable = true;
- return true;
- }
-
- public synchronized boolean isUncancellable() {
- return uncancellable;
- }
-
- @Override
- public synchronized boolean cancel(final boolean mayInterruptIfRunning) {
- return uncancellable ? false : super.cancel(mayInterruptIfRunning);
- }
-
- @Override
- public synchronized boolean set(@Nullable final V value) {
- Preconditions.checkState(uncancellable);
- return super.set(value);
- }
-
- @Override
- protected boolean setException(final Throwable throwable) {
- Preconditions.checkState(uncancellable);
- return super.setException(throwable);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
- /**
- * Implementation of netconf southbound connector
- */
-package org.opendaylight.controller.sal.connect.netconf;
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps.getSourceNode;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * SalFacade proxy that invokes keepalive RPCs to prevent session shutdown from remote device
- * and to detect incorrect session drops (netconf session is inactive, but TCP/SSH connection is still present).
- * The keepalive RPC is a get-config with empty filter.
- */
-public final class KeepaliveSalFacade implements RemoteDeviceHandler<NetconfSessionPreferences> {
-
- private static final Logger LOG = LoggerFactory.getLogger(KeepaliveSalFacade.class);
-
- // 2 minutes keepalive delay by default
- private static final long DEFAULT_DELAY = TimeUnit.MINUTES.toSeconds(2);
-
- private final RemoteDeviceId id;
- private final RemoteDeviceHandler<NetconfSessionPreferences> salFacade;
- private final ScheduledExecutorService executor;
- private final long keepaliveDelaySeconds;
- private final ResetKeepalive resetKeepaliveTask;
-
- private volatile NetconfDeviceCommunicator listener;
- private volatile ScheduledFuture<?> currentKeepalive;
- private volatile DOMRpcService currentDeviceRpc;
-
- public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ScheduledExecutorService executor, final long keepaliveDelaySeconds) {
- this.id = id;
- this.salFacade = salFacade;
- this.executor = executor;
- this.keepaliveDelaySeconds = keepaliveDelaySeconds;
- this.resetKeepaliveTask = new ResetKeepalive();
- }
-
- public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler<NetconfSessionPreferences> salFacade,
- final ScheduledExecutorService executor) {
- this(id, salFacade, executor, DEFAULT_DELAY);
- }
-
- /**
- * Set the netconf session listener whenever ready
- *
- * @param listener netconf session listener
- */
- public void setListener(final NetconfDeviceCommunicator listener) {
- this.listener = listener;
- }
-
- /**
- * Just cancel current keepalive task.
- * If its already started, let it finish ... not such a big deal.
- *
- * Then schedule next keepalive.
- */
- private void resetKeepalive() {
- LOG.trace("{}: Resetting netconf keepalive timer", id);
- if(currentKeepalive != null) {
- currentKeepalive.cancel(false);
- }
- scheduleKeepalive();
- }
-
- /**
- * Cancel current keepalive and also reset current deviceRpc
- */
- private void stopKeepalives() {
- if(currentKeepalive != null) {
- currentKeepalive.cancel(false);
- }
- currentDeviceRpc = null;
- }
-
- private void reconnect() {
- Preconditions.checkState(listener != null, "%s: Unable to reconnect, session listener is missing", id);
- stopKeepalives();
- LOG.info("{}: Reconnecting inactive netconf session", id);
- listener.disconnect();
- }
-
- @Override
- public void onDeviceConnected(final SchemaContext remoteSchemaContext, final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
- this.currentDeviceRpc = deviceRpc;
- final DOMRpcService deviceRpc1 = new KeepaliveDOMRpcService(deviceRpc, resetKeepaliveTask);
- salFacade.onDeviceConnected(remoteSchemaContext, netconfSessionPreferences, deviceRpc1);
-
- LOG.debug("{}: Netconf session initiated, starting keepalives", id);
- scheduleKeepalive();
- }
-
- private void scheduleKeepalive() {
- Preconditions.checkState(currentDeviceRpc != null);
- LOG.trace("{}: Scheduling next keepalive in {} {}", id, keepaliveDelaySeconds, TimeUnit.SECONDS);
- currentKeepalive = executor.schedule(new Keepalive(), keepaliveDelaySeconds, TimeUnit.SECONDS);
- }
-
- @Override
- public void onDeviceDisconnected() {
- stopKeepalives();
- salFacade.onDeviceDisconnected();
- }
-
- @Override
- public void onDeviceFailed(final Throwable throwable) {
- stopKeepalives();
- salFacade.onDeviceFailed(throwable);
- }
-
- @Override
- public void onNotification(final DOMNotification domNotification) {
- resetKeepalive();
- salFacade.onNotification(domNotification);
- }
-
- @Override
- public void close() {
- stopKeepalives();
- salFacade.close();
- }
-
- // Keepalive RPC static resources
- private static final SchemaPath PATH = toPath(NETCONF_GET_CONFIG_QNAME);
- private static final ContainerNode KEEPALIVE_PAYLOAD =
- NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(NETCONF_RUNNING_QNAME), NetconfMessageTransformUtil.EMPTY_FILTER);
-
- /**
- * Invoke keepalive RPC and check the response. In case of any received response the keepalive
- * is considered successful and schedules next keepalive with a fixed delay. If the response is unsuccessful (no
- * response received, or the rcp could not even be sent) immediate reconnect is triggered as netconf session
- * is considered inactive/failed.
- */
- private class Keepalive implements Runnable, FutureCallback<DOMRpcResult> {
-
- @Override
- public void run() {
- LOG.trace("{}: Invoking keepalive RPC", id);
-
- try {
- Futures.addCallback(currentDeviceRpc.invokeRpc(PATH, KEEPALIVE_PAYLOAD), this);
- } catch (NullPointerException e) {
- LOG.debug("{}: Skipping keepalive while reconnecting", id);
- // Empty catch block intentional
- // Do nothing. The currentDeviceRpc was null and it means we hit the reconnect window and
- // attempted to send keepalive while we were reconnecting. Next keepalive will be scheduled
- // after reconnect so no action necessary here.
- }
- }
-
- @Override
- public void onSuccess(final DOMRpcResult result) {
- LOG.debug("{}: Keepalive RPC successful with response: {}", id, result.getResult());
- scheduleKeepalive();
- }
-
- @Override
- public void onFailure(@Nonnull final Throwable t) {
- LOG.warn("{}: Keepalive RPC failed. Reconnecting netconf session.", id, t);
- reconnect();
- }
- }
-
- /**
- * Reset keepalive after each RPC response received
- */
- private class ResetKeepalive implements com.google.common.util.concurrent.FutureCallback<DOMRpcResult> {
- @Override
- public void onSuccess(@Nullable final DOMRpcResult result) {
- // No matter what response we got, rpc-reply or rpc-error, we got it from device so the netconf session is OK
- resetKeepalive();
- }
-
- @Override
- public void onFailure(@Nonnull final Throwable t) {
- // User/Application RPC failed (The RPC did not reach the remote device or .. TODO what other reasons could cause this ?)
- // There is no point in keeping this session. Reconnect.
- LOG.warn("{}: Rpc failure detected. Reconnecting netconf session", id, t);
- reconnect();
- }
- }
-
- /**
- * DOMRpcService proxy that attaches reset-keepalive-task to each RPC invocation.
- */
- private static final class KeepaliveDOMRpcService implements DOMRpcService {
-
- private final DOMRpcService deviceRpc;
- private ResetKeepalive resetKeepaliveTask;
-
- public KeepaliveDOMRpcService(final DOMRpcService deviceRpc, final ResetKeepalive resetKeepaliveTask) {
- this.deviceRpc = deviceRpc;
- this.resetKeepaliveTask = resetKeepaliveTask;
- }
-
- @Nonnull
- @Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, final NormalizedNode<?, ?> input) {
- final CheckedFuture<DOMRpcResult, DOMRpcException> domRpcResultDOMRpcExceptionCheckedFuture = deviceRpc.invokeRpc(type, input);
- Futures.addCallback(domRpcResultDOMRpcExceptionCheckedFuture, resetKeepaliveTask);
- return domRpcResultDOMRpcExceptionCheckedFuture;
- }
-
- @Override
- public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T listener) {
- // There is no real communication with the device (yet), no reset here
- return deviceRpc.registerRpcListener(listener);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import java.util.Collections;
-import java.util.Map;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.sal.tx.ReadOnlyTx;
-import org.opendaylight.controller.sal.connect.netconf.sal.tx.ReadWriteTx;
-import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteCandidateRunningTx;
-import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteCandidateTx;
-import org.opendaylight.controller.sal.connect.netconf.sal.tx.WriteRunningTx;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-final class NetconfDeviceDataBroker implements DOMDataBroker {
- private final RemoteDeviceId id;
- private final NetconfBaseOps netconfOps;
- private final long requestTimeoutMillis;
-
- private final boolean rollbackSupport;
- private boolean candidateSupported;
- private boolean runningWritable;
-
- public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences, long requestTimeoutMillis) {
- this.id = id;
- this.netconfOps = new NetconfBaseOps(rpc, schemaContext);
- this.requestTimeoutMillis = requestTimeoutMillis;
- // get specific attributes from netconf preferences and get rid of it
- // no need to keep the entire preferences object, its quite big with all the capability QNames
- candidateSupported = netconfSessionPreferences.isCandidateSupported();
- runningWritable = netconfSessionPreferences.isRunningWritable();
- rollbackSupport = netconfSessionPreferences.isRollbackSupported();
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- return new ReadOnlyTx(netconfOps, id);
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- return new ReadWriteTx(newReadOnlyTransaction(), newWriteOnlyTransaction());
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- if(candidateSupported) {
- if(runningWritable) {
- return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
- } else {
- return new WriteCandidateTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
- }
- } else {
- return new WriteRunningTx(id, netconfOps, rollbackSupport, requestTimeoutMillis);
- }
- }
-
- @Override
- public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store, final YangInstanceIdentifier path, final DOMDataChangeListener listener, final DataChangeScope triggeringScope) {
- throw new UnsupportedOperationException(id + ": Data change listeners not supported for netconf mount point");
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
- throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
- }
-
- @Override
- public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
- return Collections.emptyMap();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-class NetconfDeviceNotificationService implements DOMNotificationService {
-
- private final Multimap<SchemaPath, DOMNotificationListener> listeners = HashMultimap.create();
-
- // Notification publish is very simple and hijacks the thread of the caller
- // TODO shouldnt we reuse the implementation for notification router from sal-broker-impl ?
- public synchronized void publishNotification(final DOMNotification notification) {
- for (final DOMNotificationListener domNotificationListener : listeners.get(notification.getType())) {
- domNotificationListener.onNotification(notification);
- }
- }
-
- @Override
- public synchronized <T extends DOMNotificationListener> ListenerRegistration<T> registerNotificationListener(@Nonnull final T listener, @Nonnull final Collection<SchemaPath> types) {
- for (final SchemaPath type : types) {
- listeners.put(type, listener);
- }
-
- // FIXME this should invoke create-subscription rpc on the remote device for a given notification
-
- return new ListenerRegistration<T>() {
- @Override
- public void close() {
- for (final SchemaPath type : types) {
- listeners.remove(type, listener);
- }
- }
-
- @Override
- public T getInstance() {
- return listener;
- }
- };
- }
-
- @Override
- public synchronized <T extends DOMNotificationListener> ListenerRegistration<T> registerNotificationListener(@Nonnull final T listener, final SchemaPath... types) {
- return registerNotificationListener(listener, Lists.newArrayList(types));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collection;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.api.MessageTransformer;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-/**
- * Invokes RPC by sending netconf message via listener. Also transforms result from NetconfMessage to CompositeNode.
- */
-public final class NetconfDeviceRpc implements DOMRpcService {
-
- private static final Function<RpcDefinition, DOMRpcIdentifier> RPC_TO_RPC_IDENTIFIER = new Function<RpcDefinition, DOMRpcIdentifier>() {
- @Override
- public DOMRpcIdentifier apply(final RpcDefinition input) {
- // TODO add support for routed rpcs ... is it necessary in this case ?
- return DOMRpcIdentifier.create(input.getPath());
- }
- };
-
- private final RemoteDeviceCommunicator<NetconfMessage> listener;
- private final MessageTransformer<NetconfMessage> transformer;
- private final Collection<DOMRpcIdentifier> availableRpcs;
-
- public NetconfDeviceRpc(final SchemaContext schemaContext, final RemoteDeviceCommunicator<NetconfMessage> listener, final MessageTransformer<NetconfMessage> transformer) {
- this.listener = listener;
- this.transformer = transformer;
-
- availableRpcs = Collections2.transform(schemaContext.getOperations(), RPC_TO_RPC_IDENTIFIER);
- }
-
- @Nonnull
- @Override
- public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, @Nullable final NormalizedNode<?, ?> input) {
- final NetconfMessage message = transformer.toRpcRequest(type, input);
- final ListenableFuture<RpcResult<NetconfMessage>> delegateFutureWithPureResult = listener.sendRequest(message, type.getLastComponent());
-
- final ListenableFuture<DOMRpcResult> transformed = Futures.transform(delegateFutureWithPureResult, new Function<RpcResult<NetconfMessage>, DOMRpcResult>() {
- @Override
- public DOMRpcResult apply(final RpcResult<NetconfMessage> input) {
- if (input.isSuccessful()) {
- return transformer.toRpcResult(input.getResult(), type);
- } else {
- // TODO check whether the listener sets errors properly
- return new DefaultDOMRpcResult(input.getErrors());
- }
- }
- });
-
- return Futures.makeChecked(transformed, new Function<Exception, DOMRpcException>() {
- @Nullable
- @Override
- public DOMRpcException apply(@Nullable final Exception e) {
- // FIXME what other possible exceptions are there ?
- return new DOMRpcImplementationNotAvailableException(e, "Unable to invoke rpc %s", type);
- }
- });
- }
-
- @Nonnull
- @Override
- public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T listener) {
-
- listener.onRpcAvailable(availableRpcs);
-
- return new ListenerRegistration<T>() {
- @Override
- public void close() {
- // NOOP, no rpcs appear and disappear in this implementation
- }
-
- @Override
- public T getInstance() {
- return listener;
- }
- };
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDeviceHandler<NetconfSessionPreferences> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSalFacade.class);
-
- private final RemoteDeviceId id;
- private final NetconfDeviceSalProvider salProvider;
- private final long defaultRequestTimeoutMillis;
-
- private final List<AutoCloseable> salRegistrations = Lists.newArrayList();
-
- public NetconfDeviceSalFacade(final RemoteDeviceId id, final Broker domBroker, final BindingAwareBroker bindingBroker, long defaultRequestTimeoutMillis) {
- this.id = id;
- this.salProvider = new NetconfDeviceSalProvider(id);
- this.defaultRequestTimeoutMillis = defaultRequestTimeoutMillis;
- registerToSal(domBroker, bindingBroker);
- }
-
- public void registerToSal(final Broker domRegistryDependency, final BindingAwareBroker bindingBroker) {
- domRegistryDependency.registerProvider(salProvider);
- bindingBroker.registerProvider(salProvider);
- }
-
- @Override
- public synchronized void onNotification(final DOMNotification domNotification) {
- salProvider.getMountInstance().publish(domNotification);
- }
-
- @Override
- public synchronized void onDeviceConnected(final SchemaContext schemaContext,
- final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc) {
-
- final DOMDataBroker domBroker = new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences, defaultRequestTimeoutMillis);
-
- final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService();
-
- salProvider.getMountInstance().onTopologyDeviceConnected(schemaContext, domBroker, deviceRpc, notificationService);
- salProvider.getTopologyDatastoreAdapter().updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities());
- }
-
- @Override
- public synchronized void onDeviceDisconnected() {
- salProvider.getTopologyDatastoreAdapter().updateDeviceData(false,
- new NetconfDeviceCapabilities());
- salProvider.getMountInstance().onTopologyDeviceDisconnected();
- }
-
- @Override
- public synchronized void onDeviceFailed(final Throwable throwable) {
- salProvider.getTopologyDatastoreAdapter().setDeviceAsFailed(throwable);
- salProvider.getMountInstance().onTopologyDeviceDisconnected();
- }
-
- @Override
- public synchronized void close() {
- for (final AutoCloseable reg : Lists.reverse(salRegistrations)) {
- closeGracefully(reg);
- }
- closeGracefully(salProvider);
- }
-
- private void closeGracefully(final AutoCloseable resource) {
- if (resource != null) {
- try {
- resource.close();
- } catch (final Exception e) {
- LOG.warn("{}: Ignoring exception while closing {}", id,
- resource, e);
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import java.util.Collections;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
-import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.yangtools.concepts.ObjectRegistration;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class NetconfDeviceSalProvider implements AutoCloseable, Provider, BindingAwareProvider {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSalProvider.class);
-
- private final RemoteDeviceId id;
- private MountInstance mountInstance;
-
- private volatile NetconfDeviceTopologyAdapter topologyDatastoreAdapter;
-
- public NetconfDeviceSalProvider(final RemoteDeviceId deviceId) {
- this.id = deviceId;
- }
-
- public MountInstance getMountInstance() {
- Preconditions.checkState(mountInstance != null,
- "%s: Mount instance was not initialized by sal. Cannot get mount instance", id);
- return mountInstance;
- }
-
- public NetconfDeviceTopologyAdapter getTopologyDatastoreAdapter() {
- Preconditions.checkState(topologyDatastoreAdapter != null,
- "%s: Sal provider %s was not initialized by sal. Cannot get topology datastore adapter", id);
- return topologyDatastoreAdapter;
- }
-
- @Override
- public void onSessionInitiated(final Broker.ProviderSession session) {
- LOG.debug("{}: (BI)Session with sal established {}", id, session);
-
- final DOMMountPointService mountService = session.getService(DOMMountPointService.class);
- if (mountService != null) {
- mountInstance = new MountInstance(mountService, id);
- }
- }
-
- @Override
- public Collection<Provider.ProviderFunctionality> getProviderFunctionality() {
- return Collections.emptySet();
- }
-
- @Override
- public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) {
- LOG.debug("{}: Session with sal established {}", id, session);
-
- final DataBroker dataBroker = session.getSALService(DataBroker.class);
-
- topologyDatastoreAdapter = new NetconfDeviceTopologyAdapter(id, dataBroker);
- }
-
- public void close() throws Exception {
- mountInstance.close();
- topologyDatastoreAdapter.close();
- topologyDatastoreAdapter = null;
- }
-
- static final class MountInstance implements AutoCloseable {
-
- private DOMMountPointService mountService;
- private final RemoteDeviceId id;
- private NetconfDeviceNotificationService notificationService;
-
- private ObjectRegistration<DOMMountPoint> topologyRegistration;
-
- MountInstance(final DOMMountPointService mountService, final RemoteDeviceId id) {
- this.mountService = Preconditions.checkNotNull(mountService);
- this.id = Preconditions.checkNotNull(id);
- }
-
- synchronized void onTopologyDeviceConnected(final SchemaContext initialCtx,
- final DOMDataBroker broker, final DOMRpcService rpc,
- final NetconfDeviceNotificationService notificationService) {
-
- Preconditions.checkNotNull(mountService, "Closed");
- Preconditions.checkState(topologyRegistration == null, "Already initialized");
-
- final DOMMountPointService.DOMMountPointBuilder mountBuilder = mountService.createMountPoint(id.getTopologyPath());
- mountBuilder.addInitialSchemaContext(initialCtx);
-
- mountBuilder.addService(DOMDataBroker.class, broker);
- mountBuilder.addService(DOMRpcService.class, rpc);
- mountBuilder.addService(DOMNotificationService.class, notificationService);
- this.notificationService = notificationService;
-
- topologyRegistration = mountBuilder.register();
- LOG.debug("{}: TOPOLOGY Mountpoint exposed into MD-SAL {}", id,
- topologyRegistration);
-
- }
-
- synchronized void onTopologyDeviceDisconnected() {
- if(topologyRegistration == null) {
- LOG.trace(
- "{}: Not removing TOPOLOGY mountpoint from MD-SAL, mountpoint was not registered yet",
- id);
- return;
- }
-
- try {
- topologyRegistration.close();
- } catch (final Exception e) {
- // Only log and ignore
- LOG.warn(
- "Unable to unregister mount instance for {}. Ignoring exception",
- id.getTopologyPath(), e);
- } finally {
- LOG.debug("{}: TOPOLOGY Mountpoint removed from MD-SAL {}",
- id, topologyRegistration);
- topologyRegistration = null;
- }
- }
-
- @Override
- synchronized public void close() throws Exception {
- onTopologyDeviceDisconnected();
- mountService = null;
- }
-
- public synchronized void publish(final DOMNotification domNotification) {
- Preconditions.checkNotNull(notificationService, "Device not set up yet, cannot handle notification {}", domNotification);
- notificationService.publishNotification(domNotification);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map.Entry;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeFields.ConnectionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.AvailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.UnavailableCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.UnavailableCapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapability.FailureReason;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.fields.unavailable.capabilities.UnavailableCapabilityBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class NetconfDeviceTopologyAdapter implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceTopologyAdapter.class);
- public static final Function<Entry<QName, FailureReason>, UnavailableCapability> UNAVAILABLE_CAPABILITY_TRANSFORMER = new Function<Entry<QName, FailureReason>, UnavailableCapability>() {
- @Override
- public UnavailableCapability apply(final Entry<QName, FailureReason> input) {
- return new UnavailableCapabilityBuilder()
- .setCapability(input.getKey().toString())
- .setFailureReason(input.getValue()).build();
- }
- };
- public static final Function<QName, String> AVAILABLE_CAPABILITY_TRANSFORMER = new Function<QName, String>() {
- @Override
- public String apply(QName qName) {
- // intern string representation of a capability to avoid duplicates
- return qName.toString().intern();
- }
- };
-
- private final RemoteDeviceId id;
- private final BindingTransactionChain txChain;
-
- private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
- private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
- private static final String UNKNOWN_REASON = "Unknown reason";
-
- NetconfDeviceTopologyAdapter(final RemoteDeviceId id, final DataBroker dataService) {
- this.id = id;
- this.txChain = Preconditions.checkNotNull(dataService).createTransactionChain(new TransactionChainListener() {
- @Override
- public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
- LOG.error("{}: TransactionChain({}) {} FAILED!", id, chain,
- transaction.getIdentifier(), cause);
- throw new IllegalStateException(id + " TransactionChain(" + chain + ") not committed correctly", cause);
- }
-
- @Override
- public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
- LOG.trace("{}: TransactionChain({}) SUCCESSFUL", id, chain);
- }
- });
-
- this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
- this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
-
- initDeviceData();
- }
-
- private void initDeviceData() {
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
- createNetworkTopologyIfNotPresent(writeTx);
-
- final InstanceIdentifier<Node> path = id.getTopologyBindingPath();
- NodeBuilder nodeBuilder = getNodeIdBuilder(id);
- NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
- netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connecting);
- netconfNodeBuilder.setHost(id.getHost());
- netconfNodeBuilder.setPort(new PortNumber(id.getAddress().getPort()));
- nodeBuilder.addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
- Node node = nodeBuilder.build();
-
- LOG.trace(
- "{}: Init device state transaction {} putting if absent operational data started.",
- id, writeTx.getIdentifier());
- writeTx.put(LogicalDatastoreType.OPERATIONAL, path, node);
- LOG.trace(
- "{}: Init device state transaction {} putting operational data ended.",
- id, writeTx.getIdentifier());
-
- LOG.trace(
- "{}: Init device state transaction {} putting if absent config data started.",
- id, writeTx.getIdentifier());
- writeTx.put(LogicalDatastoreType.CONFIGURATION, path, getNodeWithId(id));
- LOG.trace(
- "{}: Init device state transaction {} putting config data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "init");
- }
-
- public void updateDeviceData(boolean up, NetconfDeviceCapabilities capabilities) {
- final Node data = buildDataForNetconfNode(up, capabilities);
-
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
- LOG.trace(
- "{}: Update device state transaction {} merging operational data started.",
- id, writeTx.getIdentifier());
- writeTx.put(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath(), data);
- LOG.trace(
- "{}: Update device state transaction {} merging operational data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "update");
- }
-
- public void setDeviceAsFailed(Throwable throwable) {
- String reason = (throwable != null && throwable.getMessage() != null) ? throwable.getMessage() : UNKNOWN_REASON;
-
- final NetconfNode netconfNode = new NetconfNodeBuilder().setConnectionStatus(ConnectionStatus.UnableToConnect).setConnectedMessage(reason).build();
- final Node data = getNodeIdBuilder(id).addAugmentation(NetconfNode.class, netconfNode).build();
-
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
- LOG.trace(
- "{}: Setting device state as failed {} putting operational data started.",
- id, writeTx.getIdentifier());
- writeTx.put(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath(), data);
- LOG.trace(
- "{}: Setting device state as failed {} putting operational data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "update-failed-device");
- }
-
- private Node buildDataForNetconfNode(boolean up, NetconfDeviceCapabilities capabilities) {
- List<String> capabilityList = new ArrayList<>();
- capabilityList.addAll(capabilities.getNonModuleBasedCapabilities());
- capabilityList.addAll(FluentIterable.from(capabilities.getResolvedCapabilities()).transform(AVAILABLE_CAPABILITY_TRANSFORMER).toList());
- final AvailableCapabilitiesBuilder avCapabalitiesBuilder = new AvailableCapabilitiesBuilder();
- avCapabalitiesBuilder.setAvailableCapability(capabilityList);
-
- final UnavailableCapabilities unavailableCapabilities =
- new UnavailableCapabilitiesBuilder().setUnavailableCapability(FluentIterable.from(capabilities.getUnresolvedCapabilites().entrySet())
- .transform(UNAVAILABLE_CAPABILITY_TRANSFORMER).toList()).build();
-
- final NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder()
- .setHost(id.getHost())
- .setPort(new PortNumber(id.getAddress().getPort()))
- .setConnectionStatus(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting)
- .setAvailableCapabilities(avCapabalitiesBuilder.build())
- .setUnavailableCapabilities(unavailableCapabilities);
-
- final NodeBuilder nodeBuilder = getNodeIdBuilder(id);
-
- return nodeBuilder.addAugmentation(NetconfNode.class, netconfNodeBuilder.build()).build();
- }
-
- public void removeDeviceConfiguration() {
- final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
-
- LOG.trace(
- "{}: Close device state transaction {} removing all data started.",
- id, writeTx.getIdentifier());
- writeTx.delete(LogicalDatastoreType.CONFIGURATION, id.getTopologyBindingPath());
- writeTx.delete(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath());
- LOG.trace(
- "{}: Close device state transaction {} removing all data ended.",
- id, writeTx.getIdentifier());
-
- commitTransaction(writeTx, "close");
- }
-
- private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx) {
-
- final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
- LOG.trace("{}: Merging {} container to ensure its presence", id,
- networkTopology.QNAME, writeTx.getIdentifier());
- writeTx.merge(LogicalDatastoreType.CONFIGURATION, networkTopologyPath, networkTopology);
- writeTx.merge(LogicalDatastoreType.OPERATIONAL, networkTopologyPath, networkTopology);
-
- final Topology topology = new TopologyBuilder().setTopologyId(new TopologyId(TopologyNetconf.QNAME.getLocalName())).build();
- LOG.trace("{}: Merging {} container to ensure its presence", id,
- topology.QNAME, writeTx.getIdentifier());
- writeTx.merge(LogicalDatastoreType.CONFIGURATION, topologyListPath, topology);
- writeTx.merge(LogicalDatastoreType.OPERATIONAL, topologyListPath, topology);
- }
-
- private void commitTransaction(final WriteTransaction transaction, final String txType) {
- LOG.trace("{}: Committing Transaction {}:{}", id, txType,
- transaction.getIdentifier());
- final CheckedFuture<Void, TransactionCommitFailedException> result = transaction.submit();
-
- Futures.addCallback(result, new FutureCallback<Void>() {
- @Override
- public void onSuccess(final Void result) {
- LOG.trace("{}: Transaction({}) {} SUCCESSFUL", id, txType,
- transaction.getIdentifier());
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("{}: Transaction({}) {} FAILED!", id, txType,
- transaction.getIdentifier(), t);
- throw new IllegalStateException(id + " Transaction(" + txType + ") not committed correctly", t);
- }
- });
-
- }
-
- private static Node getNodeWithId(final RemoteDeviceId id) {
- final NodeBuilder builder = getNodeIdBuilder(id);
- return builder.build();
- }
-
- private static NodeBuilder getNodeIdBuilder(final RemoteDeviceId id) {
- final NodeBuilder nodeBuilder = new NodeBuilder();
- nodeBuilder.setKey(new NodeKey(new NodeId(id.getName())));
- return nodeBuilder;
- }
-
- @Override
- public void close() throws Exception {
- removeDeviceConfiguration();
- txChain.close();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class AbstractWriteTx implements DOMDataWriteTransaction {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractWriteTx.class);
-
- private final long defaultRequestTimeoutMillis;
- protected final RemoteDeviceId id;
- protected final NetconfBaseOps netOps;
- protected final boolean rollbackSupport;
- // Allow commit to be called only once
- protected boolean finished = false;
-
- public AbstractWriteTx(final long requestTimeoutMillis, final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) {
- this.defaultRequestTimeoutMillis = requestTimeoutMillis;
- this.netOps = netOps;
- this.id = id;
- this.rollbackSupport = rollbackSupport;
- init();
- }
-
- static boolean isSuccess(final DOMRpcResult result) {
- return result.getErrors().isEmpty();
- }
-
- protected void checkNotFinished() {
- Preconditions.checkState(!isFinished(), "%s: Transaction %s already finished", id, getIdentifier());
- }
-
- protected boolean isFinished() {
- return finished;
- }
-
- protected void invokeBlocking(final String msg, final Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>> op) throws NetconfDocumentedException {
- try {
- final DOMRpcResult compositeNodeRpcResult = op.apply(netOps).get(defaultRequestTimeoutMillis, TimeUnit.MILLISECONDS);
- if(isSuccess(compositeNodeRpcResult) == false) {
- throw new NetconfDocumentedException(id + ": " + msg + " failed: " + compositeNodeRpcResult.getErrors(), NetconfDocumentedException.ErrorType.application,
- NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.warning);
- }
- } catch (final InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- } catch (final ExecutionException | TimeoutException e) {
- throw new NetconfDocumentedException(id + ": " + msg + " failed: " + e.getMessage(), e, NetconfDocumentedException.ErrorType.application,
- NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.warning);
- }
- }
-
- @Override
- public synchronized boolean cancel() {
- if(isFinished()) {
- return false;
- }
-
- finished = true;
- cleanup();
- return true;
- }
-
- protected abstract void init();
-
- protected abstract void cleanup();
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-
- @Override
- public synchronized void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- checkEditable(store);
-
- // trying to write only mixin nodes (not visible when serialized). Ignoring. Some devices cannot handle empty edit-config rpc
- if(containsOnlyNonVisibleData(path, data)) {
- LOG.debug("Ignoring put for {} and data {}. Resulting data structure is empty.", path, data);
- return;
- }
-
- try {
- editConfig(
- netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>fromNullable(data), Optional.of(ModifyAction.REPLACE), path), Optional.of(ModifyAction.NONE));
- } catch (final NetconfDocumentedException e) {
- handleEditException(path, data, e, "putting");
- }
- }
-
- protected abstract void handleEditException(YangInstanceIdentifier path, NormalizedNode<?, ?> data, NetconfDocumentedException e, String editType);
- protected abstract void handleDeleteException(YangInstanceIdentifier path, NetconfDocumentedException e);
-
- @Override
- public synchronized void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- checkEditable(store);
-
- // trying to write only mixin nodes (not visible when serialized). Ignoring. Some devices cannot handle empty edit-config rpc
- if (containsOnlyNonVisibleData(path, data)) {
- LOG.debug("Ignoring merge for {} and data {}. Resulting data structure is empty.", path, data);
- return;
- }
-
- try {
- editConfig(
- netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>fromNullable(data), Optional.<ModifyAction>absent(), path), Optional.<ModifyAction>absent());
- } catch (final NetconfDocumentedException e) {
- handleEditException(path, data, e, "merge");
- }
- }
-
- /**
- * Check whether the data to be written consists only from mixins
- */
- private static boolean containsOnlyNonVisibleData(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- // There's only one such case:top level list (pathArguments == 1 && data is Mixin)
- // any other mixin nodes are contained by a "regular" node thus visible when serialized
- return path.getPathArguments().size() == 1 && data instanceof MixinNode;
- }
-
- @Override
- public synchronized void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- checkEditable(store);
-
- try {
- editConfig(
- netOps.createEditConfigStrcture(Optional.<NormalizedNode<?, ?>>absent(), Optional.of(ModifyAction.DELETE), path), Optional.of(ModifyAction.NONE));
- } catch (final NetconfDocumentedException e) {
- handleDeleteException(path, e);
- }
- }
-
- @Override
- public final ListenableFuture<RpcResult<TransactionStatus>> commit() {
- checkNotFinished();
- finished = true;
-
- return performCommit();
- }
-
- protected abstract ListenableFuture<RpcResult<TransactionStatus>> performCommit();
-
- private void checkEditable(final LogicalDatastoreType store) {
- checkNotFinished();
- Preconditions.checkArgument(store == LogicalDatastoreType.CONFIGURATION, "Can edit only configuration data, not %s", store);
- }
-
- protected abstract void editConfig(DataContainerChild<?, ?> editStructure, Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-public final class ReadOnlyTx implements DOMDataReadOnlyTransaction {
-
- private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTx.class);
-
- private final NetconfBaseOps netconfOps;
- private final RemoteDeviceId id;
- private final FutureCallback<DOMRpcResult> loggingCallback;
-
- public ReadOnlyTx(final NetconfBaseOps netconfOps, final RemoteDeviceId id) {
- this.netconfOps = netconfOps;
- this.id = id;
-
- // Simple logging callback to log result of read operation
- loggingCallback = new FutureCallback<DOMRpcResult>() {
- @Override
- public void onSuccess(final DOMRpcResult result) {
- if(AbstractWriteTx.isSuccess(result)) {
- LOG.trace("{}: Reading data successful", id);
- } else {
- LOG.warn("{}: Reading data unsuccessful: {}", id, result.getErrors());
- }
-
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.warn("{}: Reading data failed", id, t);
- }
- };
- }
-
- private CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readConfigurationData(
- final YangInstanceIdentifier path) {
- final ListenableFuture<DOMRpcResult> configRunning = netconfOps.getConfigRunning(loggingCallback, Optional.fromNullable(path));
-
- final ListenableFuture<Optional<NormalizedNode<?, ?>>> transformedFuture = Futures.transform(configRunning, new Function<DOMRpcResult, Optional<NormalizedNode<?, ?>>>() {
- @Override
- public Optional<NormalizedNode<?, ?>> apply(final DOMRpcResult result) {
- checkReadSuccess(result, path);
-
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataNode = findDataNode(result);
- return NormalizedNodes.findNode(dataNode, path.getPathArguments());
- }
- });
-
- return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
- }
-
- private DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> findDataNode(final DOMRpcResult result) {
- return ((ContainerNode) result.getResult()).getChild(NetconfMessageTransformUtil.toId(NetconfMessageTransformUtil.NETCONF_DATA_QNAME)).get();
- }
-
- private void checkReadSuccess(final DOMRpcResult result, final YangInstanceIdentifier path) {
- try {
- Preconditions.checkArgument(AbstractWriteTx.isSuccess(result), "%s: Unable to read data: %s, errors: %s", id, path, result.getErrors());
- } catch (final IllegalArgumentException e) {
- LOG.warn("{}: Unable to read data: {}, errors: {}", id, path, result.getErrors());
- throw e;
- }
- }
-
- private CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> readOperationalData(
- final YangInstanceIdentifier path) {
- final ListenableFuture<DOMRpcResult> configCandidate = netconfOps.get(loggingCallback, Optional.fromNullable(path));
-
- // Find data node and normalize its content
- final ListenableFuture<Optional<NormalizedNode<?, ?>>> transformedFuture = Futures.transform(configCandidate, new Function<DOMRpcResult, Optional<NormalizedNode<?, ?>>>() {
- @Override
- public Optional<NormalizedNode<?, ?>> apply(final DOMRpcResult result) {
- checkReadSuccess(result, path);
-
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataNode = findDataNode(result);
- return NormalizedNodes.findNode(dataNode, path.getPathArguments());
- }
- });
-
- return MappingCheckedFuture.create(transformedFuture, ReadFailedException.MAPPER);
- }
-
- @Override
- public void close() {
- // NOOP
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- switch (store) {
- case CONFIGURATION: {
- return readConfigurationData(path);
- }
- case OPERATIONAL: {
- return readOperationalData(path);
- }
- }
-
- throw new IllegalArgumentException(String.format("%s, Cannot read data %s for %s datastore, unknown datastore type", id, path, store));
- }
-
- @Override
- public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> data = read(store, path);
-
- try {
- return Futures.immediateCheckedFuture(data.get().isPresent());
- } catch (InterruptedException | ExecutionException e) {
- return Futures.immediateFailedCheckedFuture(new ReadFailedException("Exists failed",e));
- }
- }
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public class ReadWriteTx implements DOMDataReadWriteTransaction {
-
- private final DOMDataReadTransaction delegateReadTx;
- private final DOMDataWriteTransaction delegateWriteTx;
-
- public ReadWriteTx(final DOMDataReadTransaction delegateReadTx, final DOMDataWriteTransaction delegateWriteTx) {
- this.delegateReadTx = delegateReadTx;
- this.delegateWriteTx = delegateWriteTx;
- }
-
- @Override
- public boolean cancel() {
- return delegateWriteTx.cancel();
- }
-
- @Override
- public void put(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- delegateWriteTx.put(store, path, data);
- }
-
- @Override
- public void merge(final LogicalDatastoreType store, final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
- delegateWriteTx.merge(store, path, data);
- }
-
- @Override
- public void delete(final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- delegateWriteTx.delete(store, path);
- }
-
- @Override
- public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- return delegateWriteTx.submit();
- }
-
- @Override
- public ListenableFuture<RpcResult<TransactionStatus>> commit() {
- return delegateWriteTx.commit();
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- final LogicalDatastoreType store, final YangInstanceIdentifier path) {
- return delegateReadTx.read(store, path);
- }
-
- @Override public CheckedFuture<Boolean, ReadFailedException> exists(
- final LogicalDatastoreType store,
- final YangInstanceIdentifier path) {
- final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException>
- data = read(store, path);
-
- try {
- return Futures.immediateCheckedFuture(data.get().isPresent());
- } catch (InterruptedException | ExecutionException e) {
- return Futures.immediateFailedCheckedFuture(new ReadFailedException("Exists failed",e));
- }
- }
-
- @Override
- public Object getIdentifier() {
- return this;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tx implementation for netconf devices that support only candidate datastore and writable running
- * The sequence goes exactly as with only candidate supported, with one addition:
- * <ul>
- * <li>Running datastore is locked as the first thing and this lock has to succeed</li>
- * </ul>
- */
-public class WriteCandidateRunningTx extends WriteCandidateTx {
-
- private static final Logger LOG = LoggerFactory.getLogger(WriteCandidateRunningTx.class);
-
- public WriteCandidateRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport, long requestTimeoutMillis) {
- super(id, netOps, rollbackSupport, requestTimeoutMillis);
- }
-
- @Override
- protected synchronized void init() {
- lockRunning();
- super.init();
- }
-
- @Override
- protected void cleanupOnSuccess() {
- super.cleanupOnSuccess();
- unlockRunning();
- }
-
- private void lockRunning() {
- try {
- invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
- }
- });
- } catch (final NetconfDocumentedException e) {
- LOG.warn("{}: Failed to lock running. Failed to initialize transaction", id, e);
- finished = true;
- throw new RuntimeException(id + ": Failed to lock running. Failed to initialize transaction", e);
- }
- }
-
- /**
- * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
- */
- private void unlockRunning() {
- netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tx implementation for netconf devices that support only candidate datastore and no writable running
- * The sequence goes as:
- * <ol>
- * <li/> Lock candidate datastore on tx construction
- * <ul>
- * <li/> Lock has to succeed, if it does not, an attempt to discard changes is made
- * <li/> Discard changes has to succeed
- * <li/> If discard is successful, lock is reattempted
- * <li/> Second lock attempt has to succeed
- * </ul>
- * <li/> Edit-config in candidate N times
- * <ul>
- * <li/> If any issue occurs during edit, datastore is discarded using discard-changes rpc, unlocked and an exception is thrown async
- * </ul>
- * <li/> Commit and Unlock candidate datastore async
- * </ol>
- */
-public class WriteCandidateTx extends AbstractWriteTx {
-
- private static final Logger LOG = LoggerFactory.getLogger(WriteCandidateTx.class);
-
- private static final Function<DOMRpcResult, RpcResult<TransactionStatus>> RPC_RESULT_TO_TX_STATUS = new Function<DOMRpcResult, RpcResult<TransactionStatus>>() {
- @Override
- public RpcResult<TransactionStatus> apply(final DOMRpcResult input) {
- if (isSuccess(input)) {
- return RpcResultBuilder.success(TransactionStatus.COMMITED).build();
- } else {
- final RpcResultBuilder<TransactionStatus> failed = RpcResultBuilder.failed();
- for (final RpcError rpcError : input.getErrors()) {
- failed.withError(rpcError.getErrorType(), rpcError.getTag(), rpcError.getMessage(),
- rpcError.getApplicationTag(), rpcError.getInfo(), rpcError.getCause());
- }
- return failed.build();
- }
- }
- };
-
- public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps rpc, final boolean rollbackSupport, long requestTimeoutMillis) {
- super(requestTimeoutMillis, rpc, id, rollbackSupport);
- }
-
- @Override
- protected synchronized void init() {
- LOG.trace("{}: Initializing {} transaction", id, getClass().getSimpleName());
-
- try {
- lock();
- } catch (final NetconfDocumentedException e) {
- try {
- LOG.warn("{}: Failed to lock candidate, attempting discard changes", id);
- discardChanges();
- LOG.warn("{}: Changes discarded successfully, attempting lock", id);
- lock();
- } catch (final NetconfDocumentedException secondE) {
- LOG.error("{}: Failed to prepare candidate. Failed to initialize transaction", id, secondE);
- throw new RuntimeException(id + ": Failed to prepare candidate. Failed to initialize transaction", secondE);
- }
- }
- }
-
- private void lock() throws NetconfDocumentedException {
- try {
- invokeBlocking("Lock candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return input.lockCandidate(new NetconfRpcFutureCallback("Lock candidate", id));
- }
- });
- } catch (final NetconfDocumentedException e) {
- LOG.warn("{}: Failed to lock candidate", id, e);
- throw e;
- }
- }
-
- @Override
- protected void cleanup() {
- discardChanges();
- cleanupOnSuccess();
- }
-
- @Override
- protected void handleEditException(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data, final NetconfDocumentedException e, final String editType) {
- LOG.warn("{}: Error {} data to (candidate){}, data: {}, canceling", id, editType, path, data, e);
- cancel();
- throw new RuntimeException(id + ": Error while " + editType + ": (candidate)" + path, e);
- }
-
- @Override
- protected void handleDeleteException(final YangInstanceIdentifier path, final NetconfDocumentedException e) {
- LOG.warn("{}: Error deleting data (candidate){}, canceling", id, path, e);
- cancel();
- throw new RuntimeException(id + ": Error while deleting (candidate)" + path, e);
- }
-
- @Override
- public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
- final ListenableFuture<Void> commitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
- @Override
- public Void apply(final RpcResult<TransactionStatus> input) {
- Preconditions.checkArgument(input.isSuccessful() && input.getErrors().isEmpty(), "Submit failed with errors: %s", input.getErrors());
- return null;
- }
- });
-
- return Futures.makeChecked(commitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
- @Override
- public TransactionCommitFailedException apply(final Exception input) {
- return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
- }
- });
- }
-
- /**
- * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
- */
- private void discardChanges() {
- netOps.discardChanges(new NetconfRpcFutureCallback("Discarding candidate", id));
- }
-
- @Override
- public synchronized ListenableFuture<RpcResult<TransactionStatus>> performCommit() {
- final ListenableFuture<DOMRpcResult> rpcResult = netOps.commit(new NetconfRpcFutureCallback("Commit", id) {
- @Override
- public void onSuccess(final DOMRpcResult result) {
- super.onSuccess(result);
- LOG.debug("{}: Write successful, transaction: {}. Unlocking", id, getIdentifier());
- cleanupOnSuccess();
- }
-
- @Override
- protected void onUnsuccess(final DOMRpcResult result) {
- LOG.error("{}: Write failed, transaction {}, discarding changes, unlocking: {}", id, getIdentifier(), result.getErrors());
- cleanup();
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("{}: Write failed, transaction {}, discarding changes, unlocking", id, getIdentifier(), t);
- cleanup();
- }
- });
-
- return Futures.transform(rpcResult, RPC_RESULT_TO_TX_STATUS);
- }
-
- protected void cleanupOnSuccess() {
- unlock();
- }
-
- @Override
- protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
- invokeBlocking("Edit candidate", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return defaultOperation.isPresent()
- ? input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure, defaultOperation.get(),
- rollbackSupport)
- : input.editConfigCandidate(new NetconfRpcFutureCallback("Edit candidate", id), editStructure,
- rollbackSupport);
- }
- });
- }
-
- /**
- * This has to be non blocking since it is called from a callback on commit and its netty threadpool that is really sensitive to blocking calls
- */
- private void unlock() {
- netOps.unlockCandidate(new NetconfRpcFutureCallback("Unlock candidate", id));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfRpcFutureCallback;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Tx implementation for netconf devices that support only writable-running with no candidate
- * The sequence goes as:
- * <ol>
- * <li/> Lock running datastore on tx construction
- * <ul>
- * <li/> Lock has to succeed, if it does not, transaction is failed
- * </ul>
- * <li/> Edit-config in running N times
- * <ul>
- * <li/> If any issue occurs during edit, datastore is unlocked and an exception is thrown
- * </ul>
- * <li/> Unlock running datastore on tx commit
- * </ol>
- */
-public class WriteRunningTx extends AbstractWriteTx {
-
- private static final Logger LOG = LoggerFactory.getLogger(WriteRunningTx.class);
-
- public WriteRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps,
- final boolean rollbackSupport, long requestTimeoutMillis) {
- super(requestTimeoutMillis, netOps, id, rollbackSupport);
- }
-
- @Override
- protected synchronized void init() {
- lock();
- }
-
- private void lock() {
- try {
- invokeBlocking("Lock running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return input.lockRunning(new NetconfRpcFutureCallback("Lock running", id));
- }
- });
- } catch (final NetconfDocumentedException e) {
- LOG.warn("{}: Failed to initialize netconf transaction (lock running)", id, e);
- finished = true;
- throw new RuntimeException(id + ": Failed to initialize netconf transaction (lock running)", e);
- }
- }
-
- @Override
- protected void cleanup() {
- unlock();
- }
-
- @Override
- protected void handleEditException(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data, final NetconfDocumentedException e, final String editType) {
- LOG.warn("{}: Error {} data to (running){}, data: {}, canceling", id, editType, path, data, e);
- cancel();
- throw new RuntimeException(id + ": Error while " + editType + ": (running)" + path, e);
- }
-
- @Override
- protected void handleDeleteException(final YangInstanceIdentifier path, final NetconfDocumentedException e) {
- LOG.warn("{}: Error deleting data (running){}, canceling", id, path, e);
- cancel();
- throw new RuntimeException(id + ": Error while deleting (running)" + path, e);
- }
-
- @Override
- public synchronized CheckedFuture<Void, TransactionCommitFailedException> submit() {
- final ListenableFuture<Void> commmitFutureAsVoid = Futures.transform(commit(), new Function<RpcResult<TransactionStatus>, Void>() {
- @Override
- public Void apply(final RpcResult<TransactionStatus> input) {
- return null;
- }
- });
-
- return Futures.makeChecked(commmitFutureAsVoid, new Function<Exception, TransactionCommitFailedException>() {
- @Override
- public TransactionCommitFailedException apply(final Exception input) {
- return new TransactionCommitFailedException("Submit of transaction " + getIdentifier() + " failed", input);
- }
- });
- }
-
- @Override
- public synchronized ListenableFuture<RpcResult<TransactionStatus>> performCommit() {
- unlock();
- return Futures.immediateFuture(RpcResultBuilder.success(TransactionStatus.COMMITED).build());
- }
-
- @Override
- protected void editConfig(final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation) throws NetconfDocumentedException {
- invokeBlocking("Edit running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return defaultOperation.isPresent()
- ? input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure, defaultOperation.get(),
- rollbackSupport)
- : input.editConfigRunning(new NetconfRpcFutureCallback("Edit running", id), editStructure,
- rollbackSupport);
- }
- });
- }
-
- private void unlock() {
- try {
- invokeBlocking("Unlocking running", new Function<NetconfBaseOps, ListenableFuture<DOMRpcResult>>() {
- @Override
- public ListenableFuture<DOMRpcResult> apply(final NetconfBaseOps input) {
- return input.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id));
- }
- });
- } catch (final NetconfDocumentedException e) {
- LOG.warn("{}: Failed to unlock running datastore", id, e);
- throw new RuntimeException(id + ": Failed to unlock running datastore", e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.schema;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.GET_SCHEMA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Element;
-
-public final class NetconfRemoteSchemaYangSourceProvider implements SchemaSourceProvider<YangTextSchemaSource> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfRemoteSchemaYangSourceProvider.class);
-
- private static final ExceptionMapper<SchemaSourceException> MAPPER = new ExceptionMapper<SchemaSourceException>(
- "schemaDownload", SchemaSourceException.class) {
- @Override
- protected SchemaSourceException newWithCause(final String s, final Throwable throwable) {
- return new SchemaSourceException(s, throwable);
- }
- };
-
- private final DOMRpcService rpc;
- private final RemoteDeviceId id;
-
- public NetconfRemoteSchemaYangSourceProvider(final RemoteDeviceId id, final DOMRpcService rpc) {
- this.id = id;
- this.rpc = Preconditions.checkNotNull(rpc);
- }
-
- public static ContainerNode createGetSchemaRequest(final String moduleName, final Optional<String> revision) {
- final QName identifierQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "identifier"));
- final YangInstanceIdentifier.NodeIdentifier identifierId = new YangInstanceIdentifier.NodeIdentifier(identifierQName);
- final LeafNode<String> identifier = Builders.<String>leafBuilder().withNodeIdentifier(identifierId).withValue(moduleName).build();
-
- final QName formatQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "format"));
- final YangInstanceIdentifier.NodeIdentifier formatId = new YangInstanceIdentifier.NodeIdentifier(formatQName);
- final LeafNode<QName> format = Builders.<QName>leafBuilder().withNodeIdentifier(formatId).withValue(Yang.QNAME).build();
-
- final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> builder = Builders.containerBuilder();
-
- builder.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.GET_SCHEMA_QNAME))
- .withChild(identifier).withChild(format);
-
- if(revision.isPresent()) {
- final QName revisionQName = QName.cachedReference(QName.create(NetconfMessageTransformUtil.GET_SCHEMA_QNAME, "version"));
- final YangInstanceIdentifier.NodeIdentifier revisionId = new YangInstanceIdentifier.NodeIdentifier(revisionQName);
- final LeafNode<String> revisionNode = Builders.<String>leafBuilder().withNodeIdentifier(revisionId).withValue(revision.get()).build();
-
- builder.withChild(revisionNode);
- }
-
- return builder.build();
- }
-
- private static Optional<String> getSchemaFromRpc(final RemoteDeviceId id, final NormalizedNode<?, ?> result) {
- if (result == null) {
- return Optional.absent();
- }
-
- final QName schemaWrapperNode = QName.cachedReference(QName.create(GET_SCHEMA_QNAME, NETCONF_DATA_QNAME.getLocalName()));
- final Optional<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> child = ((ContainerNode) result).getChild(toId(schemaWrapperNode));
-
- Preconditions.checkState(child.isPresent() && child.get() instanceof AnyXmlNode,
- "%s Unexpected response to get-schema, expected response with one child %s, but was %s", id,
- schemaWrapperNode, result);
-
- final DOMSource wrappedNode = ((AnyXmlNode) child.get()).getValue();
- Preconditions.checkNotNull(wrappedNode.getNode());
- final Element dataNode = (Element) wrappedNode.getNode();
-
- return Optional.of(dataNode.getTextContent().trim());
- }
-
- @Override
- public CheckedFuture<YangTextSchemaSource, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
- final String moduleName = sourceIdentifier.getName();
-
- // If formatted revision is SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION, we have to omit it from request
- final String formattedRevision = sourceIdentifier.getRevision().equals(SourceIdentifier.NOT_PRESENT_FORMATTED_REVISION) ? null : sourceIdentifier.getRevision();
- final Optional<String> revision = Optional.fromNullable(formattedRevision);
- final NormalizedNode<?, ?> getSchemaRequest = createGetSchemaRequest(moduleName, revision);
-
- LOG.trace("{}: Loading YANG schema source for {}:{}", id, moduleName,
- revision);
-
- final ListenableFuture<YangTextSchemaSource> transformed = Futures.transform(
- rpc.invokeRpc(SchemaPath.create(true, NetconfMessageTransformUtil.GET_SCHEMA_QNAME), getSchemaRequest),
- new ResultToYangSourceTransformer(id, sourceIdentifier, moduleName, revision));
-
- final CheckedFuture<YangTextSchemaSource, SchemaSourceException> checked = Futures.makeChecked(transformed, MAPPER);
-
- // / FIXME remove this get, it is only present to wait until source is retrieved
- // (goal is to limit concurrent schema download, since NetconfDevice listener does not handle concurrent messages properly)
- // TODO retest this
- try {
- LOG.trace("{}: Blocking for {}", id, sourceIdentifier);
- checked.checkedGet();
- } catch (final SchemaSourceException e) {
- return Futures.immediateFailedCheckedFuture(e);
- }
-
- return checked;
- }
-
- /**
- * Transform composite node to string schema representation and then to ASTSchemaSource
- */
- private static final class ResultToYangSourceTransformer implements
- Function<DOMRpcResult, YangTextSchemaSource> {
-
- private final RemoteDeviceId id;
- private final SourceIdentifier sourceIdentifier;
- private final String moduleName;
- private final Optional<String> revision;
-
- public ResultToYangSourceTransformer(final RemoteDeviceId id, final SourceIdentifier sourceIdentifier,
- final String moduleName, final Optional<String> revision) {
- this.id = id;
- this.sourceIdentifier = sourceIdentifier;
- this.moduleName = moduleName;
- this.revision = revision;
- }
-
- @Override
- public YangTextSchemaSource apply(final DOMRpcResult input) {
-
- if (input.getErrors().isEmpty()) {
-
- final Optional<String> schemaString = getSchemaFromRpc(id, input.getResult());
-
- Preconditions.checkState(schemaString.isPresent(),
- "%s: Unexpected response to get-schema, schema not present in message for: %s", id, sourceIdentifier);
-
- LOG.debug("{}: YANG Schema successfully retrieved for {}:{}",
- id, moduleName, revision);
- return new NetconfYangTextSchemaSource(id, sourceIdentifier, schemaString);
- }
-
- LOG.warn(
- "{}: YANG schema was not successfully retrieved for {}. Errors: {}",
- id, sourceIdentifier, input.getErrors());
-
- throw new IllegalStateException(String.format(
- "%s: YANG schema was not successfully retrieved for %s. Errors: %s", id, sourceIdentifier,
- input.getErrors()));
- }
-
- }
-
- private static class NetconfYangTextSchemaSource extends YangTextSchemaSource {
- private final RemoteDeviceId id;
- private final Optional<String> schemaString;
-
- public NetconfYangTextSchemaSource(final RemoteDeviceId id, final SourceIdentifier sId, final Optional<String> schemaString) {
- super(sId);
- this.id = id;
- this.schemaString = schemaString;
- }
-
- @Override
- protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
- return toStringHelper.add("device", id);
- }
-
- @Override
- public InputStream openStream() throws IOException {
- return new ByteArrayInputStream(schemaString.get().getBytes(Charsets.UTF_8));
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.schema.mapping;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.EVENT_TIME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RPC_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_URI;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.Nonnull;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMResult;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.MissingNameSpaceException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.netconf.util.OrderedNormalizedNodeWriter;
-import org.opendaylight.controller.sal.connect.api.MessageTransformer;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.MessageCounter;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class NetconfMessageTransformer implements MessageTransformer<NetconfMessage> {
-
- public static final String MESSAGE_ID_PREFIX = "m";
-
- private static final Logger LOG= LoggerFactory.getLogger(NetconfMessageTransformer.class);
-
-
- private static final Function<SchemaNode, QName> QNAME_FUNCTION = new Function<SchemaNode, QName>() {
- @Override
- public QName apply(final SchemaNode rpcDefinition) {
- return rpcDefinition.getQName();
- }
- };
-
- private static final Function<SchemaNode, QName> QNAME_NOREV_FUNCTION = new Function<SchemaNode, QName>() {
- @Override
- public QName apply(final SchemaNode notification) {
- return QNAME_FUNCTION.apply(notification).withoutRevision();
- }
- };
- private static final SchemaContext BASE_NETCONF_CTX;
-
- static {
- try {
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(
- Lists.newArrayList(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl.getInstance()));
- BASE_NETCONF_CTX = moduleInfoBackedContext.tryToCreateSchemaContext().get();
- } catch (final RuntimeException e) {
- LOG.error("Unable to prepare schema context for base netconf ops", e);
- throw new ExceptionInInitializerError(e);
- }
- }
- private static final Map<QName, RpcDefinition> MAPPED_BASE_RPCS = Maps.uniqueIndex(BASE_NETCONF_CTX.getOperations(), QNAME_FUNCTION);
-
- private final SchemaContext schemaContext;
- private final MessageCounter counter;
- private final Map<QName, RpcDefinition> mappedRpcs;
- private final Multimap<QName, NotificationDefinition> mappedNotifications;
- private final DomToNormalizedNodeParserFactory parserFactory;
-
- public NetconfMessageTransformer(final SchemaContext schemaContext, final boolean strictParsing) {
- this.counter = new MessageCounter();
- this.schemaContext = schemaContext;
- parserFactory = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, strictParsing);
-
- mappedRpcs = Maps.uniqueIndex(schemaContext.getOperations(), QNAME_FUNCTION);
- mappedNotifications = Multimaps.index(schemaContext.getNotifications(), QNAME_NOREV_FUNCTION);
- }
-
- @Override
- public synchronized DOMNotification toNotification(final NetconfMessage message) {
- final Map.Entry<Date, XmlElement> stripped = stripNotification(message);
- final QName notificationNoRev;
- try {
- notificationNoRev = QName.create(stripped.getValue().getNamespace(), stripped.getValue().getName()).withoutRevision();
- } catch (final MissingNameSpaceException e) {
- throw new IllegalArgumentException("Unable to parse notification " + message + ", cannot find namespace", e);
- }
-
- final Collection<NotificationDefinition> notificationDefinitions = mappedNotifications.get(notificationNoRev);
- Preconditions.checkArgument(notificationDefinitions.size() > 0,
- "Unable to parse notification %s, unknown notification. Available notifications: %s", notificationDefinitions, mappedNotifications.keySet());
-
- // FIXME if multiple revisions for same notifications are present, we should pick the most recent. Or ?
- // We should probably just put the most recent notification versions into our map. We can expect that the device sends the data according to the latest available revision of a model.
- final NotificationDefinition next = notificationDefinitions.iterator().next();
-
- // We wrap the notification as a container node in order to reuse the parsers and builders for container node
- final ContainerSchemaNode notificationAsContainerSchemaNode = NetconfMessageTransformUtil.createSchemaForNotification(next);
- final ContainerNode content = parserFactory.getContainerNodeParser().parse(Collections.singleton(stripped.getValue().getDomElement()),
- notificationAsContainerSchemaNode);
- return new NetconfDeviceNotification(content, stripped.getKey());
- }
-
- private static final ThreadLocal<SimpleDateFormat> EVENT_TIME_FORMAT = new ThreadLocal<SimpleDateFormat>() {
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT);
- }
-
- public void set(SimpleDateFormat value) {
- throw new UnsupportedOperationException();
- }
- };
-
- // FIXME move somewhere to util
- private static Map.Entry<Date, XmlElement> stripNotification(final NetconfMessage message) {
- final XmlElement xmlElement = XmlElement.fromDomDocument(message.getDocument());
- final List<XmlElement> childElements = xmlElement.getChildElements();
- Preconditions.checkArgument(childElements.size() == 2, "Unable to parse notification %s, unexpected format", message);
-
- final XmlElement eventTimeElement;
- final XmlElement notificationElement;
-
- if (childElements.get(0).getName().equals(EVENT_TIME)) {
- eventTimeElement = childElements.get(0);
- notificationElement = childElements.get(1);
- }
- else if(childElements.get(1).getName().equals(EVENT_TIME)) {
- eventTimeElement = childElements.get(1);
- notificationElement = childElements.get(0);
- } else {
- throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message);
- }
-
- try {
- return new AbstractMap.SimpleEntry<>(EVENT_TIME_FORMAT.get().parse(eventTimeElement.getTextContent()), notificationElement);
- } catch (DocumentedException e) {
- throw new IllegalArgumentException("Notification payload does not contain " + EVENT_TIME + " " + message);
- } catch (ParseException e) {
- throw new IllegalArgumentException("Unable to parse event time from " + eventTimeElement, e);
- }
- }
-
- @Override
- public NetconfMessage toRpcRequest(SchemaPath rpc, final NormalizedNode<?, ?> payload) {
- // In case no input for rpc is defined, we can simply construct the payload here
- final QName rpcQName = rpc.getLastComponent();
- Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;
-
- // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf
- // If no, use pre built base netconf operations model
- final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName);
- if(needToUseBaseCtx) {
- currentMappedRpcs = MAPPED_BASE_RPCS;
- }
-
- Preconditions.checkNotNull(currentMappedRpcs.get(rpcQName), "Unknown rpc %s, available rpcs: %s", rpcQName, currentMappedRpcs.keySet());
- if(currentMappedRpcs.get(rpcQName).getInput() == null) {
- return new NetconfMessage(prepareDomResultForRpcRequest(rpcQName).getNode().getOwnerDocument());
- }
-
- Preconditions.checkNotNull(payload, "Transforming an rpc with input: %s, payload cannot be null", rpcQName);
- Preconditions.checkArgument(payload instanceof ContainerNode,
- "Transforming an rpc with input: %s, payload has to be a container, but was: %s", rpcQName, payload);
-
- // Set the path to the input of rpc for the node stream writer
- rpc = rpc.createChild(QName.cachedReference(QName.create(rpcQName, "input")));
- final DOMResult result = prepareDomResultForRpcRequest(rpcQName);
-
- try {
- // If the schema context for netconf device does not contain model for base netconf operations, use default pre build context with just the base model
- // This way operations like lock/unlock are supported even if the source for base model was not provided
- writeNormalizedRpc(((ContainerNode) payload), result, rpc, needToUseBaseCtx ? BASE_NETCONF_CTX : schemaContext);
- } catch (final XMLStreamException | IOException | IllegalStateException e) {
- throw new IllegalStateException("Unable to serialize " + rpc, e);
- }
-
- final Document node = result.getNode().getOwnerDocument();
-
- return new NetconfMessage(node);
- }
-
- private static boolean isBaseRpc(final QName rpc) {
- return rpc.getNamespace().equals(NETCONF_URI);
- }
-
- private DOMResult prepareDomResultForRpcRequest(final QName rpcQName) {
- final Document document = XmlUtil.newDocument();
- final Element rpcNS = document.createElementNS(NETCONF_RPC_QNAME.getNamespace().toString(), NETCONF_RPC_QNAME.getLocalName());
- // set msg id
- rpcNS.setAttribute(NetconfMessageTransformUtil.MESSAGE_ID_ATTR, counter.getNewMessageId(MESSAGE_ID_PREFIX));
- final Element elementNS = document.createElementNS(rpcQName.getNamespace().toString(), rpcQName.getLocalName());
- rpcNS.appendChild(elementNS);
- document.appendChild(rpcNS);
- return new DOMResult(elementNS);
- }
-
- private void writeNormalizedRpc(final ContainerNode normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext baseNetconfCtx) throws IOException, XMLStreamException {
- final OrderedNormalizedNodeWriter normalizedNodeWriter;
- NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
- XMLStreamWriter writer = null;
- try {
- writer = NetconfMessageTransformUtil.XML_FACTORY.createXMLStreamWriter(result);
- normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, baseNetconfCtx, schemaPath);
- normalizedNodeWriter = new OrderedNormalizedNodeWriter(normalizedNodeStreamWriter, baseNetconfCtx, schemaPath);
- Collection<DataContainerChild<?, ?>> value = (Collection) normalized.getValue();
- normalizedNodeWriter.write(value);
- normalizedNodeWriter.flush();
- } finally {
- try {
- if(normalizedNodeStreamWriter != null) {
- normalizedNodeStreamWriter.close();
- }
- if(writer != null) {
- writer.close();
- }
- } catch (final Exception e) {
- LOG.warn("Unable to close resource properly", e);
- }
- }
- }
-
- @Override
- public synchronized DOMRpcResult toRpcResult(final NetconfMessage message, final SchemaPath rpc) {
- final NormalizedNode<?, ?> normalizedNode;
- final QName rpcQName = rpc.getLastComponent();
- if (NetconfMessageTransformUtil.isDataRetrievalOperation(rpcQName)) {
- final Element xmlData = NetconfMessageTransformUtil.getDataSubtree(message.getDocument());
- final ContainerSchemaNode schemaForDataRead = NetconfMessageTransformUtil.createSchemaForDataRead(schemaContext);
- final ContainerNode dataNode = parserFactory.getContainerNodeParser().parse(Collections.singleton(xmlData), schemaForDataRead);
-
- normalizedNode = Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
- .withChild(dataNode).build();
- } else {
- final Set<Element> documentElement = Collections.singleton(message.getDocument().getDocumentElement());
-
- Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;
-
- // Determine whether a base netconf operation is being invoked and also check if the device exposed model for base netconf
- // If no, use pre built base netconf operations model
- final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName);
- if(needToUseBaseCtx) {
- currentMappedRpcs = MAPPED_BASE_RPCS;
- }
-
- final RpcDefinition rpcDefinition = currentMappedRpcs.get(rpcQName);
- Preconditions.checkArgument(rpcDefinition != null, "Unable to parse response of %s, the rpc is unknown", rpcQName);
-
- // In case no input for rpc is defined, we can simply construct the payload here
- if (rpcDefinition.getOutput() == null) {
- Preconditions.checkArgument(XmlElement.fromDomDocument(message.getDocument()).getOnlyChildElementWithSameNamespaceOptionally("ok").isPresent(),
- "Unexpected content in response of rpc: %s, %s", rpcDefinition.getQName(), message);
- normalizedNode = null;
- } else {
- normalizedNode = parserFactory.getContainerNodeParser().parse(documentElement, rpcDefinition.getOutput());
- }
- }
- return new DefaultDOMRpcResult(normalizedNode);
- }
-
- private static class NetconfDeviceNotification implements DOMNotification, DOMEvent {
- private final ContainerNode content;
- private final SchemaPath schemaPath;
- private final Date eventTime;
-
- NetconfDeviceNotification(final ContainerNode content, final Date eventTime) {
- this.content = content;
- this.eventTime = eventTime;
- this.schemaPath = toPath(content.getNodeType());
- }
-
- @Nonnull
- @Override
- public SchemaPath getType() {
- return schemaPath;
-
- }
-
- @Nonnull
- @Override
- public ContainerNode getBody() {
- return content;
- }
-
- @Override
- public Date getEventTime() {
- return eventTime;
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.util;
-
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DEFAULT_OPERATION_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_ERROR_OPTION_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_SOURCE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.ROLLBACK_ON_ERROR_OPTION;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.copy.config.input.target.ConfigTarget;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.get.config.input.source.ConfigSource;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Provides base operations for netconf e.g. get, get-config, edit-config, (un)lock, commit etc.
- * According to RFC-6241
- */
-public final class NetconfBaseOps {
-
- private final DOMRpcService rpc;
- private final SchemaContext schemaContext;
-
- public NetconfBaseOps(final DOMRpcService rpc, final SchemaContext schemaContext) {
- this.rpc = rpc;
- this.schemaContext = schemaContext;
- }
-
- public ListenableFuture<DOMRpcResult> lock(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(datastore);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(datastore));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> lockCandidate(final FutureCallback<DOMRpcResult> callback) {
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_CANDIDATE_QNAME));
- Futures.addCallback(future, callback);
- return future;
- }
-
-
- public ListenableFuture<DOMRpcResult> lockRunning(final FutureCallback<DOMRpcResult> callback) {
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_LOCK_QNAME), getLockContent(NETCONF_RUNNING_QNAME));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> unlock(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(datastore);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(datastore));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> unlockRunning(final FutureCallback<DOMRpcResult> callback) {
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_RUNNING_QNAME));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> unlockCandidate(final FutureCallback<DOMRpcResult> callback) {
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_UNLOCK_QNAME), getUnLockContent(NETCONF_CANDIDATE_QNAME));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> discardChanges(final FutureCallback<DOMRpcResult> callback) {
- Preconditions.checkNotNull(callback);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_DISCARD_CHANGES_QNAME), null);
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> commit(final FutureCallback<DOMRpcResult> callback) {
- Preconditions.checkNotNull(callback);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> validate(final FutureCallback<DOMRpcResult> callback, final QName datastore) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(datastore);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_VALIDATE_QNAME), getValidateContent(datastore));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> validateCandidate(final FutureCallback<DOMRpcResult> callback) {
- return validate(callback, NETCONF_CANDIDATE_QNAME);
- }
-
-
- public ListenableFuture<DOMRpcResult> validateRunning(final FutureCallback<DOMRpcResult> callback) {
- return validate(callback, NETCONF_RUNNING_QNAME);
- }
-
- public ListenableFuture<DOMRpcResult> copyConfig(final FutureCallback<DOMRpcResult> callback, final QName source, final QName target) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(source);
- Preconditions.checkNotNull(target);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COPY_CONFIG_QNAME), getCopyConfigContent(source, target));
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> copyRunningToCandidate(final FutureCallback<DOMRpcResult> callback) {
- return copyConfig(callback, NETCONF_RUNNING_QNAME, NETCONF_CANDIDATE_QNAME);
- }
-
- public ListenableFuture<DOMRpcResult> getConfig(final FutureCallback<DOMRpcResult> callback, final QName datastore, final Optional<YangInstanceIdentifier> filterPath) {
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(datastore);
-
- final ListenableFuture<DOMRpcResult> future;
- if (isFilterPresent(filterPath)) {
- // FIXME the source node has to be wrapped in a choice
- final DataContainerChild<?, ?> node = toFilterStructure(filterPath.get(), schemaContext);
- future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
- NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore), node));
- } else {
- future = rpc.invokeRpc(toPath(NETCONF_GET_CONFIG_QNAME),
- NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, getSourceNode(datastore)));
- }
-
- Futures.addCallback(future, callback);
- return future;
- }
-
- public ListenableFuture<DOMRpcResult> getConfigRunning(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
- return getConfig(callback, NETCONF_RUNNING_QNAME, filterPath);
- }
-
- public ListenableFuture<DOMRpcResult> getConfigCandidate(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
- return getConfig(callback, NETCONF_CANDIDATE_QNAME, filterPath);
- }
-
- public ListenableFuture<DOMRpcResult> get(final FutureCallback<DOMRpcResult> callback, final Optional<YangInstanceIdentifier> filterPath) {
- Preconditions.checkNotNull(callback);
-
- final ListenableFuture<DOMRpcResult> future;
-
- future = isFilterPresent(filterPath) ?
- rpc.invokeRpc(toPath(NETCONF_GET_QNAME), NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, toFilterStructure(filterPath.get(), schemaContext))) :
- rpc.invokeRpc(toPath(NETCONF_GET_QNAME), NetconfMessageTransformUtil.GET_RPC_CONTENT);
-
- Futures.addCallback(future, callback);
- return future;
- }
-
- private boolean isFilterPresent(final Optional<YangInstanceIdentifier> filterPath) {
- return filterPath.isPresent() && !filterPath.get().isEmpty();
- }
-
- public ListenableFuture<DOMRpcResult> editConfigCandidate(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final ModifyAction modifyAction, final boolean rollback) {
- return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.of(modifyAction), rollback);
- }
-
- public ListenableFuture<DOMRpcResult> editConfigCandidate(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final boolean rollback) {
- return editConfig(callback, NETCONF_CANDIDATE_QNAME, editStructure, Optional.<ModifyAction>absent(), rollback);
- }
-
- public ListenableFuture<DOMRpcResult> editConfigRunning(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final ModifyAction modifyAction, final boolean rollback) {
- return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.of(modifyAction), rollback);
- }
-
- public ListenableFuture<DOMRpcResult> editConfigRunning(final FutureCallback<? super DOMRpcResult> callback, final DataContainerChild<?, ?> editStructure, final boolean rollback) {
- return editConfig(callback, NETCONF_RUNNING_QNAME, editStructure, Optional.<ModifyAction>absent(), rollback);
- }
-
- public ListenableFuture<DOMRpcResult> editConfig(final FutureCallback<? super DOMRpcResult> callback, final QName datastore, final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> modifyAction, final boolean rollback) {
- Preconditions.checkNotNull(editStructure);
- Preconditions.checkNotNull(callback);
- Preconditions.checkNotNull(datastore);
-
- final ListenableFuture<DOMRpcResult> future = rpc.invokeRpc(toPath(NETCONF_EDIT_CONFIG_QNAME), getEditConfigContent(datastore, editStructure, modifyAction, rollback));
-
- Futures.addCallback(future, callback);
- return future;
- }
-
- public DataContainerChild<?, ?> createEditConfigStrcture(final Optional<NormalizedNode<?, ?>> lastChild, final Optional<ModifyAction> operation, final YangInstanceIdentifier dataPath) {
- return NetconfMessageTransformUtil.createEditConfigStructure(schemaContext, dataPath, operation, lastChild);
- }
-
- private ContainerNode getEditConfigContent(final QName datastore, final DataContainerChild<?, ?> editStructure, final Optional<ModifyAction> defaultOperation, final boolean rollback) {
- final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> editBuilder = Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_EDIT_CONFIG_QNAME));
-
- // Target
- editBuilder.withChild(getTargetNode(datastore));
-
- // Default operation
- if(defaultOperation.isPresent()) {
- final String opString = defaultOperation.get().name().toLowerCase();
- editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_DEFAULT_OPERATION_QNAME)).withValue(opString).build());
- }
-
- // Error option
- if(rollback) {
- editBuilder.withChild(Builders.leafBuilder().withNodeIdentifier(toId(NETCONF_ERROR_OPTION_QNAME)).withValue(ROLLBACK_ON_ERROR_OPTION).build());
- }
-
- // Edit content
- editBuilder.withChild(editStructure);
- return editBuilder.build();
- }
-
- public static DataContainerChild<?, ?> getSourceNode(final QName datastore) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_SOURCE_QNAME))
- .withChild(
- Builders.choiceBuilder().withNodeIdentifier(toId(ConfigSource.QNAME)).withChild(
- Builders.leafBuilder().withNodeIdentifier(toId(datastore)).build()).build()
- ).build();
- }
-
- public static ContainerNode getLockContent(final QName datastore) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_LOCK_QNAME))
- .withChild(getTargetNode(datastore)).build();
- }
-
- public static DataContainerChild<?, ?> getTargetNode(final QName datastore) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_TARGET_QNAME))
- .withChild(
- Builders.choiceBuilder().withNodeIdentifier(toId(ConfigTarget.QNAME)).withChild(
- Builders.leafBuilder().withNodeIdentifier(toId(datastore)).build()).build()
- ).build();
- }
-
- public static NormalizedNode<?, ?> getCopyConfigContent(final QName source, final QName target) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_COPY_CONFIG_QNAME))
- .withChild(getTargetNode(target)).withChild(getSourceNode(source)).build();
- }
-
- public static NormalizedNode<?, ?> getValidateContent(final QName source) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_VALIDATE_QNAME))
- .withChild(getSourceNode(source)).build();
- }
-
- public static NormalizedNode<?, ?> getUnLockContent(final QName datastore) {
- return Builders.containerBuilder().withNodeIdentifier(toId(NETCONF_UNLOCK_QNAME))
- .withChild(getTargetNode(datastore)).build();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.util;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.io.IOException;
-import java.net.URI;
-import java.util.AbstractMap;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.edit.config.input.EditContent;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.CreateSubscriptionInput;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class NetconfMessageTransformUtil {
-
- private static final Logger LOG= LoggerFactory.getLogger(NetconfMessageTransformUtil.class);
-
- public static final String MESSAGE_ID_ATTR = "message-id";
- public static final XMLOutputFactory XML_FACTORY;
-
- static {
- XML_FACTORY = XMLOutputFactory.newFactory();
- XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
- }
-
- public static final QName CREATE_SUBSCRIPTION_RPC_QNAME = QName.cachedReference(QName.create(CreateSubscriptionInput.QNAME, "create-subscription"));
- private static final String SUBTREE = "subtree";
-
- // Blank document used for creation of new DOM nodes
- private static final Document BLANK_DOCUMENT = XmlUtil.newDocument();
- public static final String EVENT_TIME = "eventTime";
-
- private NetconfMessageTransformUtil() {}
-
- public static final QName IETF_NETCONF_MONITORING = QName.create(NetconfState.QNAME, "ietf-netconf-monitoring");
- public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data");
- public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema");
- public static final QName IETF_NETCONF_MONITORING_SCHEMA_FORMAT = QName.create(IETF_NETCONF_MONITORING, "format");
- public static final QName IETF_NETCONF_MONITORING_SCHEMA_LOCATION = QName.create(IETF_NETCONF_MONITORING, "location");
- public static final QName IETF_NETCONF_MONITORING_SCHEMA_IDENTIFIER = QName.create(IETF_NETCONF_MONITORING, "identifier");
- public static final QName IETF_NETCONF_MONITORING_SCHEMA_VERSION = QName.create(IETF_NETCONF_MONITORING, "version");
- public static final QName IETF_NETCONF_MONITORING_SCHEMA_NAMESPACE = QName.create(IETF_NETCONF_MONITORING, "namespace");
-
- public static final QName IETF_NETCONF_NOTIFICATIONS = QName.create(NetconfCapabilityChange.QNAME, "ietf-netconf-notifications");
-
- public static final QName NETCONF_QNAME = QName.cachedReference(QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01", "netconf"));
- public static final URI NETCONF_URI = NETCONF_QNAME.getNamespace();
-
- public static final QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
- public static final QName NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
- public static final QName NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok");
- public static final QName NETCONF_ERROR_OPTION_QNAME = QName.create(NETCONF_QNAME, "error-option");
- public static final QName NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
- public static final QName NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
- public static final QName NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
- public static final QName NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target");
- public static final QName NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
- public static final QName NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
- public static final QName NETCONF_VALIDATE_QNAME = QName.create(NETCONF_QNAME, "validate");
- public static final QName NETCONF_COPY_CONFIG_QNAME = QName.create(NETCONF_QNAME, "copy-config");
- public static final QName NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation");
- public static final QName NETCONF_DEFAULT_OPERATION_QNAME = QName.create(NETCONF_OPERATION_QNAME, "default-operation");
- public static final QName NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
- public static final QName NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
- public static final QName NETCONF_DISCARD_CHANGES_QNAME = QName.create(NETCONF_QNAME, "discard-changes");
- public static final QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
- public static final QName NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter");
- public static final QName NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get");
- public static final QName NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc");
-
- public static final URI NETCONF_ROLLBACK_ON_ERROR_URI = URI
- .create("urn:ietf:params:netconf:capability:rollback-on-error:1.0");
- public static final String ROLLBACK_ON_ERROR_OPTION = "rollback-on-error";
-
- public static final URI NETCONF_CANDIDATE_URI = URI
- .create("urn:ietf:params:netconf:capability:candidate:1.0");
-
- public static final URI NETCONF_NOTIFICATONS_URI = URI
- .create("urn:ietf:params:netconf:capability:notification:1.0");
-
- public static final URI NETCONF_RUNNING_WRITABLE_URI = URI
- .create("urn:ietf:params:netconf:capability:writable-running:1.0");
-
- public static final QName NETCONF_LOCK_QNAME = QName.create(NETCONF_QNAME, "lock");
- public static final QName NETCONF_UNLOCK_QNAME = QName.create(NETCONF_QNAME, "unlock");
-
- // Discard changes message
- public static final ContainerNode DISCARD_CHANGES_RPC_CONTENT =
- Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_DISCARD_CHANGES_QNAME)).build();
-
- // Commit changes message
- public static final ContainerNode COMMIT_RPC_CONTENT =
- Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_COMMIT_QNAME)).build();
-
- // Get message
- public static final ContainerNode GET_RPC_CONTENT =
- Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(NETCONF_GET_QNAME)).build();
-
- // Create-subscription changes message
- public static final ContainerNode CREATE_SUBSCRIPTION_RPC_CONTENT =
- Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CREATE_SUBSCRIPTION_RPC_QNAME)).build();
-
- public static final DataContainerChild<?, ?> EMPTY_FILTER;
-
- static {
- final NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder = Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_FILTER_QNAME));
- anyXmlBuilder.withAttributes(Collections.singletonMap(NETCONF_TYPE_QNAME, SUBTREE));
-
- final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
- element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree");
-
- anyXmlBuilder.withValue(new DOMSource(element));
-
- EMPTY_FILTER = anyXmlBuilder.build();
- }
-
- public static DataContainerChild<?, ?> toFilterStructure(final YangInstanceIdentifier identifier, final SchemaContext ctx) {
- final NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, DOMSource, AnyXmlNode> anyXmlBuilder = Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_FILTER_QNAME));
- anyXmlBuilder.withAttributes(Collections.singletonMap(NETCONF_TYPE_QNAME, SUBTREE));
-
- final NormalizedNode<?, ?> filterContent = ImmutableNodes.fromInstanceId(ctx, identifier);
-
- final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString()));
- element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree");
-
- try {
- writeNormalizedNode(filterContent, new DOMResult(element), SchemaPath.ROOT, ctx);
- } catch (IOException | XMLStreamException e) {
- throw new IllegalStateException("Unable to serialize filter element for path " + identifier, e);
- }
- anyXmlBuilder.withValue(new DOMSource(element));
-
- return anyXmlBuilder.build();
- }
-
- public static void checkValidReply(final NetconfMessage input, final NetconfMessage output)
- throws NetconfDocumentedException {
- final String inputMsgId = input.getDocument().getDocumentElement().getAttribute(MESSAGE_ID_ATTR);
- final String outputMsgId = output.getDocument().getDocumentElement().getAttribute(MESSAGE_ID_ATTR);
-
- if(inputMsgId.equals(outputMsgId) == false) {
- final Map<String,String> errorInfo = ImmutableMap.<String,String>builder()
- .put( "actual-message-id", outputMsgId )
- .put( "expected-message-id", inputMsgId )
- .build();
-
- throw new NetconfDocumentedException( "Response message contained unknown \"message-id\"",
- null, NetconfDocumentedException.ErrorType.protocol,
- NetconfDocumentedException.ErrorTag.bad_attribute,
- NetconfDocumentedException.ErrorSeverity.error, errorInfo );
- }
- }
-
- public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException {
- if(NetconfMessageUtil.isErrorMessage(output)) {
- throw NetconfDocumentedException.fromXMLDocument(output.getDocument());
- }
- }
-
- public static RpcError toRpcError( final NetconfDocumentedException ex ) {
- final StringBuilder infoBuilder = new StringBuilder();
- final Map<String, String> errorInfo = ex.getErrorInfo();
- if(errorInfo != null) {
- for( final Entry<String,String> e: errorInfo.entrySet() ) {
- infoBuilder.append( '<' ).append( e.getKey() ).append( '>' ).append( e.getValue() )
- .append( "</" ).append( e.getKey() ).append( '>' );
-
- }
- }
-
- final ErrorSeverity severity = toRpcErrorSeverity( ex.getErrorSeverity() );
- return severity == ErrorSeverity.ERROR ?
- RpcResultBuilder.newError(
- toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
- ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() ) :
- RpcResultBuilder.newWarning(
- toRpcErrorType( ex.getErrorType() ), ex.getErrorTag().getTagValue(),
- ex.getLocalizedMessage(), null, infoBuilder.toString(), ex.getCause() );
- }
-
- private static ErrorSeverity toRpcErrorSeverity( final NetconfDocumentedException.ErrorSeverity severity ) {
- switch (severity) {
- case warning:
- return RpcError.ErrorSeverity.WARNING;
- default:
- return RpcError.ErrorSeverity.ERROR;
- }
- }
-
- private static RpcError.ErrorType toRpcErrorType(final NetconfDocumentedException.ErrorType type) {
- switch (type) {
- case protocol:
- return RpcError.ErrorType.PROTOCOL;
- case rpc:
- return RpcError.ErrorType.RPC;
- case transport:
- return RpcError.ErrorType.TRANSPORT;
- default:
- return RpcError.ErrorType.APPLICATION;
- }
- }
-
- public static YangInstanceIdentifier.NodeIdentifier toId(final YangInstanceIdentifier.PathArgument qname) {
- return toId(qname.getNodeType());
- }
-
- public static YangInstanceIdentifier.NodeIdentifier toId(final QName nodeType) {
- return new YangInstanceIdentifier.NodeIdentifier(nodeType);
- }
-
- public static Element getDataSubtree(final Document doc) {
- return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0);
- }
-
- public static boolean isDataRetrievalOperation(final QName rpc) {
- return NETCONF_URI.equals(rpc.getNamespace())
- && (NETCONF_GET_CONFIG_QNAME.getLocalName().equals(rpc.getLocalName())
- || NETCONF_GET_QNAME.getLocalName().equals(rpc.getLocalName()));
- }
-
- public static ContainerSchemaNode createSchemaForDataRead(final SchemaContext schemaContext) {
- return new NodeContainerProxy(NETCONF_DATA_QNAME, schemaContext.getChildNodes());
- }
-
- public static ContainerSchemaNode createSchemaForNotification(final NotificationDefinition next) {
- return new NodeContainerProxy(next.getQName(), next.getChildNodes(), next.getAvailableAugmentations());
- }
-
- public static ContainerNode wrap(final QName name, final DataContainerChild<?, ?>... node) {
- return Builders.containerBuilder().withNodeIdentifier(toId(name)).withValue(ImmutableList.copyOf(node)).build();
- }
-
- public static DataContainerChild<?, ?> createEditConfigStructure(final SchemaContext ctx, final YangInstanceIdentifier dataPath,
- final Optional<ModifyAction> operation, final Optional<NormalizedNode<?, ?>> lastChildOverride) {
- final NormalizedNode<?, ?> configContent;
-
- if (dataPath.isEmpty()) {
- Preconditions.checkArgument(lastChildOverride.isPresent(), "Data has to be present when creating structure for top level element");
- Preconditions.checkArgument(lastChildOverride.get() instanceof DataContainerChild<?, ?>,
- "Data has to be either container or a list node when creating structure for top level element, but was: %s", lastChildOverride.get());
- configContent = lastChildOverride.get();
- } else {
- final Entry<QName, ModifyAction> modifyOperation =
- operation.isPresent() ? new AbstractMap.SimpleEntry<>(NETCONF_OPERATION_QNAME, operation.get()) : null;
- configContent = ImmutableNodes.fromInstanceId(ctx, dataPath, lastChildOverride, Optional.fromNullable(modifyOperation));
- }
-
- final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_CONFIG_QNAME.getLocalName(), Optional.of(NETCONF_CONFIG_QNAME.getNamespace().toString()));
- try {
- writeNormalizedNode(configContent, new DOMResult(element), SchemaPath.ROOT, ctx);
- } catch (IOException | XMLStreamException e) {
- throw new IllegalStateException("Unable to serialize edit config content element for path " + dataPath, e);
- }
- final DOMSource value = new DOMSource(element);
-
- return Builders.choiceBuilder().withNodeIdentifier(toId(EditContent.QNAME)).withChild(
- Builders.anyXmlBuilder().withNodeIdentifier(toId(NETCONF_CONFIG_QNAME)).withValue(value).build()).build();
- }
-
- public static SchemaPath toPath(final QName rpc) {
- return SchemaPath.create(true, rpc);
- }
-
- // FIXME similar code is in netconf-notifications-impl , DRY
- public static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
- throws IOException, XMLStreamException {
- NormalizedNodeWriter normalizedNodeWriter = null;
- NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
- XMLStreamWriter writer = null;
- try {
- writer = XML_FACTORY.createXMLStreamWriter(result);
- normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
- normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
-
- normalizedNodeWriter.write(normalized);
-
- normalizedNodeWriter.flush();
- } finally {
- try {
- if(normalizedNodeWriter != null) {
- normalizedNodeWriter.close();
- }
- if(normalizedNodeStreamWriter != null) {
- normalizedNodeStreamWriter.close();
- }
- if(writer != null) {
- writer.close();
- }
- } catch (final Exception e) {
- LOG.warn("Unable to close resource properly", e);
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.util;
-
-import com.google.common.util.concurrent.FutureCallback;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Simple Netconf rpc logging callback
- */
-public class NetconfRpcFutureCallback implements FutureCallback<DOMRpcResult> {
- private static final Logger LOG = LoggerFactory.getLogger(NetconfRpcFutureCallback.class);
-
- private final String type;
- private final RemoteDeviceId id;
-
- public NetconfRpcFutureCallback(final String prefix, final RemoteDeviceId id) {
- this.type = prefix;
- this.id = id;
- }
-
- @Override
- public void onSuccess(final DOMRpcResult result) {
- if(result.getErrors().isEmpty()) {
- LOG.trace("{}: {} invoked successfully", id, type);
- } else {
- onUnsuccess(result);
- }
- }
-
- protected void onUnsuccess(final DOMRpcResult result) {
- LOG.warn("{}: {} invoked unsuccessfully: {}", id, type, result.getErrors());
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.warn("{}: {} failed.", id, type, t);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.util;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.Status;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.UsesNode;
-
-/**
- * Simple proxy for container like schema nodes, where user provides a collection of children schema nodes
- */
-public final class NodeContainerProxy implements ContainerSchemaNode {
-
- private final Map<QName, DataSchemaNode> childNodes;
- private final QName qName;
- private final Set<AugmentationSchema> availableAugmentations;
-
- public NodeContainerProxy(final QName qName, final Map<QName, DataSchemaNode> childNodes, final Set<AugmentationSchema> availableAugmentations) {
- this.availableAugmentations = availableAugmentations;
- this.childNodes = Preconditions.checkNotNull(childNodes, "childNodes");
- this.qName = qName;
- }
-
- public NodeContainerProxy(final QName qName, final Collection<DataSchemaNode> childNodes) {
- this(qName, asMap(childNodes), Collections.<AugmentationSchema>emptySet());
- }
-
- public NodeContainerProxy(final QName qName, final Collection<DataSchemaNode> childNodes, final Set<AugmentationSchema> availableAugmentations) {
- this(qName, asMap(childNodes), availableAugmentations);
- }
-
- private static Map<QName, DataSchemaNode> asMap(final Collection<DataSchemaNode> childNodes) {
- return Maps.uniqueIndex(childNodes, new Function<DataSchemaNode, QName>() {
- @Override
- public QName apply(final DataSchemaNode input) {
- return input.getQName();
- }
- });
- }
-
- @Override
- public Set<TypeDefinition<?>> getTypeDefinitions() {
- return Collections.emptySet();
- }
-
- @Override
- public Set<DataSchemaNode> getChildNodes() {
- return Sets.newHashSet(childNodes.values());
- }
-
- @Override
- public Set<GroupingDefinition> getGroupings() {
- return Collections.emptySet();
- }
-
- @Override
- public DataSchemaNode getDataChildByName(final QName qName) {
- return childNodes.get(qName);
- }
-
- @Override
- public DataSchemaNode getDataChildByName(final String s) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Set<UsesNode> getUses() {
- return Collections.emptySet();
- }
-
- @Override
- public boolean isPresenceContainer() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Set<AugmentationSchema> getAvailableAugmentations() {
- return availableAugmentations;
- }
-
- @Override
- public boolean isAugmenting() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isAddedByUses() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isConfiguration() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ConstraintDefinition getConstraints() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public QName getQName() {
- return qName;
- }
-
- @Override
- public SchemaPath getPath() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getDescription() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getReference() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status getStatus() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List<UnknownSchemaNode> getUnknownSchemaNodes() {
- return Collections.emptyList();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import java.util.concurrent.atomic.AtomicInteger;
-
-public class MessageCounter {
- final AtomicInteger messageId = new AtomicInteger(0);
-
- private static final String messageIdBlueprint = "%s-%s";
-
- public String getNewMessageId(final String prefix) {
- Preconditions.checkArgument(Strings.isNullOrEmpty(prefix) == false, "Null or empty prefix");
- return String.format(messageIdBlueprint, prefix, getNewMessageId());
- }
-
- public String getNewMessageId() {
- return Integer.toString(messageId.getAndIncrement());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.util;
-
-import com.google.common.base.Preconditions;
-import java.net.InetSocketAddress;
-import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.HostBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.network.topology.topology.topology.types.TopologyNetconf;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-
-public final class RemoteDeviceId {
-
- private final String name;
- private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier path;
- private final InstanceIdentifier<Node> bindingPath;
- private final NodeKey key;
- private final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier topologyPath;
- private final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> topologyBindingPath;
- private InetSocketAddress address;
- private Host host;
-
- public RemoteDeviceId(final ModuleIdentifier identifier, InetSocketAddress address) {
- this(Preconditions.checkNotNull(identifier).getInstanceName());
- this.address = address;
- this.host = buildHost();
- }
-
- private RemoteDeviceId(final String name) {
- this.name = Preconditions.checkNotNull(name);
- this.key = new NodeKey(new NodeId(name));
- this.path = createBIPath(name);
- this.bindingPath = createBindingPath(key);
- this.topologyPath = createBIPathForTopology(name);
- this.topologyBindingPath = createBindingPathForTopology(key);
- }
-
- public RemoteDeviceId(final String name, InetSocketAddress address) {
- this(name);
- this.address = address;
- this.host = buildHost();
- }
-
- private static InstanceIdentifier<Node> createBindingPath(final NodeKey key) {
- return InstanceIdentifier.builder(Nodes.class).child(Node.class, key).build();
- }
-
- private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPath(final String name) {
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder builder =
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder();
- builder.node(Nodes.QNAME).node(Node.QNAME).nodeWithKey(Node.QNAME, QName.create(Node.QNAME.getNamespace(), Node.QNAME.getRevision(), "id"), name);
-
- return builder.build();
- }
-
- private static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> createBindingPathForTopology(final NodeKey key) {
- final InstanceIdentifier<NetworkTopology> networkTopology = InstanceIdentifier.builder(NetworkTopology.class).build();
- final KeyedInstanceIdentifier<Topology, TopologyKey> topology = networkTopology.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
- return topology
- .child(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.class,
- new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey(
- new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId(key.getId().getValue())));
- }
-
- private static org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier createBIPathForTopology(final String name) {
- final org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceIdentifierBuilder builder =
- org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.builder();
- builder
- .node(NetworkTopology.QNAME)
- .node(Topology.QNAME)
- .nodeWithKey(Topology.QNAME, QName.create(Topology.QNAME, "topology-id"), TopologyNetconf.QNAME.getLocalName())
- .node(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME)
- .nodeWithKey(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME,
- QName.create(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node.QNAME, "node-id"), name);
- return builder.build();
- }
-
- private Host buildHost() {
- return HostBuilder.getDefaultInstance(address.getHostString());
- }
-
- public String getName() {
- return name;
- }
-
- public InstanceIdentifier<Node> getBindingPath() {
- return bindingPath;
- }
-
- public org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier getPath() {
- return path;
- }
-
- public NodeKey getBindingKey() {
- return key;
- }
-
- public InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node> getTopologyBindingPath() {
- return topologyBindingPath;
- }
-
- public YangInstanceIdentifier getTopologyPath() {
- return topologyPath;
- }
-
- public InetSocketAddress getAddress() {
- return address;
- }
-
- public Host getHost() {
- return host;
- }
-
- @Override
- public String toString() {
- return "RemoteDevice{" + name +'}';
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof RemoteDeviceId)) {
- return false;
- }
-
- final RemoteDeviceId that = (RemoteDeviceId) o;
-
- if (!name.equals(that.name)) {
- return false;
- }
- if (!bindingPath.equals(that.bindingPath)) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = name.hashCode();
- result = 31 * result + bindingPath.hashCode();
- return result;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
- /**
- * Utility classes for remote connectors e.g. netconf connector
- *
- * TODO extract into separate bundle when another connector is implemented e.g. restconf connector
- */
-package org.opendaylight.controller.sal.connect.util;
+++ /dev/null
-module netconf-node-topology {
- namespace "urn:opendaylight:netconf-node-topology";
- prefix "nettop";
-
- import network-topology { prefix nt; revision-date 2013-10-21; }
- import yang-ext { prefix ext; revision-date "2013-07-09";}
- import ietf-inet-types { prefix inet; revision-date "2010-09-24"; }
-
- revision "2015-01-14" {
- description "Initial revision of Topology model";
- }
-
- augment "/nt:network-topology/nt:topology/nt:topology-types" {
- container topology-netconf {
- }
- }
-
- grouping netconf-node-fields {
- leaf connection-status {
- type enumeration {
- enum connecting;
- enum connected;
- enum unable-to-connect;
- }
- }
-
- leaf host {
- type inet:host;
- }
-
- leaf port {
- type inet:port-number;
- }
-
- leaf connected-message {
- type string;
- }
-
- container available-capabilities {
- leaf-list available-capability {
- type string;
- }
- }
-
- container unavailable-capabilities {
- list unavailable-capability {
- leaf capability {
- type string;
- }
-
- leaf failure-reason {
- type enumeration {
- enum missing-source;
- enum unable-to-resolve;
- }
- }
- }
- }
-
- container pass-through {
- when "../connection-status = connected";
- description
- "When the underlying node is connected, its NETCONF context
- is available verbatim under this container through the
- mount extension.";
- }
- }
-
- augment "/nt:network-topology/nt:topology/nt:node" {
- when "../../nt:topology-types/topology-netconf";
- ext:augment-identifier "netconf-node";
-
- uses netconf-node-fields;
- }
-}
+++ /dev/null
-module odl-sal-netconf-connector-cfg {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf";
- prefix "sal-netconf";
-
- import config { prefix config; revision-date 2013-04-05; }
- import threadpool {prefix th;}
- import netty {prefix netty;}
- import opendaylight-md-sal-dom {prefix dom;}
- import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
- import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
- import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
-
- description
- "Service definition for Binding Aware MD-SAL.";
-
- revision "2013-10-28" {
- description
- "Initial revision";
- }
-
- identity sal-netconf-connector {
- base config:module-type;
- config:java-name-prefix NetconfConnector;
- }
-
- grouping server {
- leaf address {
- type string;
- }
-
- leaf port {
- type uint32;
- }
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case sal-netconf-connector {
- when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
-
- leaf address {
- type inet:host;
- }
-
- leaf port {
- type inet:port-number;
- }
-
- leaf tcp-only {
- type boolean;
- }
-
- leaf username {
- type string;
- }
-
- leaf password {
- type string;
- }
-
- container yang-module-capabilities {
- leaf-list capability {
- type string;
- description "Set a list of capabilities to override capabilities provided in device's hello message.
- Can be used for devices that do not report any yang modules in their hello message";
- }
- }
-
- leaf reconnect-on-changed-schema {
- type boolean;
- default false;
- description "If true, the connector would auto disconnect/reconnect when schemas are changed in the remote device.
- The connector subscribes (right after connect) to base netconf notifications and listens for netconf-capability-change notification";
- }
-
- container dom-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dom:dom-broker-osgi-registry;
- }
- }
- }
-
- container binding-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity md-sal-binding:binding-broker-osgi-registry;
- }
- }
- }
-
- container event-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity netty:netty-event-executor;
- }
- }
- }
-
- container processing-executor {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity th:threadpool;
- }
- }
-
- description "Makes up for flaws in netty threading design";
- }
-
- container client-dispatcher {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity cfg-net:netconf-client-dispatcher;
- }
- }
- }
-
- leaf connection-timeout-millis {
- description "Specifies timeout in milliseconds after which connection must be established.";
- type uint32;
- default 20000;
- }
-
- leaf default-request-timeout-millis {
- description "Timeout for blocking operations within transactions.";
- type uint32;
- default 60000;
- }
-
- leaf max-connection-attempts {
- description "Maximum number of connection retries. Non positive value or null is interpreted as infinity.";
- type uint32;
- default 0; // retry forever
- }
-
- leaf between-attempts-timeout-millis {
- description "Initial timeout in milliseconds to wait between connection attempts. Will be multiplied by sleep-factor with every additional attempt";
- type uint16;
- default 2000;
- }
-
- leaf sleep-factor {
- type decimal64 {
- fraction-digits 1;
- }
- default 1.5;
- }
-
- // Keepalive configuration
- leaf keepalive-delay {
- type uint32;
- default 120;
- description "Netconf connector sends keepalive RPCs while the session is idle, this delay specifies the delay between keepalive RPC in seconds
- If a value <1 is provided, no keepalives will be sent";
- }
-
- container keepalive-executor {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity th:scheduled-threadpool;
- }
- }
-
- description "Dedicated solely to keepalive execution";
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollectionOf;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Futures;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.sal.connect.api.MessageTransformer;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.sal.NetconfDeviceRpc;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.ModuleImport;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.repo.api.MissingSchemaSourceException;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaResolutionException;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-public class NetconfDeviceTest {
-
- private static final NetconfMessage notification;
-
- private static final ContainerNode compositeNode;
-
- static {
- try {
- compositeNode = mockClass(ContainerNode.class);
- } catch (final Exception e) {
- throw new RuntimeException(e);
- }
- try {
- notification = new NetconfMessage(XmlUtil.readXmlToDocument(NetconfDeviceTest.class.getResourceAsStream("/notification-payload.xml")));
- } catch (Exception e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- private static final DOMRpcResult rpcResultC = new DefaultDOMRpcResult(compositeNode);
-
- public static final String TEST_NAMESPACE = "test:namespace";
- public static final String TEST_MODULE = "test-module";
- public static final String TEST_REVISION = "2013-07-22";
- public static final SourceIdentifier TEST_SID = new SourceIdentifier(TEST_MODULE, Optional.of(TEST_REVISION));
- public static final String TEST_CAPABILITY = TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION;
-
- public static final SourceIdentifier TEST_SID2 = new SourceIdentifier(TEST_MODULE + "2", Optional.of(TEST_REVISION));
- public static final String TEST_CAPABILITY2 = TEST_NAMESPACE + "?module=" + TEST_MODULE + "2" + "&revision=" + TEST_REVISION;
-
- private static final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() {
-
- @Override
- public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
- return NetconfStateSchemas.EMPTY;
- }
- };
-
- @Test
- public void testNetconfDeviceFailFirstSchemaFailSecondEmpty() throws Exception {
- final ArrayList<String> capList = Lists.newArrayList(TEST_CAPABILITY);
-
- final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
- final NetconfDeviceCommunicator listener = getListener();
-
- final SchemaContextFactory schemaFactory = getSchemaFactory();
-
- // Make fallback attempt to fail due to empty resolved sources
- final SchemaResolutionException schemaResolutionException
- = new SchemaResolutionException("fail first",
- Collections.<SourceIdentifier>emptyList(), HashMultimap.<SourceIdentifier, ModuleImport>create());
- doReturn(Futures.immediateFailedCheckedFuture(
- schemaResolutionException))
- .when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
- = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver);
- final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(),true);
- // Monitoring not supported
- final NetconfSessionPreferences sessionCaps = getSessionCaps(false, capList);
- device.onRemoteSessionUp(sessionCaps, listener);
-
- Mockito.verify(facade, Mockito.timeout(5000)).onDeviceDisconnected();
- Mockito.verify(listener, Mockito.timeout(5000)).close();
- Mockito.verify(schemaFactory, times(1)).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
- }
-
- @Test
- public void testNetconfDeviceMissingSource() throws Exception {
- final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
- final NetconfDeviceCommunicator listener = getListener();
- final SchemaContext schema = getSchema();
-
- final SchemaContextFactory schemaFactory = getSchemaFactory();
-
- // Make fallback attempt to fail due to empty resolved sources
- final MissingSchemaSourceException schemaResolutionException = new MissingSchemaSourceException("fail first", TEST_SID);
- doAnswer(new Answer<Object>() {
- @Override
- public Object answer(final InvocationOnMock invocation) throws Throwable {
- if(((Collection<?>) invocation.getArguments()[0]).size() == 2) {
- return Futures.immediateFailedCheckedFuture(schemaResolutionException);
- } else {
- return Futures.immediateCheckedFuture(schema);
- }
- }
- }).when(schemaFactory).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
-
- final NetconfStateSchemas.NetconfStateSchemasResolver stateSchemasResolver = new NetconfStateSchemas.NetconfStateSchemasResolver() {
- @Override
- public NetconfStateSchemas resolve(final NetconfDeviceRpc deviceRpc, final NetconfSessionPreferences remoteSessionCapabilities, final RemoteDeviceId id) {
- final Module first = Iterables.getFirst(schema.getModules(), null);
- final QName qName = QName.create(first.getQNameModule(), first.getName());
- final NetconfStateSchemas.RemoteYangSchema source1 = new NetconfStateSchemas.RemoteYangSchema(qName);
- final NetconfStateSchemas.RemoteYangSchema source2 = new NetconfStateSchemas.RemoteYangSchema(QName.create(first.getQNameModule(), "test-module2"));
- return new NetconfStateSchemas(Sets.newHashSet(source1, source2));
- }
- };
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
- = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaFactory, stateSchemasResolver);
-
- final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
- // Monitoring supported
- final NetconfSessionPreferences sessionCaps = getSessionCaps(true, Lists.newArrayList(TEST_CAPABILITY, TEST_CAPABILITY2));
- device.onRemoteSessionUp(sessionCaps, listener);
-
- Mockito.verify(facade, Mockito.timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class));
- Mockito.verify(schemaFactory, times(2)).createSchemaContext(anyCollectionOf(SourceIdentifier.class));
- }
-
- private SchemaSourceRegistry getSchemaRegistry() {
- final SchemaSourceRegistry mock = mock(SchemaSourceRegistry.class);
- final SchemaSourceRegistration<?> mockReg = mock(SchemaSourceRegistration.class);
- doNothing().when(mockReg).close();
- doReturn(mockReg).when(mock).registerSchemaSource(any(org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider.class), any(PotentialSchemaSource.class));
- return mock;
- }
-
- @Test
- public void testNotificationBeforeSchema() throws Exception {
- final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
- final NetconfDeviceCommunicator listener = getListener();
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
- = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), getSchemaFactory(), stateSchemasResolver);
- final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
-
- device.onNotification(notification);
- device.onNotification(notification);
-
- verify(facade, times(0)).onNotification(any(DOMNotification.class));
-
- final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
- Lists.newArrayList(TEST_CAPABILITY));
-
- final DOMRpcService deviceRpc = mock(DOMRpcService.class);
-
- device.handleSalInitializationSuccess(NetconfToNotificationTest.getNotificationSchemaContext(getClass()), sessionCaps, deviceRpc);
-
- verify(facade, timeout(10000).times(2)).onNotification(any(DOMNotification.class));
-
- device.onNotification(notification);
- verify(facade, timeout(10000).times(3)).onNotification(any(DOMNotification.class));
- }
-
- @Test
- public void testNetconfDeviceReconnect() throws Exception {
- final RemoteDeviceHandler<NetconfSessionPreferences> facade = getFacade();
- final NetconfDeviceCommunicator listener = getListener();
-
- final SchemaContextFactory schemaContextProviderFactory = getSchemaFactory();
-
- final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO
- = new NetconfDevice.SchemaResourcesDTO(getSchemaRegistry(), schemaContextProviderFactory, stateSchemasResolver);
- final NetconfDevice device = new NetconfDevice(schemaResourcesDTO, getId(), facade, getExecutor(), true);
- final NetconfSessionPreferences sessionCaps = getSessionCaps(true,
- Lists.newArrayList(TEST_NAMESPACE + "?module=" + TEST_MODULE + "&revision=" + TEST_REVISION));
- device.onRemoteSessionUp(sessionCaps, listener);
-
- verify(schemaContextProviderFactory, timeout(5000)).createSchemaContext(any(Collection.class));
- verify(facade, timeout(5000)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
-
- device.onRemoteSessionDown();
- verify(facade, timeout(5000)).onDeviceDisconnected();
-
- device.onRemoteSessionUp(sessionCaps, listener);
-
- verify(schemaContextProviderFactory, timeout(5000).times(2)).createSchemaContext(any(Collection.class));
- verify(facade, timeout(5000).times(2)).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
- }
-
- private SchemaContextFactory getSchemaFactory() {
- final SchemaContextFactory schemaFactory = mockClass(SchemaContextFactory.class);
- doReturn(Futures.immediateCheckedFuture(getSchema())).when(schemaFactory).createSchemaContext(any(Collection.class));
- return schemaFactory;
- }
-
- public static SchemaContext getSchema() {
- final YangParserImpl parser = new YangParserImpl();
- final List<InputStream> modelsToParse = Lists.newArrayList(
- NetconfDeviceTest.class.getResourceAsStream("/schemas/test-module.yang")
- );
- final Set<Module> models = parser.parseYangModelsFromStreams(modelsToParse);
- return parser.resolveSchemaContext(models);
- }
-
- private RemoteDeviceHandler<NetconfSessionPreferences> getFacade() throws Exception {
- final RemoteDeviceHandler<NetconfSessionPreferences> remoteDeviceHandler = mockCloseableClass(RemoteDeviceHandler.class);
- doNothing().when(remoteDeviceHandler).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(NetconfDeviceRpc.class));
- doNothing().when(remoteDeviceHandler).onDeviceDisconnected();
- doNothing().when(remoteDeviceHandler).onNotification(any(DOMNotification.class));
- return remoteDeviceHandler;
- }
-
- private <T extends AutoCloseable> T mockCloseableClass(final Class<T> remoteDeviceHandlerClass) throws Exception {
- final T mock = mockClass(remoteDeviceHandlerClass);
- doNothing().when(mock).close();
- return mock;
- }
-
- private static <T> T mockClass(final Class<T> remoteDeviceHandlerClass) {
- final T mock = mock(remoteDeviceHandlerClass);
- Mockito.doReturn(remoteDeviceHandlerClass.getSimpleName()).when(mock).toString();
- return mock;
- }
-
- public RemoteDeviceId getId() {
- return new RemoteDeviceId("test-D", InetSocketAddress.createUnresolved("localhost", 22));
- }
-
- public ExecutorService getExecutor() {
- return Executors.newSingleThreadExecutor();
- }
-
- public MessageTransformer<NetconfMessage> getMessageTransformer() throws Exception {
- final MessageTransformer<NetconfMessage> messageTransformer = mockClass(MessageTransformer.class);
- doReturn(notification).when(messageTransformer).toRpcRequest(any(SchemaPath.class), any(NormalizedNode.class));
- doReturn(rpcResultC).when(messageTransformer).toRpcResult(any(NetconfMessage.class), any(SchemaPath.class));
- doReturn(compositeNode).when(messageTransformer).toNotification(any(NetconfMessage.class));
- return messageTransformer;
- }
-
- public NetconfSessionPreferences getSessionCaps(final boolean addMonitor, final Collection<String> additionalCapabilities) {
- final ArrayList<String> capabilities = Lists.newArrayList(
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0,
- XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
-
- if(addMonitor) {
- capabilities.add(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString());
- }
-
- capabilities.addAll(additionalCapabilities);
-
- return NetconfSessionPreferences.fromStrings(
- capabilities);
- }
-
- public NetconfDeviceCommunicator getListener() throws Exception {
- final NetconfDeviceCommunicator remoteDeviceCommunicator = mockCloseableClass(NetconfDeviceCommunicator.class);
-// doReturn(Futures.immediateFuture(rpcResult)).when(remoteDeviceCommunicator).sendRequest(any(NetconfMessage.class), any(QName.class));
- return remoteDeviceCommunicator;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf;
-
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.Set;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class NetconfStateSchemasTest {
-
- @Test
- public void testCreate() throws Exception {
- final DataSchemaNode schemasNode = ((ContainerSchemaNode) NetconfDevice.INIT_SCHEMA_CTX.getDataChildByName("netconf-state")).getDataChildByName("schemas");
-
- final Document schemasXml = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml"));
- final ToNormalizedNodeParser<Element, ContainerNode, ContainerSchemaNode> containerNodeParser = DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, NetconfDevice.INIT_SCHEMA_CTX, false).getContainerNodeParser();
- final ContainerNode compositeNodeSchemas = containerNodeParser.parse(Collections.singleton(schemasXml.getDocumentElement()), (ContainerSchemaNode) schemasNode);
- final NetconfStateSchemas schemas = NetconfStateSchemas.create(new RemoteDeviceId("device", new InetSocketAddress(99)), compositeNodeSchemas);
-
- final Set<QName> availableYangSchemasQNames = schemas.getAvailableYangSchemasQNames();
- assertEquals(73, availableYangSchemasQNames.size());
-
- assertThat(availableYangSchemasQNames,
- hasItem(QName.create("urn:TBD:params:xml:ns:yang:network-topology", "2013-07-12", "network-topology")));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import com.google.common.collect.Iterables;
-import java.io.InputStream;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import javax.xml.parsers.DocumentBuilderFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.notifications.NetconfNotification;
-import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.w3c.dom.Document;
-
-public class NetconfToNotificationTest {
-
- NetconfMessageTransformer messageTransformer;
-
- NetconfMessage userNotification;
-
- @SuppressWarnings("deprecation")
- @Before
- public void setup() throws Exception {
- final SchemaContext schemaContext = getNotificationSchemaContext(getClass());
-
- messageTransformer = new NetconfMessageTransformer(schemaContext, true);
-
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- InputStream notifyPayloadStream = getClass().getResourceAsStream("/notification-payload.xml");
- assertNotNull(notifyPayloadStream);
-
- final Document doc = XmlUtil.readXmlToDocument(notifyPayloadStream);
- assertNotNull(doc);
- userNotification = new NetconfMessage(doc);
- }
-
- static SchemaContext getNotificationSchemaContext(Class<?> loadClass) {
- final List<InputStream> modelsToParse = Collections.singletonList(loadClass.getResourceAsStream("/schemas/user-notification.yang"));
- final YangContextParser parser = new YangParserImpl();
- final Set<Module> modules = parser.parseYangModelsFromStreams(modelsToParse);
- assertTrue(!modules.isEmpty());
- final SchemaContext schemaContext = parser.resolveSchemaContext(modules);
- assertNotNull(schemaContext);
- return schemaContext;
- }
-
- @Test
- public void test() throws Exception {
- final DOMNotification domNotification = messageTransformer.toNotification(userNotification);
- final ContainerNode root = domNotification.getBody();
- assertNotNull(root);
- assertEquals(6, Iterables.size(root.getValue()));
- assertEquals("user-visited-page", root.getNodeType().getLocalName());
- assertEquals(new SimpleDateFormat(NetconfNotification.RFC3339_DATE_FORMAT_BLUEPRINT).parse("2007-07-08T00:01:00Z"),
- ((DOMEvent) domNotification).getEventTime());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.collect.Sets;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.netconf.schema.mapping.NetconfMessageTransformer;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-import org.w3c.dom.Document;
-
-public class NetconfToRpcRequestTest {
-
- private final static String TEST_MODEL_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
- private final static String REVISION = "2014-07-14";
- private final static QName INPUT_QNAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "input");
- private final static QName STREAM_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "stream-name");
- private final static QName SUBSCRIBE_RPC_NAME = QName.create(TEST_MODEL_NAMESPACE, REVISION, "subscribe");
-
- private final static String CONFIG_TEST_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:config:defs";
- private final static String CONFIG_TEST_REVISION = "2014-07-21";
- private final static QName EDIT_CONFIG_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "edit-config");
- private final static QName GET_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "get");
- private final static QName GET_CONFIG_QNAME = QName.create(CONFIG_TEST_NAMESPACE, CONFIG_TEST_REVISION, "get-config");
-
- static SchemaContext cfgCtx;
- static NetconfMessageTransformer messageTransformer;
-
- @SuppressWarnings("deprecation")
- @BeforeClass
- public static void setup() throws Exception {
- List<InputStream> modelsToParse = Collections
- .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/rpc-notification-subscription.yang"));
- YangContextParser parser = new YangParserImpl();
- final Set<Module> notifModules = parser.parseYangModelsFromStreams(modelsToParse);
- assertTrue(!notifModules.isEmpty());
-
- modelsToParse = Collections
- .singletonList(NetconfToRpcRequestTest.class.getResourceAsStream("/schemas/config-test-rpc.yang"));
- parser = new YangParserImpl();
- final Set<Module> configModules = parser.parseYangModelsFromStreams(modelsToParse);
- cfgCtx = parser.resolveSchemaContext(Sets.union(configModules, notifModules));
- assertNotNull(cfgCtx);
-
- messageTransformer = new NetconfMessageTransformer(cfgCtx, true);
- }
-
- private LeafNode<Object> buildLeaf(final QName running, final Object value) {
- return Builders.leafBuilder().withNodeIdentifier(toId(running)).withValue(value).build();
- }
-
- @Test
- public void testUserDefinedRpcCall() throws Exception {
- final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> rootBuilder = Builders.containerBuilder();
- rootBuilder.withNodeIdentifier(toId(SUBSCRIBE_RPC_NAME));
-
- rootBuilder.withChild(buildLeaf(STREAM_NAME, "NETCONF"));
- final ContainerNode root = rootBuilder.build();
-
- final NetconfMessage message = messageTransformer.toRpcRequest(toPath(SUBSCRIBE_RPC_NAME), root);
- assertNotNull(message);
-
- final Document xmlDoc = message.getDocument();
- final org.w3c.dom.Node rpcChild = xmlDoc.getFirstChild();
- assertEquals(rpcChild.getLocalName(), "rpc");
-
- final org.w3c.dom.Node subscribeName = rpcChild.getFirstChild();
- assertEquals(subscribeName.getLocalName(), "subscribe");
-
- final org.w3c.dom.Node streamName = subscribeName.getFirstChild();
- assertEquals(streamName.getLocalName(), "stream-name");
-
- }
-
- // The edit config defined in yang has no output
- @Test(expected = IllegalArgumentException.class)
- public void testRpcResponse() throws Exception {
- final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
- "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"m-5\">\n" +
- "<data xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">" +
- "module schema" +
- "</data>\n" +
- "</rpc-reply>\n"
- ));
-
- messageTransformer.toRpcResult(response, toPath(EDIT_CONFIG_QNAME));
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.same;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.GenericFutureListener;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.io.ByteArrayInputStream;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.UUID;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import org.apache.commons.lang3.StringUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlMappingConstants;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
-import org.opendaylight.protocol.framework.TimedReconnectStrategy;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class NetconfDeviceCommunicatorTest {
-
- @Mock
- NetconfClientSession mockSession;
-
- @Mock
- RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> mockDevice;
-
- NetconfDeviceCommunicator communicator;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks( this );
-
- communicator = new NetconfDeviceCommunicator( new RemoteDeviceId( "test", InetSocketAddress.createUnresolved("localhost", 22)), mockDevice);
- }
-
- @SuppressWarnings("unchecked")
- void setupSession() {
- doReturn(Collections.<String>emptySet()).when(mockSession).getServerCapabilities();
- doNothing().when(mockDevice).onRemoteSessionUp(any(NetconfSessionPreferences.class),
- any(NetconfDeviceCommunicator.class));
- communicator.onSessionUp(mockSession);
- }
-
- private ListenableFuture<RpcResult<NetconfMessage>> sendRequest() throws Exception {
- return sendRequest( UUID.randomUUID().toString() );
- }
-
- @SuppressWarnings("unchecked")
- private ListenableFuture<RpcResult<NetconfMessage>> sendRequest( String messageID ) throws Exception {
- Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element element = doc.createElement( "request" );
- element.setAttribute( "message-id", messageID );
- doc.appendChild( element );
- NetconfMessage message = new NetconfMessage( doc );
-
- ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
- doReturn( mockChannelFuture ).when( mockChannelFuture )
- .addListener( any( (GenericFutureListener.class ) ) );
- doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture =
- communicator.sendRequest( message, QName.create( "mock rpc" ) );
-
- assertNotNull( "ListenableFuture is null", resultFuture );
- return resultFuture;
- }
-
- @Test
- public void testOnSessionUp() {
- String testCapability = "urn:opendaylight:params:xml:ns:test?module=test-module&revision=2014-06-02";
- Collection<String> serverCapabilities =
- Sets.newHashSet( NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString(),
- NetconfMessageTransformUtil.IETF_NETCONF_MONITORING.getNamespace().toString(),
- testCapability );
- doReturn( serverCapabilities ).when( mockSession ).getServerCapabilities();
-
- ArgumentCaptor<NetconfSessionPreferences> NetconfSessionPreferences =
- ArgumentCaptor.forClass( NetconfSessionPreferences.class );
- doNothing().when( mockDevice ).onRemoteSessionUp( NetconfSessionPreferences.capture(), eq( communicator ) );
-
- communicator.onSessionUp( mockSession );
-
- verify( mockSession ).getServerCapabilities();
- verify( mockDevice ).onRemoteSessionUp( NetconfSessionPreferences.capture(), eq( communicator ) );
-
- NetconfSessionPreferences actualCapabilites = NetconfSessionPreferences.getValue();
- assertEquals( "containsModuleCapability", true, actualCapabilites.containsNonModuleCapability(
- NetconfMessageTransformUtil.NETCONF_ROLLBACK_ON_ERROR_URI.toString()) );
- assertEquals( "containsModuleCapability", false, actualCapabilites.containsNonModuleCapability(testCapability) );
- assertEquals( "getModuleBasedCaps", Sets.newHashSet(
- QName.create( "urn:opendaylight:params:xml:ns:test", "2014-06-02", "test-module" )),
- actualCapabilites.getModuleBasedCaps() );
- assertEquals( "isRollbackSupported", true, actualCapabilites.isRollbackSupported() );
- assertEquals( "isMonitoringSupported", true, actualCapabilites.isMonitoringSupported() );
- }
-
- @SuppressWarnings("unchecked")
- @Test(timeout=5000)
- public void testOnSessionDown() throws Exception {
- setupSession();
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest();
-
- doNothing().when( mockDevice ).onRemoteSessionDown();
-
- communicator.onSessionDown( mockSession, new Exception( "mock ex" ) );
-
- verifyErrorRpcResult( resultFuture1.get(), RpcError.ErrorType.TRANSPORT, "operation-failed" );
- verifyErrorRpcResult( resultFuture2.get(), RpcError.ErrorType.TRANSPORT, "operation-failed" );
-
- verify( mockDevice ).onRemoteSessionDown();
-
- reset( mockDevice );
-
- communicator.onSessionDown( mockSession, new Exception( "mock ex" ) );
-
- verify( mockDevice, never() ).onRemoteSessionDown();
- }
-
- @Test
- public void testOnSessionTerminated() throws Exception {
- setupSession();
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest();
-
- doNothing().when( mockDevice ).onRemoteSessionDown();
-
- String reasonText = "testing terminate";
- NetconfTerminationReason reason = new NetconfTerminationReason( reasonText );
- communicator.onSessionTerminated( mockSession, reason );
-
- RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.TRANSPORT,
- "operation-failed" );
- assertEquals( "RpcError message", reasonText, rpcError.getMessage() );
-
- verify( mockDevice ).onRemoteSessionDown();
- }
-
- @Test
- public void testClose() throws Exception {
- communicator.close();
- verify( mockDevice, never() ).onRemoteSessionDown();
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Test
- public void testSendRequest() throws Exception {
- setupSession();
-
- NetconfMessage message = new NetconfMessage(
- DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
- QName rpc = QName.create( "mock rpc" );
-
- ArgumentCaptor<GenericFutureListener> futureListener =
- ArgumentCaptor.forClass( GenericFutureListener.class );
-
- ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
- doReturn( mockChannelFuture ).when( mockChannelFuture ).addListener( futureListener.capture() );
- doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
-
- verify( mockSession ).sendMessage( same( message ) );
-
- assertNotNull( "ListenableFuture is null", resultFuture );
-
- verify( mockChannelFuture ).addListener( futureListener.capture() );
- Future<Void> operationFuture = mock( Future.class );
- doReturn( true ).when( operationFuture ).isSuccess();
- doReturn( true ).when( operationFuture ).isDone();
- futureListener.getValue().operationComplete( operationFuture );
-
- try {
- resultFuture.get( 1, TimeUnit.MILLISECONDS ); // verify it's not cancelled or has an error set
- }
- catch( TimeoutException e ) {} // expected
- }
-
- @Test
- public void testSendRequestWithNoSession() throws Exception {
- NetconfMessage message = new NetconfMessage(
- DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
- QName rpc = QName.create( "mock rpc" );
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
-
- assertNotNull( "ListenableFuture is null", resultFuture );
-
- // Should have an immediate result
- RpcResult<NetconfMessage> rpcResult = resultFuture.get( 3, TimeUnit.MILLISECONDS );
-
- verifyErrorRpcResult( rpcResult, RpcError.ErrorType.TRANSPORT, "operation-failed" );
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Test
- public void testSendRequestWithWithSendFailure() throws Exception {
- setupSession();
-
- NetconfMessage message = new NetconfMessage(
- DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() );
- QName rpc = QName.create( "mock rpc" );
-
- ArgumentCaptor<GenericFutureListener> futureListener =
- ArgumentCaptor.forClass( GenericFutureListener.class );
-
- ChannelFuture mockChannelFuture = mock( ChannelFuture.class );
- doReturn( mockChannelFuture ).when( mockChannelFuture ).addListener( futureListener.capture() );
- doReturn( mockChannelFuture ).when( mockSession ).sendMessage( same( message ) );
-
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = communicator.sendRequest( message, rpc );
-
- assertNotNull( "ListenableFuture is null", resultFuture );
-
- verify( mockChannelFuture ).addListener( futureListener.capture() );
-
- Future<Void> operationFuture = mock( Future.class );
- doReturn( false ).when( operationFuture ).isSuccess();
- doReturn( true ).when( operationFuture ).isDone();
- doReturn( new Exception( "mock error" ) ).when( operationFuture ).cause();
- futureListener.getValue().operationComplete( operationFuture );
-
- // Should have an immediate result
- RpcResult<NetconfMessage> rpcResult = resultFuture.get( 3, TimeUnit.MILLISECONDS );
-
- RpcError rpcError = verifyErrorRpcResult( rpcResult, RpcError.ErrorType.TRANSPORT, "operation-failed" );
- assertEquals( "RpcError message contains \"mock error\"", true,
- rpcError.getMessage().contains( "mock error" ) );
- }
-
- private NetconfMessage createSuccessResponseMessage( String messageID ) throws ParserConfigurationException {
- Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
- Element rpcReply = doc.createElementNS( URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlMappingConstants.RPC_REPLY_KEY);
- rpcReply.setAttribute( "message-id", messageID );
- Element element = doc.createElementNS( "ns", "data" );
- element.setTextContent( messageID );
- rpcReply.appendChild( element );
- doc.appendChild( rpcReply );
-
- return new NetconfMessage( doc );
- }
-
- //Test scenario verifying whether missing message is handled
- @Test
- public void testOnMissingResponseMessage() throws Exception {
-
- setupSession();
-
- String messageID1 = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest( messageID1 );
-
- String messageID2 = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest( messageID2 );
-
- String messageID3 = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture3 = sendRequest( messageID3 );
-
- //response messages 1,2 are omitted
- communicator.onMessage( mockSession, createSuccessResponseMessage( messageID3 ) );
-
- verifyResponseMessage( resultFuture3.get(), messageID3 );
- }
-
- @Test
- public void testOnSuccessfulResponseMessage() throws Exception {
- setupSession();
-
- String messageID1 = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture1 = sendRequest( messageID1 );
-
- String messageID2 = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture2 = sendRequest( messageID2 );
-
- communicator.onMessage( mockSession, createSuccessResponseMessage( messageID1 ) );
- communicator.onMessage( mockSession, createSuccessResponseMessage( messageID2 ) );
-
- verifyResponseMessage( resultFuture1.get(), messageID1 );
- verifyResponseMessage( resultFuture2.get(), messageID2 );
- }
-
- @Test
- public void testOnResponseMessageWithError() throws Exception {
- setupSession();
-
- String messageID = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest( messageID );
-
- communicator.onMessage( mockSession, createErrorResponseMessage( messageID ) );
-
- RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.RPC,
- "missing-attribute" );
- assertEquals( "RpcError message", "Missing attribute", rpcError.getMessage() );
-
- String errorInfo = rpcError.getInfo();
- assertNotNull( "RpcError info is null", errorInfo );
- assertEquals( "Error info contains \"foo\"", true,
- errorInfo.contains( "<bad-attribute>foo</bad-attribute>" ) );
- assertEquals( "Error info contains \"bar\"", true,
- errorInfo.contains( "<bad-element>bar</bad-element>" ) );
- }
-
- /**
- * Test whether reconnect is scheduled properly
- */
- @Test
- public void testNetconfDeviceReconnectInCommunicator() throws Exception {
- final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> device = mock(RemoteDevice.class);
-
- final TimedReconnectStrategy timedReconnectStrategy = new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, 10000, 0, 1.0, null, 100L, null);
- final ReconnectStrategy reconnectStrategy = spy(new ReconnectStrategy() {
- @Override
- public int getConnectTimeout() throws Exception {
- return timedReconnectStrategy.getConnectTimeout();
- }
-
- @Override
- public Future<Void> scheduleReconnect(final Throwable cause) {
- return timedReconnectStrategy.scheduleReconnect(cause);
- }
-
- @Override
- public void reconnectSuccessful() {
- timedReconnectStrategy.reconnectSuccessful();
- }
- });
-
- final EventLoopGroup group = new NioEventLoopGroup();
- final Timer time = new HashedWheelTimer();
- try {
- final NetconfDeviceCommunicator listener = new NetconfDeviceCommunicator(new RemoteDeviceId("test", InetSocketAddress.createUnresolved("localhost", 22)), device);
- final NetconfReconnectingClientConfiguration cfg = NetconfReconnectingClientConfigurationBuilder.create()
- .withAddress(new InetSocketAddress("localhost", 65000))
- .withReconnectStrategy(reconnectStrategy)
- .withConnectStrategyFactory(new ReconnectStrategyFactory() {
- @Override
- public ReconnectStrategy createReconnectStrategy() {
- return reconnectStrategy;
- }
- })
- .withAuthHandler(new LoginPassword("admin", "admin"))
- .withConnectionTimeoutMillis(10000)
- .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH)
- .withSessionListener(listener)
- .build();
-
- listener.initializeRemoteConnection(new NetconfClientDispatcherImpl(group, group, time), cfg);
-
- verify(reconnectStrategy, timeout((int) TimeUnit.MINUTES.toMillis(3)).times(101)).scheduleReconnect(any(Throwable.class));
- } finally {
- time.stop();
- group.shutdownGracefully();
- }
- }
-
- @Test
- public void testOnResponseMessageWithWrongMessageID() throws Exception {
- setupSession();
-
- String messageID = UUID.randomUUID().toString();
- ListenableFuture<RpcResult<NetconfMessage>> resultFuture = sendRequest( messageID );
-
- communicator.onMessage( mockSession, createSuccessResponseMessage( UUID.randomUUID().toString() ) );
-
- RpcError rpcError = verifyErrorRpcResult( resultFuture.get(), RpcError.ErrorType.PROTOCOL,
- "bad-attribute" );
- assertEquals( "RpcError message non-empty", true,
- !Strings.isNullOrEmpty( rpcError.getMessage() ) );
-
- String errorInfo = rpcError.getInfo();
- assertNotNull( "RpcError info is null", errorInfo );
- assertEquals( "Error info contains \"actual-message-id\"", true,
- errorInfo.contains( "actual-message-id" ) );
- assertEquals( "Error info contains \"expected-message-id\"", true,
- errorInfo.contains( "expected-message-id" ) );
- }
-
- private NetconfMessage createErrorResponseMessage( String messageID ) throws Exception {
- String xmlStr =
- "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"" +
- " message-id=\"" + messageID + "\">" +
- " <rpc-error>" +
- " <error-type>rpc</error-type>" +
- " <error-tag>missing-attribute</error-tag>" +
- " <error-severity>error</error-severity>" +
- " <error-message>Missing attribute</error-message>" +
- " <error-info>" +
- " <bad-attribute>foo</bad-attribute>" +
- " <bad-element>bar</bad-element>" +
- " </error-info>" +
- " </rpc-error>" +
- "</rpc-reply>";
-
- ByteArrayInputStream bis = new ByteArrayInputStream( xmlStr.getBytes() );
- Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( bis );
- return new NetconfMessage( doc );
- }
-
- private void verifyResponseMessage( RpcResult<NetconfMessage> rpcResult, String dataText ) {
- assertNotNull( "RpcResult is null", rpcResult );
- assertEquals( "isSuccessful", true, rpcResult.isSuccessful() );
- NetconfMessage messageResult = rpcResult.getResult();
- assertNotNull( "getResult", messageResult );
-// List<SimpleNode<?>> nodes = messageResult.getSimpleNodesByName(
-// QName.create( URI.create( "ns" ), null, "data" ) );
-// assertNotNull( "getSimpleNodesByName", nodes );
-// assertEquals( "List<SimpleNode<?>> size", 1, nodes.size() );
-// assertEquals( "SimpleNode value", dataText, nodes.iterator().next().getValue() );
- }
-
- private RpcError verifyErrorRpcResult( RpcResult<NetconfMessage> rpcResult,
- RpcError.ErrorType expErrorType, String expErrorTag ) {
- assertNotNull( "RpcResult is null", rpcResult );
- assertEquals( "isSuccessful", false, rpcResult.isSuccessful() );
- assertNotNull( "RpcResult errors is null", rpcResult.getErrors() );
- assertEquals( "Errors size", 1, rpcResult.getErrors().size() );
- RpcError rpcError = rpcResult.getErrors().iterator().next();
- assertEquals( "getErrorSeverity", RpcError.ErrorSeverity.ERROR, rpcError.getSeverity() );
- assertEquals( "getErrorType", expErrorType, rpcError.getErrorType() );
- assertEquals( "getErrorTag", expErrorTag, rpcError.getTag() );
- assertTrue( "getMessage is empty", StringUtils.isNotEmpty( rpcError.getMessage() ) );
- return rpcError;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.listener;
-
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import com.google.common.collect.Lists;
-import java.util.List;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class NetconfSessionPreferencesTest {
-
- @Test
- public void testMerge() throws Exception {
- final List<String> caps1 = Lists.newArrayList(
- "namespace:1?module=module1&revision=2012-12-12",
- "namespace:2?module=module2&revision=2012-12-12",
- "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04",
- "urn:ietf:params:netconf:base:1.0",
- "urn:ietf:params:netconf:capability:rollback-on-error:1.0"
- );
- final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1);
- assertCaps(sessionCaps1, 2, 3);
-
- final List<String> caps2 = Lists.newArrayList(
- "namespace:3?module=module3&revision=2012-12-12",
- "namespace:4?module=module4&revision=2012-12-12",
- "randomNonModuleCap"
- );
- final NetconfSessionPreferences sessionCaps2 = NetconfSessionPreferences.fromStrings(caps2);
- assertCaps(sessionCaps2, 1, 2);
-
- final NetconfSessionPreferences merged = sessionCaps1.addModuleCaps(sessionCaps2);
- assertCaps(merged, 2, 2 + 1 /*Preserved monitoring*/ + 2 /*already present*/);
- for (final QName qName : sessionCaps2.getModuleBasedCaps()) {
- assertThat(merged.getModuleBasedCaps(), hasItem(qName));
- }
- assertThat(merged.getModuleBasedCaps(), hasItem(NetconfMessageTransformUtil.IETF_NETCONF_MONITORING));
-
- assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:base:1.0"));
- assertThat(merged.getNonModuleCaps(), hasItem("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
- }
-
- @Test
- public void testCapabilityNoRevision() throws Exception {
- final List<String> caps1 = Lists.newArrayList(
- "namespace:2?module=module2",
- "namespace:2?module=module2&revision=2012-12-12",
- "namespace:2?module=module1&RANDOMSTRING;revision=2013-12-12",
- "namespace:2?module=module2&RANDOMSTRING;revision=2013-12-12" // This one should be ignored(same as first), since revision is in wrong format
- );
-
- final NetconfSessionPreferences sessionCaps1 = NetconfSessionPreferences.fromStrings(caps1);
- assertCaps(sessionCaps1, 0, 3);
- }
-
- private void assertCaps(final NetconfSessionPreferences sessionCaps1, final int nonModuleCaps, final int moduleCaps) {
- assertEquals(nonModuleCaps, sessionCaps1.getNonModuleCaps().size());
- assertEquals(moduleCaps, sessionCaps1.getModuleBasedCaps().size());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.Futures;
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executors;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public class KeepaliveSalFacadeTest {
-
- private static final RemoteDeviceId REMOTE_DEVICE_ID = new RemoteDeviceId("test", new InetSocketAddress("localhost", 22));
-
- @Mock
- private RemoteDeviceHandler<NetconfSessionPreferences> underlyingSalFacade;
-
- private static java.util.concurrent.ScheduledExecutorService executorService;
-
- @Mock
- private NetconfDeviceCommunicator listener;
- @Mock
- private DOMRpcService deviceRpc;
-
- private DOMRpcService proxyRpc;
-
- @Before
- public void setUp() throws Exception {
- executorService = Executors.newScheduledThreadPool(1);
-
- MockitoAnnotations.initMocks(this);
-
- doNothing().when(listener).disconnect();
- doReturn("mockedRpc").when(deviceRpc).toString();
- doNothing().when(underlyingSalFacade).onDeviceConnected(
- any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
- }
-
- @After
- public void tearDown() throws Exception {
- executorService.shutdownNow();
- }
-
- @Test
- public void testKeepaliveSuccess() throws Exception {
- final DOMRpcResult result = new DefaultDOMRpcResult(Builders.containerBuilder().withNodeIdentifier(
- new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME)).build());
-
- doReturn(Futures.immediateCheckedFuture(result)).when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- final KeepaliveSalFacade keepaliveSalFacade =
- new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 1L);
- keepaliveSalFacade.setListener(listener);
-
- keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
-
- verify(underlyingSalFacade).onDeviceConnected(
- any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
-
- verify(deviceRpc, timeout(15000).times(5)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
- }
-
- @Test
- public void testKeepaliveFail() throws Exception {
- final DOMRpcResult result = new DefaultDOMRpcResult(Builders.containerBuilder().withNodeIdentifier(
- new YangInstanceIdentifier.NodeIdentifier(NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME)).build());
-
- final DOMRpcResult resultFail = new DefaultDOMRpcResult(mock(RpcError.class));
-
- doReturn(Futures.immediateCheckedFuture(result))
- .doReturn(Futures.immediateCheckedFuture(resultFail))
- .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
- .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- final KeepaliveSalFacade keepaliveSalFacade =
- new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 1L);
- keepaliveSalFacade.setListener(listener);
-
- keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
-
- verify(underlyingSalFacade).onDeviceConnected(
- any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
-
- // 1 failed that results in disconnect
- verify(listener, timeout(15000).times(1)).disconnect();
- // 3 attempts total
- verify(deviceRpc, times(3)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- // Reconnect with same keepalive responses
- doReturn(Futures.immediateCheckedFuture(result))
- .doReturn(Futures.immediateCheckedFuture(resultFail))
- .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
- .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
-
- // 1 failed that results in disconnect, 2 total with previous fail
- verify(listener, timeout(15000).times(2)).disconnect();
- // 6 attempts now total
- verify(deviceRpc, times(3 * 2)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
- }
-
- @Test
- public void testNonKeepaliveRpcFailure() throws Exception {
- doAnswer(new Answer() {
- @Override
- public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
- proxyRpc = (DOMRpcService) invocationOnMock.getArguments()[2];
- return null;
- }
- }).when(underlyingSalFacade).onDeviceConnected(any(SchemaContext.class), any(NetconfSessionPreferences.class), any(DOMRpcService.class));
-
- doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("illegal-state")))
- .when(deviceRpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- final KeepaliveSalFacade keepaliveSalFacade =
- new KeepaliveSalFacade(REMOTE_DEVICE_ID, underlyingSalFacade, executorService, 100L);
- keepaliveSalFacade.setListener(listener);
-
- keepaliveSalFacade.onDeviceConnected(null, null, deviceRpc);
-
- proxyRpc.invokeRpc(mock(SchemaPath.class), mock(NormalizedNode.class));
-
- verify(listener, times(1)).disconnect();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.Futures;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCapabilities;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public class NetconfDeviceTopologyAdapterTest {
-
- private RemoteDeviceId id = new RemoteDeviceId("test", new InetSocketAddress("localhost", 22));
-
- @Mock
- private DataBroker broker;
- @Mock
- private WriteTransaction writeTx;
- @Mock
- private BindingTransactionChain txChain;
- @Mock
- private Node data;
-
- private String txIdent = "test transaction";
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- doReturn(txChain).when(broker).createTransactionChain(any(TransactionChainListener.class));
- doReturn(writeTx).when(txChain).newWriteOnlyTransaction();
- doNothing().when(writeTx).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
- doNothing().when(writeTx).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
-
- doReturn(txIdent).when(writeTx).getIdentifier();
- }
-
- @Test
- public void testFailedDevice() throws Exception {
- doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
-
- NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
- adapter.setDeviceAsFailed(null);
-
- verify(txChain, times(2)).newWriteOnlyTransaction();
- verify(writeTx, times(3)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
- }
-
- @Test
- public void testDeviceUpdate() throws Exception {
- doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
-
- NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
- adapter.updateDeviceData(true, new NetconfDeviceCapabilities());
-
- verify(txChain, times(2)).newWriteOnlyTransaction();
- verify(writeTx, times(3)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atMost;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_FILTER_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public class NetconfDeviceWriteOnlyTxTest {
-
- private final RemoteDeviceId id = new RemoteDeviceId("test-mount", new InetSocketAddress(99));
-
- @Mock
- private DOMRpcService rpc;
- private YangInstanceIdentifier yangIId;
-
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
-
- final CheckedFuture<DefaultDOMRpcResult, Exception> successFuture =
- Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null)));
-
- doReturn(successFuture)
- .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("Failed tx")))
- .doReturn(successFuture)
- .when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- yangIId = YangInstanceIdentifier.builder().node(NetconfState.QNAME).build();
- }
-
- @Test
- public void testIgnoreNonVisibleData() {
- final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
- false, 60000L);
- final MapNode emptyList = ImmutableNodes.mapNodeBuilder(NETCONF_FILTER_QNAME).build();
- tx.merge(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
- tx.put(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(NETCONF_FILTER_QNAME)), emptyList);
-
- verify(rpc, atMost(1)).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
- }
-
- @Test
- public void testDiscardChanges() {
- final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
- false, 60000L);
- final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
- try {
- submitFuture.checkedGet();
- } catch (final TransactionCommitFailedException e) {
- // verify discard changes was sent
- final InOrder inOrder = inOrder(rpc);
- inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), NetconfBaseOps.getLockContent(NETCONF_CANDIDATE_QNAME));
- inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME), NetconfMessageTransformUtil.COMMIT_RPC_CONTENT);
- inOrder.verify(rpc).invokeRpc(eq(toPath(NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME)), any(NormalizedNode.class));
- inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME), NetconfBaseOps.getUnLockContent(NETCONF_CANDIDATE_QNAME));
- return;
- }
-
- fail("Submit should fail");
- }
-
- @Test
- public void testFailedCommit() throws Exception {
- final CheckedFuture<DefaultDOMRpcResult, Exception> rpcErrorFuture =
- Futures.immediateCheckedFuture(new DefaultDOMRpcResult(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, "a", "m")));
-
- doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))
- .doReturn(rpcErrorFuture).when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- final WriteCandidateTx tx = new WriteCandidateTx(id, new NetconfBaseOps(rpc, mock(SchemaContext.class)),
- false, 60000L);
-
- final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = tx.submit();
- try {
- submitFuture.checkedGet();
- } catch (final TransactionCommitFailedException e) {
- return;
- }
-
- fail("Submit should fail");
- }
-
- @Test
- public void testDiscardChangesNotSentWithoutCandidate() {
- doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(((NormalizedNode<?, ?>) null))))
- .doReturn(Futures.immediateFailedCheckedFuture(new IllegalStateException("Failed tx")))
- .when(rpc).invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
-
- final WriteRunningTx tx = new WriteRunningTx(id, new NetconfBaseOps(rpc, NetconfDevice.INIT_SCHEMA_CTX),
- false, 60000L);
- try {
- tx.delete(LogicalDatastoreType.CONFIGURATION, yangIId);
- } catch (final Exception e) {
- // verify discard changes was sent
- final InOrder inOrder = inOrder(rpc);
- inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_LOCK_QNAME), NetconfBaseOps.getLockContent(NETCONF_RUNNING_QNAME));
- inOrder.verify(rpc).invokeRpc(eq(toPath(NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME)), any(NormalizedNode.class));
- inOrder.verify(rpc).invokeRpc(toPath(NetconfMessageTransformUtil.NETCONF_UNLOCK_QNAME), NetconfBaseOps.getUnLockContent(NETCONF_RUNNING_QNAME));
- return;
- }
-
- fail("Delete should fail");
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.sal.tx;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import com.google.common.util.concurrent.Futures;
-import java.net.InetSocketAddress;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-public class ReadOnlyTxTest {
-
- private static final YangInstanceIdentifier path = YangInstanceIdentifier.create();
-
- @Mock
- private DOMRpcService rpc;
- @Mock
- private NormalizedNode<?, ?> mockedNode;
-
- @Before
- public void setUp() throws DataNormalizationException {
- MockitoAnnotations.initMocks(this);
- doReturn(Futures.immediateCheckedFuture(new DefaultDOMRpcResult(mockedNode))).when(rpc)
- .invokeRpc(any(SchemaPath.class), any(NormalizedNode.class));
- doReturn("node").when(mockedNode).toString();
- }
-
- @Test
- public void testRead() throws Exception {
- final NetconfBaseOps netconfOps = new NetconfBaseOps(rpc, mock(SchemaContext.class));
-
- final ReadOnlyTx readOnlyTx = new ReadOnlyTx(netconfOps, new RemoteDeviceId("a", new InetSocketAddress("localhost", 196)));
-
- readOnlyTx.read(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.create());
- verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME)), any(NormalizedNode.class));
- readOnlyTx.read(LogicalDatastoreType.OPERATIONAL, path);
- verify(rpc).invokeRpc(Mockito.eq(NetconfMessageTransformUtil.toPath(NetconfMessageTransformUtil.NETCONF_GET_QNAME)), any(NormalizedNode.class));
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connect.netconf.schema.mapping;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.GET_SCHEMA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DATA_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DISCARD_CHANGES_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_CONFIG_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_GET_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_LOCK_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_RUNNING_QNAME;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.createEditConfigStructure;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toFilterStructure;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toId;
-import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import javax.xml.transform.dom.DOMSource;
-import org.custommonkey.xmlunit.Diff;
-import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.hamcrest.CoreMatchers;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.controller.sal.connect.netconf.schema.NetconfRemoteSchemaYangSourceProvider;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfBaseOps;
-import org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.$YangModuleInfoImpl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.ModifyAction;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-public class NetconfMessageTransformerTest {
-
- private NetconfMessageTransformer netconfMessageTransformer;
- private SchemaContext schema;
-
- @Before
- public void setUp() throws Exception {
- XMLUnit.setIgnoreWhitespace(true);
- XMLUnit.setIgnoreAttributeOrder(true);
- XMLUnit.setIgnoreComments(true);
-
- schema = getSchema(true);
- netconfMessageTransformer = getTransformer(schema);
-
- }
-
- @Test
- public void testLockRequestBaseSchemaNotPresent() throws Exception {
- final SchemaContext partialSchema = getSchema(false);
- final NetconfMessageTransformer transformer = getTransformer(partialSchema);
- final NetconfMessage netconfMessage = transformer.toRpcRequest(toPath(NETCONF_LOCK_QNAME),
- NetconfBaseOps.getLockContent(NETCONF_CANDIDATE_QNAME));
-
- assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<lock"));
- assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<rpc"));
- }
-
- @Test
- public void tesLockSchemaRequest() throws Exception {
- final SchemaContext partialSchema = getSchema(false);
- final NetconfMessageTransformer transformer = getTransformer(partialSchema);
- final String result = "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>";
-
- transformer.toRpcResult(new NetconfMessage(XmlUtil.readXmlToDocument(result)), toPath(NETCONF_LOCK_QNAME));
- }
-
- @Test
- public void testDiscardChangesRequest() throws Exception {
- final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_DISCARD_CHANGES_QNAME), null);
- assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<discard"));
- assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("<rpc"));
- assertThat(XmlUtil.toString(netconfMessage.getDocument()), CoreMatchers.containsString("message-id"));
- }
-
- @Test
- public void tesGetSchemaRequest() throws Exception {
- final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(GET_SCHEMA_QNAME),
- NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")));
- assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<format>yang</format>\n" +
- "<identifier>module</identifier>\n" +
- "<version>2012-12-12</version>\n" +
- "</get-schema>\n" +
- "</rpc>");
- }
-
- @Test
- public void tesGetSchemaResponse() throws Exception {
- final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true));
- final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
- "<rpc-reply message-id=\"101\"\n" +
- "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<data\n" +
- "xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" +
- "Random YANG SCHEMA\n" +
- "</xs:schema>\n" +
- "</data>\n" +
- "</rpc-reply>"
- ));
- final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(GET_SCHEMA_QNAME));
- assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
- assertNotNull(compositeNodeRpcResult.getResult());
- final DOMSource schemaContent = ((AnyXmlNode) ((ContainerNode) compositeNodeRpcResult.getResult()).getValue().iterator().next()).getValue();
- assertThat(((Element) schemaContent.getNode()).getTextContent(), CoreMatchers.containsString("Random YANG SCHEMA"));
- }
-
- @Test
- public void testGetConfigResponse() throws Exception {
- final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc-reply message-id=\"101\"\n" +
- "xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<data>\n" +
- "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<schemas>\n" +
- "<schema>\n" +
- "<identifier>module</identifier>\n" +
- "<version>2012-12-12</version>\n" +
- "<format xmlns:x=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">x:yang</format>\n" +
- "</schema>\n" +
- "</schemas>\n" +
- "</netconf-state>\n" +
- "</data>\n" +
- "</rpc-reply>"));
-
- final NetconfMessageTransformer netconfMessageTransformer = getTransformer(getSchema(true));
- final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(NETCONF_GET_CONFIG_QNAME));
- assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
- assertNotNull(compositeNodeRpcResult.getResult());
-
- final List<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> values = Lists.newArrayList(
- NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue());
-
- final Map<QName, Object> keys = Maps.newHashMap();
- for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> value : values) {
- keys.put(value.getNodeType(), value.getValue());
- }
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates identifierWithPredicates = new YangInstanceIdentifier.NodeIdentifierWithPredicates(Schema.QNAME, keys);
- final MapEntryNode schemaNode = Builders.mapEntryBuilder().withNodeIdentifier(identifierWithPredicates).withValue(values).build();
-
- final ContainerNode data = (ContainerNode) ((ContainerNode) compositeNodeRpcResult.getResult()).getChild(toId(NETCONF_DATA_QNAME)).get();
- final ContainerNode state = (ContainerNode) data.getChild(toId(NetconfState.QNAME)).get();
- final ContainerNode schemas = (ContainerNode) state.getChild(toId(Schemas.QNAME)).get();
- final MapNode schemaParent = (MapNode) schemas.getChild(toId(Schema.QNAME)).get();
- assertEquals(1, Iterables.size(schemaParent.getValue()));
-
- assertEquals(schemaNode, schemaParent.getValue().iterator().next());
- }
-
- @Test
- public void testGetConfigRequest() throws Exception {
- final DataContainerChild<?, ?> filter = toFilterStructure(
- YangInstanceIdentifier.create(toId(NetconfState.QNAME), toId(Schemas.QNAME)), schema);
-
- final DataContainerChild<?, ?> source = NetconfBaseOps.getSourceNode(NETCONF_RUNNING_QNAME);
-
- final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_GET_CONFIG_QNAME),
- NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, source, filter));
-
- assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<get-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n" +
- "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<schemas/>\n" +
- "</netconf-state>" +
- "</filter>\n" +
- "<source>\n" +
- "<running/>\n" +
- "</source>\n" +
- "</get-config>" +
- "</rpc>");
- }
-
- @Test
- public void testEditConfigRequest() throws Exception {
- final List<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> values = Lists.newArrayList(
- NetconfRemoteSchemaYangSourceProvider.createGetSchemaRequest("module", Optional.of("2012-12-12")).getValue());
-
- final Map<QName, Object> keys = Maps.newHashMap();
- for (final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> value : values) {
- keys.put(value.getNodeType(), value.getValue());
- }
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates identifierWithPredicates = new YangInstanceIdentifier.NodeIdentifierWithPredicates(Schema.QNAME, keys);
- final MapEntryNode schemaNode = Builders.mapEntryBuilder().withNodeIdentifier(identifierWithPredicates).withValue(values).build();
-
- final YangInstanceIdentifier id = YangInstanceIdentifier.builder().node(NetconfState.QNAME).node(Schemas.QNAME).node(Schema.QNAME).nodeWithKey(Schema.QNAME, keys).build();
- final DataContainerChild<?, ?> editConfigStructure = createEditConfigStructure(NetconfDevice.INIT_SCHEMA_CTX, id, Optional.<ModifyAction>absent(), Optional.<NormalizedNode<?, ?>>fromNullable(schemaNode));
-
- final DataContainerChild<?, ?> target = NetconfBaseOps.getTargetNode(NETCONF_CANDIDATE_QNAME);
-
- final ContainerNode wrap = NetconfMessageTransformUtil.wrap(NETCONF_EDIT_CONFIG_QNAME, editConfigStructure, target);
- final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_EDIT_CONFIG_QNAME), wrap);
-
- assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<edit-config>\n" +
- "<target>\n" +
- "<candidate/>\n" +
- "</target>\n" +
- "<config>\n" +
- "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<schemas>\n" +
- "<schema>\n" +
- "<identifier>module</identifier>\n" +
- "<version>2012-12-12</version>\n" +
- "<format>yang</format>\n" +
- "</schema>\n" +
- "</schemas>\n" +
- "</netconf-state>\n" +
- "</config>\n" +
- "</edit-config>\n" +
- "</rpc>");
- }
-
- private void assertSimilarXml(final NetconfMessage netconfMessage, final String xmlContent) throws SAXException, IOException {
- final Diff diff = XMLUnit.compareXML(netconfMessage.getDocument(), XmlUtil.readXmlToDocument(xmlContent));
- diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
- assertTrue(diff.toString(), diff.similar());
- }
-
- @Test
- public void testGetRequest() throws Exception {
-
- final QName capability = QName.create(Capabilities.QNAME, "capability");
- final DataContainerChild<?, ?> filter = toFilterStructure(
- YangInstanceIdentifier.create(toId(NetconfState.QNAME), toId(Capabilities.QNAME), toId(capability), new YangInstanceIdentifier.NodeWithValue(capability, "a:b:c")), schema);
-
- final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_GET_QNAME),
- NetconfMessageTransformUtil.wrap(NETCONF_GET_QNAME, filter));
-
- assertSimilarXml(netconfMessage, "<rpc message-id=\"m-0\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">" +
- "<get xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- "<filter xmlns:ns0=\"urn:ietf:params:xml:ns:netconf:base:1.0\" ns0:type=\"subtree\">\n" +
- "<netconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
- "<capabilities>\n" +
- "<capability>a:b:c</capability>\n" +
- "</capabilities>\n" +
- "</netconf-state>" +
- "</filter>\n" +
- "</get>" +
- "</rpc>");
- }
-
- private NetconfMessageTransformer getTransformer(final SchemaContext schema) {
- return new NetconfMessageTransformer(schema, true);
- }
-
- @Test
- public void testCommitResponse() throws Exception {
- final NetconfMessage response = new NetconfMessage(XmlUtil.readXmlToDocument(
- "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><ok/></rpc-reply>"
- ));
- final DOMRpcResult compositeNodeRpcResult = netconfMessageTransformer.toRpcResult(response, toPath(NETCONF_COMMIT_QNAME));
- assertTrue(compositeNodeRpcResult.getErrors().isEmpty());
- assertNull(compositeNodeRpcResult.getResult());
- }
-
- public SchemaContext getSchema(boolean addBase) {
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- if(addBase) {
- moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance()));
- }
- moduleInfoBackedContext.addModuleInfos(Collections.singleton(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.$YangModuleInfoImpl.getInstance()));
- return moduleInfoBackedContext.tryToCreateSchemaContext().get();
- }
-}
+++ /dev/null
-<ncm:schemas xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadpool</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-04-09</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:logback:config</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>config-logging</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-07-16</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:model:statistics:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-statistics-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-25</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-config-dom-datastore</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-06-17</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:table:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-flow-table-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-15</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:meter:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-meter</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>toaster-provider-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-01-31</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:table:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-table-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-26</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:table:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-table</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-26</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>shutdown</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:port:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-port</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-07</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>netty-event-executor</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-12</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-remote</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-01-14</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:model:topology:view</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-topology-view</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-30</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadgroup</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-07</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>network-topology</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-07-12</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:fixed</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadpool-impl-fixed</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-01</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-sal-binding-broker-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-restconf</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-restconf</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:node:error:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>node-error</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-04-10</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:errors</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>flow-errors</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-16</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-flow</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:rpc-context</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>rpc-context</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-06-17</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store
- </ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-operational-dom-datastore</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-06-17</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:types:queue</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-queue-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-25</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-netconf-monitoring</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2010-10-04</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:netconf-node-inventory</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>netconf-node-inventory</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-01-08</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-yang-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-07-15</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:meter:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-meter-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-11</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:inventory</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>flow-node-inventory</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>odl-sal-netconf-connector-cfg</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:scheduled</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadpool-impl-scheduled</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-01</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:TBD:params:xml:ns:yang:network-topology</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>network-topology</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-21</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>http://netconfcentral.org/ns/toaster</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>toaster</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2009-11-20</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>odl-netconf-cfg</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-04-08</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:meter:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-meter-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-sal-dom-broker-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:topology:discovery</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>flow-topology-discovery</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:yang:extension:yang-ext</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>yang-ext</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-07-09</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadpool-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-04-05</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:types:port</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-port-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-25</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-md-sal-binding</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:packet:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>packet-processing</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-07-09</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>threadpool-impl-flexible</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-01</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:queue:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-queue</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-07</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-inet-types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-inet-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2010-09-24</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:rest:connector</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-rest-connector</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-07-24</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:transaction</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>flow-capable-transaction</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-03</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-flow-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:protocol:framework</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>protocol-framework</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-03-13</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:model:match:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-match-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-26</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-yang-types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-yang-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2010-09-24</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:group:service</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>sal-group</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-09-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-inmemory-datastore-provider</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-06-17</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty:timer</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>netty-timer</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:group:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-group-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-11</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>config</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-04-05</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>odl-netconfig-client-cfg</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-04-08</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:l2:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-l2-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-27</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:action:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-action-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-12</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-md-sal-dom</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-md-sal-common</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-28</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:group:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-group-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>ietf-netconf-monitoring-extension</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-10</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:inventory</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-inventory</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-08-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:netty</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>netty</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-11-19</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:model:topology:general</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-topology</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-30</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:port:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-port-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version></ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:queue:statistics</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-queue-statistics</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-16</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:config:kitchen-service:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>kitchen-service-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2014-01-31</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:flow:types</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-flow-types</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-26</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>shutdown-impl</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-12-18</ncm:version>
- </ncm:schema>
- <ncm:schema>
- <ncm:namespace>urn:opendaylight:model:topology:inventory</ncm:namespace>
- <ncm:location>NETCONF</ncm:location>
- <ncm:identifier>opendaylight-topology-inventory</ncm:identifier>
- <ncm:format xmlns:prefix="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">prefix:yang</ncm:format>
- <ncm:version>2013-10-30</ncm:version>
- </ncm:schema>
-</ncm:schemas>
\ No newline at end of file
+++ /dev/null
-<notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
-<eventTime>2007-07-08T00:01:00Z</eventTime>
-<user-visited-page xmlns="org:opendaylight:notification:test:ns:yang:user-notification">
- <ui:incoming-user xmlns:ui="org:opendaylight:notification:test:ns:yang:user-notification">ui:public-user</ui:incoming-user>
- <ip-address>172.23.29.104</ip-address>
- <mac>00:11:00:ff:dd:02</mac>
- <browser-id>Chrome 35.0.1916.153 m</browser-id>
- <region>
- <name>Slovakia</name>
- <time-zone>UTC/GMT+2</time-zone>
- </region>
- <visiting-date>2014-07-08 11:20:48</visiting-date>
-</user-visited-page>
-</notification>
\ No newline at end of file
+++ /dev/null
-module config-test-rpc {
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:test:rpc:config:defs";
- prefix "rpc";
-
- organization
- "Cisco Systems, Inc.";
-
- contact
- "lsedlak@cisco.com";
-
- description "Test model containing hacked definition of rpc edit-config and definitions for
- get and get-config rpc operations.
- The rpc definition is copied from rfc 6241 Appendix C: http://tools.ietf.org/html/rfc6241#appendix-C";
-
- revision 2014-07-21 {
- description "Initial revision.";
- }
-
- extension get-filter-element-attributes {
- description
- "If this extension is present within an 'anyxml'
- statement named 'filter', which must be conceptually
- defined within the RPC input section for the <get>
- and <get-config> protocol operations, then the
- following unqualified XML attribute is supported
- within the <filter> element, within a <get> or
- <get-config> protocol operation:
-
- type : optional attribute with allowed
- value strings 'subtree' and 'xpath'.
- If missing, the default value is 'subtree'.
-
- If the 'xpath' feature is supported, then the
- following unqualified XML attribute is
- also supported:
-
- select: optional attribute containing a
- string representing an XPath expression.
- The 'type' attribute must be equal to 'xpath'
- if this attribute is present.";
- }
-
- rpc edit-config {
- description "The <edit-config> operation loads all or part of a specified
- configuration to the specified target configuration.";
-
- reference "RFC 6241, Section 7.2";
-
- input {
- container target {
- description "Particular configuration to edit.";
-
- choice config-target {
- mandatory true;
- description "The configuration target.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description "The candidate configuration is the config target.";
- }
-
- leaf running {
- if-feature writable-running;
- type empty;
- description "The running configuration is the config source.";
- }
- }
- }
-
- choice edit-content {
- mandatory true;
- description "The content for the edit operation.";
-
- anyxml config {
- description
- "Inline Config content.";
- }
-
- leaf url {
- if-feature url;
- type string;
- description
- "URL-based config content.";
- }
- }
- }
- }
-
- rpc get-config {
- description
- "Retrieve all or part of a specified configuration.";
-
- reference "RFC 6241, Section 7.1";
-
- input {
- container source {
- description "Particular configuration to retrieve.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration to retrieve.";
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.
- This is optional-to-implement on the server because
- not all servers will support filtering for this
- datastore.";
- }
- }
- }
-
- anyxml filter {
- description "Subtree or XPath filter to use.";
- get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the source datastore subset that matched
- the filter criteria (if any). An empty data container
- indicates that the request did not produce any results.";
- }
- }
- }
-
- rpc get {
- description "Retrieve running configuration and device state information.";
-
- reference "RFC 6241, Section 7.7";
-
- input {
- anyxml filter {
- description
- "This parameter specifies the portion of the system
- configuration and state data to retrieve.";
- get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the running datastore subset and/or state
- data that matched the filter criteria (if any).
- An empty data container indicates that the request did not
- produce any results.";
- }
- }
- }
-
- rpc discard-changes {
- if-feature candidate;
-
- description
- "Revert the candidate configuration to the current
- running configuration.";
- reference "RFC 6241, Section 8.3.4.2";
- }
-}
+++ /dev/null
-module rpc-notification-subscription {
-
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:rpc-test";
- prefix "rpc";
-
- organization
- "Cisco Systems, Inc.";
-
- contact
- "lsedlak@cisco.com";
-
- description
- "Test model for testing of rpc INPUT parameter during subscription call.";
-
- revision 2014-07-14 {
- description
- "Initial revision.";
- }
-
- rpc subscribe {
- description
- "Test rpc to init subscription";
-
- input {
- leaf stream-name {
- type string;
- default "NETCONF";
- description
- "Optional stream name param.";
- }
-
- anyxml data {
- description
- "Optional additional data.";
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module test-module {
- yang-version 1;
- namespace "test:namespace";
- prefix "tt";
-
- description
- "Types for testing";
-
- revision "2013-07-22";
-
-
- container c {
- leaf a {
- type string;
- }
- }
-
-}
+++ /dev/null
-module user-notification {
- yang-version 1;
- namespace "org:opendaylight:notification:test:ns:yang:user-notification";
- prefix "user";
-
- organization "Cisco Systems";
- contact "Lukas Sedlak";
- description "Test model for testing notifications";
-
- revision "2014-07-08" {
- description "Initial revision";
- }
-
- identity user-identity {
- description "Identity of user incoming to Web Page";
- }
-
- identity public-user {
- base user-identity;
- description "Identity of random public non-registered user";
- }
-
- notification user-visited-page {
- leaf incoming-user {
- type identityref {
- base "user-identity";
- }
- }
-
- leaf ip-address {
- type string;
- }
-
- leaf mac {
- type string;
- }
-
- leaf browser-id {
- type string;
- }
-
- container region {
- leaf name {
- type string;
- }
-
- leaf time-zone {
- type string;
- }
- }
-
- leaf visiting-date {
- type string;
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-*.log
-cache
+++ /dev/null
-usage:
-Submit address + port for initial TCP connection (PURE TCP CONNECTIONS ARE NOT SUPPORTED YET)
-Submit username + password in addition to address + port for initial SSH connection
-If no arguments(or unexpected combination) is submitted, cli will be started without initial connection
-To use with ODL controller, run with: java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --server localhost --port 1830 --username admin --password admin
-
-Generic cli for netconf devices
-
-optional arguments:
- -h, --help show this help message and exit
-
-TCP:
- Base arguments to initiate TCP connection right away
-
- --server SERVER Netconf device ip-address/domain name
- --port PORT Netconf device port
-
-SSH:
- SSH credentials, if provided, initial connection will be attempted using SSH
-
- --username USERNAME Username for SSH connection
- --password PASSWORD Password for SSH connection
-------------------------------------------------------------------------
-
-To run the cli execute:
-
-java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --username user --password password --server serverIP --port optionalPort
-
-The cli will connect to the remote device automatically.
-The initialization may take a few moments depending on the size of schemas provided by the device.
-To view the progress, one can take a look inside netconfcli.log file (All logs are in this file starting with level TRACE).
-Cli does not print any logging messages to the console, only to the file.
-
-------------------------------------------------------------------------
-
-Correct initialization + connection should display following output:
-
-[maros@localhost target]$ java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --server localhost --port 1830 --username admin --password admin
-Connecting to localhost via SSH. Please wait.
-Cli is up, available commands:
-
-add-flow(sal-flow) add-group(sal-group)
-add-meter(sal-meter) begin-transaction(sal-remote)
-cancel-commit(ietf-netconf) cancel-toast(toaster)
-clear-toasts-made(toaster-provider-impl) close(netconf-cli)
-close-session(ietf-netconf) commit(ietf-netconf)
-connect(netconf-cli) copy-config(ietf-netconf)
-create-data-change-event-subscription(sal-remote) create-notification-stream(sal-remote)
-delete-config(ietf-netconf) discard-changes(ietf-netconf)
-disconnect(netconf-cli) edit-config(ietf-netconf)
-finish-transaction(flow-capable-transaction) get(ietf-netconf)
-get-aggregate-flow-statistics-from-flow-table-for-all-flows(opendaylight-flow-statistics) get-aggregate-flow-statistics-from-flow-table-for-given-match(opendaylight-flow-statistics)
-get-all-flow-statistics-from-flow-table(opendaylight-flow-statistics) get-all-flows-statistics-from-all-flow-tables(opendaylight-flow-statistics)
-get-all-group-statistics(opendaylight-group-statistics) get-all-meter-config-statistics(opendaylight-meter-statistics)
-get-all-meter-statistics(opendaylight-meter-statistics) get-all-node-connectors-statistics(opendaylight-port-statistics)
-get-all-queues-statistics-from-all-ports(opendaylight-queue-statistics) get-all-queues-statistics-from-given-port(opendaylight-queue-statistics)
-get-config(ietf-netconf) get-dead-events-count(threadpool-impl)
-get-flow-statistics-from-flow-table(opendaylight-flow-statistics) get-flow-tables-statistics(opendaylight-flow-table-statistics)
-get-group-description(opendaylight-group-statistics) get-group-features(opendaylight-group-statistics)
-get-group-statistics(opendaylight-group-statistics) get-meter-features(opendaylight-meter-statistics)
-get-meter-statistics(opendaylight-meter-statistics) get-next-transaction-id(flow-capable-transaction)
-get-node-connector-statistics(opendaylight-port-statistics) get-queue(sal-queue)
-get-queue-statistics-from-given-port(opendaylight-queue-statistics) get-schema(ietf-netconf-monitoring)
-help(netconf-cli) kill-session(ietf-netconf)
-lock(ietf-netconf) make-scrambled-with-wheat(kitchen-service-impl)
-make-toast(toaster) remove-flow(sal-flow)
-remove-group(sal-group) remove-meter(sal-meter)
-reset(config-logging) restock-toaster(toaster)
-shutdown(shutdown-impl) solicit-refresh(flow-topology-discovery)
-transmit-packet(packet-processing) unlock(ietf-netconf)
-update-flow(sal-flow) update-group(sal-group)
-update-meter(sal-meter) update-port(sal-port)
-update-table(sal-table) validate(ietf-netconf)
-
-netconf()>
-
-
-------------------------------------------------------------------------
-
-At this stage, any supported rpc can be invoked. To see all possible rpcs press TAB (serves as autocomplete). The output contains all the commands reported after at start-up
-
-------------------------------------------------------------------------
-
-Example step-by-step execution of get-config rpc:
-
-1. Type get-config, hit TAB, hit enter
-2. Cli will now walk all the input arguments of get-config rpc and ask for value
-3. Cli asks for filter value
-4. Submit filter (using TAB autocomplete) as a schema path or type "skip" (to not add any filter) and hit enter
-5. Cli asks for config source (e.g. which data-store to query)
-6. Use TAB to view options and submit either running or candidate data-store
-7. Cli will display configuration of the remote device e.g. :
-
-data {
- a {
- address {
- last-name a
- first-name o
- street aaaaa
- }
- address {
- last-name a
- first-name t
- }
- address {
- last-name a
- first-name y
- }
- }
-}
-
-
-------------------------------------------------------------------------
+++ /dev/null
-This file contains ODL controller specific examples:
-
-1A. Connecting to ODL controller automatically:
- a. Make sure ODL controller is running on your or any other accessible device
- b. Start the cli using this command (in folder controller/opendaylight/netconf/netconf-cli/target/):
- java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --server localhost --port 1830 --username admin --password admin
- c. The cli will start up in aprox. 20 seconds (Schema download might take some time on the first connection, subsequent attempts should take less time)
- d. You should see the list of commands avaliable in the controller e.g.:
- add-flow(sal-flow) add-group(sal-group)
- add-meter(sal-meter) begin-transaction(sal-remote)
- cancel-commit(ietf-netconf) cancel-toast(toaster)
- clear-toasts-made(toaster-provider-impl) close(netconf-cli)
- close-session(ietf-netconf) commit(ietf-netconf)
- connect(netconf-cli) copy-config(ietf-netconf)
- create-data-change-event-subscription(sal-remote) ....
-
-
-1B. Connecting to ODL from the CLI:
- a. Make sure ODL controller is running on your or any other accessible device
- b. Start the cli using this command (in folder controller/opendaylight/netconf/netconf-cli/target/):
- java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar
- c. The cli will start app right away (few seconds)
- d. You should see only the basic commands e.g. connect, close, help, disconnect
- e. Type connect, hit TAB, hit ENTER
- f. Cli will ask for connect arguments: [address-name, address-port, user-name, user-password]
- g. Address-name
- The cli will ask what type of address you want to provide (domain-name or ip-address). This is caused by the yang model for connect command, the address-name is of type ietf-inet-types:host, which is a union of domain-name and ip-address.
- Submit "domain-name" (TAB can be used for autocompete)
- Now you need to provide value, submit "localhost" (TAB can be used for autocomplete, as "localhost" is the default value)
- h. Address-port
- Submit 1830 (default port for netconf SSH server in ODL)
- i. User-name
- Submit "admin"
- j. User-password
- Submit "admin"
- k. The connection will be up in aprox. 20 seconds (Schema download might take some time on the first connection, subsequent attempts should take less time)
- l. You should see the list of commands available in the controller
-
-
-2. Disconnecting from ODL in the CLI
- a. Execute scenario 1A or 1B
- b. Type "disconn", hit TAB, hit Enter
- c. You should see the following output:
- status Connection disconnected
- d. Use TAB to see available commands, only local commands are present now
- e. Now you can use the connect command(as in 1B) to connect again
-
-
-3. Using help command
- a. Help command can be executed in connected as well as disconnected state
- b. Type "help", hit TAB, hit Enter
- c. You should see the help conent containing the list of all available commands with description for each of them e.g.
- commands {
- commands [id=close(netconf-cli)] {
- id close(netconf-cli)
- description Close the whole cli
- }
- commands [id=help(netconf-cli)] {
- id help(netconf-cli)
- description Display help
- }
- commands [id=disconnect(netconf-cli)] {
- id disconnect(netconf-cli)
- description Disconnect from a netconf device that is currently connected
- }
- commands [id=connect(netconf-cli)] {
- id connect(netconf-cli)
- description Connect to a remote netconf device, if not connected yet. Connection initialization is blocking and might take some time, depending on amount of yang schemas in remote device.
- }
- }
-
-
-4. Executing get-config command (get-config(ietf-netconf))
- a. Execute scenario 1A or 1B
- b. Type "get-config", hit TAB, hit Enter
- c. Cli will ask for get-config arguments: [filter, source]
- d. Filter
- Submit "skip" (This will ignore the filter attribute, ODL does not support filtering at this moment, but will be supported in near future)
- e. Source
- You have to choose from candidate, running, startup. Submit running.
- f. You should see the whole configuration of the ODL e.g.:
- data {
- modules {
- module {
- module [name=toaster-provider-impl] {
- name toaster-provider-impl
- type (urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl?revision=2014-01-31)toaster-provider-impl
- choice configuration (toaster-provider-impl) {
- ...
-
-
-5. Executing get command (get(ietf-netconf))
- a. Execute scenario 1A or 1B
- b. Type "get(", hit TAB, hit Enter
- c. Cli will ask for get arguments: [filter]
- d. Filter
- Submit "skip" (This will ignore the filter attribute, ODL does not support filtering at this moment, but will be supported in near future)
- f. You should see the whole data-tree of the ODL
-
-
-6. Executing edit-config command (edit-config(ietf-netconf))
- a. Execute scenario 1A or 1B
- b. Type "edit", hit TAB, hit Enter
- c. Cli will ask for edit-config arguments: [default-operation, edit-content, error-option, target, test-option]
- d. Config
- Config contains the data to be edited
- 1. First you have to specify a path pointing to a concrete data node. Use TAB to help with autocomplete.
- Submit "modules(config)/module(config)/"
- Module node is of type list and now you have to construct a whole new list entry for the module list.
- 2. The cli will ask for these nodes: [configuration, name, type]
- Name - Submit any name e.g. newModule
- Type - For Type you have to pick from available module types in the ODL, hit TAB for hints
- Submit "threadfactory-naming(threadpool-impl)" to create a new instance of threadfactory in the ODL.
- Configuration - For configuration you have to pick from available module types again
- Submit "threadfactory-naming" to match previous module type
- The cli will now ask for threadfactory-naming specific configuration: [prefix]
- Prefix - Submit any string
-
- The cli will now if you want to create another module entry.
- Submit "N".
- e. Default-operation
- Submit "skip" to skip or pick from available e.g. merge, replace etc.
- f. Error-option
- Submit "skip" to skip option.
- g. Config-target
- This is a choice between running and candidate. Submit candidate to edit configuration only in the candidate datastore.
- h. Test-option
- Submit "skip" to skip option.
- i. You should see OK response
- j. You can check the candidate datastore change by executing get-config command as in scenario 4, but pick candidate as the source.
- k. You should see this module in the output:
- module [name=newModule] {
- name newModule
- type (urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?revision=2013-04-05)threadfactory-naming
- choice configuration (threadfactory-naming) {
- name-prefix prefix
- }
- }
-
-
-7. Commiting changes from candidate to running datastore
- a. Execute scenario 6.
- b. Type commit, hit TAB, hit Enter
- c. Cli will ask for commit arguments: [confirm-timeout, confirmed, persist, persist-id]. We will skip all these arguments since they are not supported in ODL. Cli should be able to detect this and not ask for them. This is a TODO, by supporting feature/if-feature detection in the CLI.
- d. Confirm-timeout
- Skip
- e. Confirmed
- N
- f. Persist
- Skip
- g. Persist-id
- Skip
- h. You should see OK response
- i. You can check the candidate datastore change by executing get-config command as in scenario 4.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!-- Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-tools</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
- <artifactId>netconf-cli</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <!--TODO configure properly -->
- </dependency>
- <dependency>
- <groupId>jline</groupId>
- <artifactId>jline</artifactId>
- <version>2.11</version>
- </dependency>
- <dependency>
- <groupId>net.sourceforge.argparse4j</groupId>
- <artifactId>argparse4j</artifactId>
- <version>0.4.3</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-model-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-parser-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.opendaylight.controller.netconf.cli.Main</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <configuration></configuration>
- <executions>
- <execution>
- <goals>
- <goal>shade</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.opendaylight.controller.netconf.cli.Main</mainClass>
- </transformer>
- </transformers>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>executable</shadedClassifierName>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import jline.console.UserInterruptException;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
-import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
-import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.controller.netconf.cli.writer.WriteException;
-import org.opendaylight.controller.netconf.cli.writer.Writer;
-import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-
-/**
- * The top level cli state that dispatches command executions
- */
-public class Cli implements Runnable {
- private final CommandDispatcher commandRegistry;
- private final CommandArgHandlerRegistry argumentHandlerRegistry;
- private final SchemaContextRegistry schemaContextRegistry;
- private final ConsoleIO consoleIO;
-
- public Cli(final ConsoleIO consoleIO, final CommandDispatcher commandRegistry,
- final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContextRegistry schemaContextRegistry) {
- this.consoleIO = consoleIO;
- this.commandRegistry = commandRegistry;
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- this.schemaContextRegistry = schemaContextRegistry;
- }
-
- @Override
- public void run() {
- try {
- consoleIO.writeLn("Cli is up, available commands:");
- final RootConsoleContext consoleContext = new RootConsoleContext(commandRegistry);
- consoleIO.enterContext(consoleContext);
- consoleIO.complete();
- consoleIO.writeLn("");
-
- while (true) {
- final String commandName = consoleIO.read();
- final Optional<Command> commandOpt = commandRegistry.getCommand(commandName);
-
- if (commandOpt.isPresent() == false) {
- continue;
- }
-
- final Command command = commandOpt.get();
- try {
- consoleIO.enterContext(command.getConsoleContext());
- final Output response = command.invoke(handleInput(command.getInputDefinition()));
- handleOutput(command, response);
- } catch (final CommandInvocationException e) {
- consoleIO.write(e.getMessage());
- } catch (final UserInterruptException e) {
- consoleIO.writeLn("Command " + command.getCommandId() + " was terminated.");
- } finally {
- consoleIO.leaveContext();
- }
-
- }
- } catch (final IOException e) {
- throw new RuntimeException("IO failure", e);
- }
- }
-
- private void handleOutput(final Command command, final Output response) {
- final OutputDefinition outputDefinition = command.getOutputDefinition();
-
- final Writer<DataSchemaNode> outHandler = argumentHandlerRegistry.getGenericWriter();
- if (outputDefinition.isEmpty()) {
- handleEmptyOutput(command, response);
- } else {
- handleRegularOutput(response, outputDefinition, outHandler);
- }
- }
-
- private void handleRegularOutput(final Output response, final OutputDefinition outputDefinition,
- final Writer<DataSchemaNode> outHandler) {
- final Map<DataSchemaNode, List<NormalizedNode<?, ?>>> unwrap = response.unwrap(outputDefinition);
-
- for (final DataSchemaNode schemaNode : unwrap.keySet()) {
- Preconditions.checkNotNull(schemaNode);
-
- try {
-
- // FIXME move custom writer to GenericWriter/Serializers ...
- // this checks only first level
- final Optional<Class<? extends Writer<DataSchemaNode>>> customReaderClassOpt = tryGetCustomHandler(schemaNode);
-
- if (customReaderClassOpt.isPresent()) {
- final Writer<DataSchemaNode> customReaderInstance = argumentHandlerRegistry
- .getCustomWriter(customReaderClassOpt.get());
- Preconditions.checkNotNull(customReaderInstance, "Unknown custom writer: %s",
- customReaderClassOpt.get());
- customReaderInstance.write(schemaNode, unwrap.get(schemaNode));
- } else {
- outHandler.write(schemaNode, unwrap.get(schemaNode));
- }
-
- } catch (final WriteException e) {
- throw new IllegalStateException("Unable to write value for: " + schemaNode.getQName() + " from: "
- + unwrap.get(schemaNode), e);
- }
- }
- }
-
- private void handleEmptyOutput(final Command command, final Output response) {
- try {
- new NormalizedNodeWriter(consoleIO, new OutFormatter()).write(null,
- Collections.<NormalizedNode<?, ?>>singletonList(response.getOutput()));
- } catch (final WriteException e) {
- throw new IllegalStateException("Unable to write value for: " + response.getOutput().getNodeType()
- + " from: " + command.getCommandId(), e);
- }
- }
-
- private Input handleInput(final InputDefinition inputDefinition) {
- List<NormalizedNode<?, ?>> allArgs = Collections.emptyList();
- try {
- if (!inputDefinition.isEmpty()) {
- allArgs = argumentHandlerRegistry.getGenericReader(schemaContextRegistry.getLocalSchemaContext()).read(
- inputDefinition.getInput());
- }
- } catch (final ReadingException e) {
- throw new IllegalStateException("Unable to read value for: " + inputDefinition.getInput().getQName(), e);
- }
-
- return new Input(allArgs);
- }
-
- // TODO move tryGet to GenericWriter, GenericReader has the same code
- private <T> Optional<Class<? extends T>> tryGetCustomHandler(final DataSchemaNode dataSchemaNode) {
-
- for (final UnknownSchemaNode unknownSchemaNode : dataSchemaNode.getUnknownSchemaNodes()) {
-
- if (isExtenstionForCustomHandler(unknownSchemaNode)) {
- final String argumentHandlerClassName = unknownSchemaNode.getNodeParameter();
- try {
- final Class<?> argumentClass = Class.forName(argumentHandlerClassName);
- // TODO add check before cast
- return Optional.<Class<? extends T>> of((Class<? extends T>) argumentClass);
- } catch (final ClassNotFoundException e) {
- throw new IllegalArgumentException("Unknown custom reader class " + argumentHandlerClassName
- + " for: " + dataSchemaNode.getQName());
- }
- }
- }
-
- return Optional.absent();
- }
-
- private boolean isExtenstionForCustomHandler(final UnknownSchemaNode unknownSchemaNode) {
- final QName qName = unknownSchemaNode.getExtensionDefinition().getQName();
- return qName.equals(CommandConstants.ARG_HANDLER_EXT_QNAME);
- }
-
- private static final class RootConsoleContext implements ConsoleContext {
-
- private final Completer completer;
-
- public RootConsoleContext(final CommandDispatcher commandRegistry) {
- completer = new CommandCompleter(commandRegistry);
- }
-
- @Override
- public Completer getCompleter() {
- return completer;
- }
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.absent();
- }
-
- private class CommandCompleter extends StringsCompleter {
-
- private final CommandDispatcher commandRegistry;
-
- public CommandCompleter(final CommandDispatcher commandRegistry) {
- this.commandRegistry = commandRegistry;
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- getStrings().clear();
- getStrings().addAll(commandRegistry.getCommandIds());
- return super.complete(buffer, cursor, candidates);
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.Reader;
-import org.opendaylight.controller.netconf.cli.reader.custom.ConfigReader;
-import org.opendaylight.controller.netconf.cli.reader.custom.EditContentReader;
-import org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
-import org.opendaylight.controller.netconf.cli.reader.custom.PasswordReader;
-import org.opendaylight.controller.netconf.cli.reader.impl.GenericReader;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.controller.netconf.cli.writer.Writer;
-import org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
-import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Keeps custom and generic input/output arguments handlers. Custom handlers are
- * constructed lazily, due to remote schema context acquisition.
- */
-public class CommandArgHandlerRegistry {
-
- private final ConsoleIO consoleIO;
- private final SchemaContextRegistry schemaContextRegistry;
-
- private final Map<Class<? extends Reader<? extends DataSchemaNode>>, ReaderProvider> customReaders = Maps
- .newHashMap();
- private final Map<Class<? extends Writer<DataSchemaNode>>, WriterProvider> customWriters = Maps.newHashMap();
-
- public CommandArgHandlerRegistry(final ConsoleIO consoleIO, final SchemaContextRegistry schemaContextRegistry) {
- this.consoleIO = consoleIO;
- this.schemaContextRegistry = schemaContextRegistry;
-
- setUpReaders();
- setUpWriters();
- }
-
- private void setUpWriters() {
- customWriters.put(DataWriter.class, new DataWriterProvider());
- }
-
- private void setUpReaders() {
- customReaders.put(PasswordReader.class, new PasswordReaderProvider());
- customReaders.put(FilterReader.class, new FilterReaderProvider());
- customReaders.put(ConfigReader.class, new ConfigReaderProvider());
- customReaders.put(EditContentReader.class, new EditContentReaderProvider());
- }
-
- public synchronized Reader<? extends DataSchemaNode> getCustomReader(
- final Class<? extends Reader<DataSchemaNode>> readerType) {
- return customReaders.get(readerType).provide(consoleIO, this, schemaContextRegistry);
- }
-
- private static SchemaContext getRemoteSchema(final Class<?> handlerType,
- final SchemaContextRegistry schemaContextRegistry) {
- final Optional<SchemaContext> remoteSchemaContext = schemaContextRegistry.getRemoteSchemaContext();
- Preconditions.checkState(remoteSchemaContext.isPresent(),
- "Remote schema context not acquired yet, cannot get handler %s", handlerType);
- return remoteSchemaContext.get();
- }
-
- public synchronized Reader<DataSchemaNode> getGenericReader(final SchemaContext schemaContext) {
- return new GenericReader(consoleIO, this, schemaContext);
- }
-
- public synchronized Reader<DataSchemaNode> getGenericReader(final SchemaContext schemaContext,
- final boolean readConfigNode) {
- return new GenericReader(consoleIO, this, schemaContext, readConfigNode);
- }
-
- public synchronized Writer<DataSchemaNode> getCustomWriter(final Class<? extends Writer<DataSchemaNode>> writerType) {
- return customWriters.get(writerType).provide(consoleIO, getRemoteSchema(writerType, schemaContextRegistry),
- this);
- }
-
- public synchronized Writer<DataSchemaNode> getGenericWriter() {
- return new NormalizedNodeWriter(consoleIO, new OutFormatter());
- }
-
- /**
- * Reader providers, in order to construct readers lazily
- */
- private static interface ReaderProvider {
- Reader<? extends DataSchemaNode> provide(ConsoleIO consoleIO,
- final CommandArgHandlerRegistry commandArgHandlerRegistry,
- final SchemaContextRegistry schemaContextRegistry);
- }
-
- private static final class FilterReaderProvider implements ReaderProvider {
- @Override
- public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
- final CommandArgHandlerRegistry commandArgHandlerRegistry,
- final SchemaContextRegistry schemaContextRegistry) {
- return new FilterReader(consoleIO, getRemoteSchema(FilterReader.class, schemaContextRegistry));
- }
- }
-
- private static final class ConfigReaderProvider implements ReaderProvider {
- @Override
- public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
- final CommandArgHandlerRegistry commandArgHandlerRegistry,
- final SchemaContextRegistry schemaContextRegistry) {
- return new ConfigReader(consoleIO, getRemoteSchema(ConfigReader.class, schemaContextRegistry),
- commandArgHandlerRegistry);
- }
- }
-
- private static final class EditContentReaderProvider implements ReaderProvider {
- @Override
- public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
- final CommandArgHandlerRegistry commandArgHandlerRegistry,
- final SchemaContextRegistry schemaContextRegistry) {
- return new EditContentReader(consoleIO, commandArgHandlerRegistry, getRemoteSchema(EditContentReader.class,
- schemaContextRegistry));
- }
- }
-
- private static final class PasswordReaderProvider implements ReaderProvider {
- @Override
- public Reader<? extends DataSchemaNode> provide(final ConsoleIO consoleIO,
- final CommandArgHandlerRegistry commandArgHandlerRegistry,
- final SchemaContextRegistry schemaContextRegistry) {
- return new PasswordReader(consoleIO, schemaContextRegistry.getLocalSchemaContext());
- }
- }
-
- /**
- * Writer providers, in order to construct readers lazily
- */
- private static interface WriterProvider {
- Writer<DataSchemaNode> provide(ConsoleIO consoleIO, SchemaContext schema,
- final CommandArgHandlerRegistry commandArgHandlerRegistry);
- }
-
- private class DataWriterProvider implements WriterProvider {
- @Override
- public Writer<DataSchemaNode> provide(final ConsoleIO consoleIO, final SchemaContext schema,
- final CommandArgHandlerRegistry commandArgHandlerRegistry) {
- return new DataWriter(consoleIO, new OutFormatter(), schema);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import static com.google.common.base.Throwables.getStackTraceAsString;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import net.sourceforge.argparse4j.ArgumentParsers;
-import net.sourceforge.argparse4j.inf.ArgumentGroup;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import net.sourceforge.argparse4j.inf.Namespace;
-import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
-import org.opendaylight.controller.netconf.cli.commands.local.Connect;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIOImpl;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Parse arguments, start remote device connection and start CLI after the
- * connection is fully up
- */
-public class Main {
-
- public static void main(final String[] args) {
- final CliArgumentParser cliArgs = new CliArgumentParser();
- try {
- cliArgs.parse(args);
- } catch (final ArgumentParserException e) {
- // Just end the cli, exception was handled by the CliArgumentParser
- return;
- }
-
- final ConsoleIO consoleIO;
- try {
- consoleIO = new ConsoleIOImpl();
- } catch (final IOException e) {
- handleStartupException(e);
- return;
- }
-
- final SchemaContext localSchema = CommandDispatcher.parseSchema(CommandDispatcher.LOCAL_SCHEMA_PATHS);
- final SchemaContextRegistry schemaContextRegistry = new SchemaContextRegistry(localSchema);
-
- final CommandDispatcher commandDispatcher = new CommandDispatcher();
- final CommandArgHandlerRegistry argumentHandlerRegistry = new CommandArgHandlerRegistry(consoleIO,
- schemaContextRegistry);
- final NetconfDeviceConnectionManager connectionManager = new NetconfDeviceConnectionManager(commandDispatcher,
- argumentHandlerRegistry, schemaContextRegistry, consoleIO);
-
- commandDispatcher.addLocalCommands(connectionManager, localSchema, cliArgs.getConnectionTimeoutMs());
-
- switch (cliArgs.connectionArgsPresent()) {
- case TCP: {
- // FIXME support pure TCP
- handleRunningException(new UnsupportedOperationException("PURE TCP CONNECTIONS ARE NOT SUPPORTED YET, USE SSH INSTEAD BY PROVIDING USERNAME AND PASSWORD AS WELL"));
- return;
- }
- case SSH: {
- writeStatus(consoleIO, "Connecting to %s via SSH. Please wait.", cliArgs.getAddress());
- connectionManager.connectBlocking(cliArgs.getAddress(), cliArgs.getServerAddress(), getClientSshConfig(cliArgs));
- break;
- }
- case NONE: {/* Do not connect initially */
- writeStatus(consoleIO, "No initial connection. To connect use the connect command");
- }
- }
-
- try {
- new Cli(consoleIO, commandDispatcher, argumentHandlerRegistry, schemaContextRegistry).run();
- } catch (final Exception e) {
- // TODO Running exceptions have to be handled properly
- handleRunningException(e);
- System.exit(0);
- }
- }
-
- private static NetconfClientConfigurationBuilder getClientConfig(final CliArgumentParser cliArgs) {
- return NetconfClientConfigurationBuilder.create().withAddress(cliArgs.getServerAddress())
- .withConnectionTimeoutMillis(cliArgs.getConnectionTimeoutMs())
- .withReconnectStrategy(Connect.getReconnectStrategy())
- .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.TCP);
- }
-
- private static NetconfClientConfigurationBuilder getClientSshConfig(final CliArgumentParser cliArgs) {
- return NetconfClientConfigurationBuilder.create().withAddress(cliArgs.getServerAddress())
- .withConnectionTimeoutMillis(cliArgs.getConnectionTimeoutMs())
- .withReconnectStrategy(Connect.getReconnectStrategy())
- .withAuthHandler(cliArgs.getCredentials())
- .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
- }
-
- private static void handleStartupException(final IOException e) {
- handleException(e, "Unable to initialize CLI");
- }
-
- private static void handleException(final Exception e, final String message) {
- System.console().writer().println(String.format("Error %s cause %s", message, getStackTraceAsString(e.fillInStackTrace())));
- }
-
- private static void writeStatus(final ConsoleIO io, final String blueprint, final Object... args) {
- try {
- io.formatLn(blueprint, args);
- } catch (final IOException e) {
- handleStartupException(e);
- }
- }
-
- private static void handleRunningException(final Exception e) {
- handleException(e, "Unexpected CLI runtime exception");
- }
-
- private static final class CliArgumentParser {
-
- public static final String USERNAME = "username";
- public static final String PASSWORD = "password";
- public static final String SERVER = "server";
- public static final String PORT = "port";
-
- public static final String CONNECT_TIMEOUT = "connectionTimeout";
- public static final int DEFAULT_CONNECTION_TIMEOUT_MS = 50000;
-
- private final ArgumentParser parser;
- private Namespace parsed;
-
- private CliArgumentParser() {
- parser = ArgumentParsers.newArgumentParser("Netconf cli").defaultHelp(true)
- .description("Generic cli for netconf devices")
- .usage("Submit address + port for initial TCP connection (PURE TCP CONNECTIONS ARE NOT SUPPORTED YET)\n" +
- "Submit username + password in addition to address + port for initial SSH connection\n" +
- "If no arguments(or unexpected combination) is submitted, cli will be started without initial connection\n" +
- "To use with ODL controller, run with: java -jar netconf-cli-0.2.5-SNAPSHOT-executable.jar --server localhost --port 1830 --username admin --password admin");
-
- final ArgumentGroup tcpGroup = parser.addArgumentGroup("TCP")
- .description("Base arguments to initiate TCP connection right away");
-
- tcpGroup.addArgument("--" + SERVER).help("Netconf device ip-address/domain name");
- tcpGroup.addArgument("--" + PORT).type(Integer.class).help("Netconf device port");
- tcpGroup.addArgument("--" + CONNECT_TIMEOUT)
- .type(Integer.class)
- .setDefault(DEFAULT_CONNECTION_TIMEOUT_MS)
- .help("Timeout(in ms) for connection to succeed, if the connection is not fully established by the time is up, " +
- "connection attempt is considered a failure. This attribute is not working as expected yet");
-
- final ArgumentGroup sshGroup = parser.addArgumentGroup("SSH")
- .description("SSH credentials, if provided, initial connection will be attempted using SSH");
-
- sshGroup.addArgument("--" + USERNAME).help("Username for SSH connection");
- sshGroup.addArgument("--" + PASSWORD).help("Password for SSH connection");
- }
-
- public void parse(final String[] args) throws ArgumentParserException {
- try {
- this.parsed = parser.parseArgs(args);
- } catch (final ArgumentParserException e) {
- parser.handleError(e);
- throw e;
- }
- }
-
- public InetSocketAddress getServerAddress() {
- try {
- return new InetSocketAddress(InetAddress.getByName(getAddress()), getPort());
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private Integer getPort() {
- checkParsed();
- return parsed.getInt(PORT);
- }
-
- private String getAddress() {
- checkParsed();
- return getString(SERVER);
- }
-
- private Integer getConnectionTimeoutMs() {
- checkParsed();
- return parsed.getInt(CONNECT_TIMEOUT);
- }
-
- private void checkParsed() {
- Preconditions.checkState(parsed != null, "No arguments were parsed yet");
- }
-
- public String getUsername() {
- checkParsed();
- return getString(USERNAME);
- }
-
- private String getString(final String key) {
- return parsed.getString(key);
- }
-
- public LoginPassword getCredentials() {
- return new LoginPassword(getUsername(), getPassword());
- }
-
- public String getPassword() {
- checkParsed();
- return getString(PASSWORD);
- }
-
- public InitialConnectionType connectionArgsPresent() {
- if(getAddress() != null && getPort() != null) {
- if(getUsername() != null && getPassword() != null) {
- return InitialConnectionType.SSH;
- }
- return InitialConnectionType.TCP;
- }
- return InitialConnectionType.NONE;
- }
-
- enum InitialConnectionType {
- TCP, SSH, NONE
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import com.google.common.base.Optional;
-import jline.console.completer.Completer;
-import jline.console.completer.NullCompleter;
-import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceHandler;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Implementation of RemoteDeviceHandler. Integrates cli with
- * sal-netconf-connector.
- */
-public class NetconfDeviceConnectionHandler implements RemoteDeviceHandler<NetconfSessionPreferences> {
-
- private final CommandDispatcher commandDispatcher;
- private final SchemaContextRegistry schemaContextRegistry;
- private final ConsoleIO console;
- private final String deviceId;
-
- private boolean up = false;
-
- public NetconfDeviceConnectionHandler(final CommandDispatcher commandDispatcher,
- final SchemaContextRegistry schemaContextRegistry, final ConsoleIO console, final String deviceId) {
- this.commandDispatcher = commandDispatcher;
- this.schemaContextRegistry = schemaContextRegistry;
- this.console = console;
- this.deviceId = deviceId;
- }
-
- @Override
- public synchronized void onDeviceConnected(final SchemaContext context,
- final NetconfSessionPreferences preferences, final DOMRpcService rpcService) {
- console.enterRootContext(new ConsoleContext() {
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.of(deviceId);
- }
-
- @Override
- public Completer getCompleter() {
- return new NullCompleter();
- }
- });
-
- // TODO Load schemas for base netconf + inet types from remote device if
- // possible
- // TODO detect netconf base version
- // TODO detect inet types version
- commandDispatcher.addRemoteCommands(rpcService, context);
- schemaContextRegistry.setRemoteSchemaContext(context);
- up = true;
- this.notify();
- }
-
- /**
- * @return true if connection was fully established
- */
- public synchronized boolean isUp() {
- return up;
- }
-
- @Override
- public synchronized void onDeviceDisconnected() {
- console.leaveRootContext();
- commandDispatcher.removeRemoteCommands();
- schemaContextRegistry.setRemoteSchemaContext(null);
- up = false;
- }
-
- @Override
- public void onDeviceFailed(Throwable throwable) {
- // FIXME
- }
-
- @Override
- public void onNotification(DOMNotification domNotification) {
-
- }
-
- @Override
- public void close() {
- // FIXME
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import com.google.common.base.Preconditions;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
-import org.opendaylight.controller.sal.connect.netconf.NetconfDevice.SchemaResourcesDTO;
-import org.opendaylight.controller.sal.connect.netconf.NetconfStateSchemas.NetconfStateSchemasResolverImpl;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactory;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
-import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
-import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
-
-/**
- * Manages connect/disconnect to 1 remote device
- */
-public class NetconfDeviceConnectionManager implements Closeable {
-
- private final CommandDispatcher commandDispatcher;
- private final SchemaContextRegistry schemaContextRegistry;
- private final ConsoleIO console;
-
- private final ExecutorService executor;
- private final NioEventLoopGroup nettyThreadGroup;
- private final NetconfClientDispatcherImpl netconfClientDispatcher;
-
- private static final String CACHE = "cache/schema";
-
- // Connection
- private NetconfDeviceConnectionHandler handler;
- private NetconfDevice device;
- private NetconfDeviceCommunicator listener;
-
- public NetconfDeviceConnectionManager(final CommandDispatcher commandDispatcher,
- final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContextRegistry schemaContextRegistry,
- final ConsoleIO consoleIO) {
- this.commandDispatcher = commandDispatcher;
- this.schemaContextRegistry = schemaContextRegistry;
- this.console = consoleIO;
-
- executor = Executors.newSingleThreadExecutor();
- nettyThreadGroup = new NioEventLoopGroup();
- netconfClientDispatcher = new NetconfClientDispatcherImpl(nettyThreadGroup, nettyThreadGroup,
- new HashedWheelTimer());
- }
-
- // TODO we receive configBuilder in order to add SessionListener, Session
- // Listener should not be part of config
- public synchronized void connect(final String name, final InetSocketAddress address, final NetconfClientConfigurationBuilder configBuilder) {
- // TODO change IllegalState exceptions to custom ConnectionException
- Preconditions.checkState(listener == null, "Already connected");
-
- final RemoteDeviceId deviceId = new RemoteDeviceId(name, address);
-
- handler = new NetconfDeviceConnectionHandler(commandDispatcher, schemaContextRegistry,
- console, name);
-
- final SharedSchemaRepository repository = new SharedSchemaRepository("repo");
- final SchemaContextFactory schemaContextFactory = repository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
- final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(repository, YangTextSchemaSource.class, new File(CACHE));
- repository.registerSchemaSourceListener(cache);
- repository.registerSchemaSourceListener(TextToASTTransformer.create(repository, repository));
-
- device = new NetconfDevice(new SchemaResourcesDTO(repository, schemaContextFactory, new NetconfStateSchemasResolverImpl()),
- deviceId, handler, executor, true);
- listener = new NetconfDeviceCommunicator(deviceId, device);
- configBuilder.withSessionListener(listener);
- listener.initializeRemoteConnection(netconfClientDispatcher, configBuilder.build());
- }
-
- /**
- * Blocks thread until connection is fully established
- */
- public synchronized Set<String> connectBlocking(final String name, final InetSocketAddress address, final NetconfClientConfigurationBuilder configBuilder) {
- this.connect(name, address, configBuilder);
- synchronized (handler) {
- while (handler.isUp() == false) {
- try {
- // TODO implement Timeout for unsuccessful connection
- handler.wait();
- } catch (final InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new IllegalArgumentException(e);
- }
- }
- }
-
- return commandDispatcher.getRemoteCommandIds();
- }
-
- public synchronized void disconnect() {
- Preconditions.checkState(listener != null, "Not connected yet");
- Preconditions.checkState(handler.isUp(), "Not connected yet");
- listener.close();
- listener = null;
- device = null;
- handler.close();
- handler = null;
- }
-
- private static AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider() {
- // FIXME move to args
- final String storageFile = "cache/schema";
- final File directory = new File(storageFile);
- final SchemaSourceProvider<String> defaultProvider = SchemaSourceProviders.noopProvider();
- return FilesystemSchemaCachingProvider.createFromStringSourceProvider(defaultProvider, directory);
- }
-
- @Override
- public void close() throws IOException {
- executor.shutdownNow();
- nettyThreadGroup.shutdownGracefully();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import com.google.common.base.Optional;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Contains the local schema context (containing local commands) and remote schema context (remote commands)
- *
- * Remote commands are set only after the connection is fully established. So classes using the remote schema context
- */
-public class SchemaContextRegistry {
-
- private final SchemaContext localSchemaContext;
- private SchemaContext remoteSchemaContext;
-
- public SchemaContextRegistry(final SchemaContext localSchemaContext) {
- this.localSchemaContext = localSchemaContext;
- }
-
- public synchronized Optional<SchemaContext> getRemoteSchemaContext() {
- return Optional.fromNullable(remoteSchemaContext);
- }
-
- public SchemaContext getLocalSchemaContext() {
- return localSchemaContext;
- }
-
- public synchronized void setRemoteSchemaContext(final SchemaContext remoteSchemaContext) {
- this.remoteSchemaContext = remoteSchemaContext;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands;
-
-import com.google.common.base.Optional;
-import jline.console.completer.Completer;
-import jline.console.completer.NullCompleter;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-
-public abstract class AbstractCommand implements Command {
-
- private final QName qName;
- private final InputDefinition args;
- private final OutputDefinition output;
- private final String description;
-
- public AbstractCommand(final QName qName, final InputDefinition args, final OutputDefinition output,
- final String description) {
- this.qName = qName;
- this.args = args;
- this.output = output;
- this.description = description;
- }
-
- protected static OutputDefinition getOutputDefinition(final RpcDefinition rpcDefinition) {
- final ContainerSchemaNode output = rpcDefinition.getOutput();
- return output != null ? OutputDefinition.fromOutput(output) : OutputDefinition.empty();
- }
-
- protected static InputDefinition getInputDefinition(final RpcDefinition rpcDefinition) {
- final ContainerSchemaNode input = rpcDefinition.getInput();
- return InputDefinition.fromInput(input);
- }
-
- @Override
- public InputDefinition getInputDefinition() {
- return args;
- }
-
- @Override
- public OutputDefinition getOutputDefinition() {
- return output;
- }
-
- @Override
- public QName getCommandId() {
- return qName;
- }
-
- @Override
- public ConsoleContext getConsoleContext() {
- return new ConsoleContext() {
-
- @Override
- public Completer getCompleter() {
- return new NullCompleter();
- }
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.of(qName.getLocalName());
- }
- };
- }
-
- @Override
- public Optional<String> getCommandDescription() {
- return Optional.fromNullable(description);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.yangtools.yang.common.QName;
-
-/**
- * Local command e.g. help or remote rpc e.g. get-config must conform to this interface
- */
-public interface Command {
-
- Output invoke(Input inputArgs) throws CommandInvocationException;
-
- InputDefinition getInputDefinition();
-
- OutputDefinition getOutputDefinition();
-
- QName getCommandId();
-
- Optional<String> getCommandDescription();
-
- ConsoleContext getConsoleContext();
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands;
-
-import java.net.URI;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class CommandConstants {
-
- // Local command ids are defined here, this links the implementation to the rpc definition in yang
- // Better way needs to be found to provide this link instead of hardcoded QNames (e.g. yang extension)
- public static final QName HELP_QNAME = QName.create(URI.create("netconf:cli"), IOUtil.parseDate("2014-05-22"), "help");
- public static final QName CLOSE_QNAME = QName.create(HELP_QNAME, "close");
- public static final QName CONNECT_QNAME = QName.create(HELP_QNAME, "connect");
- public static final QName DISCONNECT_QNAME = QName.create(CONNECT_QNAME, "disconnect");
-
- public static final QName ARG_HANDLER_EXT_QNAME = QName.create(
- URI.create("urn:ietf:params:xml:ns:netconf:base:1.0:cli"), IOUtil.parseDate("2014-05-26"),
- "argument-handler");
-
- public static final QName NETCONF_BASE_QNAME = QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01",
- "netconf");
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionHandler;
-import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
-import org.opendaylight.controller.netconf.cli.commands.local.Close;
-import org.opendaylight.controller.netconf.cli.commands.local.Connect;
-import org.opendaylight.controller.netconf.cli.commands.local.Disconnect;
-import org.opendaylight.controller.netconf.cli.commands.local.Help;
-import org.opendaylight.controller.netconf.cli.commands.remote.RemoteCommand;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-/**
- * The registry of available commands local + remote. Created from schema contexts.
- */
-public class CommandDispatcher {
-
- // TODO extract interface
-
- private final Map<QName, Command> localCommands = Maps.newHashMap();
- private final Map<String, QName> nameToQNameLocal = Maps.newHashMap();
-
- private final Map<QName, Command> remoteCommands = Maps.newHashMap();
- private final Map<String, QName> nameToQNameRemote = Maps.newHashMap();
-
- public synchronized Map<QName, Command> getCommands() {
- return Collections.unmodifiableMap(mergeCommands());
- }
-
- private Map<QName, Command> mergeCommands() {
- // TODO cache this merged map
- return mergeMaps(remoteCommands, localCommands);
- }
-
- private Map<String, QName> mergeCommandIds() {
- // TODO cache this merged map
- return mergeMaps(nameToQNameRemote, nameToQNameLocal);
- }
-
- private <K, V> Map<K, V> mergeMaps(final Map<K, V> remoteMap, final Map<K, V> localMap) {
- final Map<K, V> mergedCommands = Maps.newHashMap();
- mergedCommands.putAll(remoteMap);
- mergedCommands.putAll(localMap);
- return mergedCommands;
- }
-
- public synchronized Set<String> getCommandIds() {
- return mergeCommandIds().keySet();
- }
-
- public synchronized Set<String> getRemoteCommandIds() {
- return nameToQNameRemote.keySet();
- }
-
- public synchronized Optional<Command> getCommand(final String nameWithModule) {
- final QName commandQName = mergeCommandIds().get(nameWithModule);
- final Map<QName, Command> qNameCommandMap = mergeCommands();
- if(commandQName == null || qNameCommandMap.containsKey(commandQName) == false) {
- return Optional.absent();
- }
-
- return Optional.of(qNameCommandMap.get(commandQName));
- }
-
- public synchronized Optional<Command> getCommand(final QName qName) {
- return Optional.fromNullable(mergeCommands().get(qName));
- }
-
- private static Optional<Command> getCommand(final Map<String, QName> commandNameMap, final Map<QName, Command> commands, final String nameWithModule) {
- final QName qName = commandNameMap.get(nameWithModule);
- if(qName == null)
- return Optional.absent();
-
- final Command command = commands.get(qName);
- if(command == null) {
- return Optional.absent();
- }
-
- return Optional.of(command);
- }
-
- public static final Collection<String> BASE_NETCONF_SCHEMA_PATHS = Lists.newArrayList("/schema/remote/ietf-netconf.yang",
- "/schema/common/netconf-cli-ext.yang", "/schema/common/ietf-inet-types.yang");
-
- public synchronized void addRemoteCommands(final DOMRpcService rpcService, final SchemaContext remoteSchema) {
- this.addRemoteCommands(rpcService, remoteSchema, parseSchema(BASE_NETCONF_SCHEMA_PATHS));
- }
-
- public synchronized void addRemoteCommands(final DOMRpcService rpcService, final SchemaContext remoteSchema, final SchemaContext baseNetconfSchema) {
- for (final SchemaContext context : Lists.newArrayList(remoteSchema, baseNetconfSchema)) {
- for (final Module module : context.getModules()) {
- for (final RpcDefinition rpcDefinition : module.getRpcs()) {
- final Command command = RemoteCommand.fromRpc(rpcDefinition, rpcService);
- remoteCommands.put(rpcDefinition.getQName(), command);
- nameToQNameRemote.put(getCommandName(rpcDefinition, module), rpcDefinition.getQName());
- }
- }
- }
- }
-
- public synchronized void removeRemoteCommands() {
- remoteCommands.clear();
- nameToQNameRemote.clear();
- }
-
- public static final Collection<String> LOCAL_SCHEMA_PATHS = Lists.newArrayList("/schema/local/netconf-cli.yang", "/schema/common/netconf-cli-ext.yang",
- "/schema/common/ietf-inet-types.yang");
-
- public synchronized void addLocalCommands(final NetconfDeviceConnectionManager connectionManager, final SchemaContext localSchema, final Integer connectionTimeout) {
- for (final Module module : localSchema.getModules()) {
- for (final RpcDefinition rpcDefinition : module.getRpcs()) {
-
- // FIXME make local commands extensible
- // e.g. by yang extension defining java class to be instantiated
- // problem is with command specific resources
- // e.g. Help would need command registry
- final Command localCommand;
- if (rpcDefinition.getQName().equals(CommandConstants.HELP_QNAME)) {
- localCommand = Help.create(rpcDefinition, this);
- } else if (rpcDefinition.getQName().equals(CommandConstants.CLOSE_QNAME)) {
- localCommand = Close.create(rpcDefinition);
- } else if (rpcDefinition.getQName().equals(CommandConstants.CONNECT_QNAME)) {
- localCommand = Connect.create(rpcDefinition, connectionManager, connectionTimeout);
- } else if (rpcDefinition.getQName().equals(CommandConstants.DISCONNECT_QNAME)) {
- localCommand = Disconnect.create(rpcDefinition, connectionManager);
- } else {
- throw new IllegalStateException("No command implementation available for local command: " + rpcDefinition.getQName());
- }
-
- localCommands.put(localCommand.getCommandId(), localCommand);
- nameToQNameLocal.put(getCommandName(rpcDefinition, module), localCommand.getCommandId());
- }
- }
- }
-
- private static String getCommandName(final RpcDefinition rpcDefinition, final Module module) {
- return IOUtil.qNameToKeyString(rpcDefinition.getQName(), module.getName());
- }
-
- public static SchemaContext parseSchema(final Collection<String> yangPath) {
- final YangParserImpl yangParserImpl = new YangParserImpl();
- // TODO change deprecated method
- final Set<Module> modules = yangParserImpl.parseYangModelsFromStreams(loadYangs(yangPath));
- return yangParserImpl.resolveSchemaContext(modules);
- }
-
- private static List<InputStream> loadYangs(final Collection<String> yangPaths) {
-
- return Lists.newArrayList(Collections2.transform(Lists.newArrayList(yangPaths),
- new Function<String, InputStream>() {
- @Override
- public InputStream apply(final String input) {
- final InputStream resourceAsStream = NetconfDeviceConnectionHandler.class.getResourceAsStream(input);
- Preconditions.checkNotNull(resourceAsStream, "File %s was null", input);
- return resourceAsStream;
- }
- }));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands;
-
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class CommandInvocationException extends Exception {
-
- public CommandInvocationException(final QName qName, final Throwable cause) {
- this("Command " + qName + " invocation failed: " + cause.getMessage(), cause);
- }
-
- protected CommandInvocationException(final String message, final Throwable cause) {
- super(message, cause);
- }
-
- public static class CommandTimeoutException extends CommandInvocationException {
-
- public CommandTimeoutException(final QName qName, final Throwable e) {
- super("Command " + qName + " timed out: " + e.getMessage(), e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.input;
-
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-
-/**
- * Input arguments for and rpc/command execution
- */
-public class Input {
-
- private final List<NormalizedNode<?, ?>> args;
-
- private final Map<String, NormalizedNode<?, ?>> nameToArg = new HashMap<>();
-
- public Input(final List<NormalizedNode<?, ?>> args) {
- // FIXME empty Input should be constructed from static factory method
- if(args.isEmpty()) {
- this.args = Collections.emptyList();
- return;
- }
-
- final NormalizedNode<?, ?> input = args.iterator().next();
- Preconditions
- .checkArgument(input instanceof DataContainerChild<?, ?>, "Input container has to be of type Data Container Child.");
- this.args = new ArrayList<>((Collection) input.getValue());
-
- for (final NormalizedNode<?, ?> arg : this.args) {
- nameToArg.put(arg.getNodeType().getLocalName(), arg);
- }
- }
-
- public NormalizedNode<?, ?> getArg(final String name) {
- return nameToArg.get(name);
- }
-
- public NormalizedNode<?, ?> wrap(final QName rpcQName) {
- //TODO just add the list as children to the node
- return ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(rpcQName))
- .withValue((Collection) args).build();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.input;
-
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-
-/**
- * The definition of input arguments represented by schema nodes parsed from
- * yang rpc definition
- */
-public class InputDefinition {
-
- private final ContainerSchemaNode inputContainer;
-
- public InputDefinition(final ContainerSchemaNode inputContainer) {
- this.inputContainer = inputContainer;
- }
-
- public static InputDefinition fromInput(final ContainerSchemaNode input) {
- return new InputDefinition(input);
- }
-
- public ContainerSchemaNode getInput() {
- return inputContainer;
- }
-
- // FIXME add empty as in output
- public boolean isEmpty() {
- return inputContainer == null;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.local;
-
-import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-
-/**
- * Local command to shut down the cli
- */
-public class Close extends AbstractCommand {
-
- public Close(final QName qName, final InputDefinition args, final OutputDefinition output, final String description) {
- super(qName, args, output, description);
- }
-
- @Override
- public Output invoke(final Input inputArgs) throws CommandInvocationException {
- // FIXME clean up, close session and then close
- System.exit(0);
- return null;
- }
-
- public static Command create(final RpcDefinition rpcDefinition) {
- return new Close(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
- getOutputDefinition(rpcDefinition), rpcDefinition.getDescription());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.local;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Set;
-import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
-import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.opendaylight.protocol.framework.ReconnectStrategy;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-
-/**
- * Local command to connect to a remote device
- */
-public class Connect extends AbstractCommand {
-
- private final NetconfDeviceConnectionManager connectManager;
- private final Integer connectionTimeout;
-
- private Connect(final QName qName, final InputDefinition args, final OutputDefinition output,
- final NetconfDeviceConnectionManager connectManager, final String description, final Integer connectionTimeout) {
- super(qName, args, output, description);
- this.connectManager = connectManager;
- this.connectionTimeout = connectionTimeout;
- }
-
- @Override
- public Output invoke(final Input inputArgs) {
- final NetconfClientConfigurationBuilder config = getConfig(inputArgs);
- return invoke(config, getArgument(inputArgs, "address-name", String.class), inputArgs);
- }
-
- private Output invoke(final NetconfClientConfigurationBuilder config, final String addressName, final Input inputArgs) {
- final Set<String> remoteCmds = connectManager.connectBlocking(addressName, getAdress(inputArgs), config);
-
- final ArrayList<DataContainerChild<?, ?>> output = Lists.newArrayList();
- output.add(ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "status")))
- .withValue("Connection initiated").build());
-
- final ArrayList<LeafSetEntryNode<Object>> leafListChildren = Lists.newArrayList();
- for (final String cmdId : remoteCmds) {
- leafListChildren.add(ImmutableLeafSetEntryNodeBuilder.create()
- .withNodeIdentifier(new NodeWithValue(QName.create(getCommandId(), "remote-commands"), cmdId))
- .withValue(cmdId).build());
- }
-
- return new Output(ImmutableLeafSetNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "remote-commands")))
- .withValue(leafListChildren).build());
- }
-
- private NetconfClientConfigurationBuilder getConfig(final Input inputArgs) {
-
- final ReconnectStrategy strategy = getReconnectStrategy();
-
- final String address = getArgument(inputArgs, "address-name", String.class);
- final Integer port = getArgument(inputArgs, "address-port", Integer.class);
- final String username = getArgument(inputArgs, "user-name", String.class);
- final String passwd = getArgument(inputArgs, "user-password", String.class);
-
- final InetSocketAddress inetAddress;
- try {
- inetAddress = new InetSocketAddress(InetAddress.getByName(address), port);
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unable to use address: " + address, e);
- }
-
- return NetconfClientConfigurationBuilder.create().withAddress(inetAddress)
- .withConnectionTimeoutMillis(connectionTimeout)
- .withReconnectStrategy(strategy)
- .withAuthHandler(new LoginPassword(username, passwd))
- .withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
- }
-
- private InetSocketAddress getAdress(final Input inputArgs) {
- final String address = getArgument(inputArgs, "address-name", String.class);
- final InetSocketAddress inetAddress;
- try {
- inetAddress = new InetSocketAddress(InetAddress.getByName(address), getArgument(inputArgs, "address-port", Integer.class));
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unable to use address: " + address, e);
- }
- return inetAddress;
- }
-
- private <T> Optional<T> getArgumentOpt(final Input inputArgs, final String argName, final Class<T> type) {
- final QName argQName = QName.create(getCommandId(), argName);
- final NormalizedNode<?, ?> argumentNode = inputArgs.getArg(argName);
- if (argumentNode == null) {
- return Optional.absent();
- }
- Preconditions.checkArgument(argumentNode instanceof LeafNode, "Only simple type argument supported, %s",
- argQName);
-
- final Object value = argumentNode.getValue();
- Preconditions.checkArgument(type.isInstance(value), "Unexpected instance type: %s for argument: %s",
- value.getClass(), argQName);
- return Optional.of(type.cast(value));
- }
-
- private <T> T getArgument(final Input inputArgs, final String argName, final Class<T> type) {
- final Optional<T> argumentOpt = getArgumentOpt(inputArgs, argName, type);
- Preconditions.checkState(argumentOpt.isPresent(), "Argument: %s is missing but is required", argName);
- return argumentOpt.get();
- }
-
- public static ReconnectStrategy getReconnectStrategy() {
- // FIXME move to args either start-up args or input nodes for connect or both
- return new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 1000);
- }
-
- public static Command create(final RpcDefinition rpcDefinition, final NetconfDeviceConnectionManager connectManager, final Integer connectionTimeout) {
- return new Connect(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
- getOutputDefinition(rpcDefinition), connectManager, rpcDefinition.getDescription(), connectionTimeout);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.local;
-
-import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager;
-import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-
-/**
- * Local disconnect command
- */
-public class Disconnect extends AbstractCommand {
-
- private final NetconfDeviceConnectionManager connectionManager;
-
- public Disconnect(final QName qName, final InputDefinition inputDefinition,
- final OutputDefinition outputDefinition, final NetconfDeviceConnectionManager connectionManager,
- final String description) {
- super(qName, inputDefinition, outputDefinition, description);
- this.connectionManager = connectionManager;
- }
-
- @Override
- public Output invoke(final Input inputArgs) {
- connectionManager.disconnect();
-
- return new Output(
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(getCommandId()))
- .withChild(ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "status")))
- .withValue("Connection disconnected").build()).build());
- }
-
- public static Command create(final RpcDefinition rpcDefinition,
- final NetconfDeviceConnectionManager commandDispatcher) {
- return new Disconnect(rpcDefinition.getQName(), getInputDefinition(rpcDefinition),
- getOutputDefinition(rpcDefinition), commandDispatcher, rpcDefinition.getDescription());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.local;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.CommandDispatcher;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-
-/**
- * Local Help command. Displays all commands with description.
- */
-public class Help extends AbstractCommand {
-
- private final CommandDispatcher commandDispatcher;
-
- public Help(final QName qName, final InputDefinition argsDefinition, final OutputDefinition output, final String description, final CommandDispatcher commandDispatcher) {
- super(qName, argsDefinition, output, description);
- this.commandDispatcher = commandDispatcher;
- }
-
- @Override
- public Output invoke(final Input inputArgs) {
- final ArrayList<MapEntryNode> value = Lists.newArrayList();
-
- for (final String id : commandDispatcher.getCommandIds()) {
- final Optional<Command> cmd = commandDispatcher.getCommand(id);
- Preconditions.checkState(cmd.isPresent(), "Command %s has to be present in command dispatcher", id);
- final Optional<String> description = cmd.get().getCommandDescription();
- final List<DataContainerChild<?, ?>> nameAndDescription = Lists.newArrayList();
- nameAndDescription.add(
- ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "id")))
- .withValue(id).build());
- if(description.isPresent()) {
- nameAndDescription.add(
- ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "description")))
- .withValue(description.get()).build());
- }
- value.add(ImmutableMapEntryNodeBuilder.create()
- .withValue(nameAndDescription)
- .withNodeIdentifier(
- new NodeIdentifierWithPredicates(QName.create(getCommandId(), "commands"),
- QName.create(getCommandId(), "id"), id)).build());
- }
- MapNode mappedHelp = ImmutableMapNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(QName.create(getCommandId(), "commands")))
- .withValue(value).build();
-
- return new Output(mappedHelp);
- }
-
- public static Command create(final RpcDefinition rpcDefinition, final CommandDispatcher commandDispatcher) {
- return new Help(rpcDefinition.getQName(), getInputDefinition(rpcDefinition), getOutputDefinition(rpcDefinition), rpcDefinition.getDescription(), commandDispatcher);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.output;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-/**
- * Output values for and rpc/command execution
- */
-public class Output {
-
- private final NormalizedNode<?, ?> output;
-
- public Output(final NormalizedNode<?, ?> output) {
- if (output instanceof ContainerNode && output.getNodeType().getLocalName() == "rpc-reply") {
- this.output = ((ContainerNode) output).getValue().iterator().next();
- } else {
- this.output = output;
- }
- }
-
- public Map<DataSchemaNode, List<NormalizedNode<?, ?>>> unwrap(final OutputDefinition outputDefinition) {
- Preconditions.checkArgument(outputDefinition.isEmpty() == false);
-
- final Map<QName, DataSchemaNode> mappedSchemaNodes = mapOutput(outputDefinition);
- final Map<DataSchemaNode, List<NormalizedNode<?, ?>>> mappedNodesToSchema = Maps.newHashMap();
-
- final DataSchemaNode schemaNode = mappedSchemaNodes.get(output.getNodeType().withoutRevision());
- final List<NormalizedNode<?, ?>> list = mappedNodesToSchema.get(schemaNode) == null ? Lists.<NormalizedNode<?, ?>>newArrayList()
- : mappedNodesToSchema.get(schemaNode);
- list.add(output);
- mappedNodesToSchema.put(schemaNode, list);
-
- return mappedNodesToSchema;
- }
-
- public NormalizedNode<?, ?> getOutput() {
- return output;
- }
-
- private Map<QName, DataSchemaNode> mapOutput(final OutputDefinition outputDefinition) {
- final Map<QName, DataSchemaNode> mapped = Maps.newHashMap();
- for (final DataSchemaNode dataSchemaNode : outputDefinition) {
- // without revision since data QNames come without revision
- mapped.put(dataSchemaNode.getQName().withoutRevision(), dataSchemaNode);
- }
-
- return mapped;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.output;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import java.util.Iterator;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-/**
- * The definition of output elements represented by schema nodes parsed from yang rpc definition
- */
-public class OutputDefinition implements Iterable<DataSchemaNode> {
-
- public static final OutputDefinition EMPTY_OUTPUT = new OutputDefinition(Collections.<DataSchemaNode>emptySet());
- private final Iterable<DataSchemaNode> childNodes;
-
- public OutputDefinition(final Iterable<DataSchemaNode> childNodes) {
- this.childNodes = childNodes;
- }
-
- @Override
- public Iterator<DataSchemaNode> iterator() {
- return childNodes.iterator();
- }
-
- public static OutputDefinition fromOutput(final ContainerSchemaNode output) {
- Preconditions.checkNotNull(output);
- return new OutputDefinition(output.getChildNodes());
- }
-
- public static OutputDefinition empty() {
- return EMPTY_OUTPUT;
- }
-
- public boolean isEmpty() {
- return this == EMPTY_OUTPUT;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.commands.remote;
-
-import com.google.common.util.concurrent.CheckedFuture;
-import java.util.Collections;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.netconf.cli.commands.AbstractCommand;
-import org.opendaylight.controller.netconf.cli.commands.Command;
-import org.opendaylight.controller.netconf.cli.commands.CommandInvocationException;
-import org.opendaylight.controller.netconf.cli.commands.input.Input;
-import org.opendaylight.controller.netconf.cli.commands.input.InputDefinition;
-import org.opendaylight.controller.netconf.cli.commands.output.Output;
-import org.opendaylight.controller.netconf.cli.commands.output.OutputDefinition;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-/**
- * Generic remote command implementation that sends the rpc xml to the remote device and waits for response
- * Waiting is limited with TIMEOUT
- */
-public class RemoteCommand extends AbstractCommand {
-
- // TODO make this configurable
- private static final long DEFAULT_TIMEOUT = 10000;
- private static final TimeUnit DEFAULT_TIMEOUT_UNIT = TimeUnit.MILLISECONDS;
- private final DOMRpcService rpcService;
-
- public RemoteCommand(final QName qName, final InputDefinition args, final OutputDefinition output, final String description, final DOMRpcService rpcService) {
- super(qName, args, output, description);
- this.rpcService = rpcService;
- }
-
- @Override
- public Output invoke(final Input inputArgs) throws CommandInvocationException {
- final CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc =
- rpcService.invokeRpc(SchemaPath.create(Collections.singletonList(getCommandId()), true), inputArgs.wrap(getCommandId()));
-
- try {
- return new Output(invokeRpc.get(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_UNIT).getResult());
- } catch (final ExecutionException e) {
- throw new CommandInvocationException(getCommandId(), e);
- } catch (final TimeoutException e) {
- // Request timed out, cancel request
- invokeRpc.cancel(true);
- throw new CommandInvocationException.CommandTimeoutException(getCommandId(), e);
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static Command fromRpc(final RpcDefinition rpcDefinition, final DOMRpcService rpcService) {
- final InputDefinition args = getInputDefinition(rpcDefinition);
- final OutputDefinition retVal = getOutputDefinition(rpcDefinition);
-
- return new RemoteCommand(rpcDefinition.getQName(), args, retVal, rpcDefinition.getDescription(), rpcService);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import jline.console.completer.AggregateCompleter;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-public class BaseConsoleContext<T extends DataSchemaNode> implements ConsoleContext {
-
- private static final Completer SKIP_COMPLETER = new StringsCompleter(IOUtil.SKIP);
-
- private final T dataSchemaNode;
-
- public BaseConsoleContext(final T dataSchemaNode) {
- Preconditions.checkNotNull(dataSchemaNode);
- this.dataSchemaNode = dataSchemaNode;
- }
-
- @Override
- public Completer getCompleter() {
- final ArrayList<Completer> completers = Lists.newArrayList(SKIP_COMPLETER);
- completers.addAll(getAdditionalCompleters());
- return new AggregateCompleter(completers);
- }
-
- protected List<Completer> getAdditionalCompleters() {
- return Collections.emptyList();
- }
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.of(dataSchemaNode.getQName().getLocalName());
- }
-
- protected T getDataSchemaNode() {
- return dataSchemaNode;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import com.google.common.base.Optional;
-import jline.console.completer.Completer;
-
-/**
- * Context to be set in the IO. Different prompts + completers are required in different contexts of the CLI.
- */
-public interface ConsoleContext {
-
- Completer getCompleter();
-
- Optional<String> getPrompt();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import java.io.IOException;
-
-/**
- * Definition of IO interface
- */
-public interface ConsoleIO {
-
- String read() throws IOException;
-
- String read(Character mask) throws IOException;
-
- void write(CharSequence data) throws IOException;
-
- void writeLn(CharSequence data) throws IOException;
-
- void formatLn(String format, Object... args) throws IOException;
-
- void enterContext(ConsoleContext consoleContext);
-
- void enterRootContext(ConsoleContext consoleContext);
-
- void leaveContext();
-
- void leaveRootContext();
-
- void complete();
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.PATH_SEPARATOR;
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.IOException;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.Iterator;
-import jline.console.ConsoleReader;
-import jline.console.completer.Completer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Jline based IO implementation
- */
-public class ConsoleIOImpl implements ConsoleIO {
-
- private static final Logger LOG = LoggerFactory.getLogger(ConsoleIOImpl.class);
-
- private final ConsoleReader console;
- private final Deque<ConsoleContext> contexts = new ArrayDeque<>();
-
- public ConsoleIOImpl() throws IOException {
- console = new ConsoleReader();
- console.setHandleUserInterrupt(true);
- console.setPaginationEnabled(true);
- console.setHistoryEnabled(true);
-
- // TODO trifferedActions not supported by jline in current version
- // https://github.com/jline/jline2/issues/149
- console.addTriggeredAction('?', new QuestionMarkActionListener());
- }
-
- @Override
- public String read() throws IOException {
- return console.readLine().trim();
- }
-
- @Override
- public String read(final Character mask) throws IOException {
- return console.readLine(mask).trim();
- }
-
- @Override
- public void write(final CharSequence data) throws IOException {
- console.print(data);
- console.flush();
- }
-
- @Override
- public void writeLn(final CharSequence data) throws IOException {
- console.println(data);
- console.flush();
- }
-
- @Override
- public void formatLn(final String format, final Object... args) throws IOException {
- console.println(String.format(format, args));
- console.flush();
- }
-
- @Override
- public void enterContext(final ConsoleContext consoleContext) {
- contexts.push(consoleContext);
- enterCtx(consoleContext);
- }
-
-
- @Override
- public void enterRootContext(final ConsoleContext consoleContext) {
- contexts.addLast(consoleContext);
- enterCtx(consoleContext);
- }
-
- private void enterCtx(final ConsoleContext consoleContext) {
- setCompleter(consoleContext.getCompleter());
- console.setPrompt(buildPrompt());
- }
-
- @Override
- public void leaveContext() {
- contexts.pollFirst();
- leaveCtx();
- }
-
- @Override
- public void leaveRootContext() {
- contexts.pollLast();
- leaveCtx();
- }
-
- private void leaveCtx() {
- console.setPrompt(buildPrompt());
- if (contexts.peek() != null) {
- setCompleter(contexts.peek().getCompleter());
- }
- }
-
- protected String buildPrompt() {
- final StringBuilder newPrompt = new StringBuilder();
-
- final Iterator<ConsoleContext> descendingIterator = contexts.descendingIterator();
- while (descendingIterator.hasNext()) {
- final ConsoleContext consoleContext = descendingIterator.next();
- final Optional<String> promptPart = consoleContext.getPrompt();
- if (promptPart.isPresent()) {
- newPrompt.append(PATH_SEPARATOR);
- newPrompt.append(promptPart.get());
- }
- }
- if (newPrompt.length() ==0) {
- newPrompt.append(PATH_SEPARATOR);
- }
-
- newPrompt.append(PROMPT_SUFIX);
-
- return newPrompt.toString();
- }
-
- private void setCompleter(final Completer newCompleter) {
- for (final Completer concreteCompleter : console.getCompleters()) {
- console.removeCompleter(concreteCompleter);
- }
- console.addCompleter(newCompleter);
- }
-
- private class QuestionMarkActionListener implements ActionListener {
- @Override
- public void actionPerformed(final ActionEvent e) {
- ConsoleIOImpl.this.complete();
- }
- }
-
- public void complete() {
- final ArrayList<CharSequence> candidates = Lists.newArrayList();
- contexts.peek().getCompleter().complete("", 0, candidates);
- try {
- console.getCompletionHandler().complete(console, candidates, 0);
- } catch (final IOException ex) {
- throw new IllegalStateException("Unable to write to output", ex);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-
-public class IOUtil {
-
- public static final String SKIP = "skip";
- public static final String PROMPT_SUFIX = ">";
- public static final String PATH_SEPARATOR = "/";
-
- private IOUtil() {
- }
-
- public static boolean isQName(final String qName) {
- final Matcher matcher = patternNew.matcher(qName);
- return matcher.matches();
- }
-
- public static Date parseDate(final String revision) {
- final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
- try {
- return formatter.parse(revision);
- } catch (final ParseException e) {
- throw new IllegalArgumentException("Date not valid", e);
- }
- }
-
- public static String listType(final SchemaNode schemaNode) {
- if (schemaNode instanceof LeafListSchemaNode) {
- return "Leaf-list";
- } else if (schemaNode instanceof ListSchemaNode) {
- return "List";
- } else if (schemaNode instanceof LeafSchemaNode) {
- return "Leaf";
- }
- // FIXME throw exception on unexpected state, not null/emptyString
- return "";
- }
-
- public static String qNameToKeyString(final QName qName, final String moduleName) {
- return String.format("%s(%s)", qName.getLocalName(), moduleName);
- }
-
- // TODO test and check regex + review format of string for QName
- final static Pattern patternNew = Pattern.compile("([^\\)]+)\\(([^\\)]+)\\)");
-
- public static QName qNameFromKeyString(final String qName, final Map<String, QName> mappedModules)
- throws ReadingException {
- final Matcher matcher = patternNew.matcher(qName);
- if (!matcher.matches()) {
- final String message = String.format("QName in wrong format: %s should be: %s", qName, patternNew);
- throw new ReadingException(message);
- }
- final QName base = mappedModules.get(matcher.group(2));
- if (base == null) {
- final String message = String.format("Module %s cannot be found", matcher.group(2));
- throw new ReadingException(message);
- }
- return QName.create(base, matcher.group(1));
- }
-
- public static boolean isSkipInput(final String rawValue) {
- return rawValue.equals(SKIP);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Strings;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import jline.console.completer.Completer;
-import jline.console.completer.NullCompleter;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
-
-public abstract class AbstractReader<T extends DataSchemaNode> implements Reader<T> {
-
- public static final NullContext NULL_CONTEXT = new NullContext();
-
- // TODO make console private add protected getter
- protected ConsoleIO console;
- private final SchemaContext context;
- private boolean readConfigNode = false;
-
- public AbstractReader(final ConsoleIO console, final SchemaContext context) {
- this.console = console;
- this.context = context;
- }
-
- public AbstractReader(final ConsoleIO console, final SchemaContext context, final boolean readConfigNode) {
- this(console, context);
- this.readConfigNode = readConfigNode;
- }
-
- protected SchemaContext getSchemaContext() {
- return context;
- }
-
- protected ConsoleIO getConsole() {
- return console;
- }
-
- protected boolean getReadConfigNode() {
- return readConfigNode;
- }
-
- @Override
- public List<NormalizedNode<?, ?>> read(final T schemaNode) throws ReadingException {
- if (isReadingWanted(schemaNode)) {
- final ConsoleContext ctx = getContext(schemaNode);
- console.enterContext(ctx);
- try {
- return readWithContext(schemaNode);
- } catch (final IOException e) {
- throw new ReadingException("Unable to read data from input for " + schemaNode.getQName(), e);
- } finally {
- console.leaveContext();
- }
- }
- return Collections.emptyList();
- }
-
- private boolean isReadingWanted(final DataSchemaNode node) {
- if (readConfigNode && !node.isConfiguration()) {
- return false;
- }
- return true;
- }
-
- // TODO javadoc
-
- protected abstract List<NormalizedNode<?, ?>> readWithContext(T schemaNode) throws IOException, ReadingException;
-
- protected abstract ConsoleContext getContext(T schemaNode);
-
- protected Optional<String> getDefaultValue(final T schemaNode) {
- String defaultValue = null;
- if (schemaNode instanceof LeafSchemaNode) {
- defaultValue = ((LeafSchemaNode) schemaNode).getDefault();
- } else if (schemaNode instanceof ChoiceSchemaNode) {
- defaultValue = ((ChoiceSchemaNode) schemaNode).getDefaultCase();
- }
-
- return Optional.fromNullable(defaultValue);
- }
-
- protected boolean isEmptyInput(final String rawValue) {
- return Strings.isNullOrEmpty(rawValue);
- }
-
- protected static boolean isEmptyType(final TypeDefinition<?> type) {
- return type instanceof EmptyTypeDefinition;
- }
-
- private static class NullContext implements ConsoleContext {
- @Override
- public Completer getCompleter() {
- return new NullCompleter();
- }
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.absent();
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader;
-
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-/**
- * marker interface to mark reader which can be used with GenericListReader
- */
-public interface GenericListEntryReader<T extends DataSchemaNode> extends Reader<T> {
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader;
-
-import java.util.List;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-/**
- * Generic provider(reader) of input arguments for commands
- */
-public interface Reader<T extends DataSchemaNode> {
-
- List<NormalizedNode<?, ?>> read(T schemaNode) throws ReadingException;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader;
-
-public class ReadingException extends Exception {
-
- private static final long serialVersionUID = -298382323286156591L;
-
- public ReadingException(final String msg, final Exception e) {
- super(msg, e);
- }
-
- public ReadingException(final String msg) {
- super(msg);
- }
-
- public static class IncorrectValueException extends ReadingException {
-
- private static final long serialVersionUID = 164168437058431592L;
-
- public IncorrectValueException(final String msg) {
- super(msg);
- }
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.custom;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import jline.console.completer.Completer;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Custom reader implementation for filter elements in get/get-config rpcs. This
- * reader overrides the default anyxml reader and reads filter as a schema path.
- */
-public class ConfigReader extends AbstractReader<DataSchemaNode> {
-
- public static final String SEPARATOR = "/";
-
- private final CommandArgHandlerRegistry commandArgHandlerRegistry;
- private final Map<String, QName> mappedModules;
- private final Map<URI, QName> mappedModulesNamespace;
-
- public ConfigReader(final ConsoleIO console, final SchemaContext remoteSchemaContext,
- final CommandArgHandlerRegistry commandArgHandlerRegistry) {
- super(console, remoteSchemaContext);
- this.commandArgHandlerRegistry = commandArgHandlerRegistry;
-
- mappedModules = Maps.newHashMap();
- mappedModulesNamespace = Maps.newHashMap();
- for (final Module module : remoteSchemaContext.getModules()) {
- final QName moduleQName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
- mappedModules.put(moduleQName.getLocalName(), moduleQName);
- mappedModulesNamespace.put(moduleQName.getNamespace(), moduleQName);
- }
- }
-
- // FIXME refactor + unite common code with FilterReader
-
- @Override
- protected List<NormalizedNode<?, ?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
- console.writeLn("Config " + schemaNode.getQName().getLocalName());
- console.writeLn("Submit path of the data to edit. Use TAB for autocomplete");
-
- final String rawValue = console.read();
-
- // FIXME isSkip check should be somewhere in abstractReader
- if (isSkipInput(rawValue) || Strings.isNullOrEmpty(rawValue)) {
- return Collections.emptyList();
- }
-
- final List<QName> filterPartsQNames = Lists.newArrayList();
-
- for (final String part : rawValue.split(SEPARATOR)) {
- final QName qName = IOUtil.qNameFromKeyString(part, mappedModules);
- filterPartsQNames.add(qName);
- }
-
- List<? extends NormalizedNode<?, ?>> previous = readInnerNode(rawValue);
-
- for (final QName qName : Lists.reverse(filterPartsQNames).subList(1, filterPartsQNames.size())) {
- previous = Collections.<NormalizedNode<?, ?>>singletonList(
- ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(qName))
- .withValue(previous == null ? Collections.<DataContainerChild<?, ?>>emptyList() : (Collection) previous).build()
- );
- }
-
- if (previous == null) {
- return Collections.singletonList(null);
- }
-
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = ImmutableContainerNodeBuilder.create();
- builder.withNodeIdentifier(new NodeIdentifier(schemaNode.getQName()));
- builder.withValue((Collection<DataContainerChild<?, ?>>) previous);
-
- return Collections.<NormalizedNode<?, ?>> singletonList(builder.build());
- }
-
- private List<NormalizedNode<?, ?>> readInnerNode(final String pathString) throws ReadingException {
- final Optional<DataSchemaNode> schema = getCurrentNode(getSchemaContext(), pathString);
- Preconditions.checkState(schema.isPresent(), "Unable to find schema for %s", pathString);
- return commandArgHandlerRegistry.getGenericReader(getSchemaContext(), true).read(schema.get());
- }
-
- @Override
- protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
- return new FilterConsoleContext(schemaNode, getSchemaContext());
- }
-
- private final class FilterConsoleContext extends BaseConsoleContext<DataSchemaNode> {
-
- private final SchemaContext remoteSchemaContext;
-
- public FilterConsoleContext(final DataSchemaNode schemaNode, final SchemaContext remoteSchemaContext) {
- super(schemaNode);
- this.remoteSchemaContext = remoteSchemaContext;
- }
-
- @Override
- protected List<Completer> getAdditionalCompleters() {
- return Collections.<Completer> singletonList(new FilterCompleter(remoteSchemaContext));
- }
- }
-
- private final class FilterCompleter implements Completer {
-
- private final SchemaContext remoteSchemaContext;
-
- public FilterCompleter(final SchemaContext remoteSchemaContext) {
- this.remoteSchemaContext = remoteSchemaContext;
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- final int idx = buffer.lastIndexOf(SEPARATOR);
-
- final Optional<DataSchemaNode> currentNode = getCurrentNode(remoteSchemaContext, buffer);
- if (currentNode.isPresent() && currentNode.get() instanceof DataNodeContainer) {
- final Collection<DataSchemaNode> childNodes = ((DataNodeContainer) currentNode.get()).getChildNodes();
- final Collection<String> transformed = Collections2.transform(childNodes,
- new Function<DataSchemaNode, String>() {
- @Override
- public String apply(final DataSchemaNode input) {
- return IOUtil.qNameToKeyString(input.getQName(),
- mappedModulesNamespace.get(input.getQName().getNamespace()).getLocalName());
- }
- });
-
- fillCandidates(buffer.substring(idx + 1), candidates, transformed);
- }
-
- return idx == -1 ? 0 : idx + 1;
- }
-
- private void fillCandidates(final String buffer, final List<CharSequence> candidates,
- final Collection<String> transformed) {
- final SortedSet<String> strings = new TreeSet<>(transformed);
-
- if (buffer == null) {
- candidates.addAll(strings);
- } else {
- for (final String match : strings.tailSet(buffer)) {
- if (!match.startsWith(buffer)) {
- break;
- }
- candidates.add(match);
- }
- }
-
- if (candidates.size() == 1) {
- candidates.set(0, candidates.get(0) + SEPARATOR);
- }
- }
-
- }
-
- private Optional<DataSchemaNode> getCurrentNode(DataSchemaNode parent, final String buffer) {
- for (final String part : buffer.split(SEPARATOR)) {
- if (IOUtil.isQName(part) == false) {
- return Optional.of(parent);
- }
-
- final QName qName;
- try {
- qName = IOUtil.qNameFromKeyString(part, mappedModules);
- } catch (final ReadingException e) {
- return Optional.of(parent);
- }
- if (parent instanceof DataNodeContainer) {
- parent = ((DataNodeContainer) parent).getDataChildByName(qName);
- } else {
- // This should check if we are at the end of buffer ?
- return Optional.of(parent);
- }
- }
- return Optional.of(parent);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.custom;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.controller.netconf.cli.reader.impl.ChoiceReader;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class EditContentReader extends ChoiceReader {
-
- public static final QName EDIT_CONTENT_QNAME = QName.create(CommandConstants.NETCONF_BASE_QNAME, "edit-content");
- public static final QName CONFIG_QNAME = QName.create(EDIT_CONTENT_QNAME, "config");
-
- // FIXME this could be removed if feature/if-feature are supported
-
- public EditContentReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry, final SchemaContext schemaContext) {
- super(console, argumentHandlerRegistry, schemaContext);
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final ChoiceSchemaNode choiceNode) throws IOException, ReadingException {
- Preconditions.checkState(choiceNode.getQName().equals(EDIT_CONTENT_QNAME), "Unexpected choice %s, expected %s", choiceNode, EDIT_CONTENT_QNAME);
- final ChoiceCaseNode selectedCase = choiceNode.getCaseNodeByName(CONFIG_QNAME);
- Preconditions.checkNotNull(selectedCase, "Unexpected choice %s, expected %s that contains %s", choiceNode, EDIT_CONTENT_QNAME, CONFIG_QNAME);
- return readSelectedCase(selectedCase);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.custom;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Strings;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import jline.console.completer.Completer;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Custom reader implementation for filter elements in get/get-config rpcs. This
- * reader overrides the default anyxml reader and reads filter as a schema path.
- */
-public class FilterReader extends AbstractReader<DataSchemaNode> {
-
- private static final Logger LOG = LoggerFactory.getLogger(FilterReader.class);
-
- public static final String SEPARATOR = "/";
-
- private final Map<String, QName> mappedModules;
- private final Map<URI, QName> mappedModulesNamespace;
-
- public FilterReader(final ConsoleIO console, final SchemaContext remoteSchemaContext) {
- super(console, remoteSchemaContext);
-
- mappedModules = Maps.newHashMap();
- mappedModulesNamespace = Maps.newHashMap();
- for (final Module module : remoteSchemaContext.getModules()) {
- final QName moduleQName = QName.create(module.getNamespace(), module.getRevision(), module.getName());
- mappedModules.put(moduleQName.getLocalName(), moduleQName);
- mappedModulesNamespace.put(moduleQName.getNamespace(), moduleQName);
- }
- }
-
- // FIXME refactor
-
- public static final QName FILTER_TYPE_QNAME = QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "2011-06-01",
- "type");
- public static final String FILTER_TYPE_VALUE_DEFAULT = "subtree";
-
- @Override
- protected List<NormalizedNode<?, ?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
- boolean redSuccessfuly = false;
- DataContainerChild<?, ?> newNode = null;
- do {
- console.writeLn("Filter " + schemaNode.getQName().getLocalName());
- console.writeLn("Submit path of the data to retrieve. Use TAB for autocomplete");
-
- final String rawValue = console.read();
-
- // FIXME skip should be somewhere in abstractReader
- if (isSkipInput(rawValue) || Strings.isNullOrEmpty(rawValue)) {
- return Collections.emptyList();
- }
-
- final List<QName> filterPartsQNames = Lists.newArrayList();
-
- try {
- for (final String part : rawValue.split(SEPARATOR)) {
- final QName qName = IOUtil.qNameFromKeyString(part, mappedModules);
- filterPartsQNames.add(qName);
- }
-
- DataContainerChild<?, ?> previous = null;
-
- for (final QName qName : Lists.reverse(filterPartsQNames)) {
- previous = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(qName))
- .withValue(previous == null ? Collections.<DataContainerChild<?, ?>>emptyList()
- : Collections.<DataContainerChild<?, ?>>singletonList(previous)).build();
- }
-
- final Map<QName, String> attributes = Collections.singletonMap(FILTER_TYPE_QNAME,
- FILTER_TYPE_VALUE_DEFAULT);
- newNode = previous == null ? null : ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(schemaNode.getQName())).withChild(previous).build();
- redSuccessfuly = true;
- } catch (final ReadingException e) {
- final String message = "Specified filter path isn't correct.";
- LOG.error(message, e);
- console.writeLn(message);
- }
- } while (!redSuccessfuly);
- return Collections.<NormalizedNode<?, ?>> singletonList(newNode);
- }
-
- @Override
- protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
- return new FilterConsoleContext(schemaNode, getSchemaContext());
- }
-
- private final class FilterConsoleContext extends BaseConsoleContext<DataSchemaNode> {
-
- private final SchemaContext remoteSchemaContext;
-
- public FilterConsoleContext(final DataSchemaNode schemaNode, final SchemaContext remoteSchemaContext) {
- super(schemaNode);
- this.remoteSchemaContext = remoteSchemaContext;
- }
-
- @Override
- protected List<Completer> getAdditionalCompleters() {
- return Collections.<Completer> singletonList(new FilterCompleter(remoteSchemaContext));
- }
-
- }
-
- private final class FilterCompleter implements Completer {
-
- private final SchemaContext remoteSchemaContext;
-
- // TODO add skip to filter completer, better soulution would be to add
- // SKIP completer before context completer if possible
-
- public FilterCompleter(final SchemaContext remoteSchemaContext) {
- this.remoteSchemaContext = remoteSchemaContext;
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- final int idx = buffer.lastIndexOf(SEPARATOR);
-
- final Optional<DataNodeContainer> currentNode = getCurrentNode(remoteSchemaContext, buffer);
- if (currentNode.isPresent()) {
-
- final Collection<String> transformed = Collections2.transform(currentNode.get().getChildNodes(),
- new Function<DataSchemaNode, String>() {
- @Override
- public String apply(final DataSchemaNode input) {
- return IOUtil.qNameToKeyString(input.getQName(),
- mappedModulesNamespace.get(input.getQName().getNamespace()).getLocalName());
- }
- });
-
- fillCandidates(buffer.substring(idx + 1), candidates, transformed);
- }
-
- return idx == -1 ? 0 : idx + 1;
- }
-
- private void fillCandidates(final String buffer, final List<CharSequence> candidates,
- final Collection<String> transformed) {
- final SortedSet<String> strings = new TreeSet<>(transformed);
-
- if (buffer == null) {
- candidates.addAll(strings);
- } else {
- for (final String match : strings.tailSet(buffer)) {
- if (!match.startsWith(buffer)) {
- break;
- }
- candidates.add(match);
- }
- }
-
- if (candidates.size() == 1) {
- candidates.set(0, candidates.get(0) + SEPARATOR);
- }
- }
-
- private Optional<DataNodeContainer> getCurrentNode(DataNodeContainer parent, final String buffer) {
- for (final String part : buffer.split(SEPARATOR)) {
- if (!IOUtil.isQName(part)) {
- return Optional.of(parent);
- }
-
- QName qName;
- try {
- qName = IOUtil.qNameFromKeyString(part, mappedModules);
- } catch (final ReadingException e) {
- return Optional.of(parent);
- }
-
- final DataSchemaNode dataChildByName = parent.getDataChildByName(qName);
- if (dataChildByName instanceof DataNodeContainer) {
- parent = (DataNodeContainer) dataChildByName;
- } else {
- return Optional.absent();
- }
- }
- return Optional.of(parent);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.custom;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import jline.console.completer.Completer;
-import jline.console.completer.NullCompleter;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.impl.BasicDataHolderReader;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-public class PasswordReader extends BasicDataHolderReader<DataSchemaNode> {
-
- private static final char PASSWORD_MASK = '*';
-
- public PasswordReader(final ConsoleIO console, final SchemaContext schemaContext) {
- super(console, schemaContext);
- }
-
- @Override
- protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
- return new BaseConsoleContext<DataSchemaNode>(schemaNode) {
- @Override
- public Completer getCompleter() {
- return new NullCompleter();
- }
- };
- }
-
- @Override
- protected TypeDefinition<?> getType(final DataSchemaNode schemaNode) {
- Preconditions.checkArgument(schemaNode instanceof LeafSchemaNode);
- return ((LeafSchemaNode)schemaNode).getType();
- }
-
- @Override
- protected String readValue() throws IOException {
- return console.read(PASSWORD_MASK);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
-
-import com.google.common.base.Optional;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-public class AnyXmlReader extends AbstractReader<AnyXmlSchemaNode> {
-
- public AnyXmlReader(final ConsoleIO console, final SchemaContext schemaContext) {
- super(console, schemaContext);
- }
-
- public AnyXmlReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- }
-
- @Override
- protected List<NormalizedNode<?, ?>> readWithContext(final AnyXmlSchemaNode schemaNode) throws IOException, ReadingException {
- console.writeLn(listType(schemaNode) + " " + schemaNode.getQName().getLocalName());
-
- final String rawValue = console.read();
-
- DataContainerChild<?, ?> newNode = null;
- if (!isSkipInput(rawValue)) {
- final Optional<DataContainerChild<?, ?>> value = tryParse(rawValue, schemaNode);
-
- if (value.isPresent()) {
- newNode = ImmutableContainerNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(schemaNode.getQName()))
- .withChild(value.get()).build();
- } else {
- newNode = ImmutableLeafNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(schemaNode.getQName())).withValue(rawValue).build();
- }
- }
-
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- newNodes.add(newNode);
- return newNodes;
- }
-
- private Optional<DataContainerChild<?, ?>> tryParse(final String rawValue, final AnyXmlSchemaNode schemaNode) {
- try {
- final Document dom = XmlUtil.readXmlToDocument(rawValue);
- return Optional.<DataContainerChild<?, ?>> of(
- DomToNormalizedNodeParserFactory.
- getInstance(DomUtils.defaultValueCodecProvider(), getSchemaContext()).
- getAnyXmlNodeParser().
- parse(Collections.singletonList(dom.getDocumentElement()), schemaNode)
- );
- } catch (SAXException | IOException e) {
- // TODO log
- return Optional.absent();
- }
- }
-
- @Override
- protected ConsoleContext getContext(final AnyXmlSchemaNode schemaNode) {
- return new BaseConsoleContext<>(schemaNode);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.HashBiMap;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
-import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class BasicDataHolderReader<T extends DataSchemaNode> extends AbstractReader<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(BasicDataHolderReader.class);
- private DataHolderCompleter currentCompleter;
-
- public BasicDataHolderReader(final ConsoleIO console, final SchemaContext schemaContext,
- final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- }
-
- public BasicDataHolderReader(final ConsoleIO console, final SchemaContext schemaContext) {
- super(console, schemaContext);
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final T schemaNode) throws IOException, ReadingException {
- TypeDefinition<?> type = getType(schemaNode);
- console.formatLn("Submit %s %s(%s)", listType(schemaNode), schemaNode.getQName().getLocalName(), type.getQName().getLocalName());
-
- while (baseTypeFor(type) instanceof UnionTypeDefinition) {
- final Optional<TypeDefinition<?>> optionalTypeDef = new UnionTypeReader(console).read(type);
- if (!optionalTypeDef.isPresent()) {
- return postSkipOperations(schemaNode);
- }
- type = optionalTypeDef.get();
- }
-
- if (currentCompleter == null) {
- currentCompleter = getBaseCompleter(schemaNode);
- }
-
- // TODO what if type is leafref, instance-identifier?
-
- // Handle empty type leaf by question
- if (isEmptyType(type)) {
- final Optional<Boolean> shouldAddEmpty = new DecisionReader().read(console, "Add empty type leaf %s ?",
- schemaNode.getQName().getLocalName());
- if (shouldAddEmpty.isPresent()) {
- if (shouldAddEmpty.get()) {
- return wrapValue(schemaNode, "");
- } else {
- return Collections.emptyList();
- }
- } else {
- return postSkipOperations(schemaNode);
- }
- }
-
- final String rawValue = readValue();
- if (isSkipInput(rawValue)) {
- return postSkipOperations(schemaNode);
- }
-
- final Object resolvedValue = currentCompleter.resolveValue(rawValue);
-
- // Reset state TODO should be in finally
- currentCompleter = null;
- return wrapValue(schemaNode, resolvedValue);
- }
-
- private List<NormalizedNode<?, ?>> postSkipOperations(final DataSchemaNode schemaNode) throws IOException {
- console.formatLn("Skipping %s", schemaNode.getQName());
- return Collections.emptyList();
- }
-
- private TypeDefinition<?> baseTypeFor(final TypeDefinition<?> type) {
- if (type.getBaseType() != null) {
- return baseTypeFor(type.getBaseType());
- }
- return type;
- }
-
- protected String readValue() throws IOException {
- return console.read();
- }
-
- private List<NormalizedNode<?, ?>> wrapValue(final T schemaNode, final Object value) {
- final NormalizedNode<?, ?> newNode = ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(schemaNode.getQName()))
- .withValue(value).build();
- return Collections.<NormalizedNode<?, ?>>singletonList(newNode);
- }
-
- protected abstract TypeDefinition<?> getType(final T schemaNode);
-
- protected final DataHolderCompleter getBaseCompleter(final T schemaNode) {
- final TypeDefinition<?> type = getType(schemaNode);
- final DataHolderCompleter currentCompleter;
-
- // Add enum completer
- if (type instanceof EnumTypeDefinition) {
- currentCompleter = new EnumDataHolderCompleter(type);
- } else if (type instanceof IdentityrefTypeDefinition) {
- currentCompleter = new IdentityRefDataHolderCompleter(type, getSchemaContext());
- } else {
- currentCompleter = new GeneralDataHolderCompleter(type);
- }
- this.currentCompleter = currentCompleter;
- return currentCompleter;
- }
-
- private static interface DataHolderCompleter extends Completer {
-
- Object resolveValue(String rawValue) throws ReadingException;
- }
-
- private static class GeneralDataHolderCompleter implements DataHolderCompleter {
-
- private final Optional<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> codec;
- private final TypeDefinition<?> type;
-
- public GeneralDataHolderCompleter(final TypeDefinition<?> type) {
- this.type = type;
- codec = getCodecForType(type);
- }
-
- protected TypeDefinition<?> getType() {
- return type;
- }
-
- private Optional<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> getCodecForType(
- final TypeDefinition<?> type) {
- if (type != null) {
- return Optional
- .<TypeDefinitionAwareCodec<Object, ? extends TypeDefinition<?>>> fromNullable(TypeDefinitionAwareCodec
- .from(type));
- }
- return Optional.absent();
- }
-
- @Override
- public Object resolveValue(final String rawValue) throws ReadingException {
- try {
- return codec.isPresent() ? codec.get().deserialize(rawValue) : rawValue;
- } catch (final RuntimeException e) {
- final String message = "It wasn't possible deserialize value " + rawValue + ".";
- LOG.error(message, e);
- throw new ReadingException(message, e);
- }
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- return 0;
- }
- }
-
- private static final class EnumDataHolderCompleter extends GeneralDataHolderCompleter {
-
- public EnumDataHolderCompleter(final TypeDefinition<?> type) {
- super(type);
- }
-
- @Override
- public Object resolveValue(final String rawValue) throws ReadingException {
- return super.resolveValue(rawValue);
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
- return new StringsCompleter(Collections2.transform(((EnumTypeDefinition) getType()).getValues(),
- new Function<EnumPair, String>() {
- @Override
- public String apply(final EnumPair input) {
- return input.getName();
- }
- })).complete(buffer, cursor, candidates);
- }
- }
-
- private static final class IdentityRefDataHolderCompleter extends GeneralDataHolderCompleter {
-
- private final BiMap<String, QName> identityMap;
-
- public IdentityRefDataHolderCompleter(final TypeDefinition<?> type, final SchemaContext schemaContext) {
- super(type);
- this.identityMap = getIdentityMap(schemaContext);
- }
-
- private static BiMap<String, QName> getIdentityMap(final SchemaContext schemaContext) {
- final BiMap<String, QName> identityMap = HashBiMap.create();
- for (final Module module : schemaContext.getModules()) {
- for (final IdentitySchemaNode identity : module.getIdentities()) {
- identityMap.put(getIdentityName(identity, module), identity.getQName());
- }
- }
- return identityMap;
- }
-
- private static String getIdentityName(final IdentitySchemaNode rpcDefinition, final Module module) {
- return IOUtil.qNameToKeyString(rpcDefinition.getQName(), module.getName());
- }
-
- @Override
- public Object resolveValue(final String rawValue) throws ReadingException {
- final QName qName = identityMap.get(rawValue);
- if (qName == null) {
- throw new ReadingException("No identity found for " + rawValue + " available " + identityMap.keySet());
- }
- return qName;
- }
-
- @Override
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
-
- return new StringsCompleter(Collections2.transform(((IdentityrefTypeDefinition) getType()).getIdentity()
- .getDerivedIdentities(), new Function<IdentitySchemaNode, String>() {
- @Override
- public String apply(final IdentitySchemaNode input) {
- return identityMap.inverse().get(input.getQName());
- }
- })).complete(buffer, cursor, candidates);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ChoiceReader extends AbstractReader<ChoiceSchemaNode> {
-
- private static final Logger LOG = LoggerFactory.getLogger(ChoiceReader.class);
-
- private final CommandArgHandlerRegistry argumentHandlerRegistry;
-
- public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext) {
- super(console, schemaContext);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- public ChoiceReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final ChoiceSchemaNode choiceNode) throws IOException, ReadingException {
- final Map<String, ChoiceCaseNode> availableCases = collectAllCases(choiceNode);
- console.formatLn("Select case for choice %s from: %s", choiceNode.getQName().getLocalName(),
- formatSet(availableCases.keySet()));
-
- ChoiceCaseNode selectedCase = null;
- final String rawValue = console.read();
- if (isSkipInput(rawValue)) {
- return Collections.emptyList();
- }
-
- selectedCase = availableCases.get(rawValue);
- if (selectedCase == null) {
- final String message = String.format("Incorrect value (%s) for choice %s was selected.", rawValue,
- choiceNode.getQName().getLocalName());
- LOG.error(message);
- throw new ReadingException(message);
- }
-
- return Collections.<NormalizedNode<?, ?>>singletonList(
- ImmutableChoiceNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(choiceNode.getQName()))
- .withValue(((Collection) readSelectedCase(selectedCase))).build());
- }
-
- protected List<NormalizedNode<?, ?>> readSelectedCase(final ChoiceCaseNode selectedCase) throws ReadingException {
- // IF there is a case that contains only one Empty type leaf, create the
- // leaf without question, since the case was selected
- if (containsOnlyOneEmptyLeaf(selectedCase)) {
- final NormalizedNode<?, ?> newNode = ImmutableLeafNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(selectedCase.getChildNodes().iterator().next().getQName())).build();
- return Collections.<NormalizedNode<?, ?>>singletonList(newNode);
- }
-
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- for (final DataSchemaNode schemaNode : selectedCase.getChildNodes()) {
- newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
- schemaNode));
- }
- return newNodes;
- }
-
- private Object formatSet(final Set<String> values) {
- final StringBuilder formatedValues = new StringBuilder();
- for (final String value : values) {
- formatedValues.append("\n ");
- formatedValues.append(value);
- }
- return formatedValues.toString();
- }
-
- private boolean containsOnlyOneEmptyLeaf(final ChoiceCaseNode selectedCase) {
- if (selectedCase.getChildNodes().size() != 1) {
- return false;
- }
- final DataSchemaNode next = selectedCase.getChildNodes().iterator().next();
- if (next instanceof LeafSchemaNode) {
- final TypeDefinition<?> type = ((LeafSchemaNode) next).getType();
- if (isEmptyType(type)) {
- return true;
- }
- }
- return false;
- }
-
- private Map<String, ChoiceCaseNode> collectAllCases(final ChoiceSchemaNode schemaNode) {
- return Maps.uniqueIndex(schemaNode.getCases(), new Function<ChoiceCaseNode, String>() {
- @Override
- public String apply(final ChoiceCaseNode input) {
- return input.getQName().getLocalName();
- }
- });
- }
-
- @Override
- protected ConsoleContext getContext(final ChoiceSchemaNode schemaNode) {
- return new BaseConsoleContext<ChoiceSchemaNode>(schemaNode) {
- @Override
- public List<Completer> getAdditionalCompleters() {
- return Collections
- .<Completer> singletonList(new StringsCompleter(collectAllCases(schemaNode).keySet()));
- }
- };
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class ContainerReader extends AbstractReader<ContainerSchemaNode> {
-
- private final CommandArgHandlerRegistry argumentHandlerRegistry;
- private static final InputArgsLocalNameComparator CONTAINER_CHILDS_SORTER = new InputArgsLocalNameComparator();
-
- public ContainerReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext) {
- super(console, schemaContext);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- public ContainerReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final ContainerSchemaNode containerNode) throws IOException, ReadingException {
- console.formatLn("Submit child nodes for container: %s, %s", containerNode.getQName().getLocalName(),
- Collections2.transform(containerNode.getChildNodes(), new Function<DataSchemaNode, String>() {
- @Override
- public String apply(final DataSchemaNode input) {
- return input.getQName().getLocalName();
- }
- }));
- final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = ImmutableContainerNodeBuilder.create();
- builder.withNodeIdentifier(new NodeIdentifier(containerNode.getQName()));
-
- final ArrayList<NormalizedNode<?, ?>> nodesToAdd = new ArrayList<>();
- final SeparatedNodes separatedNodes = SeparatedNodes.separateNodes(containerNode, getReadConfigNode());
- for (final DataSchemaNode childNode : sortChildren(separatedNodes.getMandatoryNotKey())) {
- final List<NormalizedNode<?, ?>> redNodes = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
- getReadConfigNode()).read(childNode);
- if (redNodes.isEmpty()) {
- console.formatLn("No data specified for mandatory element %s.", childNode.getQName().getLocalName());
- return Collections.emptyList();
- } else {
- nodesToAdd.addAll(redNodes);
- }
- }
-
- for (final DataSchemaNode childNode : sortChildren(separatedNodes.getOthers())) {
- nodesToAdd.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(),
- getReadConfigNode()).read(childNode));
- }
- return Collections.<NormalizedNode<?, ?>> singletonList(builder.withValue((ArrayList) nodesToAdd).build());
- }
-
- private List<DataSchemaNode> sortChildren(final Set<DataSchemaNode> unsortedNodes) {
- final List<DataSchemaNode> childNodes = Lists.newArrayList(unsortedNodes);
- Collections.sort(childNodes, CONTAINER_CHILDS_SORTER);
- return childNodes;
- }
-
- @Override
- protected ConsoleContext getContext(final ContainerSchemaNode schemaNode) {
- return new BaseConsoleContext<>(schemaNode);
- }
-
- private static class InputArgsLocalNameComparator implements Comparator<DataSchemaNode> {
- @Override
- public int compare(final DataSchemaNode o1, final DataSchemaNode o2) {
- return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.SKIP;
-
-import com.google.common.base.Optional;
-import java.io.IOException;
-import jline.console.completer.AggregateCompleter;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import jline.internal.Log;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-
-public class DecisionReader {
-
- private static final String YES = "Y";
- private static final String NO = "N";
- public static final Completer YES_NO_COMPLETER = new StringsCompleter(YES, NO);
-
- public Optional<Boolean> read(final ConsoleIO console, final String questionMessageBlueprint,
- final Object... questionMessageArgs) throws IOException, ReadingException {
- final ConsoleContext ctx = getContext();
- console.enterContext(ctx);
- try {
- console.formatLn(questionMessageBlueprint, questionMessageArgs);
- final String rawValue = console.read();
- if (YES.equals(rawValue.toUpperCase())) {
- return Optional.of(Boolean.TRUE);
- } else if (NO.equals(rawValue.toUpperCase())) {
- return Optional.of(Boolean.FALSE);
- } else if (SKIP.equals(rawValue)) {
- return Optional.absent();
- } else {
- final String message = String.format("Incorrect possibility (%s) was selected", rawValue);
- Log.error(message);
- throw new ReadingException(message);
- }
- } finally {
- console.leaveContext();
- }
- }
-
- private static ConsoleContext getContext() {
- return new ConsoleContext() {
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.absent();
- }
-
- @Override
- public Completer getCompleter() {
- return new AggregateCompleter(YES_NO_COMPLETER, new StringsCompleter(IOUtil.SKIP));
- }
-
- };
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.listType;
-
-import com.google.common.base.Optional;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class GenericListReader<T extends DataSchemaNode> extends AbstractReader<T> {
- private static final Logger LOG = LoggerFactory.getLogger(GenericListReader.class);
-
- private final GenericListEntryReader<T> concreteListEntryReader;
-
- public GenericListReader(final ConsoleIO console, final GenericListEntryReader<T> concreteListEntryReader,
- final SchemaContext schemaContext) {
- super(console, schemaContext);
- this.concreteListEntryReader = concreteListEntryReader;
- }
-
- public GenericListReader(final ConsoleIO console, final GenericListEntryReader<T> concreteListEntryReader,
- final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- this.concreteListEntryReader = concreteListEntryReader;
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final T schemaNode) throws IOException, ReadingException {
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- Optional<Boolean> readNextListEntry = Optional.of(Boolean.TRUE);
- console.formatLn("Reading collection type argument: %s", schemaNode.getQName().getLocalName());
- while (readNextListEntry.isPresent() && readNextListEntry.get()) {
- try {
- newNodes.addAll(concreteListEntryReader.read(schemaNode));
- } catch (final ReadingException e) {
- console.writeLn(e.getMessage());
- }
- readNextListEntry = new DecisionReader().read(console, "Add other entry to " + listType(schemaNode) + " "
- + schemaNode.getQName().getLocalName() + " " + " [Y|N]?");
- }
- console.formatLn("Collection type argument: %s read finished", schemaNode.getQName().getLocalName());
-
- return newNodes;
- }
-
- @Override
- protected ConsoleContext getContext(final T schemaNode) {
- return new BaseConsoleContext<>(schemaNode);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
-import org.opendaylight.controller.netconf.cli.reader.Reader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-
-public class GenericReader extends AbstractReader<DataSchemaNode> {
-
- private final CommandArgHandlerRegistry argumentHandlerRegistry;
-
- public GenericReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext) {
- super(console, schemaContext);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- public GenericReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- @Override
- protected List<NormalizedNode<?, ?>> readWithContext(final DataSchemaNode schemaNode) throws IOException, ReadingException {
- final Optional<Class<? extends Reader<DataSchemaNode>>> customReaderClassOpt = tryGetCustomHandler(schemaNode);
-
- if (customReaderClassOpt.isPresent()) {
- // TODO resolve class cast of generic custom readers
- final Reader<DataSchemaNode> customReaderInstance = (Reader<DataSchemaNode>) argumentHandlerRegistry
- .getCustomReader(customReaderClassOpt.get());
- Preconditions.checkNotNull(customReaderInstance, "Unknown custom reader: %s", customReaderClassOpt.get());
- return customReaderInstance.read(schemaNode);
- } else {
- return readGeneric(schemaNode);
- }
-
- // TODO reuse instances
- }
-
- private List<NormalizedNode<?, ?>> readGeneric(final DataSchemaNode schemaNode) throws ReadingException, IOException {
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- boolean isRedCorrectly = false;
- do {
- try {
- if (schemaNode instanceof LeafSchemaNode) {
- return new LeafReader(console, getSchemaContext(), getReadConfigNode())
- .read((LeafSchemaNode) schemaNode);
- } else if (schemaNode instanceof ContainerSchemaNode) {
- return new ContainerReader(console, argumentHandlerRegistry, getSchemaContext(),
- getReadConfigNode()).read((ContainerSchemaNode) schemaNode);
- } else if (schemaNode instanceof ListSchemaNode) {
- final GenericListEntryReader<ListSchemaNode> entryReader = new ListEntryReader(console,
- argumentHandlerRegistry, getSchemaContext(), getReadConfigNode());
- return new GenericListReader<>(console, entryReader, getSchemaContext(), getReadConfigNode())
- .read((ListSchemaNode) schemaNode);
- } else if (schemaNode instanceof LeafListSchemaNode) {
- final GenericListEntryReader<LeafListSchemaNode> entryReader = new LeafListEntryReader(console,
- getSchemaContext(), getReadConfigNode());
- return new GenericListReader<>(console, entryReader, getSchemaContext(), getReadConfigNode())
- .read((LeafListSchemaNode) schemaNode);
- } else if (schemaNode instanceof ChoiceSchemaNode) {
- return new ChoiceReader(console, argumentHandlerRegistry, getSchemaContext(), getReadConfigNode())
- .read((ChoiceSchemaNode) schemaNode);
- } else if (schemaNode instanceof AnyXmlSchemaNode) {
- return new AnyXmlReader(console, getSchemaContext(), getReadConfigNode())
- .read((AnyXmlSchemaNode) schemaNode);
- }
- isRedCorrectly = true;
- } catch (final ReadingException e) {
- console.writeLn(e.getMessage());
- }
- } while (!isRedCorrectly);
- return newNodes;
- }
-
- @Override
- protected ConsoleContext getContext(final DataSchemaNode schemaNode) {
- // return null context, leave context to specific implementations
- return NULL_CONTEXT;
- }
-
- private <T> Optional<Class<? extends T>> tryGetCustomHandler(final DataSchemaNode dataSchemaNode) {
-
- for (final UnknownSchemaNode unknownSchemaNode : dataSchemaNode.getUnknownSchemaNodes()) {
-
- if (isExtenstionForCustomHandler(unknownSchemaNode)) {
- final String argumentHandlerClassName = unknownSchemaNode.getNodeParameter();
- try {
- final Class<?> argumentClass = Class.forName(argumentHandlerClassName);
- // TODO add check before cast
- return Optional.<Class<? extends T>> of((Class<? extends T>) argumentClass);
- } catch (final ClassNotFoundException e) {
- throw new IllegalArgumentException("Unknown custom reader class " + argumentHandlerClassName
- + " for: " + dataSchemaNode.getQName());
- }
- }
- }
-
- return Optional.absent();
- }
-
- private boolean isExtenstionForCustomHandler(final UnknownSchemaNode unknownSchemaNode) {
- final QName qName = unknownSchemaNode.getExtensionDefinition().getQName();
- return qName.equals(CommandConstants.ARG_HANDLER_EXT_QNAME);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import java.util.List;
-import jline.console.completer.Completer;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-class LeafListEntryReader extends BasicDataHolderReader<LeafListSchemaNode> implements
- GenericListEntryReader<LeafListSchemaNode> {
-
- public LeafListEntryReader(final ConsoleIO console, final SchemaContext schemaContext) {
- super(console, schemaContext);
- }
-
- public LeafListEntryReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- }
-
- @Override
- protected TypeDefinition<?> getType(final LeafListSchemaNode schemaNode) {
- return schemaNode.getType();
- }
-
- @Override
- protected ConsoleContext getContext(final LeafListSchemaNode schemaNode) {
- return new BaseConsoleContext<LeafListSchemaNode>(schemaNode) {
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.of("[entry]");
- }
-
- @Override
- protected List<Completer> getAdditionalCompleters() {
- return Lists.<Completer> newArrayList(getBaseCompleter(getDataSchemaNode()));
- }
- };
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import java.util.List;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
-public class LeafReader extends BasicDataHolderReader<LeafSchemaNode> {
-
- public LeafReader(final ConsoleIO console, final SchemaContext schemaContext) {
- super(console, schemaContext);
- }
-
- public LeafReader(final ConsoleIO console, final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- }
-
- @Override
- protected TypeDefinition<?> getType(final LeafSchemaNode schemaNode) {
- return schemaNode.getType();
- }
-
- @Override
- protected ConsoleContext getContext(final LeafSchemaNode schemaNode) {
- return new BaseConsoleContext<LeafSchemaNode>(schemaNode) {
- @Override
- public List<Completer> getAdditionalCompleters() {
- final List<Completer> completers = Lists.<Completer> newArrayList(getBaseCompleter(schemaNode));
- final Optional<String> defaultValue = getDefaultValue(schemaNode);
- if (defaultValue.isPresent()) {
- completers.add(new StringsCompleter(defaultValue.get()));
- }
- return completers;
- }
- };
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.Collections2;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.controller.netconf.cli.CommandArgHandlerRegistry;
-import org.opendaylight.controller.netconf.cli.io.BaseConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.reader.AbstractReader;
-import org.opendaylight.controller.netconf.cli.reader.GenericListEntryReader;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class ListEntryReader extends AbstractReader<ListSchemaNode> implements GenericListEntryReader<ListSchemaNode> {
- private static final Logger LOG = LoggerFactory.getLogger(ListEntryReader.class);
-
- private final CommandArgHandlerRegistry argumentHandlerRegistry;
-
- public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext) {
- super(console, schemaContext);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- public ListEntryReader(final ConsoleIO console, final CommandArgHandlerRegistry argumentHandlerRegistry,
- final SchemaContext schemaContext, final boolean readConfigNode) {
- super(console, schemaContext, readConfigNode);
- this.argumentHandlerRegistry = argumentHandlerRegistry;
- }
-
- @Override
- public List<NormalizedNode<?, ?>> readWithContext(final ListSchemaNode listNode) throws IOException, ReadingException {
- console.formatLn("Submit child nodes for list entry: %s, %s", listNode.getQName().getLocalName(),
- Collections2.transform(listNode.getChildNodes(), new Function<DataSchemaNode, String>() {
- @Override
- public String apply(final DataSchemaNode input) {
- return input.getQName().getLocalName();
- }
- }));
-
- final String listName = listNode.getQName().getLocalName();
-
- final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
- ImmutableMapEntryNodeBuilder.create();
-// final CompositeNodeBuilder<ImmutableCompositeNode> compositeNodeBuilder = ImmutableCompositeNode.builder();
-// compositeNodeBuilder.setQName(listNode.getQName());
-
- final SeparatedNodes separatedChildNodes = SeparatedNodes.separateNodes(listNode, getReadConfigNode());
-
- final List<NormalizedNode<?, ?>> nodes = readKeys(separatedChildNodes.getKeyNodes());
- final Map<QName, Object> qnameToValues = new HashMap<>();
- for (NormalizedNode node : nodes) {
- qnameToValues.put(node.getNodeType(), node.getValue());
- }
- builder.withNodeIdentifier(new NodeIdentifierWithPredicates(listNode.getQName(), qnameToValues));
-
- nodes.addAll(readMandatoryNotKeys(separatedChildNodes.getMandatoryNotKey()));
- if (!separatedChildNodes.getOthers().isEmpty()) {
- final Optional<Boolean> readNodesWhichAreNotKey = new DecisionReader().read(console,
- "Add non-key, non-mandatory nodes to list %s? [Y|N]", listName);
- if (readNodesWhichAreNotKey.isPresent() && readNodesWhichAreNotKey.get()) {
- nodes.addAll(readNotKeys(separatedChildNodes.getOthers()));
- }
- }
-
- if (!nodes.isEmpty()) {
-// compositeNodeBuilder.addAll(nodes);
- builder.withValue((List) nodes);
- return Collections.<NormalizedNode<?, ?>>singletonList(
- ImmutableMapNodeBuilder.create()
- .withNodeIdentifier(new NodeIdentifier(listNode.getQName()))
- .withChild(builder.build()).build());
-// return Collections.<DataContainerChild<?, ?>> singletonList(compositeNodeBuilder.toInstance());
- } else {
- return Collections.emptyList();
- }
- }
-
- private List<NormalizedNode<?, ?>> readKeys(final Set<DataSchemaNode> keys) throws ReadingException, IOException {
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- console.writeLn("Reading keys:");
- for (final DataSchemaNode key : keys) {
- final List<NormalizedNode<?, ?>> readKey = new LeafReader(console, getSchemaContext(), getReadConfigNode())
- .read((LeafSchemaNode) key);
- if (readKey.size() != 1) {
- final String message = String.format(
- "Value for key element %s has to be set. Creation of this entry is canceled.", key.getQName()
- .getLocalName());
- LOG.error(message);
- throw new ReadingException(message);
- }
- newNodes.addAll(readKey);
- }
-
- return newNodes;
- }
-
- private List<NormalizedNode<?, ?>> readMandatoryNotKeys(final Set<DataSchemaNode> mandatoryNotKeys) throws ReadingException,
- IOException {
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- console.writeLn("Reading mandatory not keys nodes:");
-
- for (final DataSchemaNode mandatoryNode : mandatoryNotKeys) {
- final List<NormalizedNode<?, ?>> redValue = argumentHandlerRegistry.getGenericReader(getSchemaContext(),
- getReadConfigNode()).read(mandatoryNode);
- if (redValue.isEmpty()) {
- final String message = String.format(
- "Value for mandatory element %s has to be set. Creation of this entry is canceled.",
- mandatoryNode.getQName().getLocalName());
- LOG.error(message);
- throw new ReadingException(message);
- }
- newNodes.addAll(redValue);
- }
- return newNodes;
- }
-
- private List<NormalizedNode<?, ?>> readNotKeys(final Set<DataSchemaNode> notKeys) throws ReadingException {
- final List<NormalizedNode<?, ?>> newNodes = new ArrayList<>();
- for (final DataSchemaNode notKey : notKeys) {
- newNodes.addAll(argumentHandlerRegistry.getGenericReader(getSchemaContext(), getReadConfigNode()).read(
- notKey));
- }
- return newNodes;
- }
-
- @Override
- protected ConsoleContext getContext(final ListSchemaNode schemaNode) {
- return new BaseConsoleContext<ListSchemaNode>(schemaNode) {
- @Override
- public Optional<String> getPrompt() {
- return Optional.of("[entry]");
- }
- };
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-class SeparatedNodes {
- private final Set<DataSchemaNode> keyNodes;
- private final Set<DataSchemaNode> mandatoryNotKey;
- private final Set<DataSchemaNode> otherNodes;
-
- public SeparatedNodes(final Set<DataSchemaNode> keyNodes, final Set<DataSchemaNode> mandatoryNotKey,
- final Set<DataSchemaNode> otherNodes) {
- this.keyNodes = keyNodes;
- this.mandatoryNotKey = mandatoryNotKey;
- this.otherNodes = otherNodes;
- }
-
- public Set<DataSchemaNode> getKeyNodes() {
- return keyNodes;
- }
-
- public Set<DataSchemaNode> getMandatoryNotKey() {
- return mandatoryNotKey;
- }
-
- public Set<DataSchemaNode> getOthers() {
- return otherNodes;
- }
-
- static SeparatedNodes separateNodes(final DataNodeContainer dataNodeContainer) {
- return separateNodes(dataNodeContainer, false);
- }
-
- static SeparatedNodes separateNodes(final DataNodeContainer dataNodeContainer, final boolean removeConfigFalseNodes) {
- final Set<DataSchemaNode> keys = new HashSet<>();
- final Set<DataSchemaNode> mandatoryNotKeys = new HashSet<>();
- final Set<DataSchemaNode> others = new HashSet<>();
-
- List<QName> keyQNames = Collections.emptyList();
- if (dataNodeContainer instanceof ListSchemaNode) {
- keyQNames = ((ListSchemaNode) dataNodeContainer).getKeyDefinition();
- }
-
- for (final DataSchemaNode dataSchemaNode : dataNodeContainer.getChildNodes()) {
- if (removeConfigFalseNodes) {
- if (!dataSchemaNode.isConfiguration()) {
- continue;
- }
- }
- if (keyQNames.contains(dataSchemaNode.getQName())) {
- Preconditions.checkArgument(dataSchemaNode instanceof LeafSchemaNode);
- keys.add(dataSchemaNode);
- } else if (dataSchemaNode.getConstraints().isMandatory()) {
- mandatoryNotKeys.add(dataSchemaNode);
- } else {
- others.add(dataSchemaNode);
- }
- }
-
- return new SeparatedNodes(keys, mandatoryNotKeys, others);
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.reader.impl;
-
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.isSkipInput;
-
-import com.google.common.base.Optional;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import jline.console.completer.AggregateCompleter;
-import jline.console.completer.Completer;
-import jline.console.completer.StringsCompleter;
-import org.opendaylight.controller.netconf.cli.io.ConsoleContext;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.io.IOUtil;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class UnionTypeReader {
- private static final Logger LOG = LoggerFactory.getLogger(UnionTypeReader.class);
-
- private final ConsoleIO console;
-
- public UnionTypeReader(final ConsoleIO console) {
- this.console = console;
- }
-
- public Optional<TypeDefinition<?>> read(final TypeDefinition<?> unionTypeDefinition) throws IOException,
- ReadingException {
- final ConsoleContext context = getContext(unionTypeDefinition);
- console.enterContext(context);
- try {
- final Map<String, TypeDefinition<?>> mapping = ((UnionConsoleContext) context).getMenuItemMapping();
- console.formatLn("The element is of type union. Choose concrete type from: %s", mapping.keySet());
-
- final String rawValue = console.read();
- if (isSkipInput(rawValue)) {
- return Optional.absent();
- }
- final TypeDefinition<?> value = mapping.get(rawValue);
- if (value != null) {
- return Optional.<TypeDefinition<?>> of(value);
- } else {
- final String message = String.format("Incorrect type (%s) was specified for union type definition", rawValue);
- LOG.error(message);
- throw new ReadingException(message);
- }
- } finally {
- console.leaveContext();
- }
- }
-
- private UnionConsoleContext getContext(final TypeDefinition<?> typeDefinition) {
- return new UnionConsoleContext(typeDefinition);
- }
-
- private class UnionConsoleContext implements ConsoleContext {
-
- private final TypeDefinition<?> typeDef;
- private final Map<String, TypeDefinition<?>> menuItemsToTypeDefinitions = new HashMap<>();
-
- public UnionConsoleContext(final TypeDefinition<?> typeDef) {
- this.typeDef = typeDef;
- }
-
- @Override
- public Optional<String> getPrompt() {
- return Optional.of("type[" + typeDef.getQName().getLocalName() + "]");
- }
-
- @Override
- public Completer getCompleter() {
- List<TypeDefinition<?>> subtypesForMenu = resolveSubtypesFrom(typeDef);
- if (subtypesForMenu.isEmpty()) {
- subtypesForMenu = Collections.<TypeDefinition<?>> singletonList(typeDef);
- }
- final Collection<String> menuItems = toMenuItem(subtypesForMenu);
- return new AggregateCompleter(new StringsCompleter(menuItems), new StringsCompleter(IOUtil.SKIP));
- }
-
- public Map<String, TypeDefinition<?>> getMenuItemMapping() {
- return menuItemsToTypeDefinitions;
- }
-
- private Collection<String> toMenuItem(final List<TypeDefinition<?>> allTypesBehindUnion) {
- final List<String> result = new ArrayList<String>();
- for (final TypeDefinition<?> type : allTypesBehindUnion) {
- final String menuItem = type.getQName().getLocalName();
- menuItemsToTypeDefinitions.put(menuItem, type);
- result.add(menuItem);
- }
- return result;
- }
-
- /**
- *
- * If union type is found in potentialEndTypeCandidate as subtype then
- * it these subtypes become candidates.
- *
- * @param potentialEndTypeCandidate
- * candidate to node which has no union subtype
- */
- private List<TypeDefinition<?>> resolveSubtypesFrom(final TypeDefinition<?> potentialEndTypeCandidate) {
- if (potentialEndTypeCandidate instanceof UnionTypeDefinition) {
- return ((UnionTypeDefinition) potentialEndTypeCandidate).getTypes();
- }
- if (potentialEndTypeCandidate.getBaseType() == null) {
- return Collections.emptyList();
- }
- return resolveSubtypesFrom(potentialEndTypeCandidate.getBaseType());
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer;
-
-public class OutFormatter {
-
- public static final String INDENT_STEP = " ";
- public static final String COMPOSITE_OPEN_NODE = " {";
- public static final String COMPOSITE_CLOSE_NODE = "}";
- public static final String NEW_LINE = "\n";
-
- int indentLevel = -1;
- private String currentIndent = "";
-
- public OutFormatter indent(final StringBuilder buffer) {
- buffer.append(currentIndent);
- return this;
- }
-
- public OutFormatter openComposite(final StringBuilder buffer) {
- buffer.append(COMPOSITE_OPEN_NODE);
- return this;
- }
-
- public OutFormatter closeCompositeWithIndent(final StringBuilder buffer) {
- buffer.append(currentIndent);
- buffer.append(COMPOSITE_CLOSE_NODE);
- return this;
- }
-
- public OutFormatter newLine(final StringBuilder buffer) {
- buffer.append(NEW_LINE);
- return this;
- }
-
- private void prepareIndent() {
- final StringBuilder output = new StringBuilder();
- for (int i = 0; i < indentLevel; i++) {
- output.append(INDENT_STEP);
- }
- currentIndent = output.toString();
- }
-
- public OutFormatter increaseIndent() {
- indentLevel++;
- prepareIndent();
- return this;
- }
-
- public OutFormatter decreaseIndent() {
- indentLevel--;
- prepareIndent();
- return this;
- }
-
- public OutFormatter addStringWithIndent(final StringBuilder buffer, final String value) {
- indent(buffer);
- buffer.append(value);
- return this;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer;
-
-public class WriteException extends Exception {
-
- private static final long serialVersionUID = 8401242676753560336L;
-
- public WriteException(final String msg, final Exception e) {
- super(msg, e);
- }
-
- public WriteException(final String msg) {
- super(msg);
- }
-
- public static class IncorrectNumberOfNodes extends WriteException {
- private static final long serialVersionUID = 8910285140705622920L;
-
- public IncorrectNumberOfNodes(final String msg) {
- super(msg);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer;
-
-import java.util.List;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-/**
- * Generic handler(writer) of output elements for commands
- */
-public interface Writer<T extends DataSchemaNode> {
-
- void write(T dataSchemaNode, List<NormalizedNode<?, ?>> dataNodes) throws WriteException;
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.custom;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.controller.netconf.cli.writer.WriteException;
-import org.opendaylight.controller.netconf.cli.writer.impl.AbstractWriter;
-import org.opendaylight.controller.netconf.cli.writer.impl.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class DataWriter extends AbstractWriter<DataSchemaNode> {
-
- private final OutFormatter out;
- private final SchemaContext remoteSchemaContext;
-
- public DataWriter(final ConsoleIO console, final OutFormatter out, final SchemaContext remoteSchemaContext) {
- super(console);
- this.out = out;
- this.remoteSchemaContext = remoteSchemaContext;
- }
-
- @Override
- protected void writeInner(final DataSchemaNode dataSchemaNode, final List<NormalizedNode<?, ?>> dataNodes) throws IOException, WriteException {
- Preconditions.checkArgument(dataNodes.size() == 1, "Expected only 1 element for data node");
- final NormalizedNode<?, ?> dataNode = dataNodes.get(0);
- Preconditions.checkArgument(dataNode instanceof ContainerNode, "Unexpected node type: %s, should be %s", dataNode, ContainerNode.class);
-
- StringBuilder output = new StringBuilder();
- out.increaseIndent().addStringWithIndent(output, dataSchemaNode.getQName().getLocalName()).openComposite(output);
- console.writeLn(output.toString());
-
- for (final Object oChildNode : ((DataContainerNode) dataNode).getValue()) {
- final NormalizedNode<?, ?> childNode = (NormalizedNode<?, ?>) oChildNode;
- final Optional<DataSchemaNode> schemaNode = XmlDocumentUtils.findFirstSchema(childNode.getNodeType(), remoteSchemaContext.getDataDefinitions());
- Preconditions.checkState(schemaNode.isPresent(), "Unknown data node %s, not defined in schema", childNode.getNodeType());
- new NormalizedNodeWriter(console, out).write(schemaNode.get(), Collections.<NormalizedNode<?, ?>>singletonList(childNode));
- }
-
- output = new StringBuilder();
- out.decreaseIndent().closeCompositeWithIndent(output);
- console.writeLn(output.toString());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import java.io.IOException;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.writer.WriteException;
-import org.opendaylight.controller.netconf.cli.writer.Writer;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-
-public abstract class AbstractWriter<T extends DataSchemaNode> implements Writer<T> {
-
- protected ConsoleIO console;
-
- public AbstractWriter(final ConsoleIO console) {
- this.console = console;
- }
-
- @Override
- public void write(final T dataSchemaNode, final List<NormalizedNode<?, ?>> dataNodes) throws WriteException {
- try {
- writeInner(dataSchemaNode, dataNodes);
- } catch (final IOException e) {
- throw new WriteException("Unable to write data to output for " + dataSchemaNode.getQName(), e);
- }
- }
-
- protected abstract void writeInner(final T dataSchemaNode, final List<NormalizedNode<?, ?>> dataNodes) throws IOException,
- WriteException;
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.AugmentationNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-final class AugmentationNodeCliSerializer extends AugmentationNodeBaseSerializer<String> {
-
- private final NodeSerializerDispatcher<String> dispatcher;
- private final OutFormatter out;
-
- AugmentationNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
- this.out = Preconditions.checkNotNull(out);
- this.dispatcher = Preconditions.checkNotNull(dispatcher);
- }
-
- @Override
- public Iterable<String> serialize(final AugmentationSchema schema, final AugmentationNode node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, "augment");
- out.openComposite(output);
- out.newLine(output);
-
- for (final String childOutput : super.serialize(schema, node)) {
- output.append(childOutput);
- out.newLine(output);
- }
-
- out.closeCompositeWithIndent(output);
- out.decreaseIndent();
- return Collections.singletonList(output.toString());
- }
-
- @Override
- protected NodeSerializerDispatcher<String> getNodeDispatcher() {
- return dispatcher;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.ChoiceNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-
-final class ChoiceNodeCliSerializer extends ChoiceNodeBaseSerializer<String> {
- private final NodeSerializerDispatcher<String> dispatcher;
- private final OutFormatter out;
-
- ChoiceNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
- this.out = Preconditions.checkNotNull(out);
- this.dispatcher = Preconditions.checkNotNull(dispatcher);
- }
-
- @Override
- public Iterable<String> serialize(final ChoiceSchemaNode schema, final ChoiceNode node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, "choice ");
- output.append(schema.getQName().getLocalName());
- output.append(" (");
- output.append(detectCase(schema, node));
- output.append(") ");
- out.openComposite(output);
- out.newLine(output);
-
- for (final String childOutput : super.serialize(schema, node)) {
- output.append(childOutput);
- out.newLine(output);
- }
-
- out.closeCompositeWithIndent(output);
- out.decreaseIndent();
- return Collections.singletonList(output.toString());
- }
-
- private String detectCase(final ChoiceSchemaNode schema, final ChoiceNode node) {
- for (final DataContainerChild<? extends PathArgument, ?> caseChild : node.getValue()) {
- final QName presentChildQName = caseChild.getNodeType();
- for (final ChoiceCaseNode choiceCaseNode : schema.getCases()) {
- if (choiceCaseNode.getDataChildByName(presentChildQName) != null) {
- // Pick the first case that contains first child node
- return choiceCaseNode.getQName().getLocalName();
- }
- }
- }
-
- // Should not happen, nodes should come from one of the cases
- throw new IllegalStateException("Choice node " + node + " does not conform to choice schema " + schema);
- }
-
- @Override
- protected NodeSerializerDispatcher<String> getNodeDispatcher() {
- return dispatcher;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializerFactory;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-public final class CliOutputFromNormalizedNodeSerializerFactory implements FromNormalizedNodeSerializerFactory<String> {
- private final ContainerNodeCliSerializer containerSerializer;
- private final ChoiceNodeCliSerializer choiceSerializer;
- private final AugmentationNodeCliSerializer augmentSerializer;
- private final LeafNodeCliSerializer leafNodeSerializer;
- private final LeafSetNodeCliSerializer leafSetSerializer;
- private final MapNodeCliSerializer mapNodeSerializer;
- private final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer;
- private final MapEntryNodeCliSerializer mapEntryNodeSerializer;
- final NodeSerializerDispatcher<String> dispatcher = new NodeCliSerializerDispatcher(this);
-
- private CliOutputFromNormalizedNodeSerializerFactory(final OutFormatter out, final XmlCodecProvider codecProvider) {
-
- containerSerializer = new ContainerNodeCliSerializer(out, dispatcher);
- choiceSerializer = new ChoiceNodeCliSerializer(out, dispatcher);
- augmentSerializer = new AugmentationNodeCliSerializer(out, dispatcher);
- leafNodeSerializer = new LeafNodeCliSerializer(out);
-
- leafSetEntryNodeSerializer = new LeafSetEntryNodeCliSerializer(out);
- leafSetSerializer = new LeafSetNodeCliSerializer(out, leafSetEntryNodeSerializer);
-
- mapEntryNodeSerializer = new MapEntryNodeCliSerializer(out, dispatcher);
- mapNodeSerializer = new MapNodeCliSerializer(out, mapEntryNodeSerializer);
- }
-
- public NodeSerializerDispatcher<String> getDispatcher() {
- return dispatcher;
- }
-
- public static CliOutputFromNormalizedNodeSerializerFactory getInstance(final OutFormatter out,
- final XmlCodecProvider codecProvider) {
- return new CliOutputFromNormalizedNodeSerializerFactory(out, codecProvider);
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, AugmentationNode, AugmentationSchema> getAugmentationNodeSerializer() {
- return augmentSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, ChoiceNode, ChoiceSchemaNode> getChoiceNodeSerializer() {
- return choiceSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, ContainerNode, ContainerSchemaNode> getContainerNodeSerializer() {
- return containerSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, LeafNode<?>, LeafSchemaNode> getLeafNodeSerializer() {
- return leafNodeSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, LeafSetEntryNode<?>, LeafListSchemaNode> getLeafSetEntryNodeSerializer() {
- return leafSetEntryNodeSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, LeafSetNode<?>, LeafListSchemaNode> getLeafSetNodeSerializer() {
- return leafSetSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, MapEntryNode, ListSchemaNode> getMapEntryNodeSerializer() {
- return mapEntryNodeSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, UnkeyedListNode, ListSchemaNode> getUnkeyedListNodeSerializer() {
- return null;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, MapNode, ListSchemaNode> getMapNodeSerializer() {
- return mapNodeSerializer;
- }
-
- @Override
- public FromNormalizedNodeSerializer<String, AnyXmlNode, AnyXmlSchemaNode> getAnyXmlNodeSerializer() {
- throw new UnsupportedOperationException();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.ContainerNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-
-final class ContainerNodeCliSerializer extends ContainerNodeBaseSerializer<String> {
-
- private final NodeSerializerDispatcher<String> dispatcher;
- private final OutFormatter out;
-
- ContainerNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
- this.out = Preconditions.checkNotNull(out);
- this.dispatcher = Preconditions.checkNotNull(dispatcher);
- }
-
- @Override
- public Iterable<String> serialize(final ContainerSchemaNode schema, final ContainerNode containerNode) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, containerNode.getNodeType().getLocalName());
- out.openComposite(output);
- out.newLine(output);
-
- for (final String childOutput : super.serialize(schema, containerNode)) {
- output.append(childOutput);
- out.newLine(output);
- }
-
- out.closeCompositeWithIndent(output);
- out.decreaseIndent();
- return Collections.singletonList(output.toString());
- }
-
- @Override
- protected NodeSerializerDispatcher<String> getNodeDispatcher() {
- return dispatcher;
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.LeafNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-
-final class LeafNodeCliSerializer extends LeafNodeBaseSerializer<String> {
- private final OutFormatter out;
-
- LeafNodeCliSerializer(final OutFormatter out) {
- this.out = Preconditions.checkNotNull(out);
- }
-
- @Override
- public String serializeLeaf(final LeafSchemaNode schema, final LeafNode<?> node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, node.getNodeType().getLocalName());
- output.append(" ");
- output.append(node.getValue());
- out.decreaseIndent();
- return output.toString();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.LeafSetEntryNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-
-final class LeafSetEntryNodeCliSerializer extends LeafSetEntryNodeBaseSerializer<String> {
-
- private final OutFormatter out;
-
- public LeafSetEntryNodeCliSerializer(final OutFormatter out) {
- this.out = out;
- }
-
- @Override
- protected String serializeLeaf(final LeafListSchemaNode schema, final LeafSetEntryNode<?> node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, node.getValue().toString());
- out.decreaseIndent();
- return output.toString();
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import java.util.Collections;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-
-final class LeafSetNodeCliSerializer implements
- FromNormalizedNodeSerializer<String, LeafSetNode<?>, LeafListSchemaNode> {
- private final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer;
- private final OutFormatter out;
-
- LeafSetNodeCliSerializer(final OutFormatter out, final LeafSetEntryNodeCliSerializer leafSetEntryNodeSerializer) {
- this.out = out;
- this.leafSetEntryNodeSerializer = leafSetEntryNodeSerializer;
- }
-
- @Override
- public Iterable<String> serialize(final LeafListSchemaNode schema, final LeafSetNode<?> node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, node.getNodeType().getLocalName());
- out.openComposite(output);
- out.newLine(output);
- for (final LeafSetEntryNode<?> leafEntryNode : node.getValue()) {
- final Iterable<String> valueFromLeafSetEntry = leafSetEntryNodeSerializer.serialize(schema, leafEntryNode);
- output.append(valueFromLeafSetEntry.iterator().next());
- out.newLine(output);
- }
- out.closeCompositeWithIndent(output);
- out.decreaseIndent();
- return Collections.singletonList(output.toString());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.ListEntryNodeBaseSerializer;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-final class MapEntryNodeCliSerializer extends ListEntryNodeBaseSerializer<String,MapEntryNode> {
-
- private final NodeSerializerDispatcher<String> dispatcher;
- private final OutFormatter out;
-
- MapEntryNodeCliSerializer(final OutFormatter out, final NodeSerializerDispatcher<String> dispatcher) {
- this.out = Preconditions.checkNotNull(out);
- this.dispatcher = Preconditions.checkNotNull(dispatcher);
- }
-
- @Override
- public Iterable<String> serialize(final ListSchemaNode schema, final MapEntryNode node) {
- final StringBuilder output = new StringBuilder();
- out.increaseIndent();
- out.addStringWithIndent(output, node.getNodeType().getLocalName());
- serializeKeysIfPresent(node, output);
-
- out.openComposite(output);
- out.newLine(output);
-
- for (final String childOutput : super.serialize(schema, node)) {
- output.append(childOutput);
- out.newLine(output);
- }
-
- out.closeCompositeWithIndent(output);
- out.newLine(output);
- out.decreaseIndent();
- return Collections.singletonList(output.toString());
- }
-
- private void serializeKeysIfPresent(final MapEntryNode node, final StringBuilder output) {
- final Map<QName, Object> keyValues = node.getIdentifier().getKeyValues();
- if (keyValues.isEmpty()) {
- return;
- }
-
- int i = 0;
- output.append(" [");
- for (final Entry<QName, Object> qNameObjectEntry : keyValues.entrySet()) {
- output.append(qNameObjectEntry.getKey().getLocalName());
- output.append("=");
- output.append(qNameObjectEntry.getValue().toString());
- if (++i != keyValues.size()) {
- output.append(", ");
- }
- }
- output.append("]");
- }
-
- @Override
- protected NodeSerializerDispatcher<String> getNodeDispatcher() {
- return dispatcher;
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import java.util.Collections;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-final class MapNodeCliSerializer implements FromNormalizedNodeSerializer<String, MapNode, ListSchemaNode> {
-
- private final FromNormalizedNodeSerializer<String, MapEntryNode, ListSchemaNode> mapEntrySerializer;
- private final OutFormatter out;
-
- MapNodeCliSerializer(final OutFormatter out, final MapEntryNodeCliSerializer mapEntrySerializer) {
- this.out = Preconditions.checkNotNull(out);
- this.mapEntrySerializer = mapEntrySerializer;
- }
-
- @Override
- public Iterable<String> serialize(final ListSchemaNode schema, final MapNode node) {
- final StringBuilder output = new StringBuilder();
-
- out.increaseIndent();
- out.addStringWithIndent(output, node.getNodeType().getLocalName());
- output.append(" ");
- out.openComposite(output);
- out.newLine(output);
-
- for (final MapEntryNode mapEntryNode : node.getValue()) {
- final Iterable<String> valueFromLeafSetEntry = mapEntrySerializer.serialize(schema, mapEntryNode);
- output.append(valueFromLeafSetEntry.iterator().next());
- }
-
- out.closeCompositeWithIndent(output);
- out.decreaseIndent();
-
- return Collections.singletonList(output.toString());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.FromNormalizedNodeSerializerFactory;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-public class NodeCliSerializerDispatcher implements NodeSerializerDispatcher<String> {
- private final FromNormalizedNodeSerializerFactory<String> factory;
-
- public NodeCliSerializerDispatcher(final FromNormalizedNodeSerializerFactory<String> factory) {
- this.factory = Preconditions.checkNotNull(factory);
- }
-
- @Override
- public final Iterable<String> dispatchChildElement(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- if (dataContainerChild instanceof ContainerNode) {
- return onContainerNode(childSchema, dataContainerChild);
- } else if (dataContainerChild instanceof LeafNode<?>) {
- return onLeafNode(childSchema, dataContainerChild);
- } else if (dataContainerChild instanceof MixinNode) {
- if (dataContainerChild instanceof LeafSetNode<?>) {
- return onLeafListNode(childSchema, dataContainerChild);
- } else if (dataContainerChild instanceof MapNode) {
- return onListNode(childSchema, dataContainerChild);
- } else if (dataContainerChild instanceof ChoiceNode) {
- return onChoiceNode(childSchema, dataContainerChild);
- } else if (dataContainerChild instanceof AugmentationNode) {
- return onAugmentationSchema(childSchema, dataContainerChild);
- }
- }
- throw new IllegalArgumentException("Unable to serialize " + childSchema);
- }
-
- private Iterable<String> onAugmentationSchema(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, AugmentationSchema.class, dataContainerChild);
- return factory.getAugmentationNodeSerializer().serialize((AugmentationSchema) childSchema,
- (AugmentationNode) dataContainerChild);
- }
-
- private Iterable<String> onChoiceNode(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, ChoiceSchemaNode.class, dataContainerChild);
- return factory.getChoiceNodeSerializer().serialize(
- (ChoiceSchemaNode) childSchema, (ChoiceNode) dataContainerChild);
- }
-
- private Iterable<String> onListNode(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, ListSchemaNode.class, dataContainerChild);
- return factory.getMapNodeSerializer().serialize((ListSchemaNode) childSchema, (MapNode) dataContainerChild);
- }
-
- private Iterable<String> onLeafListNode(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, LeafListSchemaNode.class, dataContainerChild);
- return factory.getLeafSetNodeSerializer().serialize((LeafListSchemaNode) childSchema,
- (LeafSetNode<?>) dataContainerChild);
- }
-
- private Iterable<String> onLeafNode(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, LeafSchemaNode.class, dataContainerChild);
- final Iterable<String> elements = factory.getLeafNodeSerializer().serialize((LeafSchemaNode) childSchema,
- (LeafNode<?>) dataContainerChild);
- checkOnlyOneSerializedElement(elements, dataContainerChild);
- return elements;
- }
-
- private static void checkOnlyOneSerializedElement(final Iterable<?> elements,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- final int size = Iterables.size(elements);
- Preconditions.checkArgument(size == 1,
- "Unexpected count of elements for entry serialized from: %s, should be 1, was: %s", dataContainerChild,
- size);
- }
-
- private Iterable<String> onContainerNode(final Object childSchema,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- checkSchemaCompatibility(childSchema, ContainerSchemaNode.class, dataContainerChild);
-
- final Iterable<String> elements = factory.getContainerNodeSerializer().serialize(
- (ContainerSchemaNode) childSchema, (ContainerNode) dataContainerChild);
- checkOnlyOneSerializedElement(elements, dataContainerChild);
- return elements;
- }
-
- private static void checkSchemaCompatibility(final Object childSchema, final Class<?> containerSchemaNodeClass,
- final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild) {
- Preconditions.checkArgument(containerSchemaNodeClass.isAssignableFrom(childSchema.getClass()),
- "Incompatible schema: %s with node: %s, expected: %s", childSchema, dataContainerChild,
- containerSchemaNodeClass);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.writer.impl;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIO;
-import org.opendaylight.controller.netconf.cli.writer.OutFormatter;
-import org.opendaylight.controller.netconf.cli.writer.WriteException;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer.NodeSerializerDispatcher;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NormalizedNodeWriter extends AbstractWriter<DataSchemaNode> {
-
- private static final Logger LOG = LoggerFactory.getLogger(NormalizedNodeWriter.class);
- private final OutFormatter out;
-
- public NormalizedNodeWriter(final ConsoleIO console, final OutFormatter out) {
- super(console);
- this.out = out;
- }
-
- public void writeInner(final DataSchemaNode dataSchemaNode, final List<NormalizedNode<?, ?>> dataNodes) throws WriteException,
- IOException {
- //Preconditions.checkState(dataNodes.size() == 1);
- // TODO - add getDispatcher method to CnSnToNormalizedNodeParserFactory
- // to be able call dispatchChildElement
- final NormalizedNode<?, ?> dataContainerChild = dataNodes.get(0);
-
- if (dataContainerChild != null) {
- console.writeLn(serializeToCliOutput(dataContainerChild, dataSchemaNode));
- }
-
- }
-
- private String serializeToCliOutput(final NormalizedNode<?, ?> dataContainerChild,
- final DataSchemaNode childSchema) {
- final CliOutputFromNormalizedNodeSerializerFactory factorySerialization = CliOutputFromNormalizedNodeSerializerFactory
- .getInstance(out, DomUtils.defaultValueCodecProvider());
- final NodeSerializerDispatcher<String> dispatcher = factorySerialization.getDispatcher();
- final Iterable<String> result = dispatcher.dispatchChildElement(childSchema, (DataContainerChild<?, ?>) dataContainerChild);
-
- if (result == null) {
- return "";
- }
-
- final Iterator<String> output = result.iterator();
- if (!output.hasNext()) {
- return "";
- }
-
- return output.next();
- }
-
-}
+++ /dev/null
-
-<configuration scan="true">
- <appender name="netconfcli.log" class="ch.qos.logback.core.FileAppender">
- <file>netconfcli.log</file>
-
- <encoder>
- <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level
- %logger{35} - %msg%n</pattern>
- </encoder>
-
- </appender>
-
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder
- by default -->
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
- </pattern>
- </encoder>
- </appender>
-
-
-
- <root level="trace">
- <appender-ref ref="netconfcli.log" />
- <!-- <appender-ref ref="STDOUT" /> -->
- </root>
-
- <!-- <logger name="org.opendaylight.yangtools.yang.model.api" level="TRACE"
- additivity="false"> <appender-ref ref="netconfcli.log" /> </logger> -->
-</configuration>
+++ /dev/null
-module ietf-inet-types {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
- prefix "inet";
-
- organization
- "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netmod/>
- WG List: <mailto:netmod@ietf.org>
-
- WG Chair: David Partain
- <mailto:david.partain@ericsson.com>
-
- WG Chair: David Kessens
- <mailto:david.kessens@nsn.com>
-
- Editor: Juergen Schoenwaelder
- <mailto:j.schoenwaelder@jacobs-university.de>";
-
- description
- "This module contains a collection of generally useful derived
- YANG data types for Internet addresses and related things.
-
- Copyright (c) 2010 IETF Trust and the persons identified as
- authors of the code. All rights reserved.
-
-
-
- Redistribution and use in source and binary forms, with or without
- modification, is permitted pursuant to, and subject to the license
- terms contained in, the Simplified BSD License set forth in Section
- 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6021; see
- the RFC itself for full legal notices.";
-
- revision 2010-09-24 {
- description
- "Initial revision.";
- reference
- "RFC 6021: Common YANG Data Types";
- }
-
- /*** collection of protocol field related types ***/
-
- typedef ip-version {
- type enumeration {
- enum unknown {
- value "0";
- description
- "An unknown or unspecified version of the Internet protocol.";
- }
- enum ipv4 {
- value "1";
- description
- "The IPv4 protocol as defined in RFC 791.";
- }
- enum ipv6 {
- value "2";
- description
- "The IPv6 protocol as defined in RFC 2460.";
- }
- }
- description
- "This value represents the version of the IP protocol.
-
- In the value set and its semantics, this type is equivalent
- to the InetVersion textual convention of the SMIv2.";
- reference
- "RFC 791: Internet Protocol
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- typedef dscp {
- type uint8 {
- range "0..63";
- }
- description
- "The dscp type represents a Differentiated Services Code-Point
- that may be used for marking packets in a traffic stream.
-
- In the value set and its semantics, this type is equivalent
- to the Dscp textual convention of the SMIv2.";
- reference
- "RFC 3289: Management Information Base for the Differentiated
- Services Architecture
- RFC 2474: Definition of the Differentiated Services Field
- (DS Field) in the IPv4 and IPv6 Headers
- RFC 2780: IANA Allocation Guidelines For Values In
- the Internet Protocol and Related Headers";
- }
-
- typedef ipv6-flow-label {
- type uint32 {
- range "0..1048575";
- }
- description
- "The flow-label type represents flow identifier or Flow Label
- in an IPv6 packet header that may be used to discriminate
- traffic flows.
-
- In the value set and its semantics, this type is equivalent
- to the IPv6FlowLabel textual convention of the SMIv2.";
- reference
- "RFC 3595: Textual Conventions for IPv6 Flow Label
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
- }
-
- typedef port-number {
- type uint16 {
- range "0..65535";
- }
- description
- "The port-number type represents a 16-bit port number of an
- Internet transport layer protocol such as UDP, TCP, DCCP, or
- SCTP. Port numbers are assigned by IANA. A current list of
- all assignments is available from <http://www.iana.org/>.
-
- Note that the port number value zero is reserved by IANA. In
- situations where the value zero does not make sense, it can
- be excluded by subtyping the port-number type.
-
- In the value set and its semantics, this type is equivalent
- to the InetPortNumber textual convention of the SMIv2.";
- reference
- "RFC 768: User Datagram Protocol
- RFC 793: Transmission Control Protocol
- RFC 4960: Stream Control Transmission Protocol
- RFC 4340: Datagram Congestion Control Protocol (DCCP)
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- /*** collection of autonomous system related types ***/
-
- typedef as-number {
- type uint32;
- description
- "The as-number type represents autonomous system numbers
- which identify an Autonomous System (AS). An AS is a set
- of routers under a single technical administration, using
- an interior gateway protocol and common metrics to route
- packets within the AS, and using an exterior gateway
- protocol to route packets to other ASs'. IANA maintains
- the AS number space and has delegated large parts to the
- regional registries.
-
- Autonomous system numbers were originally limited to 16
- bits. BGP extensions have enlarged the autonomous system
- number space to 32 bits. This type therefore uses an uint32
- base type without a range restriction in order to support
- a larger autonomous system number space.
-
- In the value set and its semantics, this type is equivalent
- to the InetAutonomousSystemNumber textual convention of
- the SMIv2.";
- reference
- "RFC 1930: Guidelines for creation, selection, and registration
- of an Autonomous System (AS)
- RFC 4271: A Border Gateway Protocol 4 (BGP-4)
- RFC 4893: BGP Support for Four-octet AS Number Space
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- /*** collection of IP address and hostname related types ***/
-
- typedef ip-address {
- type union {
- type inet:ipv4-address;
- type inet:ipv6-address;
- }
- description
- "The ip-address type represents an IP address and is IP
- version neutral. The format of the textual representations
- implies the IP version.";
- }
-
- typedef ipv4-address {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '(%[\p{N}\p{L}]+)?';
- }
- description
- "The ipv4-address type represents an IPv4 address in
- dotted-quad notation. The IPv4 address may include a zone
- index, separated by a % sign.
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
- The canonical format for the zone index is the numerical
- format";
- }
-
- typedef ipv6-address {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(%[\p{N}\p{L}]+)?';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(%.+)?';
- }
- description
- "The ipv6-address type represents an IPv6 address in full,
- mixed, shortened, and shortened-mixed notation. The IPv6
- address may include a zone index, separated by a % sign.
-
-
-
-
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
- The canonical format of IPv6 addresses uses the compressed
- format described in RFC 4291, Section 2.2, item 2 with the
- following additional rules: the :: substitution must be
- applied to the longest sequence of all-zero 16-bit chunks
- in an IPv6 address. If there is a tie, the first sequence
- of all-zero 16-bit chunks is replaced by ::. Single
- all-zero 16-bit chunks are not compressed. The canonical
- format uses lowercase characters and leading zeros are
- not allowed. The canonical format for the zone index is
- the numerical format as described in RFC 4007, Section
- 11.2.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture
- RFC 4007: IPv6 Scoped Address Architecture
- RFC 5952: A Recommendation for IPv6 Address Text Representation";
- }
-
- typedef ip-prefix {
- type union {
- type inet:ipv4-prefix;
- type inet:ipv6-prefix;
- }
- description
- "The ip-prefix type represents an IP prefix and is IP
- version neutral. The format of the textual representations
- implies the IP version.";
- }
-
- typedef ipv4-prefix {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
- }
- description
- "The ipv4-prefix type represents an IPv4 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal to 32.
-
-
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The canonical format of an IPv4 prefix has all bits of
- the IPv4 address set to zero that are not part of the
- IPv4 prefix.";
- }
-
- typedef ipv6-prefix {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(/.+)';
- }
- description
- "The ipv6-prefix type represents an IPv6 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal 128.
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The IPv6 address should have all bits that do not belong
- to the prefix set to zero.
-
- The canonical format of an IPv6 prefix has all bits of
- the IPv6 address set to zero that are not part of the
- IPv6 prefix. Furthermore, IPv6 address is represented
- in the compressed format described in RFC 4291, Section
- 2.2, item 2 with the following additional rules: the ::
- substitution must be applied to the longest sequence of
- all-zero 16-bit chunks in an IPv6 address. If there is
- a tie, the first sequence of all-zero 16-bit chunks is
- replaced by ::. Single all-zero 16-bit chunks are not
- compressed. The canonical format uses lowercase
- characters and leading zeros are not allowed.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture";
- }
-
-
- /*** collection of domain name and URI types ***/
-
- typedef domain-name {
- type string {
- pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
- + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
- + '|\.';
- length "1..253";
- }
- description
- "The domain-name type represents a DNS domain name. The
- name SHOULD be fully qualified whenever possible.
-
- Internet domain names are only loosely specified. Section
- 3.5 of RFC 1034 recommends a syntax (modified in Section
- 2.1 of RFC 1123). The pattern above is intended to allow
- for current practice in domain name use, and some possible
- future expansion. It is designed to hold various types of
- domain names, including names used for A or AAAA records
- (host names) and other records, such as SRV records. Note
- that Internet host names have a stricter syntax (described
- in RFC 952) than the DNS recommendations in RFCs 1034 and
- 1123, and that systems that want to store host names in
- schema nodes using the domain-name type are recommended to
- adhere to this stricter standard to ensure interoperability.
-
- The encoding of DNS names in the DNS protocol is limited
- to 255 characters. Since the encoding consists of labels
- prefixed by a length bytes and there is a trailing NULL
- byte, only 253 characters can appear in the textual dotted
- notation.
-
- The description clause of schema nodes using the domain-name
- type MUST describe when and how these names are resolved to
- IP addresses. Note that the resolution of a domain-name value
- may require to query multiple DNS records (e.g., A for IPv4
- and AAAA for IPv6). The order of the resolution process and
- which DNS record takes precedence can either be defined
- explicitely or it may depend on the configuration of the
- resolver.
-
- Domain-name values use the US-ASCII encoding. Their canonical
- format uses lowercase US-ASCII characters. Internationalized
- domain names MUST be encoded in punycode as described in RFC
- 3492";
- reference
- "RFC 952: DoD Internet Host Table Specification
- RFC 1034: Domain Names - Concepts and Facilities
- RFC 1123: Requirements for Internet Hosts -- Application
- and Support
- RFC 2782: A DNS RR for specifying the location of services
- (DNS SRV)
- RFC 3492: Punycode: A Bootstring encoding of Unicode for
- Internationalized Domain Names in Applications
- (IDNA)
- RFC 5891: Internationalizing Domain Names in Applications
- (IDNA): Protocol";
- }
-
- typedef host {
- type union {
- type inet:ip-address;
- type inet:domain-name;
- }
- description
- "The host type represents either an IP address or a DNS
- domain name.";
- }
-
- typedef uri {
- type string;
- description
- "The uri type represents a Uniform Resource Identifier
- (URI) as defined by STD 66.
-
- Objects using the uri type MUST be in US-ASCII encoding,
- and MUST be normalized as described by RFC 3986 Sections
- 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
- percent-encoding is removed, and all case-insensitive
- characters are set to lowercase except for hexadecimal
- digits, which are normalized to uppercase as described in
- Section 6.2.2.1.
-
- The purpose of this normalization is to help provide
- unique URIs. Note that this normalization is not
- sufficient to provide uniqueness. Two URIs that are
- textually distinct after this normalization may still be
- equivalent.
-
- Objects using the uri type may restrict the schemes that
- they permit. For example, 'data:' and 'urn:' schemes
- might not be appropriate.
-
- A zero-length URI is not a valid URI. This can be used to
- express 'URI absent' where required.
-
- In the value set and its semantics, this type is equivalent
- to the Uri SMIv2 textual convention defined in RFC 5017.";
- reference
- "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
- Group: Uniform Resource Identifiers (URIs), URLs,
- and Uniform Resource Names (URNs): Clarifications
- and Recommendations
- RFC 5017: MIB Textual Conventions for Uniform Resource
- Identifiers (URIs)";
- }
-
-}
+++ /dev/null
-module netconf-cli-ext {
-
- namespace "urn:ietf:params:xml:ns:netconf:base:1.0:cli";
-
- prefix cliext;
-
- revision 2014-05-26 {
- description
- "Initial revision";
- }
-
- extension argument-handler {
- description
- "Links custom argument reader to an input argument";
- argument "name";
- }
-
-}
+++ /dev/null
-module netconf-cli {
-
- namespace "netconf:cli";
- prefix ncli;
-
- import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
- import netconf-cli-ext { prefix cliext; revision-date 2014-05-26; }
-
-
- revision 2014-05-22 {
- description
- "Initial revision.";
- }
-
- extension java-class {
- description
- "This could be used to link between rpc yang definition and custom command implementation";
-
- argument "name";
- }
-
- rpc help {
- description
- "Display help";
-
- output {
- list commands {
-
- key "id";
- leaf id {
- type string;
- }
- leaf description {
- type string;
- }
- }
- }
- }
-
- rpc close {
- description
- "Close the whole cli";
- }
-
- rpc connect {
-
- description
- "Connect to a remote netconf device, if not connected yet. Connection initialization is blocking and might take some time, depending on amount of yang schemas in remote device.";
-
- input {
-
- // TODO yangtools keep input arguments unordered so the ordering in cli is random
- leaf address-name {
- type inet:host;
- default localhost;
- }
-
- leaf address-port {
- type inet:port-number;
- default 830;
- }
-
- leaf user-name {
- type string;
- }
-
- leaf user-password {
- cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.PasswordReader;
- type string;
- }
- }
-
- output {
- leaf status {
- type string;
- }
-
- leaf-list remote-commands {
- type string;
- }
- }
- }
-
-
- rpc disconnect {
-
- description
- "Disconnect from a netconf device that is currently connected";
-
- output {
- leaf status {
- type string;
- }
- }
- }
-
-}
+++ /dev/null
-module ietf-netconf {
-
- // the namespace for NETCONF XML definitions is unchanged
- // from RFC 4741, which this document replaces
- namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
-
- prefix nc;
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import netconf-cli-ext { prefix cliext; revision-date 2014-05-26; }
-
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netconf/>
- WG List: <netconf@ietf.org>
-
- WG Chair: Bert Wijnen
- <bertietf@bwijnen.net>
-
- WG Chair: Mehmet Ersue
- <mehmet.ersue@nsn.com>
-
- Editor: Martin Bjorklund
- <mbj@tail-f.com>
-
- Editor: Juergen Schoenwaelder
- <j.schoenwaelder@jacobs-university.de>
-
- Editor: Andy Bierman
- <andy.bierman@brocade.com>";
- description
- "NETCONF Protocol Data Types and Protocol Operations.
-
- Copyright (c) 2011 IETF Trust and the persons identified as
- the document authors. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6241; see
- the RFC itself for full legal notices.";
- revision 2011-06-01 {
- description
- "Initial revision";
- reference
- "RFC 6241: Network Configuration Protocol";
- }
-
- extension get-filter-element-attributes {
- description
- "If this extension is present within an 'anyxml'
- statement named 'filter', which must be conceptually
- defined within the RPC input section for the <get>
- and <get-config> protocol operations, then the
- following unqualified XML attribute is supported
- within the <filter> element, within a <get> or
- <get-config> protocol operation:
-
- type : optional attribute with allowed
- value strings 'subtree' and 'xpath'.
- If missing, the default value is 'subtree'.
-
- If the 'xpath' feature is supported, then the
- following unqualified XML attribute is
- also supported:
-
- select: optional attribute containing a
- string representing an XPath expression.
- The 'type' attribute must be equal to 'xpath'
- if this attribute is present.";
- }
-
- // NETCONF capabilities defined as features
- feature writable-running {
- description
- "NETCONF :writable-running capability;
- If the server advertises the :writable-running
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.2";
- }
-
- feature candidate {
- description
- "NETCONF :candidate capability;
- If the server advertises the :candidate
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.3";
- }
-
- feature confirmed-commit {
- if-feature candidate;
- description
- "NETCONF :confirmed-commit:1.1 capability;
- If the server advertises the :confirmed-commit:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
-
- reference "RFC 6241, Section 8.4";
- }
-
- feature rollback-on-error {
- description
- "NETCONF :rollback-on-error capability;
- If the server advertises the :rollback-on-error
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.5";
- }
-
- feature validate {
- description
- "NETCONF :validate:1.1 capability;
- If the server advertises the :validate:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.6";
- }
-
- feature startup {
- description
- "NETCONF :startup capability;
- If the server advertises the :startup
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.7";
- }
-
- feature url {
- description
- "NETCONF :url capability;
- If the server advertises the :url
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.8";
- }
-
- feature xpath {
- description
- "NETCONF :xpath capability;
- If the server advertises the :xpath
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.9";
- }
-
- // NETCONF Simple Types
-
- typedef session-id-type {
- type uint32 {
- range "1..max";
- }
- description
- "NETCONF Session Id";
- }
-
- typedef session-id-or-zero-type {
- type uint32;
- description
- "NETCONF Session Id or Zero to indicate none";
- }
- typedef error-tag-type {
- type enumeration {
- enum in-use {
- description
- "The request requires a resource that
- already is in use.";
- }
- enum invalid-value {
- description
- "The request specifies an unacceptable value for one
- or more parameters.";
- }
- enum too-big {
- description
- "The request or response (that would be generated) is
- too large for the implementation to handle.";
- }
- enum missing-attribute {
- description
- "An expected attribute is missing.";
- }
- enum bad-attribute {
- description
- "An attribute value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-attribute {
- description
- "An unexpected attribute is present.";
- }
- enum missing-element {
- description
- "An expected element is missing.";
- }
- enum bad-element {
- description
- "An element value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-element {
- description
- "An unexpected element is present.";
- }
- enum unknown-namespace {
- description
- "An unexpected namespace is present.";
- }
- enum access-denied {
- description
- "Access to the requested protocol operation or
- data model is denied because authorization failed.";
- }
- enum lock-denied {
- description
- "Access to the requested lock is denied because the
- lock is currently held by another entity.";
- }
- enum resource-denied {
- description
- "Request could not be completed because of
- insufficient resources.";
- }
- enum rollback-failed {
- description
- "Request to roll back some configuration change (via
- rollback-on-error or <discard-changes> operations)
- was not completed for some reason.";
-
- }
- enum data-exists {
- description
- "Request could not be completed because the relevant
- data model content already exists. For example,
- a 'create' operation was attempted on data that
- already exists.";
- }
- enum data-missing {
- description
- "Request could not be completed because the relevant
- data model content does not exist. For example,
- a 'delete' operation was attempted on
- data that does not exist.";
- }
- enum operation-not-supported {
- description
- "Request could not be completed because the requested
- operation is not supported by this implementation.";
- }
- enum operation-failed {
- description
- "Request could not be completed because the requested
- operation failed for some reason not covered by
- any other error condition.";
- }
- enum partial-operation {
- description
- "This error-tag is obsolete, and SHOULD NOT be sent
- by servers conforming to this document.";
- }
- enum malformed-message {
- description
- "A message could not be handled because it failed to
- be parsed correctly. For example, the message is not
- well-formed XML or it uses an invalid character set.";
- }
- }
- description "NETCONF Error Tag";
- reference "RFC 6241, Appendix A";
- }
-
- typedef error-severity-type {
- type enumeration {
- enum error {
- description "Error severity";
- }
- enum warning {
- description "Warning severity";
- }
- }
- description "NETCONF Error Severity";
- reference "RFC 6241, Section 4.3";
- }
-
- typedef edit-operation-type {
- type enumeration {
- enum merge {
- description
- "The configuration data identified by the
- element containing this attribute is merged
- with the configuration at the corresponding
- level in the configuration datastore identified
- by the target parameter.";
- }
- enum replace {
- description
- "The configuration data identified by the element
- containing this attribute replaces any related
- configuration in the configuration datastore
- identified by the target parameter. If no such
- configuration data exists in the configuration
- datastore, it is created. Unlike a
- <copy-config> operation, which replaces the
- entire target configuration, only the configuration
- actually present in the config parameter is affected.";
- }
- enum create {
- description
- "The configuration data identified by the element
- containing this attribute is added to the
- configuration if and only if the configuration
- data does not already exist in the configuration
- datastore. If the configuration data exists, an
- <rpc-error> element is returned with an
- <error-tag> value of 'data-exists'.";
- }
- enum delete {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if and only if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, an <rpc-error> element is returned with
- an <error-tag> value of 'data-missing'.";
- }
- enum remove {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, the 'remove' operation is silently ignored
- by the server.";
- }
- }
- default "merge";
- description "NETCONF 'operation' attribute values";
- reference "RFC 6241, Section 7.2";
- }
-
- // NETCONF Standard Protocol Operations
-
- rpc get-config {
- description
- "Retrieve all or part of a specified configuration.";
-
- reference "RFC 6241, Section 7.1";
-
- input {
- container source {
- description
- "Particular configuration to retrieve.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration to retrieve.";
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.
- This is optional-to-implement on the server because
- not all servers will support filtering for this
- datastore.";
- }
- }
- }
-
- anyxml filter {
- description
- "Subtree or XPath filter to use.";
- nc:get-filter-element-attributes;
- // TODO this extension should be augmented (anyxml nodes cannot be augmented)
- // or we can identify custom input/output arguments by schemaPath defined for custom handlers
- cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the source datastore subset that matched
- the filter criteria (if any). An empty data container
- indicates that the request did not produce any results.";
- cliext:argument-handler org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
- }
- }
- }
-
- rpc edit-config {
- description
- "The <edit-config> operation loads all or part of a specified
- configuration to the specified target configuration.";
-
- reference "RFC 6241, Section 7.2";
-
- input {
- container target {
- description
- "Particular configuration to edit.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config source.";
- }
- }
- }
-
- leaf default-operation {
- type enumeration {
- enum merge {
- description
- "The default operation is merge.";
- }
- enum replace {
- description
- "The default operation is replace.";
- }
- enum none {
- description
- "There is no default operation.";
- }
- }
- default "merge";
- description
- "The default operation to use.";
- }
-
- leaf test-option {
- if-feature validate;
- type enumeration {
- enum test-then-set {
- description
- "The server will test and then set if no errors.";
- }
- enum set {
- description
- "The server will set without a test first.";
- }
-
- enum test-only {
- description
- "The server will only test and not set, even
- if there are no errors.";
- }
- }
- default "test-then-set";
- description
- "The test option to use.";
- }
-
- leaf error-option {
- type enumeration {
- enum stop-on-error {
- description
- "The server will stop on errors.";
- }
- enum continue-on-error {
- description
- "The server may continue on errors.";
- }
- enum rollback-on-error {
- description
- "The server will roll back on errors.
- This value can only be used if the 'rollback-on-error'
- feature is supported.";
- }
- }
- default "stop-on-error";
- description
- "The error option to use.";
- }
-
- choice edit-content {
- mandatory true;
- description
- "The content for the edit operation.";
-
- cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.EditContentReader;
-
- anyxml config {
- description
- "Inline Config content.";
- cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.ConfigReader;
- }
-
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "URL-based config content.";
- }
- }
- }
- }
-
- rpc copy-config {
- description
- "Create or replace an entire configuration datastore with the
- contents of another complete configuration datastore.";
-
- reference "RFC 6241, Section 7.3";
-
- input {
- container target {
- description
- "Particular configuration to copy to.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target of the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config target.
- This is optional-to-implement on the server.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
-
- container source {
- description
- "Particular configuration to copy from.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source for the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
- rpc delete-config {
- description
- "Delete a configuration datastore.";
-
- reference "RFC 6241, Section 7.4";
-
- input {
- container target {
- description
- "Particular configuration to delete.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to delete.";
-
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc lock {
- description
- "The lock operation allows the client to lock the configuration
- system of a device.";
-
- reference "RFC 6241, Section 7.5";
-
- input {
- container target {
- description
- "Particular configuration to lock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to lock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc unlock {
- description
- "The unlock operation is used to release a configuration lock,
- previously obtained with the 'lock' operation.";
-
- reference "RFC 6241, Section 7.6";
-
- input {
- container target {
- description
- "Particular configuration to unlock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to unlock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc get {
- description
- "Retrieve running configuration and device state information.";
-
- reference "RFC 6241, Section 7.7";
-
- input {
- anyxml filter {
- description
- "This parameter specifies the portion of the system
- configuration and state data to retrieve.";
- nc:get-filter-element-attributes;
- // TODO this extension should be augmented (anyxml nodes cannot be augmented)
- cliext:argument-handler org.opendaylight.controller.netconf.cli.reader.custom.FilterReader;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the running datastore subset and/or state
- data that matched the filter criteria (if any).
- An empty data container indicates that the request did not
- produce any results.";
-
- cliext:argument-handler org.opendaylight.controller.netconf.cli.writer.custom.DataWriter;
-
- }
- }
- }
-
- rpc close-session {
- description
- "Request graceful termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.8";
- }
-
- rpc kill-session {
- description
- "Force the termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.9";
-
- input {
- leaf session-id {
- type session-id-type;
- mandatory true;
- description
- "Particular session to kill.";
- }
- }
- }
-
- rpc commit {
- if-feature candidate;
-
- description
- "Commit the candidate configuration as the device's new
- current configuration.";
-
- reference "RFC 6241, Section 8.3.4.1";
-
- input {
- leaf confirmed {
- if-feature confirmed-commit;
- type empty;
- description
- "Requests a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf confirm-timeout {
- if-feature confirmed-commit;
- type uint32 {
- range "1..max";
- }
- units "seconds";
- default "600"; // 10 minutes
- description
- "The timeout interval for a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is used to make a confirmed commit
- persistent. A persistent confirmed commit is not aborted
- if the NETCONF session terminates. The only way to abort
- a persistent confirmed commit is to let the timer expire,
- or to use the <cancel-commit> operation.
-
- The value of this parameter is a token that must be given
- in the 'persist-id' parameter of <commit> or
- <cancel-commit> operations in order to confirm or cancel
- the persistent confirmed commit.
-
- The token should be a random string.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist-id {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is given in order to commit a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- }
- }
-
- rpc discard-changes {
- if-feature candidate;
-
- description
- "Revert the candidate configuration to the current
- running configuration.";
- reference "RFC 6241, Section 8.3.4.2";
- }
-
- rpc cancel-commit {
- if-feature confirmed-commit;
- description
- "This operation is used to cancel an ongoing confirmed commit.
- If the confirmed commit is persistent, the parameter
- 'persist-id' must be given, and it must match the value of the
- 'persist' parameter.";
- reference "RFC 6241, Section 8.4.4.1";
-
- input {
- leaf persist-id {
- type string;
- description
- "This parameter is given in order to cancel a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- }
- }
- }
-
- rpc validate {
- if-feature validate;
-
- description
- "Validates the contents of the specified configuration.";
-
- reference "RFC 6241, Section 8.6.4.1";
-
- input {
- container source {
- description
- "Particular configuration to validate.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source to validate.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import java.io.IOException;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.opendaylight.controller.netconf.cli.io.ConsoleIOImpl;
-
-public class ConsoleIOTestImpl extends ConsoleIOImpl {
-
- Map<String, Deque<String>> inputValues = new HashMap<>();
- String lastMessage;
- private final List<ValueForMessage> valuesForMessages;
-
- public ConsoleIOTestImpl(final Map<String, Deque<String>> inputValues, final List<ValueForMessage> valuesForMessages)
- throws IOException {
- super();
- this.inputValues = inputValues;
- this.valuesForMessages = valuesForMessages;
- }
-
- StringBuilder output = new StringBuilder();
-
- @Override
- public String read() throws IOException {
- final String prompt = buildPrompt();
- output.append(prompt);
- System.console().writer().print(prompt);
-
- String value = inputValues.get(prompt).pollFirst();
- if (value == null) {
- value = getValueForLastMessage();
- }
-
- value = value != null ? value : "****NO VALUE****";
-
- output.append(value + "\n");
- System.console().writer().println(value + "\n");
- return value;
- }
-
- private String getValueForLastMessage() {
- for (final ValueForMessage valueForMessage : valuesForMessages) {
- if (containsLastMessageKeyWords(valueForMessage.getKeyWords())) {
- return valueForMessage.getValue();
- }
- }
- return null;
- }
-
- private boolean containsLastMessageKeyWords(final List<String> keyWords) {
- for (final String keyWord : keyWords) {
- if (!lastMessage.contains(keyWord)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public void write(final CharSequence data) throws IOException {
- output.append(data);
- lastMessage = (String) data;
- System.console().writer().print(data);
- }
-
- @Override
- public void writeLn(final CharSequence data) throws IOException {
- write(data);
- output.append("\n");
- System.console().writer().print("\n");
- }
-
- public String getConsoleOutput() {
- return output.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import static org.junit.Assert.assertNotNull;
-import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.cli.reader.ReadingException;
-import org.opendaylight.controller.netconf.cli.writer.WriteException;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-@Ignore
-public class NetconfCliTest {
-
- private final static YangContextParser parser = new YangParserImpl();
-
- private static SchemaContext loadSchemaContext(final String resourceDirectory) throws IOException,
- URISyntaxException {
- final URI uri = NetconfCliTest.class.getResource(resourceDirectory).toURI();
- final File testDir = new File(uri);
- final String[] fileList = testDir.list();
- final List<File> testFiles = new ArrayList<File>();
- if (fileList == null) {
- throw new FileNotFoundException(resourceDirectory);
- }
- for (final String fileName : fileList) {
- if (new File(testDir, fileName).isDirectory() == false) {
- testFiles.add(new File(testDir, fileName));
- }
- }
- return parser.parseFiles(testFiles);
- }
-
- @Test
- public void cliTest() throws ReadingException, IOException, WriteException, URISyntaxException {
-
- final SchemaContext schemaContext = loadSchemaContext("/schema-context");
- assertNotNull(schemaContext);
-
- final DataSchemaNode cont1 = findTopLevelElement("ns:model1", "2014-05-14", "cont1", schemaContext);
- final Map<String, Deque<String>> values = new HashMap<>();
-
- values.put(prompt("/cont1/cont11/lst111/[entry]/lf1111"), value("55", "32"));
- values.put(prompt("/cont1/cont11/lst111/[entry]"), value("Y", "Y"));
- values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lf1112"),
- value("value for lf1112", "2value for lf1112"));
- values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lflst1111"), value("Y", "N", "Y", "N"));
- values.put(prompt("/cont1/cont11/lst111/[entry]/cont111/lflst1111/[entry]"), value("10", "15", "20", "30"));
-
- values.put(prompt("/cont1/cont11/lst111"), value("Y", "N"));
-
- values.put(prompt("/cont1/cont12/chcA"), value("AB"));
- values.put(prompt("/cont1/cont12/chcA/cont12AB1/lf12AB1"), value("value for lf12AB1"));
-
- values.put(prompt("/cont1/cont12/lst121/[entry]/lf1211"), value("value for lf12112", "2value for lf12112"));
- values.put(prompt("/cont1/cont12/lst121/[entry]"), value("Y", "Y"));
- values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211"), value("Y", "N", "Y", "N"));
- values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]"), value("Y", "Y", "Y", "Y"));
- values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]/lf12111"), value("5", "10", "21", "50"));
- values.put(prompt("/cont1/cont12/lst121/[entry]/lst1211/[entry]/lf12112"),
- value("value for lf12112", "2value for lf12112", "3value for lf12112", "4value for lf12112"));
-
- values.put(prompt("/cont1/cont12/lst121"), value("Y", "N"));
-
- values.put(prompt("/cont1/cont12/lst122"), value("Y", "N"));
-
- values.put(prompt("/cont1/lst11"), value("Y", "Y", "N"));
- values.put(prompt("/cont1/lst11/[entry]"), value("Y", "Y", "Y"));
- values.put(prompt("/cont1/lst11/[entry]/lf111"),
- value("1value for lf111", "2value for lf111", "3value for lf111"));
-
- values.put(prompt("/cont1/cont12/data"), value("<el1><el11>value</el11><el12>value1</el12></el1>"));
-
- final List<ValueForMessage> valuesForMessages = new ArrayList<>();
- valuesForMessages.add(new ValueForMessage("Y", "lst111", "[Y|N]"));
- valuesForMessages.add(new ValueForMessage("Y", "lst121", "[Y|N]"));
- valuesForMessages.add(new ValueForMessage("Y", "lst11", "[Y|N]"));
-
- final ConsoleIOTestImpl console = new ConsoleIOTestImpl(values, valuesForMessages);
-
-// final List<Node<?>> redData = new GenericReader(console, new CommandArgHandlerRegistry(console,
-// new SchemaContextRegistry(schemaContext)), schemaContext).read(cont1);
-// assertNotNull(redData);
-// assertEquals(1, redData.size());
-//
-// assertTrue(redData.get(0) instanceof CompositeNode);
-// final CompositeNode redTopLevelNode = (CompositeNode) redData.get(0);
-
- //new NormalizedNodeWriter(console, new OutFormatter()).write(cont1, redData);
-
- }
-
- private Deque<String> value(final String... values) {
- return new ArrayDeque<>(Arrays.asList(values));
- }
-
- private String prompt(final String path) {
- return "/localhost" + path + PROMPT_SUFIX;
- }
-
- private DataSchemaNode findTopLevelElement(final String namespace, final String revision,
- final String topLevelElement, final SchemaContext schemaContext) {
- final QName requiredElement = QName.create(namespace, revision, topLevelElement);
- for (final DataSchemaNode dataSchemaNode : schemaContext.getChildNodes()) {
- if (dataSchemaNode.getQName().equals(requiredElement)) {
- return dataSchemaNode;
- }
- }
- return null;
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli;
-
-import java.util.Arrays;
-import java.util.List;
-
-class ValueForMessage {
- List<String> messageKeyWords;
- String value;
-
- public ValueForMessage(final String value, final String... messageKeyWords) {
- this.messageKeyWords = Arrays.asList(messageKeyWords);
- this.value = value;
- }
-
- public List<String> getKeyWords() {
- return messageKeyWords;
- }
-
- public String getValue() {
- return value;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.cli.io;
-
-import com.google.common.collect.Maps;
-import java.util.Map;
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.controller.netconf.cli.commands.CommandConstants;
-import org.opendaylight.yangtools.yang.common.QName;
-
-public class IOUtilTest {
-
- @Test
- public void testQNameFromKeyStringNew() throws Exception {
- final String s = IOUtil.qNameToKeyString(CommandConstants.HELP_QNAME, "module");
- final Map<String, QName> modulesMap = Maps.newHashMap();
- modulesMap.put("module", QName.create(CommandConstants.HELP_QNAME, "module"));
- final QName qName = IOUtil.qNameFromKeyString(s, modulesMap);
- Assert.assertEquals(CommandConstants.HELP_QNAME, qName);
- }
-}
+++ /dev/null
- module ietf-inet-types {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
- prefix "inet";
-
- organization
- "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netmod/>
- WG List: <mailto:netmod@ietf.org>
-
- WG Chair: David Partain
- <mailto:david.partain@ericsson.com>
-
- WG Chair: David Kessens
- <mailto:david.kessens@nsn.com>
-
- Editor: Juergen Schoenwaelder
- <mailto:j.schoenwaelder@jacobs-university.de>";
-
- description
- "This module contains a collection of generally useful derived
- YANG data types for Internet addresses and related things.
-
- Copyright (c) 2010 IETF Trust and the persons identified as
- authors of the code. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, is permitted pursuant to, and subject to the license
- terms contained in, the Simplified BSD License set forth in Section
- 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6021; see
- the RFC itself for full legal notices.";
-
- revision 2010-09-24 {
- description
- "Initial revision.";
- reference
- "RFC 6021: Common YANG Data Types";
- }
-
- /*** collection of protocol field related types ***/
-
- typedef ip-version {
- type enumeration {
- enum unknown {
- value "0";
- description
- "An unknown or unspecified version of the Internet protocol.";
- }
- enum ipv4 {
- value "1";
- description
- "The IPv4 protocol as defined in RFC 791.";
- }
- enum ipv6 {
- value "2";
- description
- "The IPv6 protocol as defined in RFC 2460.";
- }
- }
- description
- "This value represents the version of the IP protocol.
-
- In the value set and its semantics, this type is equivalent
- to the InetVersion textual convention of the SMIv2.";
- reference
- "RFC 791: Internet Protocol
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- typedef dscp {
- type uint8 {
- range "0..63";
- }
- description
- "The dscp type represents a Differentiated Services Code-Point
- that may be used for marking packets in a traffic stream.
-
- In the value set and its semantics, this type is equivalent
- to the Dscp textual convention of the SMIv2.";
- reference
- "RFC 3289: Management Information Base for the Differentiated
- Services Architecture
- RFC 2474: Definition of the Differentiated Services Field
- (DS Field) in the IPv4 and IPv6 Headers
- RFC 2780: IANA Allocation Guidelines For Values In
- the Internet Protocol and Related Headers";
- }
-
- typedef ipv6-flow-label {
- type uint32 {
- range "0..1048575";
- }
- description
- "The flow-label type represents flow identifier or Flow Label
- in an IPv6 packet header that may be used to discriminate
- traffic flows.
-
- In the value set and its semantics, this type is equivalent
- to the IPv6FlowLabel textual convention of the SMIv2.";
- reference
- "RFC 3595: Textual Conventions for IPv6 Flow Label
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
- }
-
- typedef port-number {
- type uint16 {
- range "0..65535";
- }
- description
- "The port-number type represents a 16-bit port number of an
- Internet transport layer protocol such as UDP, TCP, DCCP, or
- SCTP. Port numbers are assigned by IANA. A current list of
- all assignments is available from <http://www.iana.org/>.
-
- Note that the port number value zero is reserved by IANA. In
- situations where the value zero does not make sense, it can
- be excluded by subtyping the port-number type.
-
- In the value set and its semantics, this type is equivalent
- to the InetPortNumber textual convention of the SMIv2.";
- reference
- "RFC 768: User Datagram Protocol
- RFC 793: Transmission Control Protocol
- RFC 4960: Stream Control Transmission Protocol
- RFC 4340: Datagram Congestion Control Protocol (DCCP)
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- /*** collection of autonomous system related types ***/
-
- typedef as-number {
- type uint32;
- description
- "The as-number type represents autonomous system numbers
- which identify an Autonomous System (AS). An AS is a set
- of routers under a single technical administration, using
- an interior gateway protocol and common metrics to route
- packets within the AS, and using an exterior gateway
- protocol to route packets to other ASs'. IANA maintains
- the AS number space and has delegated large parts to the
- regional registries.
-
- Autonomous system numbers were originally limited to 16
- bits. BGP extensions have enlarged the autonomous system
- number space to 32 bits. This type therefore uses an uint32
- base type without a range restriction in order to support
- a larger autonomous system number space.
-
- In the value set and its semantics, this type is equivalent
- to the InetAutonomousSystemNumber textual convention of
- the SMIv2.";
- reference
- "RFC 1930: Guidelines for creation, selection, and registration
- of an Autonomous System (AS)
- RFC 4271: A Border Gateway Protocol 4 (BGP-4)
- RFC 4893: BGP Support for Four-octet AS Number Space
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- /*** collection of IP address and hostname related types ***/
-
- typedef ip-address {
- type union {
- type inet:ipv4-address;
- type inet:ipv6-address;
- }
- description
- "The ip-address type represents an IP address and is IP
- version neutral. The format of the textual representations
- implies the IP version.";
- }
-
- typedef ipv4-address {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '(%[\p{N}\p{L}]+)?';
- }
- description
- "The ipv4-address type represents an IPv4 address in
- dotted-quad notation. The IPv4 address may include a zone
- index, separated by a % sign.
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
- The canonical format for the zone index is the numerical
- format";
- }
-
- typedef ipv6-address {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(%[\p{N}\p{L}]+)?';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(%.+)?';
- }
- description
- "The ipv6-address type represents an IPv6 address in full,
- mixed, shortened, and shortened-mixed notation. The IPv6
- address may include a zone index, separated by a % sign.
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
- The canonical format of IPv6 addresses uses the compressed
- format described in RFC 4291, Section 2.2, item 2 with the
- following additional rules: the :: substitution must be
- applied to the longest sequence of all-zero 16-bit chunks
- in an IPv6 address. If there is a tie, the first sequence
- of all-zero 16-bit chunks is replaced by ::. Single
- all-zero 16-bit chunks are not compressed. The canonical
- format uses lowercase characters and leading zeros are
- not allowed. The canonical format for the zone index is
- the numerical format as described in RFC 4007, Section
- 11.2.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture
- RFC 4007: IPv6 Scoped Address Architecture
- RFC 5952: A Recommendation for IPv6 Address Text Representation";
- }
-
- typedef ip-prefix {
- type union {
- type inet:ipv4-prefix;
- type inet:ipv6-prefix;
- }
- description
- "The ip-prefix type represents an IP prefix and is IP
- version neutral. The format of the textual representations
- implies the IP version.";
- }
-
- typedef ipv4-prefix {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
- }
- description
- "The ipv4-prefix type represents an IPv4 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal to 32.
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The canonical format of an IPv4 prefix has all bits of
- the IPv4 address set to zero that are not part of the
- IPv4 prefix.";
- }
-
- typedef ipv6-prefix {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(/.+)';
- }
- description
- "The ipv6-prefix type represents an IPv6 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal 128.
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The IPv6 address should have all bits that do not belong
- to the prefix set to zero.
-
- The canonical format of an IPv6 prefix has all bits of
- the IPv6 address set to zero that are not part of the
- IPv6 prefix. Furthermore, IPv6 address is represented
- in the compressed format described in RFC 4291, Section
- 2.2, item 2 with the following additional rules: the ::
- substitution must be applied to the longest sequence of
- all-zero 16-bit chunks in an IPv6 address. If there is
- a tie, the first sequence of all-zero 16-bit chunks is
- replaced by ::. Single all-zero 16-bit chunks are not
- compressed. The canonical format uses lowercase
- characters and leading zeros are not allowed.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture";
- }
-
- /*** collection of domain name and URI types ***/
-
- typedef domain-name {
- type string {
- pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
- + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
- + '|\.';
- length "1..253";
- }
- description
- "The domain-name type represents a DNS domain name. The
- name SHOULD be fully qualified whenever possible.
-
- Internet domain names are only loosely specified. Section
- 3.5 of RFC 1034 recommends a syntax (modified in Section
- 2.1 of RFC 1123). The pattern above is intended to allow
- for current practice in domain name use, and some possible
- future expansion. It is designed to hold various types of
- domain names, including names used for A or AAAA records
- (host names) and other records, such as SRV records. Note
- that Internet host names have a stricter syntax (described
- in RFC 952) than the DNS recommendations in RFCs 1034 and
- 1123, and that systems that want to store host names in
- schema nodes using the domain-name type are recommended to
- adhere to this stricter standard to ensure interoperability.
-
- The encoding of DNS names in the DNS protocol is limited
- to 255 characters. Since the encoding consists of labels
- prefixed by a length bytes and there is a trailing NULL
- byte, only 253 characters can appear in the textual dotted
- notation.
-
- The description clause of schema nodes using the domain-name
- type MUST describe when and how these names are resolved to
- IP addresses. Note that the resolution of a domain-name value
- may require to query multiple DNS records (e.g., A for IPv4
- and AAAA for IPv6). The order of the resolution process and
- which DNS record takes precedence can either be defined
- explicitely or it may depend on the configuration of the
- resolver.
-
- Domain-name values use the US-ASCII encoding. Their canonical
- format uses lowercase US-ASCII characters. Internationalized
- domain names MUST be encoded in punycode as described in RFC
- 3492";
- reference
- "RFC 952: DoD Internet Host Table Specification
- RFC 1034: Domain Names - Concepts and Facilities
- RFC 1123: Requirements for Internet Hosts -- Application
- and Support
- RFC 2782: A DNS RR for specifying the location of services
- (DNS SRV)
- RFC 3492: Punycode: A Bootstring encoding of Unicode for
- Internationalized Domain Names in Applications
- (IDNA)
- RFC 5891: Internationalizing Domain Names in Applications
- (IDNA): Protocol";
- }
-
- typedef host {
- type union {
- type inet:ip-address;
- type inet:domain-name;
- }
- description
- "The host type represents either an IP address or a DNS
- domain name.";
- }
-
- typedef uri {
- type string;
- description
- "The uri type represents a Uniform Resource Identifier
- (URI) as defined by STD 66.
-
- Objects using the uri type MUST be in US-ASCII encoding,
- and MUST be normalized as described by RFC 3986 Sections
- 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
- percent-encoding is removed, and all case-insensitive
- characters are set to lowercase except for hexadecimal
- digits, which are normalized to uppercase as described in
- Section 6.2.2.1.
-
- The purpose of this normalization is to help provide
- unique URIs. Note that this normalization is not
- sufficient to provide uniqueness. Two URIs that are
- textually distinct after this normalization may still be
- equivalent.
-
- Objects using the uri type may restrict the schemes that
- they permit. For example, 'data:' and 'urn:' schemes
- might not be appropriate.
-
- A zero-length URI is not a valid URI. This can be used to
- express 'URI absent' where required.
-
- In the value set and its semantics, this type is equivalent
- to the Uri SMIv2 textual convention defined in RFC 5017.";
- reference
- "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
- Group: Uniform Resource Identifiers (URIs), URLs,
- and Uniform Resource Names (URNs): Clarifications
- and Recommendations
- RFC 5017: MIB Textual Conventions for Uniform Resource
- Identifiers (URIs)";
- }
-
- }
+++ /dev/null
-module ietf-netconf {
-
- // the namespace for NETCONF XML definitions is unchanged
- // from RFC 4741, which this document replaces
- namespace "urn:ietf:params:xml:ns:netconf:base:1.0";
-
- prefix nc;
-
- import ietf-inet-types {
- prefix inet;
- }
-
- organization
- "IETF NETCONF (Network Configuration) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netconf/>
- WG List: <netconf@ietf.org>
-
- WG Chair: Bert Wijnen
- <bertietf@bwijnen.net>
-
- WG Chair: Mehmet Ersue
- <mehmet.ersue@nsn.com>
-
- Editor: Martin Bjorklund
- <mbj@tail-f.com>
-
- Editor: Juergen Schoenwaelder
- <j.schoenwaelder@jacobs-university.de>
-
- Editor: Andy Bierman
- <andy.bierman@brocade.com>";
- description
- "NETCONF Protocol Data Types and Protocol Operations.
-
- Copyright (c) 2011 IETF Trust and the persons identified as
- the document authors. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6241; see
- the RFC itself for full legal notices.";
- revision 2011-06-01 {
- description
- "Initial revision";
- reference
- "RFC 6241: Network Configuration Protocol";
- }
-
- extension get-filter-element-attributes {
- description
- "If this extension is present within an 'anyxml'
- statement named 'filter', which must be conceptually
- defined within the RPC input section for the <get>
- and <get-config> protocol operations, then the
- following unqualified XML attribute is supported
- within the <filter> element, within a <get> or
- <get-config> protocol operation:
-
- type : optional attribute with allowed
- value strings 'subtree' and 'xpath'.
- If missing, the default value is 'subtree'.
-
- If the 'xpath' feature is supported, then the
- following unqualified XML attribute is
- also supported:
-
- select: optional attribute containing a
- string representing an XPath expression.
- The 'type' attribute must be equal to 'xpath'
- if this attribute is present.";
- }
-
- // NETCONF capabilities defined as features
- feature writable-running {
- description
- "NETCONF :writable-running capability;
- If the server advertises the :writable-running
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.2";
- }
-
- feature candidate {
- description
- "NETCONF :candidate capability;
- If the server advertises the :candidate
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.3";
- }
-
- feature confirmed-commit {
- if-feature candidate;
- description
- "NETCONF :confirmed-commit:1.1 capability;
- If the server advertises the :confirmed-commit:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
-
- reference "RFC 6241, Section 8.4";
- }
-
- feature rollback-on-error {
- description
- "NETCONF :rollback-on-error capability;
- If the server advertises the :rollback-on-error
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.5";
- }
-
- feature validate {
- description
- "NETCONF :validate:1.1 capability;
- If the server advertises the :validate:1.1
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.6";
- }
-
- feature startup {
- description
- "NETCONF :startup capability;
- If the server advertises the :startup
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.7";
- }
-
- feature url {
- description
- "NETCONF :url capability;
- If the server advertises the :url
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.8";
- }
-
- feature xpath {
- description
- "NETCONF :xpath capability;
- If the server advertises the :xpath
- capability for a session, then this feature must
- also be enabled for that session. Otherwise,
- this feature must not be enabled.";
- reference "RFC 6241, Section 8.9";
- }
-
- // NETCONF Simple Types
-
- typedef session-id-type {
- type uint32 {
- range "1..max";
- }
- description
- "NETCONF Session Id";
- }
-
- typedef session-id-or-zero-type {
- type uint32;
- description
- "NETCONF Session Id or Zero to indicate none";
- }
- typedef error-tag-type {
- type enumeration {
- enum in-use {
- description
- "The request requires a resource that
- already is in use.";
- }
- enum invalid-value {
- description
- "The request specifies an unacceptable value for one
- or more parameters.";
- }
- enum too-big {
- description
- "The request or response (that would be generated) is
- too large for the implementation to handle.";
- }
- enum missing-attribute {
- description
- "An expected attribute is missing.";
- }
- enum bad-attribute {
- description
- "An attribute value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-attribute {
- description
- "An unexpected attribute is present.";
- }
- enum missing-element {
- description
- "An expected element is missing.";
- }
- enum bad-element {
- description
- "An element value is not correct; e.g., wrong type,
- out of range, pattern mismatch.";
- }
- enum unknown-element {
- description
- "An unexpected element is present.";
- }
- enum unknown-namespace {
- description
- "An unexpected namespace is present.";
- }
- enum access-denied {
- description
- "Access to the requested protocol operation or
- data model is denied because authorization failed.";
- }
- enum lock-denied {
- description
- "Access to the requested lock is denied because the
- lock is currently held by another entity.";
- }
- enum resource-denied {
- description
- "Request could not be completed because of
- insufficient resources.";
- }
- enum rollback-failed {
- description
- "Request to roll back some configuration change (via
- rollback-on-error or <discard-changes> operations)
- was not completed for some reason.";
-
- }
- enum data-exists {
- description
- "Request could not be completed because the relevant
- data model content already exists. For example,
- a 'create' operation was attempted on data that
- already exists.";
- }
- enum data-missing {
- description
- "Request could not be completed because the relevant
- data model content does not exist. For example,
- a 'delete' operation was attempted on
- data that does not exist.";
- }
- enum operation-not-supported {
- description
- "Request could not be completed because the requested
- operation is not supported by this implementation.";
- }
- enum operation-failed {
- description
- "Request could not be completed because the requested
- operation failed for some reason not covered by
- any other error condition.";
- }
- enum partial-operation {
- description
- "This error-tag is obsolete, and SHOULD NOT be sent
- by servers conforming to this document.";
- }
- enum malformed-message {
- description
- "A message could not be handled because it failed to
- be parsed correctly. For example, the message is not
- well-formed XML or it uses an invalid character set.";
- }
- }
- description "NETCONF Error Tag";
- reference "RFC 6241, Appendix A";
- }
-
- typedef error-severity-type {
- type enumeration {
- enum error {
- description "Error severity";
- }
- enum warning {
- description "Warning severity";
- }
- }
- description "NETCONF Error Severity";
- reference "RFC 6241, Section 4.3";
- }
-
- typedef edit-operation-type {
- type enumeration {
- enum merge {
- description
- "The configuration data identified by the
- element containing this attribute is merged
- with the configuration at the corresponding
- level in the configuration datastore identified
- by the target parameter.";
- }
- enum replace {
- description
- "The configuration data identified by the element
- containing this attribute replaces any related
- configuration in the configuration datastore
- identified by the target parameter. If no such
- configuration data exists in the configuration
- datastore, it is created. Unlike a
- <copy-config> operation, which replaces the
- entire target configuration, only the configuration
- actually present in the config parameter is affected.";
- }
- enum create {
- description
- "The configuration data identified by the element
- containing this attribute is added to the
- configuration if and only if the configuration
- data does not already exist in the configuration
- datastore. If the configuration data exists, an
- <rpc-error> element is returned with an
- <error-tag> value of 'data-exists'.";
- }
- enum delete {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if and only if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, an <rpc-error> element is returned with
- an <error-tag> value of 'data-missing'.";
- }
- enum remove {
- description
- "The configuration data identified by the element
- containing this attribute is deleted from the
- configuration if the configuration
- data currently exists in the configuration
- datastore. If the configuration data does not
- exist, the 'remove' operation is silently ignored
- by the server.";
- }
- }
- default "merge";
- description "NETCONF 'operation' attribute values";
- reference "RFC 6241, Section 7.2";
- }
-
- // NETCONF Standard Protocol Operations
-
- rpc get-config {
- description
- "Retrieve all or part of a specified configuration.";
-
- reference "RFC 6241, Section 7.1";
-
- input {
- container source {
- description
- "Particular configuration to retrieve.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration to retrieve.";
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.
- This is optional-to-implement on the server because
- not all servers will support filtering for this
- datastore.";
- }
- }
- }
-
- anyxml filter {
- description
- "Subtree or XPath filter to use.";
- nc:get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the source datastore subset that matched
- the filter criteria (if any). An empty data container
- indicates that the request did not produce any results.";
- }
- }
- }
-
- rpc edit-config {
- description
- "The <edit-config> operation loads all or part of a specified
- configuration to the specified target configuration.";
-
- reference "RFC 6241, Section 7.2";
-
- input {
- container target {
- description
- "Particular configuration to edit.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config source.";
- }
- }
- }
-
- leaf default-operation {
- type enumeration {
- enum merge {
- description
- "The default operation is merge.";
- }
- enum replace {
- description
- "The default operation is replace.";
- }
- enum none {
- description
- "There is no default operation.";
- }
- }
- default "merge";
- description
- "The default operation to use.";
- }
-
- leaf test-option {
- if-feature validate;
- type enumeration {
- enum test-then-set {
- description
- "The server will test and then set if no errors.";
- }
- enum set {
- description
- "The server will set without a test first.";
- }
-
- enum test-only {
- description
- "The server will only test and not set, even
- if there are no errors.";
- }
- }
- default "test-then-set";
- description
- "The test option to use.";
- }
-
- leaf error-option {
- type enumeration {
- enum stop-on-error {
- description
- "The server will stop on errors.";
- }
- enum continue-on-error {
- description
- "The server may continue on errors.";
- }
- enum rollback-on-error {
- description
- "The server will roll back on errors.
- This value can only be used if the 'rollback-on-error'
- feature is supported.";
- }
- }
- default "stop-on-error";
- description
- "The error option to use.";
- }
-
- choice edit-content {
- mandatory true;
- description
- "The content for the edit operation.";
-
- anyxml config {
- description
- "Inline Config content.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "URL-based config content.";
- }
- }
- }
- }
-
- rpc copy-config {
- description
- "Create or replace an entire configuration datastore with the
- contents of another complete configuration datastore.";
-
- reference "RFC 6241, Section 7.3";
-
- input {
- container target {
- description
- "Particular configuration to copy to.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target of the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- if-feature writable-running;
- type empty;
- description
- "The running configuration is the config target.
- This is optional-to-implement on the server.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
-
- container source {
- description
- "Particular configuration to copy from.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source for the copy operation.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
- rpc delete-config {
- description
- "Delete a configuration datastore.";
-
- reference "RFC 6241, Section 7.4";
-
- input {
- container target {
- description
- "Particular configuration to delete.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to delete.";
-
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc lock {
- description
- "The lock operation allows the client to lock the configuration
- system of a device.";
-
- reference "RFC 6241, Section 7.5";
-
- input {
- container target {
- description
- "Particular configuration to lock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to lock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc unlock {
- description
- "The unlock operation is used to release a configuration lock,
- previously obtained with the 'lock' operation.";
-
- reference "RFC 6241, Section 7.6";
-
- input {
- container target {
- description
- "Particular configuration to unlock.";
-
- choice config-target {
- mandatory true;
- description
- "The configuration target to unlock.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config target.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config target.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config target.";
- }
- }
- }
- }
- }
-
- rpc get {
- description
- "Retrieve running configuration and device state information.";
-
- reference "RFC 6241, Section 7.7";
-
- input {
- anyxml filter {
- description
- "This parameter specifies the portion of the system
- configuration and state data to retrieve.";
- nc:get-filter-element-attributes;
- }
- }
-
- output {
- anyxml data {
- description
- "Copy of the running datastore subset and/or state
- data that matched the filter criteria (if any).
- An empty data container indicates that the request did not
- produce any results.";
- }
- }
- }
-
- rpc close-session {
- description
- "Request graceful termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.8";
- }
-
- rpc kill-session {
- description
- "Force the termination of a NETCONF session.";
-
- reference "RFC 6241, Section 7.9";
-
- input {
- leaf session-id {
- type session-id-type;
- mandatory true;
- description
- "Particular session to kill.";
- }
- }
- }
-
- rpc commit {
- if-feature candidate;
-
- description
- "Commit the candidate configuration as the device's new
- current configuration.";
-
- reference "RFC 6241, Section 8.3.4.1";
-
- input {
- leaf confirmed {
- if-feature confirmed-commit;
- type empty;
- description
- "Requests a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf confirm-timeout {
- if-feature confirmed-commit;
- type uint32 {
- range "1..max";
- }
- units "seconds";
- default "600"; // 10 minutes
- description
- "The timeout interval for a confirmed commit.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is used to make a confirmed commit
- persistent. A persistent confirmed commit is not aborted
- if the NETCONF session terminates. The only way to abort
- a persistent confirmed commit is to let the timer expire,
- or to use the <cancel-commit> operation.
-
- The value of this parameter is a token that must be given
- in the 'persist-id' parameter of <commit> or
- <cancel-commit> operations in order to confirm or cancel
- the persistent confirmed commit.
-
- The token should be a random string.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- leaf persist-id {
- if-feature confirmed-commit;
- type string;
- description
- "This parameter is given in order to commit a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- reference "RFC 6241, Section 8.3.4.1";
- }
-
- }
- }
-
- rpc discard-changes {
- if-feature candidate;
-
- description
- "Revert the candidate configuration to the current
- running configuration.";
- reference "RFC 6241, Section 8.3.4.2";
- }
-
- rpc cancel-commit {
- if-feature confirmed-commit;
- description
- "This operation is used to cancel an ongoing confirmed commit.
- If the confirmed commit is persistent, the parameter
- 'persist-id' must be given, and it must match the value of the
- 'persist' parameter.";
- reference "RFC 6241, Section 8.4.4.1";
-
- input {
- leaf persist-id {
- type string;
- description
- "This parameter is given in order to cancel a persistent
- confirmed commit. The value must be equal to the value
- given in the 'persist' parameter to the <commit> operation.
- If it does not match, the operation fails with an
- 'invalid-value' error.";
- }
- }
- }
-
- rpc validate {
- if-feature validate;
-
- description
- "Validates the contents of the specified configuration.";
-
- reference "RFC 6241, Section 8.6.4.1";
-
- input {
- container source {
- description
- "Particular configuration to validate.";
-
- choice config-source {
- mandatory true;
- description
- "The configuration source to validate.";
-
- leaf candidate {
- if-feature candidate;
- type empty;
- description
- "The candidate configuration is the config source.";
- }
- leaf running {
- type empty;
- description
- "The running configuration is the config source.";
- }
- leaf startup {
- if-feature startup;
- type empty;
- description
- "The startup configuration is the config source.";
- }
- leaf url {
- if-feature url;
- type inet:uri;
- description
- "The URL-based configuration is the config source.";
- }
- anyxml config {
- description
- "Inline Config content: <config> element. Represents
- an entire configuration datastore, not
- a subset of the running datastore.";
- }
- }
- }
- }
- }
-
-}
+++ /dev/null
-module model1 {
- namespace "ns:model1";
- prefix "mod1";
-
- revision "2014-05-14" {
- }
-
- container cont1 {
- container cont11 {
- list lst111 {
- key lf1111;
- leaf lf1111 {
- type int32;
- }
- container cont111 {
- leaf lf1112 {
- type string;
- }
- leaf-list lflst1111 {
- type int8;
- }
- }
- }
- }
-
- container cont12 {
- list lst121 {
- key lf1211;
- leaf lf1211 {
- type string;
- }
- list lst1211 {
- leaf lf12111 {
- type uint8;
- }
- leaf lf12112 {
- type string;
- }
- }
- }
- choice chcA {
- case AA {
- leaf lf12AA1 {
- type string;
- }
- }
- case AB {
- container cont12AB1 {
- leaf lf12AB1 {
- type string;
- }
- }
- }
- leaf lf121 { //should be standalone case
- type string;
- }
- }
- list lst122 {
- }
- }
- }
-
- container cont2 {
- container cont23 {
- }
- }
-
- container contA {
- }
-
- container contB {
- }
-
-}
\ No newline at end of file
+++ /dev/null
-module model2 {
- namespace "ns:model2";
- prefix "mod2";
-
- import model1 {prefix model1; revision-date 2014-05-14;}
-
- revision "2014-05-14" {
- }
-
- container contA {
- }
-
- container contB {
- }
-
- augment "/model1:cont2" {
- container cont21 {
- }
-
- container cont22 {
- }
- }
-
- augment "/model1:cont1" {
- list lst11 {
- leaf lf111 {
- type string;
- }
- }
- }
-
-}
\ No newline at end of file
+++ /dev/null
-<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-<module>
-<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
-<name>name{MSG_ID}</name>
-<name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
-</module>
-</modules>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-tools</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>netconf-testtool</artifactId>
- <name>${project.artifactId}</name>
-
- <dependencies>
- <dependency>
- <groupId>net.sourceforge.argparse4j</groupId>
- <artifactId>argparse4j</artifactId>
- <version>0.4.3</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>com.ning</groupId>
- <artifactId>async-http-client</artifactId>
- <version>1.9.24</version>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk15on</artifactId>
- </dependency>
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-netty-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-auth</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.logback_settings</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-netconf-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>logback-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>config-util</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring-extension</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-mapping-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netconf-ssh</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>netty-config-api</artifactId>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <executions>
- <execution>
- <id>stress-client dependency copy</id>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
- <artifactItem>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcpkix-jdk15on</artifactId>
- <outputDirectory>${project.build.directory}/lib</outputDirectory>
- <overWrite>true</overWrite>
- <destFileName>bcpkix-jdk15on.jar</destFileName>
- </artifactItem>
- <artifactItem>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15on</artifactId>
- <outputDirectory>${project.build.directory}/lib</outputDirectory>
- <overWrite>true</overWrite>
- <destFileName>bcprov-jdk15on.jar</destFileName>
- </artifactItem>
- </artifactItems>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <configuration></configuration>
- <executions>
- <execution>
- <goals>
- <goal>shade</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <!-- TODO investigate why jar fails without this filter-->
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.client</exclude>
- </excludes>
- </filter>
- </filters>
- <artifactSet>
- <excludes>
- <exclude>com.ning</exclude>
- </excludes>
- </artifactSet>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.opendaylight.controller.netconf.test.tool.Main</mainClass>
- </transformer>
- </transformers>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>executable</shadedClassifierName>
- </configuration>
- </execution>
-
- <execution>
- <id>stress-client</id>
- <goals>
- <goal>shade</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <shadedArtifactId>stress-client</shadedArtifactId>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.client.http</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.rpc</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.AcceptingAuthProvider</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.DummyMonitoringService</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.FakeModuleBuilderCapability</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.Main</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.ModuleBuilderCapability</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator</exclude>
- </excludes>
- </filter>
- </filters>
- <artifactSet>
- <excludes>
- <exclude>org.bouncycastle:*</exclude>
- </excludes>
- </artifactSet>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <manifestEntries>
- <Main-Class>org.opendaylight.controller.netconf.test.tool.client.stress.StressClient</Main-Class>
- <Class-Path>. lib lib/bcprov-jdk15on.jar lib/bcpkix-jdk15on.jar</Class-Path>
- </manifestEntries>
- </transformer>
- </transformers>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>stress-client</shadedClassifierName>
- </configuration>
- </execution>
-
- <execution>
- <id>restconf-perf-client</id>
- <goals>
- <goal>shade</goal>
- </goals>
- <phase>package</phase>
- <configuration>
- <shadedArtifactId>rest-perf-client</shadedArtifactId>
- <filters>
- <filter>
- <artifact>*:*</artifact>
- <excludes>
- <exclude>META-INF/*.SF</exclude>
- <exclude>META-INF/*.DSA</exclude>
- <exclude>META-INF/*.RSA</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.rpc</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.AcceptingAuthProvider</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.DummyMonitoringService</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.FakeModuleBuilderCapability</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.Main</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.ModuleBuilderCapability</exclude>
- <exclude>org.opendaylight.controller.netconf.test.tool.NetconfDeviceSimulator</exclude>
- </excludes>
- </filter>
- </filters>
- <artifactSet>
- <excludes>
- <exclude>org.bouncycastle:*</exclude>
- <exclude>com.google:*</exclude>
- <exclude>org.opendaylight.yangtools</exclude>
- <exclude>org.opendaylight.yang</exclude>
- </excludes>
- </artifactSet>
- <transformers>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>org.opendaylight.controller.netconf.test.tool.client.http.perf.RestPerfClient</mainClass>
- </transformer>
- </transformers>
- <shadedArtifactAttached>true</shadedArtifactAttached>
- <shadedClassifierName>rest-perf-client</shadedClassifierName>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <configuration>
- <descriptors>
- <descriptor>src/main/assembly/stress-client.xml</descriptor>
- </descriptors>
- <finalName>stress-client-${project.version}-package</finalName>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<assembly>
- <id>stress-client</id>
- <formats>
- <format>tar.gz</format>
- </formats>
- <fileSets>
- <fileSet>
- <directory>target/lib</directory>
- <outputDirectory>/lib</outputDirectory>
- <includes>
- <include>*</include>
- </includes>
- </fileSet>
- <fileSet>
- <directory>target</directory>
- <outputDirectory></outputDirectory>
- <includes>
- <include>stress-client*.jar</include>
- </includes>
- </fileSet>
- </fileSets>
-</assembly>
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import org.opendaylight.controller.netconf.auth.AuthProvider;
-
-class AcceptingAuthProvider implements AuthProvider {
-
- @Override
- public synchronized boolean authenticated(final String username, final String password) {
- return true;
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import java.util.Collections;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.CapabilitiesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SchemasBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Sessions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.SessionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.Schema.Location.Enumeration;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.schemas.SchemaKey;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
-
-public class DummyMonitoringService implements NetconfMonitoringService {
-
- private static final Sessions EMPTY_SESSIONS = new SessionsBuilder().setSession(Collections.<Session>emptyList()).build();
- private static final Function<Capability, Uri> CAPABILITY_URI_FUNCTION = new Function<Capability, Uri>() {
- @Nullable
- @Override
- public Uri apply(Capability capability) {
- return new Uri(capability.getCapabilityUri());
- }
- };
-
- private static final Function<Capability, Schema> CAPABILITY_SCHEMA_FUNCTION = new Function<Capability, Schema>() {
- @Nullable
- @Override
- public Schema apply(@Nullable Capability capability) {
- return new SchemaBuilder()
- .setIdentifier(capability.getModuleName().get())
- .setNamespace(new Uri(capability.getModuleNamespace().get()))
- .setFormat(Yang.class)
- .setVersion(capability.getRevision().get())
- .setLocation(Collections.singletonList(new Location(Enumeration.NETCONF)))
- .setKey(new SchemaKey(Yang.class, capability.getModuleName().get(), capability.getRevision().get())).build();
- }
- };
-
- private final Capabilities capabilities;
- private final ArrayListMultimap<String, Capability> capabilityMultiMap;
- private final Schemas schemas;
-
- public DummyMonitoringService(Set<Capability> capabilities) {
-
- this.capabilities = new CapabilitiesBuilder().setCapability(
- Lists.newArrayList(Collections2.transform(capabilities, CAPABILITY_URI_FUNCTION))).build();
-
- this.capabilityMultiMap = ArrayListMultimap.create();
- for (Capability cap : capabilities) {
- capabilityMultiMap.put(cap.getModuleName().get(), cap);
- }
-
- this.schemas = new SchemasBuilder().setSchema(Lists.newArrayList(Collections2.transform(capabilities, CAPABILITY_SCHEMA_FUNCTION))).build();
- }
-
- @Override
- public Sessions getSessions() {
- return EMPTY_SESSIONS;
- }
-
- @Override
- public Schemas getSchemas() {
- return schemas;
- }
-
- @Override
- public String getSchemaForCapability(String moduleName, Optional<String> revision) {
-
- for (Capability capability : capabilityMultiMap.get(moduleName)) {
- if (capability.getRevision().get().equals(revision.get())) {
- return capability.getCapabilitySchema().get();
- }
- }
- throw new IllegalArgumentException("Module with name: " + moduleName + " and revision: " + revision + " does not exist");
- }
-
- @Override
- public Capabilities getCapabilities() {
- return capabilities;
- }
-
- @Override
- public AutoCloseable registerListener(MonitoringListener listener) {
- return null;
- }
-
- @Override
- public void onSessionUp(NetconfManagementSession session) {
-
- }
-
- @Override
- public void onSessionDown(NetconfManagementSession session) {
-
- }
-
- @Override
- public void onCapabilitiesChanged(Set<Capability> added, Set<Capability> removed) {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import com.google.common.base.Optional;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-
-/**
- * Can be passed instead of ModuleBuilderCapability when building capabilities
- * in NetconfDeviceSimulator when testing various schema resolution related exceptions.
- */
-public class FakeModuleBuilderCapability extends ModuleBuilderCapability {
-
- public FakeModuleBuilderCapability(final ModuleBuilder input, final String inputStream) {
- super(input, inputStream);
- }
-
- /**
- *
- * @return empty schema source to trigger schema resolution exception.
- */
- @Override
- public Optional<String> getCapabilitySchema() {
- return Optional.absent();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import ch.qos.logback.classic.Level;
-import com.google.common.base.Charsets;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.io.ByteStreams;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Files;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import net.sourceforge.argparse4j.ArgumentParsers;
-import net.sourceforge.argparse4j.annotation.Arg;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-public final class Main {
-
- private static final Logger LOG = LoggerFactory.getLogger(Main.class);
-
- public static class Params {
-
- @Arg(dest = "schemas-dir")
- public File schemasDir;
-
- @Arg(dest = "devices-count")
- public int deviceCount;
-
- @Arg(dest = "starting-port")
- public int startingPort;
-
- @Arg(dest = "generate-config-connection-timeout")
- public int generateConfigsTimeout;
-
- @Arg(dest = "generate-config-address")
- public String generateConfigsAddress;
-
- @Arg(dest = "distro-folder")
- public File distroFolder;
-
- @Arg(dest = "generate-configs-batch-size")
- public int generateConfigBatchSize;
-
- @Arg(dest = "ssh")
- public boolean ssh;
-
- @Arg(dest = "exi")
- public boolean exi;
-
- @Arg(dest = "debug")
- public boolean debug;
-
- @Arg(dest = "notification-file")
- public File notificationFile;
-
- static ArgumentParser getParser() {
- final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf testool");
-
- parser.description("Netconf device simulator. Detailed info can be found at https://wiki.opendaylight.org/view/OpenDaylight_Controller:Netconf:Testtool#Building_testtool");
-
- parser.addArgument("--device-count")
- .type(Integer.class)
- .setDefault(1)
- .type(Integer.class)
- .help("Number of simulated netconf devices to spin")
- .dest("devices-count");
-
- parser.addArgument("--schemas-dir")
- .type(File.class)
- .help("Directory containing yang schemas to describe simulated devices. Some schemas e.g. netconf monitoring and inet types are included by default")
- .dest("schemas-dir");
-
- parser.addArgument("--notification-file")
- .type(File.class)
- .help("Xml file containing notifications that should be sent to clients after create subscription is called")
- .dest("notification-file");
-
- parser.addArgument("--starting-port")
- .type(Integer.class)
- .setDefault(17830)
- .help("First port for simulated device. Each other device will have previous+1 port number")
- .dest("starting-port");
-
- parser.addArgument("--generate-config-connection-timeout")
- .type(Integer.class)
- .setDefault((int)TimeUnit.MINUTES.toMillis(30))
- .help("Timeout to be generated in initial config files")
- .dest("generate-config-connection-timeout");
-
- parser.addArgument("--generate-config-address")
- .type(String.class)
- .setDefault("127.0.0.1")
- .help("Address to be placed in generated configs")
- .dest("generate-config-address");
-
- parser.addArgument("--generate-configs-batch-size")
- .type(Integer.class)
- .setDefault(4000)
- .help("Number of connector configs per generated file")
- .dest("generate-configs-batch-size");
-
- parser.addArgument("--distribution-folder")
- .type(File.class)
- .help("Directory where the karaf distribution for controller is located")
- .dest("distro-folder");
-
- parser.addArgument("--ssh")
- .type(Boolean.class)
- .setDefault(true)
- .help("Whether to use ssh for transport or just pure tcp")
- .dest("ssh");
-
- parser.addArgument("--exi")
- .type(Boolean.class)
- .setDefault(true)
- .help("Whether to use exi to transport xml content")
- .dest("exi");
-
- parser.addArgument("--debug")
- .type(Boolean.class)
- .setDefault(false)
- .help("Whether to use debug log level instead of INFO")
- .dest("debug");
-
- return parser;
- }
-
- void validate() {
- checkArgument(deviceCount > 0, "Device count has to be > 0");
- checkArgument(startingPort > 1023, "Starting port has to be > 1023");
-
- if(schemasDir != null) {
- checkArgument(schemasDir.exists(), "Schemas dir has to exist");
- checkArgument(schemasDir.isDirectory(), "Schemas dir has to be a directory");
- checkArgument(schemasDir.canRead(), "Schemas dir has to be readable");
- }
- }
- }
-
- public static void main(final String[] args) {
- final Params params = parseArgs(args, Params.getParser());
- params.validate();
-
- final ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- root.setLevel(params.debug ? Level.DEBUG : Level.INFO);
-
- final NetconfDeviceSimulator netconfDeviceSimulator = new NetconfDeviceSimulator();
- try {
- final List<Integer> openDevices = netconfDeviceSimulator.start(params);
- if (openDevices.size() == 0) {
- LOG.error("Failed to start any simulated devices, exiting...");
- System.exit(1);
- }
- if(params.distroFolder != null) {
- final ConfigGenerator configGenerator = new ConfigGenerator(params.distroFolder, openDevices);
- final List<File> generated = configGenerator.generate(params.ssh, params.generateConfigBatchSize, params.generateConfigsTimeout, params.generateConfigsAddress);
- configGenerator.updateFeatureFile(generated);
- configGenerator.changeLoadOrder();
- }
- } catch (final Exception e) {
- LOG.error("Unhandled exception", e);
- netconfDeviceSimulator.close();
- System.exit(1);
- }
-
- // Block main thread
- synchronized (netconfDeviceSimulator) {
- try {
- netconfDeviceSimulator.wait();
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- private static Params parseArgs(final String[] args, final ArgumentParser parser) {
- final Params opt = new Params();
- try {
- parser.parseArgs(args, opt);
- return opt;
- } catch (final ArgumentParserException e) {
- parser.handleError(e);
- }
-
- System.exit(1);
- return null;
- }
-
- private static class ConfigGenerator {
- public static final String NETCONF_CONNECTOR_XML = "/99-netconf-connector-simulated.xml";
- public static final String SIM_DEVICE_SUFFIX = "-sim-device";
-
- private static final String SIM_DEVICE_CFG_PREFIX = "simulated-devices_";
- private static final String ETC_KARAF_PATH = "etc/";
- private static final String ETC_OPENDAYLIGHT_KARAF_PATH = ETC_KARAF_PATH + "opendaylight/karaf/";
-
- public static final String NETCONF_CONNECTOR_ALL_FEATURE = "odl-netconf-connector-all";
- private static final String ORG_OPS4J_PAX_URL_MVN_CFG = "org.ops4j.pax.url.mvn.cfg";
-
- private final File configDir;
- private final List<Integer> openDevices;
- private final List<File> ncFeatureFiles;
- private final File etcDir;
- private final File loadOrderCfgFile;
-
- public ConfigGenerator(final File directory, final List<Integer> openDevices) {
- this.configDir = new File(directory, ETC_OPENDAYLIGHT_KARAF_PATH);
- this.etcDir = new File(directory, ETC_KARAF_PATH);
- this.loadOrderCfgFile = new File(etcDir, ORG_OPS4J_PAX_URL_MVN_CFG);
- this.ncFeatureFiles = getFeatureFile(directory, "features-netconf-connector", "xml");
- this.openDevices = openDevices;
- }
-
- public List<File> generate(final boolean useSsh, final int batchSize, final int generateConfigsTimeout, final String address) {
- if(configDir.exists() == false) {
- Preconditions.checkState(configDir.mkdirs(), "Unable to create directory " + configDir);
- }
-
- for (final File file : configDir.listFiles(new FileFilter() {
- @Override
- public boolean accept(final File pathname) {
- return !pathname.isDirectory() && pathname.getName().startsWith(SIM_DEVICE_CFG_PREFIX);
- }
- })) {
- Preconditions.checkState(file.delete(), "Unable to clean previous generated file %s", file);
- }
-
- try(InputStream stream = Main.class.getResourceAsStream(NETCONF_CONNECTOR_XML)) {
- checkNotNull(stream, "Cannot load %s", NETCONF_CONNECTOR_XML);
- String configBlueprint = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
-
- final String before = configBlueprint.substring(0, configBlueprint.indexOf("<module>"));
- final String middleBlueprint = configBlueprint.substring(configBlueprint.indexOf("<module>"), configBlueprint.indexOf("</module>"));
- final String after = configBlueprint.substring(configBlueprint.indexOf("</module>") + "</module>".length());
-
- int connectorCount = 0;
- Integer batchStart = null;
- StringBuilder b = new StringBuilder();
- b.append(before);
-
- final List<File> generatedConfigs = Lists.newArrayList();
-
- for (final Integer openDevice : openDevices) {
- if(batchStart == null) {
- batchStart = openDevice;
- }
-
- final String name = String.valueOf(openDevice) + SIM_DEVICE_SUFFIX;
- String configContent = String.format(middleBlueprint, name, address, String.valueOf(openDevice), String.valueOf(!useSsh));
- configContent = String.format("%s%s%d%s\n%s\n", configContent, "<connection-timeout-millis>", generateConfigsTimeout, "</connection-timeout-millis>", "</module>");
-
- b.append(configContent);
- connectorCount++;
- if(connectorCount == batchSize) {
- b.append(after);
- final File to = new File(configDir, String.format(SIM_DEVICE_CFG_PREFIX + "%d-%d.xml", batchStart, openDevice));
- generatedConfigs.add(to);
- Files.write(b.toString(), to, Charsets.UTF_8);
- connectorCount = 0;
- b = new StringBuilder();
- b.append(before);
- batchStart = null;
- }
- }
-
- // Write remaining
- if(connectorCount != 0) {
- b.append(after);
- final File to = new File(configDir, String.format(SIM_DEVICE_CFG_PREFIX + "%d-%d.xml", batchStart, openDevices.get(openDevices.size() - 1)));
- generatedConfigs.add(to);
- Files.write(b.toString(), to, Charsets.UTF_8);
- }
-
- LOG.info("Config files generated in {}", configDir);
- return generatedConfigs;
- } catch (final IOException e) {
- throw new RuntimeException("Unable to generate config files", e);
- }
- }
-
-
- public void updateFeatureFile(final List<File> generated) {
- // TODO karaf core contains jaxb for feature files, use that for
- // modification
- try {
- for (final File featureFile : ncFeatureFiles) {
- final Document document = XmlUtil.readXmlToDocument(Files
- .toString(featureFile, Charsets.UTF_8));
- final NodeList childNodes = document.getDocumentElement().getChildNodes();
-
- for (int i = 0; i < childNodes.getLength(); i++) {
- final Node item = childNodes.item(i);
- if (item instanceof Element == false) {
- continue;
- }
- if (item.getLocalName().equals("feature") == false) {
- continue;
- }
-
- if (NETCONF_CONNECTOR_ALL_FEATURE
- .equals(((Element) item).getAttribute("name"))) {
- final Element ncAllFeatureDefinition = (Element) item;
- // Clean previous generated files
- for (final XmlElement configfile : XmlElement
- .fromDomElement(ncAllFeatureDefinition)
- .getChildElements("configfile")) {
- ncAllFeatureDefinition.removeChild(configfile.getDomElement());
- }
- for (final File file : generated) {
- final Element configfile = document.createElement("configfile");
- configfile.setTextContent("file:"
- + ETC_OPENDAYLIGHT_KARAF_PATH
- + file.getName());
- configfile.setAttribute(
- "finalname",
- ETC_OPENDAYLIGHT_KARAF_PATH
- + file.getName());
- ncAllFeatureDefinition.appendChild(configfile);
- }
- }
- }
-
- Files.write(XmlUtil.toString(document), featureFile,Charsets.UTF_8);
- LOG.info("Feature file {} updated", featureFile);
- }
- } catch (final IOException e) {
- throw new RuntimeException("Unable to load features file as a resource");
- } catch (final SAXException e) {
- throw new RuntimeException("Unable to parse features file");
- }
- }
-
-
- private static List<File> getFeatureFile(final File distroFolder, final String featureName, final String suffix) {
- checkExistingDir(distroFolder, String.format("Folder %s does not exist", distroFolder));
-
- final File systemDir = checkExistingDir(new File(distroFolder, "system"), String.format("Folder %s does not contain a karaf distro, folder system is missing", distroFolder));
- final File netconfConnectorFeaturesParentDir = checkExistingDir(new File(systemDir, "org/opendaylight/controller/" + featureName), String.format("Karaf distro in %s does not contain netconf-connector features", distroFolder));
-
- // Find newest version for features
- final File newestVersionDir = Collections.max(
- Lists.newArrayList(netconfConnectorFeaturesParentDir.listFiles(new FileFilter() {
- @Override
- public boolean accept(final File pathname) {
- return pathname.isDirectory();
- }
- })), new Comparator<File>() {
- @Override
- public int compare(final File o1, final File o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
-
- return Lists.newArrayList(newestVersionDir.listFiles(new FileFilter() {
- @Override
- public boolean accept(final File pathname) {
- return pathname.getName().contains(featureName)
- && Files.getFileExtension(pathname.getName()).equals(suffix);
- }
- }));
- }
-
- private static File checkExistingDir(final File folder, final String msg) {
- Preconditions.checkArgument(folder.exists(), msg);
- Preconditions.checkArgument(folder.isDirectory(), msg);
- return folder;
- }
-
- public void changeLoadOrder() {
- try {
- Files.write(ByteStreams.toByteArray(getClass().getResourceAsStream("/" +ORG_OPS4J_PAX_URL_MVN_CFG)), loadOrderCfgFile);
- LOG.info("Load order changed to prefer local bundles/features by rewriting file {}", loadOrderCfgFile);
- } catch (IOException e) {
- throw new RuntimeException("Unable to rewrite features file " + loadOrderCfgFile, e);
- }
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import com.google.common.base.Optional;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import org.opendaylight.controller.config.facade.xml.util.Util;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-
-class ModuleBuilderCapability implements Capability {
- private static final Date NO_REVISION = new Date(0);
- private static final List<String> NETCONF = Collections.singletonList("NETCONF");
- private final ModuleBuilder input;
- private final Optional<String> content;
-
- public ModuleBuilderCapability(final ModuleBuilder input, final String inputStream) {
- this.input = input;
- this.content = Optional.of(inputStream);
- }
-
- @Override
- public String getCapabilityUri() {
- final String withoutRevision = getModuleNamespace().get() + "?module=" + getModuleName().get();
- return hasRevision() ? withoutRevision + "&revision=" + Util.writeDate(input.getRevision()) : withoutRevision;
- }
-
- @Override
- public Optional<String> getModuleNamespace() {
- return Optional.of(input.getNamespace().toString());
- }
-
- @Override
- public Optional<String> getModuleName() {
- return Optional.of(input.getName());
- }
-
- @Override
- public Optional<String> getRevision() {
- return Optional.of(hasRevision() ? QName.formattedRevision(input.getRevision()) : "");
- }
-
- private boolean hasRevision() {
- return !input.getRevision().equals(NO_REVISION);
- }
-
- @Override
- public Optional<String> getCapabilitySchema() {
- return content;
- }
-
- @Override
- public List<String> getLocation() {
- return NETCONF;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Optional;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.io.CharStreams;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.local.LocalAddress;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import java.io.Closeable;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.BindException;
-import java.net.Inet4Address;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.UnknownHostException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.AbstractMap;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import org.antlr.v4.runtime.ParserRuleContext;
-import org.antlr.v4.runtime.tree.ParseTreeWalker;
-import org.apache.sshd.common.util.ThreadUtils;
-import org.apache.sshd.server.PasswordAuthenticator;
-import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
-import org.apache.sshd.server.session.ServerSession;
-import org.opendaylight.controller.config.util.capability.Capability;
-import org.opendaylight.controller.netconf.api.monitoring.CapabilityListener;
-import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.NetconfServerDispatcherImpl;
-import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.impl.SessionIdProvider;
-import org.opendaylight.controller.netconf.impl.osgi.AggregatedNetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
-import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator;
-import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService;
-import org.opendaylight.controller.netconf.ssh.SshProxyServer;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfiguration;
-import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.controller.netconf.test.tool.rpc.DataList;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedCommit;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedCreateSubscription;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedEditConfig;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedGet;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedGetConfig;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedLock;
-import org.opendaylight.controller.netconf.test.tool.rpc.SimulatedUnLock;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
-import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceRepresentation;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
-import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceListener;
-import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
-import org.opendaylight.yangtools.yang.model.repo.util.FilesystemSchemaSourceCache;
-import org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserListenerImpl;
-import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
-import org.opendaylight.yangtools.yang.parser.util.ASTSchemaSource;
-import org.opendaylight.yangtools.yang.parser.util.TextToASTTransformer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetconfDeviceSimulator implements Closeable {
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceSimulator.class);
-
- private final NioEventLoopGroup nettyThreadgroup;
- private final HashedWheelTimer hashedWheelTimer;
- private final List<Channel> devicesChannels = Lists.newArrayList();
- private final List<SshProxyServer> sshWrappers = Lists.newArrayList();
- private final ScheduledExecutorService minaTimerExecutor;
- private final ExecutorService nioExecutor;
-
- private boolean sendFakeSchema = false;
-
- public NetconfDeviceSimulator() {
- // TODO make pool size configurable
- this(new NioEventLoopGroup(), new HashedWheelTimer(),
- Executors.newScheduledThreadPool(8, new ThreadFactoryBuilder().setNameFormat("netconf-ssh-server-mina-timers-%d").build()),
- ThreadUtils.newFixedThreadPool("netconf-ssh-server-nio-group", 8));
- }
-
- private NetconfDeviceSimulator(final NioEventLoopGroup eventExecutors, final HashedWheelTimer hashedWheelTimer, final ScheduledExecutorService minaTimerExecutor, final ExecutorService nioExecutor) {
- this.nettyThreadgroup = eventExecutors;
- this.hashedWheelTimer = hashedWheelTimer;
- this.minaTimerExecutor = minaTimerExecutor;
- this.nioExecutor = nioExecutor;
- }
-
- private NetconfServerDispatcherImpl createDispatcher(final Map<ModuleBuilder, String> moduleBuilders, final boolean exi, final int generateConfigsTimeout, final Optional<File> notificationsFile) {
-
- final Set<Capability> capabilities = Sets.newHashSet(Collections2.transform(moduleBuilders.keySet(), new Function<ModuleBuilder, Capability>() {
- @Override
- public Capability apply(final ModuleBuilder input) {
- if (sendFakeSchema) {
- sendFakeSchema = false;
- return new FakeModuleBuilderCapability(input, moduleBuilders.get(input));
- } else {
- return new ModuleBuilderCapability(input, moduleBuilders.get(input));
- }
- }
- }));
-
- final SessionIdProvider idProvider = new SessionIdProvider();
-
- final AggregatedNetconfOperationServiceFactory aggregatedNetconfOperationServiceFactory = new AggregatedNetconfOperationServiceFactory();
- final SimulatedOperationProvider simulatedOperationProvider = new SimulatedOperationProvider(idProvider, capabilities, notificationsFile);
-
- final NetconfMonitoringService monitoringService1 = new DummyMonitoringService(capabilities);
-
- final NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory monitoringService =
- new NetconfMonitoringActivator.NetconfMonitoringOperationServiceFactory(
- new NetconfMonitoringOperationService(monitoringService1));
- aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(simulatedOperationProvider);
- aggregatedNetconfOperationServiceFactory.onAddNetconfOperationServiceFactory(monitoringService);
-
- final Set<String> serverCapabilities = exi
- ? NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES
- : Sets.newHashSet(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1);
-
- final NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
- hashedWheelTimer, aggregatedNetconfOperationServiceFactory, idProvider, generateConfigsTimeout, monitoringService1, serverCapabilities);
-
- final NetconfServerDispatcherImpl.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcherImpl.ServerChannelInitializer(
- serverNegotiatorFactory);
- return new NetconfServerDispatcherImpl(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup);
- }
-
- private Map<ModuleBuilder, String> toModuleBuilders(final Map<SourceIdentifier, Map.Entry<ASTSchemaSource, YangTextSchemaSource>> sources) {
- final Map<SourceIdentifier, ParserRuleContext> asts = Maps.transformValues(sources, new Function<Map.Entry<ASTSchemaSource, YangTextSchemaSource>, ParserRuleContext>() {
- @Override
- public ParserRuleContext apply(final Map.Entry<ASTSchemaSource, YangTextSchemaSource> input) {
- return input.getKey().getAST();
- }
- });
- final Map<String, NavigableMap<Date, URI>> namespaceContext = BuilderUtils.createYangNamespaceContext(
- asts.values(), Optional.<SchemaContext>absent());
-
- final ParseTreeWalker walker = new ParseTreeWalker();
- final Map<ModuleBuilder, String> sourceToBuilder = new HashMap<>();
-
- for (final Map.Entry<SourceIdentifier, ParserRuleContext> entry : asts.entrySet()) {
- final ModuleBuilder moduleBuilder = YangParserListenerImpl.create(namespaceContext, entry.getKey().getName(),
- walker, entry.getValue()).getModuleBuilder();
-
- try(InputStreamReader stream = new InputStreamReader(sources.get(entry.getKey()).getValue().openStream(), Charsets.UTF_8)) {
- sourceToBuilder.put(moduleBuilder, CharStreams.toString(stream));
- } catch (final IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- return sourceToBuilder;
- }
-
-
- public List<Integer> start(final Main.Params params) {
- LOG.info("Starting {}, {} simulated devices starting on port {}", params.deviceCount, params.ssh ? "SSH" : "TCP", params.startingPort);
-
- final Map<ModuleBuilder, String> moduleBuilders = parseSchemasToModuleBuilders(params);
-
- final NetconfServerDispatcherImpl dispatcher = createDispatcher(moduleBuilders, params.exi, params.generateConfigsTimeout, Optional.fromNullable(params.notificationFile));
-
- int currentPort = params.startingPort;
-
- final List<Integer> openDevices = Lists.newArrayList();
-
- // Generate key to temp folder
- final PEMGeneratorHostKeyProvider keyPairProvider = getPemGeneratorHostKeyProvider();
-
- for (int i = 0; i < params.deviceCount; i++) {
- if (currentPort > 65535) {
- LOG.warn("Port cannot be greater than 65535, stopping further attempts.");
- break;
- }
- final InetSocketAddress address = getAddress(currentPort);
-
- final ChannelFuture server;
- if(params.ssh) {
- final InetSocketAddress bindingAddress = InetSocketAddress.createUnresolved("0.0.0.0", currentPort);
- final LocalAddress tcpLocalAddress = new LocalAddress(address.toString());
-
- server = dispatcher.createLocalServer(tcpLocalAddress);
- try {
- final SshProxyServer sshServer = new SshProxyServer(minaTimerExecutor, nettyThreadgroup, nioExecutor);
- sshServer.bind(getSshConfiguration(bindingAddress, tcpLocalAddress, keyPairProvider));
- sshWrappers.add(sshServer);
- } catch (final BindException e) {
- LOG.warn("Cannot start simulated device on {}, port already in use. Skipping.", address);
- // Close local server and continue
- server.cancel(true);
- if(server.isDone()) {
- server.channel().close();
- }
- continue;
- } catch (final IOException e) {
- LOG.warn("Cannot start simulated device on {} due to IOException.", address, e);
- break;
- } finally {
- currentPort++;
- }
-
- try {
- server.get();
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException e) {
- LOG.warn("Cannot start ssh simulated device on {}, skipping", address, e);
- continue;
- }
-
- LOG.debug("Simulated SSH device started on {}", address);
-
- } else {
- server = dispatcher.createServer(address);
- currentPort++;
-
- try {
- server.get();
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException e) {
- LOG.warn("Cannot start tcp simulated device on {}, skipping", address, e);
- continue;
- }
-
- LOG.debug("Simulated TCP device started on {}", address);
- }
-
- devicesChannels.add(server.channel());
- openDevices.add(currentPort - 1);
- }
-
- if(openDevices.size() == params.deviceCount) {
- LOG.info("All simulated devices started successfully from port {} to {}", params.startingPort, currentPort - 1);
- } else if (openDevices.size() == 0) {
- LOG.warn("No simulated devices started.");
- } else {
- LOG.warn("Not all simulated devices started successfully. Started devices ar on ports {}", openDevices);
- }
-
- return openDevices;
- }
-
- private SshProxyServerConfiguration getSshConfiguration(final InetSocketAddress bindingAddress, final LocalAddress tcpLocalAddress, final PEMGeneratorHostKeyProvider keyPairProvider) throws IOException {
- return new SshProxyServerConfigurationBuilder()
- .setBindingAddress(bindingAddress)
- .setLocalAddress(tcpLocalAddress)
- .setAuthenticator(new PasswordAuthenticator() {
- @Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
- return true;
- }
- })
- .setKeyPairProvider(keyPairProvider)
- .setIdleTimeout(Integer.MAX_VALUE)
- .createSshProxyServerConfiguration();
- }
-
- private PEMGeneratorHostKeyProvider getPemGeneratorHostKeyProvider() {
- try {
- final Path tempFile = Files.createTempFile("tempKeyNetconfTest", "suffix");
- return new PEMGeneratorHostKeyProvider(tempFile.toAbsolutePath().toString());
- } catch (final IOException e) {
- LOG.error("Unable to generate PEM key", e);
- throw new RuntimeException(e);
- }
- }
-
- private Map<ModuleBuilder, String> parseSchemasToModuleBuilders(final Main.Params params) {
- final SharedSchemaRepository consumer = new SharedSchemaRepository("netconf-simulator");
- consumer.registerSchemaSourceListener(TextToASTTransformer.create(consumer, consumer));
-
- final Set<SourceIdentifier> loadedSources = Sets.newHashSet();
-
- consumer.registerSchemaSourceListener(new SchemaSourceListener() {
- @Override
- public void schemaSourceEncountered(final SchemaSourceRepresentation schemaSourceRepresentation) {}
-
- @Override
- public void schemaSourceRegistered(final Iterable<PotentialSchemaSource<?>> potentialSchemaSources) {
- for (final PotentialSchemaSource<?> potentialSchemaSource : potentialSchemaSources) {
- loadedSources.add(potentialSchemaSource.getSourceIdentifier());
- }
- }
-
- @Override
- public void schemaSourceUnregistered(final PotentialSchemaSource<?> potentialSchemaSource) {}
- });
-
- if(params.schemasDir != null) {
- final FilesystemSchemaSourceCache<YangTextSchemaSource> cache = new FilesystemSchemaSourceCache<>(consumer, YangTextSchemaSource.class, params.schemasDir);
- consumer.registerSchemaSourceListener(cache);
- }
-
- addDefaultSchemas(consumer);
-
- final Map<SourceIdentifier, Map.Entry<ASTSchemaSource, YangTextSchemaSource>> asts = Maps.newHashMap();
- for (final SourceIdentifier loadedSource : loadedSources) {
- try {
- final CheckedFuture<ASTSchemaSource, SchemaSourceException> ast = consumer.getSchemaSource(loadedSource, ASTSchemaSource.class);
- final CheckedFuture<YangTextSchemaSource, SchemaSourceException> text = consumer.getSchemaSource(loadedSource, YangTextSchemaSource.class);
- asts.put(loadedSource, new AbstractMap.SimpleEntry<>(ast.get(), text.get()));
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException e) {
- throw new RuntimeException("Cannot parse schema context", e);
- }
- }
- return toModuleBuilders(asts);
- }
-
- private void addDefaultSchemas(final SharedSchemaRepository consumer) {
- SourceIdentifier sId = new SourceIdentifier("ietf-netconf-monitoring", "2010-10-04");
- registerSource(consumer, "/META-INF/yang/ietf-netconf-monitoring.yang", sId);
-
- sId = new SourceIdentifier("ietf-netconf-monitoring-extension", "2013-12-10");
- registerSource(consumer, "/META-INF/yang/ietf-netconf-monitoring-extension.yang", sId);
-
- sId = new SourceIdentifier("ietf-yang-types", "2010-09-24");
- registerSource(consumer, "/META-INF/yang/ietf-yang-types.yang", sId);
-
- sId = new SourceIdentifier("ietf-inet-types", "2010-09-24");
- registerSource(consumer, "/META-INF/yang/ietf-inet-types.yang", sId);
- }
-
- private void registerSource(final SharedSchemaRepository consumer, final String resource, final SourceIdentifier sourceId) {
- consumer.registerSchemaSource(new SchemaSourceProvider<SchemaSourceRepresentation>() {
- @Override
- public CheckedFuture<? extends SchemaSourceRepresentation, SchemaSourceException> getSource(final SourceIdentifier sourceIdentifier) {
- return Futures.immediateCheckedFuture(new YangTextSchemaSource(sourceId) {
- @Override
- protected MoreObjects.ToStringHelper addToStringAttributes(final MoreObjects.ToStringHelper toStringHelper) {
- return toStringHelper;
- }
-
- @Override
- public InputStream openStream() throws IOException {
- return getClass().getResourceAsStream(resource);
- }
- });
- }
- }, PotentialSchemaSource.create(sourceId, YangTextSchemaSource.class, PotentialSchemaSource.Costs.IMMEDIATE.getValue()));
- }
-
- private static InetSocketAddress getAddress(final int port) {
- try {
- // TODO make address configurable
- return new InetSocketAddress(Inet4Address.getByName("0.0.0.0"), port);
- } catch (final UnknownHostException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void close() {
- for (final SshProxyServer sshWrapper : sshWrappers) {
- sshWrapper.close();
- }
- for (final Channel deviceCh : devicesChannels) {
- deviceCh.close();
- }
- nettyThreadgroup.shutdownGracefully();
- minaTimerExecutor.shutdownNow();
- nioExecutor.shutdownNow();
- // close Everything
- }
-
- private static class SimulatedOperationProvider implements NetconfOperationServiceFactory {
- private final Set<Capability> caps;
- private final SimulatedOperationService simulatedOperationService;
-
-
- public SimulatedOperationProvider(final SessionIdProvider idProvider, final Set<Capability> caps, final Optional<File> notificationsFile) {
- this.caps = caps;
- simulatedOperationService = new SimulatedOperationService(idProvider.getCurrentSessionId(), notificationsFile);
- }
-
- @Override
- public Set<Capability> getCapabilities() {
- return caps;
- }
-
- @Override
- public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
- listener.onCapabilitiesChanged(caps, Collections.<Capability>emptySet());
- return new AutoCloseable() {
- @Override
- public void close() throws Exception {}
- };
- }
-
- @Override
- public NetconfOperationService createService(final String netconfSessionIdForReporting) {
- return simulatedOperationService;
- }
-
- static class SimulatedOperationService implements NetconfOperationService {
- private final long currentSessionId;
- private final Optional<File> notificationsFile;
-
- public SimulatedOperationService(final long currentSessionId, final Optional<File> notificationsFile) {
- this.currentSessionId = currentSessionId;
- this.notificationsFile = notificationsFile;
- }
-
- @Override
- public Set<NetconfOperation> getNetconfOperations() {
- final DataList storage = new DataList();
- final SimulatedGet sGet = new SimulatedGet(String.valueOf(currentSessionId), storage);
- final SimulatedEditConfig sEditConfig = new SimulatedEditConfig(String.valueOf(currentSessionId), storage);
- final SimulatedGetConfig sGetConfig = new SimulatedGetConfig(String.valueOf(currentSessionId), storage);
- final SimulatedCommit sCommit = new SimulatedCommit(String.valueOf(currentSessionId));
- final SimulatedLock sLock = new SimulatedLock(String.valueOf(currentSessionId));
- final SimulatedUnLock sUnlock = new SimulatedUnLock(String.valueOf(currentSessionId));
- final SimulatedCreateSubscription sCreateSubs = new SimulatedCreateSubscription(String.valueOf(currentSessionId), notificationsFile);
- return Sets.<NetconfOperation>newHashSet(sGet, sGetConfig, sEditConfig, sCommit, sLock, sUnlock, sCreateSubs);
- }
-
- @Override
- public void close() {
- }
-
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool;
-
-public class TestToolUtils {
-
- public static String getMac(long mac) {
- StringBuilder m = new StringBuilder(Long.toString(mac, 16));
-
- for (int i = m.length(); i < 12; i++) {
- m.insert(0, "0");
- }
-
- for (int j = m.length() - 2; j >= 2; j -= 2) {
- m.insert(j, ":");
- }
-
- return m.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.http.perf;
-
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.HttpResponseStatus;
-import com.ning.http.client.ListenableFuture;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-import org.opendaylight.controller.netconf.test.tool.client.stress.ExecutionStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class AsyncExecutionStrategy implements ExecutionStrategy{
-
- private static final Logger LOG = LoggerFactory.getLogger(AsyncExecutionStrategy.class);
-
- private final Parameters params;
- private final ArrayList<Request> payloads;
- private final AsyncHttpClient asyncHttpClient;
- private final Semaphore semaphore;
-
- AsyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient, final ArrayList<Request> payloads) {
- this.params = params;
- this.asyncHttpClient = asyncHttpClient;
- this.payloads = payloads;
- this.semaphore = new Semaphore(RestPerfClient.throttle);
- }
-
- @Override
- public void invoke() {
- final ArrayList<ListenableFuture<Response>> futures = new ArrayList<>();
- LOG.info("Begin sending async requests");
-
- for (final Request request : payloads) {
- try {
- semaphore.acquire();
- } catch (InterruptedException e) {
- LOG.warn("Semaphore acquire interrupted");
- }
- futures.add(asyncHttpClient.executeRequest(request, new AsyncCompletionHandler<Response>() {
- @Override
- public STATE onStatusReceived(HttpResponseStatus status) throws Exception {
- super.onStatusReceived(status);
- if (status.getStatusCode() != 200 && status.getStatusCode() != 204) {
- LOG.warn("Request failed, status code: {}", status.getStatusCode() + status.getStatusText());
- LOG.warn("request: {}", request.toString());
- }
- return STATE.CONTINUE;
- }
-
- @Override
- public Response onCompleted(Response response) throws Exception {
- semaphore.release();
- return response;
- }
- }));
- }
- LOG.info("Requests sent, waiting for responses");
-
- try {
- semaphore.acquire(RestPerfClient.throttle);
- } catch (InterruptedException e) {
- LOG.warn("Semaphore acquire interrupted");
- }
-
- LOG.info("Responses received, ending...");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.http.perf;
-
-import com.google.common.base.Preconditions;
-import java.io.File;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import net.sourceforge.argparse4j.ArgumentParsers;
-import net.sourceforge.argparse4j.annotation.Arg;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-
-public class Parameters {
-
- @Arg(dest = "ip")
- public String ip;
-
- @Arg(dest = "port")
- public int port;
-
- @Arg(dest = "destination")
- public String destination;
-
- @Arg(dest = "edit-count")
- public int editCount;
-
- @Arg(dest = "edit-content")
- public File editContent;
-
- @Arg(dest = "async")
- public boolean async;
-
- @Arg(dest = "thread-amount")
- public int threadAmount;
-
- @Arg(dest = "same-device")
- public boolean sameDevice;
-
- @Arg(dest = "device-port-range-start")
- public int devicePortRangeStart;
-
- @Arg(dest = "throttle")
- public int throttle;
-
- static ArgumentParser getParser() {
- final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
-
- parser.description("Netconf stress client");
-
- parser.addArgument("--ip")
- .type(String.class)
- .setDefault("127.0.0.1")
- .help("Restconf server IP")
- .dest("ip");
-
- parser.addArgument("--port")
- .type(Integer.class)
- .setDefault(8181)
- .help("Restconf server port")
- .dest("port");
-
- parser.addArgument("--destination")
- .type(String.class)
- .setDefault("/restconf/config/network-topology:network-topology/topology/topology-netconf/node/" +
- "{DEVICE_PORT}-sim-device/yang-ext:mount/cisco-vpp:vpp/bridge-domains/bridge-domain/a")
- .help("Destination to send the requests to after the ip:port part of the uri. " +
- "Use {DEVICE_PORT} tag to use the device-port-range-start argument")
- .dest("destination");
-
- parser.addArgument("--edits")
- .type(Integer.class)
- .setDefault(50000)
- .help("Amount requests to be sent")
- .dest("edit-count");
-
- parser.addArgument("--edit-content")
- .type(File.class)
- .setDefault(new File("edit.txt"))
- .dest("edit-content");
-
- parser.addArgument("--async-requests")
- .type(Boolean.class)
- .setDefault(true)
- .dest("async");
-
- parser.addArgument("--thread-amount")
- .type(Integer.class)
- .setDefault(1)
- .dest("thread-amount");
-
- parser.addArgument("--same-device")
- .type(Boolean.class)
- .setDefault(true)
- .help("If true, every thread edits the device at the first port. If false, n-th thread edits device at n-th port.")
- .dest("same-device");
-
- parser.addArgument("--device-port-range-start")
- .type(Integer.class)
- .setDefault(17830)
- .dest("device-port-range-start");
-
- parser.addArgument("--throttle")
- .type(Integer.class)
- .setDefault(5000)
- .help("Maximum amount of async requests that can be open at a time, " +
- "with mutltiple threads this gets divided among all threads")
- .dest("throttle");
-
- return parser;
- }
-
- void validate() {
- Preconditions.checkArgument(port > 0, "Port =< 0");
- Preconditions.checkArgument(editCount > 0, "Edit count =< 0");
-
- Preconditions.checkArgument(editContent.exists(), "Edit content file missing");
- Preconditions.checkArgument(editContent.isDirectory() == false, "Edit content file is a dir");
- Preconditions.checkArgument(editContent.canRead(), "Edit content file is unreadable");
- // TODO validate
- }
-
- public InetSocketAddress getInetAddress() {
- try {
- return new InetSocketAddress(InetAddress.getByName(ip), port);
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unknown ip", e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.http.perf;
-
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
-import com.ning.http.client.Request;
-import java.util.ArrayList;
-import java.util.concurrent.Callable;
-import org.opendaylight.controller.netconf.test.tool.client.http.perf.RestPerfClient.DestToPayload;
-import org.opendaylight.controller.netconf.test.tool.client.stress.ExecutionStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class PerfClientCallable implements Callable<Void>{
-
- private static final Logger LOG = LoggerFactory.getLogger(PerfClientCallable.class);
-
- private final Parameters params;
- private final ArrayList<Request> payloads;
- private final AsyncHttpClient asyncHttpClient;
- private ExecutionStrategy executionStrategy;
-
- public PerfClientCallable(Parameters params, ArrayList<DestToPayload> payloads) {
- this.params = params;
- this.asyncHttpClient = new AsyncHttpClient(new AsyncHttpClientConfig.Builder()
- .setConnectTimeout(Integer.MAX_VALUE)
- .setRequestTimeout(Integer.MAX_VALUE)
- .setAllowPoolingConnections(true)
- .build());
- this.payloads = new ArrayList<>();
- for (DestToPayload payload : payloads) {
- this.payloads.add(asyncHttpClient.preparePost(payload.getDestination())
- .addHeader("content-type", "application/json")
- .addHeader("Accept", "application/xml")
- .setBody(payload.getPayload())
- .setRequestTimeout(Integer.MAX_VALUE)
- .build());
- }
- executionStrategy = getExecutionStrategy();
- }
-
- private ExecutionStrategy getExecutionStrategy() {
- return params.async
- ? new AsyncExecutionStrategy(params, asyncHttpClient, payloads)
- : new SyncExecutionStrategy(params, asyncHttpClient, payloads);
- }
-
- @Override
- public Void call() throws Exception{
-
- executionStrategy.invoke();
- asyncHttpClient.closeAsynchronously();
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.http.perf;
-
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Stopwatch;
-import com.google.common.io.Files;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import org.opendaylight.controller.netconf.test.tool.TestToolUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RestPerfClient {
-
- private static final Logger LOG = LoggerFactory.getLogger(RestPerfClient.class);
-
- private static final String HOST_KEY = "{HOST}";
- private static final String PORT_KEY = "{PORT}";
- private static final String DEVICE_PORT_KEY = "{DEVICE_PORT}";
-
- private static final String PEER_KEY = "{PEERID}";
- private static final String INT_LEAF_KEY = "{INTLEAF}";
-
- private static final String PHYS_ADDR_PLACEHOLDER = "{PHYS_ADDR}";
-
- private static final String dest = "http://{HOST}:{PORT}";
-
- private static long macStart = 0xAABBCCDD0000L;
-
- static int throttle;
-
- static final class DestToPayload {
-
- private final String destination;
- private final String payload;
-
- public DestToPayload(String destination, String payload) {
- this.destination = destination;
- this.payload = payload;
- }
-
- public String getDestination() {
- return destination;
- }
-
- public String getPayload() {
- return payload;
- }
- }
-
- public static void main(String[] args) throws IOException {
-
- Parameters parameters = parseArgs(args, Parameters.getParser());
- parameters.validate();
- throttle = parameters.throttle / parameters.threadAmount;
-
- if (parameters.async && parameters.threadAmount > 1) {
- LOG.info("Throttling per thread: {}", throttle);
- }
-
- final String editContentString;
- try {
- editContentString = Files.toString(parameters.editContent, Charsets.UTF_8);
- } catch (final IOException e) {
- throw new IllegalArgumentException("Cannot read content of " + parameters.editContent);
- }
-
- final int threadAmount = parameters.threadAmount;
- LOG.info("thread amount: {}", threadAmount);
- final int requestsPerThread = parameters.editCount / parameters.threadAmount;
- LOG.info("requestsPerThread: {}", requestsPerThread);
- final int leftoverRequests = parameters.editCount % parameters.threadAmount;
- LOG.info("leftoverRequests: {}", leftoverRequests);
-
- final ArrayList<ArrayList<DestToPayload>> allThreadsPayloads = new ArrayList<>();
- for (int i = 0; i < threadAmount; i++) {
- final ArrayList<DestToPayload> payloads = new ArrayList<>();
- for (int j = 0; j < requestsPerThread; j++) {
- final int devicePort = parameters.sameDevice ? parameters.devicePortRangeStart : parameters.devicePortRangeStart + i;
- final StringBuilder destBuilder = new StringBuilder(dest);
- destBuilder.replace(destBuilder.indexOf(HOST_KEY), destBuilder.indexOf(HOST_KEY) + HOST_KEY.length(), parameters.ip)
- .replace(destBuilder.indexOf(PORT_KEY), destBuilder.indexOf(PORT_KEY) + PORT_KEY.length(), parameters.port + "");
- final StringBuilder suffixBuilder = new StringBuilder(parameters.destination);
- if (suffixBuilder.indexOf(DEVICE_PORT_KEY) != -1) {
- suffixBuilder.replace(suffixBuilder.indexOf(DEVICE_PORT_KEY), suffixBuilder.indexOf(DEVICE_PORT_KEY) + DEVICE_PORT_KEY.length(), devicePort + "");
- }
- destBuilder.append(suffixBuilder);
-
- payloads.add(new DestToPayload(destBuilder.toString(), prepareMessage(i, j, editContentString)));
- }
- allThreadsPayloads.add(payloads);
- }
-
- for (int i = 0; i < leftoverRequests; i++) {
- ArrayList<DestToPayload> payloads = allThreadsPayloads.get(allThreadsPayloads.size() - 1);
-
- final int devicePort = parameters.sameDevice ? parameters.devicePortRangeStart : parameters.devicePortRangeStart + threadAmount - 1;
- final StringBuilder destBuilder = new StringBuilder(dest);
- destBuilder.replace(destBuilder.indexOf(HOST_KEY), destBuilder.indexOf(HOST_KEY) + HOST_KEY.length(), parameters.ip)
- .replace(destBuilder.indexOf(PORT_KEY), destBuilder.indexOf(PORT_KEY) + PORT_KEY.length(), parameters.port + "");
- final StringBuilder suffixBuilder = new StringBuilder(parameters.destination);
- if (suffixBuilder.indexOf(DEVICE_PORT_KEY) != -1) {
- suffixBuilder.replace(suffixBuilder.indexOf(DEVICE_PORT_KEY), suffixBuilder.indexOf(DEVICE_PORT_KEY) + DEVICE_PORT_KEY.length(), devicePort + "");
- }
- destBuilder.append(suffixBuilder);
- payloads.add(new DestToPayload(destBuilder.toString(), prepareMessage(threadAmount - 1, requestsPerThread + i, editContentString)));
- }
-
- final ArrayList<PerfClientCallable> callables = new ArrayList<>();
- for (ArrayList<DestToPayload> payloads : allThreadsPayloads) {
- callables.add(new PerfClientCallable(parameters, payloads));
- }
-
- final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount);
-
- LOG.info("Starting performance test");
- final Stopwatch started = Stopwatch.createStarted();
- try {
- final List<Future<Void>> futures = executorService.invokeAll(callables, 5, TimeUnit.MINUTES);
- for (final Future<Void> future : futures) {
- try {
- future.get(4L, TimeUnit.MINUTES);
- } catch (ExecutionException | TimeoutException e) {
- throw new RuntimeException(e);
- }
- }
- executorService.shutdownNow();
- } catch (final InterruptedException e) {
- throw new RuntimeException("Unable to execute requests", e);
- }
- started.stop();
-
- LOG.info("FINISHED. Execution time: {}", started);
- LOG.info("Requests per second: {}", (parameters.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
-
- System.exit(0);
- }
-
- private static Parameters parseArgs(final String[] args, final ArgumentParser parser) {
- final Parameters opt = new Parameters();
- try {
- parser.parseArgs(args, opt);
- return opt;
- } catch (final ArgumentParserException e) {
- parser.handleError(e);
- }
-
- System.exit(1);
- return null;
- }
-
- private static String prepareMessage(final int idi, final int idj, final String editContentString) {
- StringBuilder messageBuilder = new StringBuilder(editContentString);
- if (editContentString.contains(PEER_KEY)) {
- messageBuilder.replace(messageBuilder.indexOf(PEER_KEY), messageBuilder.indexOf(PEER_KEY) + PEER_KEY.length(), Integer.toString(idi))
- .replace(messageBuilder.indexOf(INT_LEAF_KEY), messageBuilder.indexOf(INT_LEAF_KEY) + INT_LEAF_KEY.length(), Integer.toString(idj));
- }
-
- int idx = messageBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
-
- while (idx != -1) {
- messageBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), TestToolUtils.getMac(macStart++));
- idx = messageBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
- }
-
- return messageBuilder.toString();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.http.perf;
-
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.Request;
-import com.ning.http.client.Response;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.netconf.test.tool.client.stress.ExecutionStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SyncExecutionStrategy implements ExecutionStrategy{
-
- private static final Logger LOG = LoggerFactory.getLogger(SyncExecutionStrategy.class);
-
- private final Parameters params;
- private final ArrayList<Request> payloads;
- private final AsyncHttpClient asyncHttpClient;
-
- SyncExecutionStrategy(final Parameters params, final AsyncHttpClient asyncHttpClient, final ArrayList<Request> payloads) {
- this.params = params;
- this.asyncHttpClient = asyncHttpClient;
- this.payloads = payloads;
- }
-
- @Override
- public void invoke() {
-
- LOG.info("Begin sending sync requests");
- for (Request request : payloads) {
- try {
- Response response = asyncHttpClient.executeRequest(request).get();
- if (response.getStatusCode() != 200 && response.getStatusCode() != 204) {
- LOG.warn("Status code: {}", response.getStatusCode());
- LOG.warn("url: {}", request.getUrl());
- LOG.warn(response.getResponseBody());
- }
- } catch (InterruptedException | ExecutionException | IOException e) {
- LOG.warn(e.toString());
- }
- }
- LOG.info("End sending sync requests");
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-class AsyncExecutionStrategy implements ExecutionStrategy {
- private static final Logger LOG = LoggerFactory.getLogger(AsyncExecutionStrategy.class);
-
- private final Parameters params;
- private final List<NetconfMessage> preparedMessages;
- private final NetconfDeviceCommunicator sessionListener;
- private final List<Integer> editBatches;
- private final int editAmount;
-
- public AsyncExecutionStrategy(final Parameters params, final List<NetconfMessage> editConfigMsgs, final NetconfDeviceCommunicator sessionListener) {
- this.params = params;
- this.preparedMessages = editConfigMsgs;
- this.sessionListener = sessionListener;
- this.editBatches = countEditBatchSizes(params, editConfigMsgs.size());
- editAmount = editConfigMsgs.size();
- }
-
- private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
- final List<Integer> editBatches = Lists.newArrayList();
- if (params.editBatchSize != amount) {
- final int fullBatches = amount / params.editBatchSize;
- for (int i = 0; i < fullBatches; i++) {
- editBatches.add(params.editBatchSize);
- }
-
- if (amount % params.editBatchSize != 0) {
- editBatches.add(amount % params.editBatchSize);
- }
- } else {
- editBatches.add(params.editBatchSize);
- }
- return editBatches;
- }
-
- @Override
- public void invoke() {
- final AtomicInteger responseCounter = new AtomicInteger(0);
- final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
-
- int batchI = 0;
- for (final Integer editBatch : editBatches) {
- for (int i = 0; i < editBatch; i++) {
- final int msgId = i + (batchI * params.editBatchSize);
- final NetconfMessage msg = preparedMessages.get(msgId);
- LOG.debug("Sending message {}", msgId);
- if(LOG.isDebugEnabled()) {
- LOG.debug("Sending message {}", XmlUtil.toString(msg.getDocument()));
- }
- final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture =
- sessionListener.sendRequest(msg, StressClient.EDIT_QNAME);
- futures.add(netconfMessageFuture);
- }
- batchI++;
- LOG.info("Batch {} with size {} sent. Committing", batchI, editBatch);
- futures.add(sessionListener.sendRequest(StressClient.COMMIT_MSG, StressClient.COMMIT_QNAME));
- }
-
- LOG.info("All batches sent. Waiting for responses");
- // Wait for every future
- for (final ListenableFuture<RpcResult<NetconfMessage>> future : futures) {
- try {
- final RpcResult<NetconfMessage> netconfMessageRpcResult = future.get(params.msgTimeout, TimeUnit.SECONDS);
- if(netconfMessageRpcResult.isSuccessful()) {
- responseCounter.incrementAndGet();
- LOG.debug("Received response {}", responseCounter.get());
- } else {
- LOG.warn("Request failed {}", netconfMessageRpcResult);
- }
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException | TimeoutException e) {
- throw new RuntimeException("Request not finished", e);
- }
- }
-
- Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import io.netty.channel.EventLoopGroup;
-import io.netty.util.Timer;
-import java.util.Set;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSessionNegotiatorFactory;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-
-public class ConfigurableClientDispatcher extends NetconfClientDispatcherImpl {
-
- private final Set<String> capabilities;
-
- private ConfigurableClientDispatcher(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer, final Set<String> capabilities) {
- super(bossGroup, workerGroup, timer);
- this.capabilities = capabilities;
- }
-
- /**
- * EXI + chunked framing
- */
- public static ConfigurableClientDispatcher createChunkedExi(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
- return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer, NetconfClientSessionNegotiatorFactory.EXI_CLIENT_CAPABILITIES);
- }
-
- /**
- * EXI + ]]>]]> framing
- */
- public static ConfigurableClientDispatcher createLegacyExi(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
- return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer, NetconfClientSessionNegotiatorFactory.LEGACY_EXI_CLIENT_CAPABILITIES);
- }
-
- /**
- * Chunked framing
- */
- public static ConfigurableClientDispatcher createChunked(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
- return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer, NetconfClientSessionNegotiatorFactory.DEFAULT_CLIENT_CAPABILITIES);
- }
-
- /**
- * ]]>]]> framing
- */
- public static ConfigurableClientDispatcher createLegacy(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup, final Timer timer) {
- return new ConfigurableClientDispatcher(bossGroup, workerGroup, timer, NetconfClientSessionNegotiatorFactory.LEGACY_FRAMING_CLIENT_CAPABILITIES);
- }
-
- @Override
- protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
- return new NetconfClientSessionNegotiatorFactory(getTimer(), cfg.getAdditionalHeader(), cfg.getConnectionTimeoutMillis(), capabilities);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-/**
- * Created by mmarsale on 18.4.2015.
- */
-public interface ExecutionStrategy {
- void invoke();
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import com.google.common.base.Preconditions;
-import java.io.File;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import net.sourceforge.argparse4j.ArgumentParsers;
-import net.sourceforge.argparse4j.annotation.Arg;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-
-public class Parameters {
-
- @Arg(dest = "ip")
- public String ip;
-
- @Arg(dest = "port")
- public int port;
-
- @Arg(dest = "edit-count")
- public int editCount;
-
- @Arg(dest = "edit-content")
- public File editContent;
-
- @Arg(dest = "edit-batch-size")
- public int editBatchSize;
-
- @Arg(dest = "debug")
- public boolean debug;
-
- @Arg(dest = "legacy-framing")
- public boolean legacyFraming;
-
- @Arg(dest = "exi")
- public boolean exi;
-
- @Arg(dest = "async")
- public boolean async;
-
- @Arg(dest = "ssh")
- public boolean ssh;
-
- @Arg(dest = "username")
- public String username;
-
- @Arg(dest = "password")
- public String password;
-
- @Arg(dest = "msg-timeout")
- public long msgTimeout;
-
- @Arg(dest = "tcp-header")
- public String tcpHeader;
-
- @Arg(dest = "thread-amount")
- public int threadAmount;
-
- static ArgumentParser getParser() {
- final ArgumentParser parser = ArgumentParsers.newArgumentParser("netconf stress client");
-
- parser.description("Netconf stress client");
-
- parser.addArgument("--ip")
- .type(String.class)
- .setDefault("127.0.0.1")
- .type(String.class)
- .help("Netconf server IP")
- .dest("ip");
-
- parser.addArgument("--port")
- .type(Integer.class)
- .setDefault(2830)
- .type(Integer.class)
- .help("Netconf server port")
- .dest("port");
-
- parser.addArgument("--edits")
- .type(Integer.class)
- .setDefault(50000)
- .type(Integer.class)
- .help("Netconf edit rpcs to be sent")
- .dest("edit-count");
-
- parser.addArgument("--edit-content")
- .type(File.class)
- .setDefault(new File("edit.txt"))
- .type(File.class)
- .dest("edit-content");
-
- parser.addArgument("--edit-batch-size")
- .type(Integer.class)
- .required(false)
- .setDefault(-1)
- .type(Integer.class)
- .dest("edit-batch-size");
-
- parser.addArgument("--debug")
- .type(Boolean.class)
- .setDefault(false)
- .help("Whether to use debug log level instead of INFO")
- .dest("debug");
-
- parser.addArgument("--legacy-framing")
- .type(Boolean.class)
- .setDefault(false)
- .dest("legacy-framing");
-
- parser.addArgument("--exi")
- .type(Boolean.class)
- .setDefault(false)
- .dest("exi");
-
- parser.addArgument("--async-requests")
- .type(Boolean.class)
- .setDefault(true)
- .dest("async");
-
- parser.addArgument("--msg-timeout")
- .type(Integer.class)
- .setDefault(60)
- .dest("msg-timeout");
-
- parser.addArgument("--ssh")
- .type(Boolean.class)
- .setDefault(false)
- .dest("ssh");
-
- parser.addArgument("--username")
- .type(String.class)
- .setDefault("admin")
- .dest("username");
-
- parser.addArgument("--password")
- .type(String.class)
- .setDefault("admin")
- .dest("password");
-
- parser.addArgument("--tcp-header")
- .type(String.class)
- .required(false)
- .dest("tcp-header");
-
- parser.addArgument("--thread-amount")
- .type(Integer.class)
- .setDefault(1)
- .dest("thread-amount");
-
- // TODO add get-config option instead of edit + commit
- // TODO different edit config content
-
- return parser;
- }
-
- void validate() {
- Preconditions.checkArgument(port > 0, "Port =< 0");
- Preconditions.checkArgument(editCount > 0, "Edit count =< 0");
- if (editBatchSize == -1) {
- editBatchSize = editCount;
- } else {
- Preconditions.checkArgument(editBatchSize <= editCount, "Edit count =< 0");
- }
-
- Preconditions.checkArgument(editContent.exists(), "Edit content file missing");
- Preconditions.checkArgument(editContent.isDirectory() == false, "Edit content file is a dir");
- Preconditions.checkArgument(editContent.canRead(), "Edit content file is unreadable");
- // TODO validate
- }
-
- public InetSocketAddress getInetAddress() {
- try {
- return new InetSocketAddress(InetAddress.getByName(ip), port);
- } catch (final UnknownHostException e) {
- throw new IllegalArgumentException("Unknown ip", e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import ch.qos.logback.classic.Level;
-import com.google.common.base.Charsets;
-import com.google.common.base.Stopwatch;
-import com.google.common.io.Files;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import java.io.IOException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import net.sourceforge.argparse4j.inf.ArgumentParser;
-import net.sourceforge.argparse4j.inf.ArgumentParserException;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
-import org.opendaylight.controller.netconf.test.tool.TestToolUtils;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.CommitInput;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.base._1._0.rev110601.EditConfigInput;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
-
-public final class StressClient {
-
- private static final Logger LOG = LoggerFactory.getLogger(StressClient.class);
-
- static final QName COMMIT_QNAME = QName.create(CommitInput.QNAME, "commit");
- public static final NetconfMessage COMMIT_MSG;
-
- static {
- try {
- COMMIT_MSG = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc message-id=\"commit-batch\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <commit/>\n" +
- "</rpc>"));
- } catch (SAXException | IOException e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- static final QName EDIT_QNAME = QName.create(EditConfigInput.QNAME, "edit-config");
- static final org.w3c.dom.Document editBlueprint;
-
- static {
- try {
- editBlueprint = XmlUtil.readXmlToDocument(
- "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <edit-config xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
- " <target>\n" +
- " <candidate/>\n" +
- " </target>\n" +
- " <default-operation>none</default-operation>" +
- " <config/>\n" +
- " </edit-config>\n" +
- "</rpc>");
- } catch (SAXException | IOException e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- private static final String MSG_ID_PLACEHOLDER_REGEX = "\\{MSG_ID\\}";
- private static final String PHYS_ADDR_PLACEHOLDER = "{PHYS_ADDR}";
-
- private static long macStart = 0xAABBCCDD0000L;
-
- public static void main(final String[] args) {
-
- final Parameters params = parseArgs(args, Parameters.getParser());
- params.validate();
-
- final ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
- root.setLevel(params.debug ? Level.DEBUG : Level.INFO);
-
- final int threadAmount = params.threadAmount;
- LOG.info("thread amount: " + threadAmount);
- final int requestsPerThread = params.editCount / params.threadAmount;
- LOG.info("requestsPerThread: " + requestsPerThread);
- final int leftoverRequests = params.editCount % params.threadAmount;
- LOG.info("leftoverRequests: " + leftoverRequests);
-
-
- LOG.info("Preparing messages");
- // Prepare all msgs up front
- final List<List<NetconfMessage>> allPreparedMessages = new ArrayList<>(threadAmount);
- for (int i = 0; i < threadAmount; i++) {
- if (i != threadAmount - 1) {
- allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread));
- } else {
- allPreparedMessages.add(new ArrayList<NetconfMessage>(requestsPerThread + leftoverRequests));
- }
- }
-
-
- final String editContentString;
- try {
- editContentString = Files.toString(params.editContent, Charsets.UTF_8);
- } catch (final IOException e) {
- throw new IllegalArgumentException("Cannot read content of " + params.editContent);
- }
-
- for (int i = 0; i < threadAmount; i++) {
- final List<NetconfMessage> preparedMessages = allPreparedMessages.get(i);
- int padding = 0;
- if (i == threadAmount - 1) {
- padding = leftoverRequests;
- }
- for (int j = 0; j < requestsPerThread + padding; j++) {
- LOG.debug("id: " + (i * requestsPerThread + j));
- preparedMessages.add(prepareMessage(i * requestsPerThread + j, editContentString));
- }
- }
-
- final NioEventLoopGroup nioGroup = new NioEventLoopGroup();
- final Timer timer = new HashedWheelTimer();
-
- final NetconfClientDispatcherImpl netconfClientDispatcher = configureClientDispatcher(params, nioGroup, timer);
-
- final List<StressClientCallable> callables = new ArrayList<>(threadAmount);
- for (final List<NetconfMessage> messages : allPreparedMessages) {
- callables.add(new StressClientCallable(params, netconfClientDispatcher, messages));
- }
-
- final ExecutorService executorService = Executors.newFixedThreadPool(threadAmount);
-
- LOG.info("Starting stress test");
- final Stopwatch started = Stopwatch.createStarted();
- try {
- final List<Future<Boolean>> futures = executorService.invokeAll(callables);
- for (final Future<Boolean> future : futures) {
- try {
- future.get(4L, TimeUnit.MINUTES);
- } catch (ExecutionException | TimeoutException e) {
- throw new RuntimeException(e);
- }
- }
- executorService.shutdownNow();
- } catch (final InterruptedException e) {
- throw new RuntimeException("Unable to execute requests", e);
- }
- started.stop();
-
- LOG.info("FINISHED. Execution time: {}", started);
- LOG.info("Requests per second: {}", (params.editCount * 1000.0 / started.elapsed(TimeUnit.MILLISECONDS)));
-
- // Cleanup
- timer.stop();
- try {
- nioGroup.shutdownGracefully().get(20L, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- LOG.warn("Unable to close executor properly", e);
- }
- //stop the underlying ssh thread that gets spawned if we use ssh
- if (params.ssh) {
- AsyncSshHandler.DEFAULT_CLIENT.stop();
- }
- }
-
- static NetconfMessage prepareMessage(final int id, final String editContentString) {
- final Document msg = XmlUtil.createDocumentCopy(editBlueprint);
- msg.getDocumentElement().setAttribute("message-id", Integer.toString(id));
- final NetconfMessage netconfMessage = new NetconfMessage(msg);
-
- final Element editContentElement;
- try {
- // Insert message id where needed
- String specificEditContent = editContentString.replaceAll(MSG_ID_PLACEHOLDER_REGEX, Integer.toString(id));
-
- final StringBuilder stringBuilder = new StringBuilder(specificEditContent);
- int idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
- while (idx!= -1) {
- stringBuilder.replace(idx, idx + PHYS_ADDR_PLACEHOLDER.length(), TestToolUtils.getMac(macStart++));
- idx = stringBuilder.indexOf(PHYS_ADDR_PLACEHOLDER);
- }
- specificEditContent = stringBuilder.toString();
-
- editContentElement = XmlUtil.readXmlToElement(specificEditContent);
- final Node config = ((Element) msg.getDocumentElement().getElementsByTagName("edit-config").item(0)).
- getElementsByTagName("config").item(0);
- config.appendChild(msg.importNode(editContentElement, true));
- } catch (final IOException | SAXException e) {
- throw new IllegalArgumentException("Edit content file is unreadable", e);
- }
-
- return netconfMessage;
- }
-
- private static NetconfClientDispatcherImpl configureClientDispatcher(final Parameters params, final NioEventLoopGroup nioGroup, final Timer timer) {
- final NetconfClientDispatcherImpl netconfClientDispatcher;
- if(params.exi) {
- if(params.legacyFraming) {
- netconfClientDispatcher= ConfigurableClientDispatcher.createLegacyExi(nioGroup, nioGroup, timer);
- } else {
- netconfClientDispatcher = ConfigurableClientDispatcher.createChunkedExi(nioGroup, nioGroup, timer);
- }
- } else {
- if(params.legacyFraming) {
- netconfClientDispatcher = ConfigurableClientDispatcher.createLegacy(nioGroup, nioGroup, timer);
- } else {
- netconfClientDispatcher = ConfigurableClientDispatcher.createChunked(nioGroup, nioGroup, timer);
- }
- }
- return netconfClientDispatcher;
- }
-
- private static Parameters parseArgs(final String[] args, final ArgumentParser parser) {
- final Parameters opt = new Parameters();
- try {
- parser.parseArgs(args, opt);
- return opt;
- } catch (final ArgumentParserException e) {
- parser.handleError(e);
- }
-
- System.exit(1);
- return null;
- }
-
-
- static class LoggingRemoteDevice implements RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> {
- @Override
- public void onRemoteSessionUp(final NetconfSessionPreferences remoteSessionCapabilities, final NetconfDeviceCommunicator netconfDeviceCommunicator) {
- LOG.info("Session established");
- }
-
- @Override
- public void onRemoteSessionDown() {
- LOG.info("Session down");
- }
-
- @Override
- public void onRemoteSessionFailed(final Throwable throwable) {
- LOG.info("Session failed");
- }
-
- @Override
- public void onNotification(final NetconfMessage notification) {
- LOG.info("Notification received: {}", notification.toString());
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import io.netty.util.concurrent.GlobalEventExecutor;
-import java.net.InetSocketAddress;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
-import org.opendaylight.controller.netconf.client.NetconfClientSession;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
-import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
-import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.protocol.framework.NeverReconnectStrategy;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class StressClientCallable implements Callable<Boolean>{
-
- private static final Logger LOG = LoggerFactory.getLogger(StressClientCallable.class);
-
- private Parameters params;
- private final NetconfDeviceCommunicator sessionListener;
- private final NetconfClientDispatcherImpl netconfClientDispatcher;
- private final NetconfClientConfiguration cfg;
- private final NetconfClientSession netconfClientSession;
- private final ExecutionStrategy executionStrategy;
-
- public StressClientCallable(final Parameters params,
- final NetconfClientDispatcherImpl netconfClientDispatcher,
- final List<NetconfMessage> preparedMessages) {
- this.params = params;
- this.sessionListener = getSessionListener(params.getInetAddress());
- this.netconfClientDispatcher = netconfClientDispatcher;
- cfg = getNetconfClientConfiguration(this.params, this.sessionListener);
-
- LOG.info("Connecting to netconf server {}:{}", params.ip, params.port);
- try {
- netconfClientSession = netconfClientDispatcher.createClient(cfg).get();
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException e) {
- throw new RuntimeException("Unable to connect", e);
- }
- executionStrategy = getExecutionStrategy(params, preparedMessages, sessionListener);
- }
-
- @Override
- public Boolean call() throws Exception {
- executionStrategy.invoke();
- netconfClientSession.close();
- return true;
- }
-
- private static ExecutionStrategy getExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
- if(params.async) {
- return new AsyncExecutionStrategy(params, preparedMessages, sessionListener);
- } else {
- return new SyncExecutionStrategy(params, preparedMessages, sessionListener);
- }
- }
-
- private static NetconfDeviceCommunicator getSessionListener(final InetSocketAddress inetAddress) {
- final RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> loggingRemoteDevice = new StressClient.LoggingRemoteDevice();
- return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test", inetAddress), loggingRemoteDevice);
- }
-
- private static NetconfClientConfiguration getNetconfClientConfiguration(final Parameters params, final NetconfDeviceCommunicator sessionListener) {
- final NetconfClientConfigurationBuilder netconfClientConfigurationBuilder = NetconfClientConfigurationBuilder.create();
- netconfClientConfigurationBuilder.withSessionListener(sessionListener);
- netconfClientConfigurationBuilder.withAddress(params.getInetAddress());
- if(params.tcpHeader != null) {
- final String header = params.tcpHeader.replaceAll("\"", "").trim() + "\n";
- netconfClientConfigurationBuilder.withAdditionalHeader(new NetconfHelloMessageAdditionalHeader(null, null, null, null, null) {
- @Override
- public String toFormattedString() {
- LOG.debug("Sending TCP header {}", header);
- return header;
- }
- });
- }
- netconfClientConfigurationBuilder.withProtocol(params.ssh ? NetconfClientConfiguration.NetconfClientProtocol.SSH : NetconfClientConfiguration.NetconfClientProtocol.TCP);
- netconfClientConfigurationBuilder.withAuthHandler(new LoginPassword(params.username, params.password));
- netconfClientConfigurationBuilder.withConnectionTimeoutMillis(20000L);
- netconfClientConfigurationBuilder.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
- return netconfClientConfigurationBuilder.build();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.client.stress;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-// TODO reuse code from org.opendaylight.controller.netconf.test.tool.client.stress.AsyncExecutionStrategy
-class SyncExecutionStrategy implements ExecutionStrategy {
- private static final Logger LOG = LoggerFactory.getLogger(SyncExecutionStrategy.class);
-
- private final Parameters params;
- private final List<NetconfMessage> preparedMessages;
- private final NetconfDeviceCommunicator sessionListener;
- private final List<Integer> editBatches;
- private final int editAmount;
-
- public SyncExecutionStrategy(final Parameters params, final List<NetconfMessage> preparedMessages, final NetconfDeviceCommunicator sessionListener) {
- this.params = params;
- this.preparedMessages = preparedMessages;
- this.sessionListener = sessionListener;
- this.editBatches = countEditBatchSizes(params, preparedMessages.size());
- editAmount = preparedMessages.size();
- }
-
- private static List<Integer> countEditBatchSizes(final Parameters params, final int amount) {
- final List<Integer> editBatches = Lists.newArrayList();
- if (params.editBatchSize != amount) {
- final int fullBatches = amount / params.editBatchSize;
- for (int i = 0; i < fullBatches; i++) {
- editBatches.add(params.editBatchSize);
- }
-
- if (amount % params.editBatchSize != 0) {
- editBatches.add(amount % params.editBatchSize);
- }
- } else {
- editBatches.add(params.editBatchSize);
- }
- return editBatches;
- }
-
- public void invoke() {
- final AtomicInteger responseCounter = new AtomicInteger(0);
-
- int batchI = 0;
- for (final Integer editBatch : editBatches) {
- for (int i = 0; i < editBatch; i++) {
- final int msgId = i + (batchI * params.editBatchSize);
- final NetconfMessage msg = preparedMessages.get(msgId);
- LOG.debug("Sending message {}", msgId);
- if(LOG.isDebugEnabled()) {
- LOG.debug("Sending message {}", XmlUtil.toString(msg.getDocument()));
- }
- final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture =
- sessionListener.sendRequest(msg, StressClient.EDIT_QNAME);
- // Wait for response
- waitForResponse(responseCounter, netconfMessageFuture);
-
- }
- batchI++;
- LOG.info("Batch {} with size {} sent. Committing", batchI, editBatch);
-
- // Commit batch sync
- waitForResponse(responseCounter,
- sessionListener.sendRequest(StressClient.COMMIT_MSG, StressClient.COMMIT_QNAME));
- }
-
- Preconditions.checkState(responseCounter.get() == editAmount + editBatches.size(), "Not all responses were received, only %s from %s", responseCounter.get(), params.editCount + editBatches.size());
- }
-
- private void waitForResponse(AtomicInteger responseCounter, final ListenableFuture<RpcResult<NetconfMessage>> netconfMessageFuture) {
- try {
- final RpcResult<NetconfMessage> netconfMessageRpcResult =
- netconfMessageFuture.get(params.msgTimeout, TimeUnit.SECONDS);
- if (netconfMessageRpcResult.isSuccessful()) {
- responseCounter.incrementAndGet();
- LOG.debug("Received response {}", responseCounter.get());
- } else {
- LOG.warn("Request failed {}", netconfMessageRpcResult);
- }
-
- } catch (final InterruptedException e) {
- throw new RuntimeException(e);
- } catch (final ExecutionException | TimeoutException e) {
- throw new RuntimeException("Request not finished", e);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-
-public class DataList {
-
- private List<XmlElement> configList = Collections.emptyList();
-
- public List<XmlElement> getConfigList() {
- return configList;
- }
-
- public void setConfigList(List<XmlElement> configList) {
- this.configList = configList;
- }
-
- public void resetConfigList() {
- configList = Collections.emptyList();
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedCommit extends AbstractConfigNetconfOperation {
-
- public SimulatedCommit(final String netconfSessionIdForReporting) {
- super(null, netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.COMMIT;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-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.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-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.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.impl.NetconfServerSession;
-import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation;
-import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.SAXException;
-
-public class SimulatedCreateSubscription extends AbstractLastNetconfOperation implements DefaultNetconfOperation {
-
- private final Map<Notification, NetconfMessage> notifications;
- private NetconfServerSession session;
- private ScheduledExecutorService scheduledExecutorService;
-
- public SimulatedCreateSubscription(final String id, final Optional<File> notificationsFile) {
- super(id);
-
- Optional<Notifications> notifications;
-
- if(notificationsFile.isPresent()) {
- notifications = Optional.of(loadNotifications(notificationsFile.get()));
- scheduledExecutorService = Executors.newScheduledThreadPool(1);
- } else {
- notifications = Optional.absent();
- }
-
- if(notifications.isPresent()) {
- Map<Notification, NetconfMessage> preparedMessages = Maps.newHashMapWithExpectedSize(notifications.get().getNotificationList().size());
- for (final Notification notification : notifications.get().getNotificationList()) {
- final NetconfMessage parsedNotification = parseNetconfNotification(notification.getContent());
- preparedMessages.put(notification, parsedNotification);
- }
- this.notifications = preparedMessages;
- } else {
- this.notifications = Collections.emptyMap();
- }
-
- }
-
- private 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("Canot 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) throws DocumentedException {
- long delayAggregator = 0;
-
- for (final Map.Entry<Notification, NetconfMessage> notification : notifications.entrySet()) {
- for (int i = 0; i <= notification.getKey().getTimes(); i++) {
-
- delayAggregator += notification.getKey().getDelayInSeconds();
-
- scheduledExecutorService.schedule(new Runnable() {
- @Override
- public void run() {
- Preconditions.checkState(session != null, "Session is not set, cannot process notifications");
- session.sendMessage(notification.getValue());
- }
- }, delayAggregator, TimeUnit.SECONDS);
- }
- }
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- private static NetconfMessage parseNetconfNotification(String content) {
- final int startEventTime = content.indexOf("<eventTime>") + "<eventTime>".length();
- final int endEventTime = content.indexOf("</eventTime>");
- 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 s) {
- this.session = s;
- }
-
- @XmlRootElement(name = "notifications")
- public static final class Notifications {
-
- @javax.xml.bind.annotation.XmlElement(nillable = false, name = "notification", required = true)
- private List<Notification> notificationList;
-
- public List<Notification> getNotificationList() {
- return notificationList;
- }
-
- @Override
- public String toString() {
- final StringBuffer sb = new StringBuffer("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 StringBuffer sb = new StringBuffer("Notification{");
- sb.append("delayInSeconds=").append(delayInSeconds);
- sb.append(", times=").append(times);
- sb.append(", content='").append(content).append('\'');
- sb.append('}');
- return sb.toString();
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedEditConfig extends AbstractConfigNetconfOperation {
- private static final String DELETE_EDIT_CONFIG = "delete";
- private static final String OPERATION = "operation";
- private static final String REMOVE_EDIT_CONFIG = "remove";
- private final DataList storage;
-
- public SimulatedEditConfig(final String netconfSessionIdForReporting, final DataList storage) {
- super(null, netconfSessionIdForReporting);
- this.storage = storage;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final XmlElement configElementData = operationElement.getOnlyChildElement(XmlNetconfConstants.CONFIG_KEY);
-
- containsDelete(configElementData);
- if(containsDelete(configElementData)){
- storage.resetConfigList();
- } else {
- storage.setConfigList(configElementData.getChildElements());
- }
-
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return EditConfigXmlParser.EDIT_CONFIG;
- }
-
- private boolean containsDelete(final XmlElement element) {
- for (final Attr o : element.getAttributes().values()) {
- if (o.getLocalName().equals(OPERATION)
- && (o.getValue().equals(DELETE_EDIT_CONFIG) || o.getValue()
- .equals(REMOVE_EDIT_CONFIG))) {
- return true;
- }
-
- }
-
- for (final XmlElement xmlElement : element.getChildElements()) {
- if (containsDelete(xmlElement)) {
- return true;
- }
-
- }
-
- return false;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedGet extends AbstractConfigNetconfOperation {
-
- private final DataList storage;
-
- public SimulatedGet(final String netconfSessionIdForReporting, final DataList storage) {
- super(null, netconfSessionIdForReporting);
- this.storage = storage;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Element element = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
-
- for(final XmlElement e : storage.getConfigList()) {
- final Element domElement = e.getDomElement();
- element.appendChild(element.getOwnerDocument().importNode(domElement, true));
- }
-
- return element;
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.GET;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedGetConfig extends AbstractConfigNetconfOperation {
-
- private final DataList storage;
-
- public SimulatedGetConfig(final String netconfSessionIdForReporting, final DataList storage) {
- super(null, netconfSessionIdForReporting);
- this.storage = storage;
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- final Element element = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.<String>absent());
-
- for(final XmlElement e : storage.getConfigList()) {
- final Element domElement = e.getDomElement();
- element.appendChild(element.getOwnerDocument().importNode(domElement, true));
- }
-
- return element;
- }
-
- @Override
- protected String getOperationName() {
- return XmlNetconfConstants.GET_CONFIG;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedLock extends AbstractConfigNetconfOperation {
-
- public SimulatedLock(final String netconfSessionIdForReporting) {
- super(null, netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return "lock";
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.netconf.test.tool.rpc;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.util.xml.DocumentedException;
-import org.opendaylight.controller.config.util.xml.XmlElement;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
-import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-public class SimulatedUnLock extends AbstractConfigNetconfOperation {
-
- public SimulatedUnLock(final String netconfSessionIdForReporting) {
- super(null, netconfSessionIdForReporting);
- }
-
- @Override
- protected Element handleWithNoSubsequentOperations(final Document document, final XmlElement operationElement) throws DocumentedException {
- return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
- }
-
- @Override
- protected String getOperationName() {
- return "unlock";
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <!-- Netconf connection to simulated netconf device -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
- <name>%s</name>
- <address xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">%s</address>
- <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">%s</port>
- <username xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</username>
- <password xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">admin</password>
- <tcp-only xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">%s</tcp-only>
- <reconnect-on-changed-schema xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">false</reconnect-on-changed-schema>
- <keepalive-delay xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">-1</keepalive-delay>
- <event-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-event-executor</type>
- <name>global-event-executor</name>
- </event-executor>
- <binding-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
- <name>binding-osgi-broker</name>
- </binding-registry>
- <dom-registry xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
- <name>dom-broker</name>
- </dom-registry>
- <client-dispatcher xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- </client-dispatcher>
- <processing-executor xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <name>global-netconf-processing-executor</name>
- </processing-executor>
- </module>
- </modules>
- </data>
- </configuration>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&revision=2013-10-28</capability>
- </required-capabilities>
-</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
- ~ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- ~
- ~ This program and the accompanying materials are made available under the
- ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
- ~ and is available at http://www.eclipse.org/legal/epl-v10.html
- -->
-
-<configuration>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
- </encoder>
- </appender>
-
- <root level="INFO">
- <appender-ref ref="STDOUT"/>
- </root>
-
- <logger name="com.ning.http.client" level="WARN"/>
-</configuration>
\ No newline at end of file
+++ /dev/null
-################################################################################
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License 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.
-#
-################################################################################
-
-#
-# If set to true, the following property will not allow any certificate to be used
-# when accessing Maven repositories through SSL
-#
-#org.ops4j.pax.url.mvn.certificateCheck=
-
-#
-# Path to the local Maven settings file.
-# The repositories defined in this file will be automatically added to the list
-# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property
-# below is not set.
-# The following locations are checked for the existence of the settings.xml file
-# * 1. looks for the specified url
-# * 2. if not found looks for ${user.home}/.m2/settings.xml
-# * 3. if not found looks for ${maven.home}/conf/settings.xml
-# * 4. if not found looks for ${M2_HOME}/conf/settings.xml
-#
-#org.ops4j.pax.url.mvn.settings=
-
-#
-# Path to the local Maven repository which is used to avoid downloading
-# artifacts when they already exist locally.
-# The value of this property will be extracted from the settings.xml file
-# above, or defaulted to:
-# System.getProperty( "user.home" ) + "/.m2/repository"
-#
-org.ops4j.pax.url.mvn.localRepository=${karaf.home}/${karaf.default.repository}
-
-#
-# Default this to false. It's just weird to use undocumented repos
-#
-org.ops4j.pax.url.mvn.useFallbackRepositories=false
-
-#
-# Uncomment if you don't wanna use the proxy settings
-# from the Maven conf/settings.xml file
-#
-# org.ops4j.pax.url.mvn.proxySupport=false
-
-#
-# Disable aether support by default. This ensure that the defaultRepositories
-# below will be used
-#
-#org.ops4j.pax.url.mvn.disableAether=true
-
-#
-# Comma separated list of repositories scanned when resolving an artifact.
-# Those repositories will be checked before iterating through the
-# below list of repositories and even before the local repository
-# A repository url can be appended with zero or more of the following flags:
-# @snapshots : the repository contains snaphots
-# @noreleases : the repository does not contain any released artifacts
-#
-# The following property value will add the system folder as a repo.
-#
-#org.ops4j.pax.url.mvn.defaultRepositories=
-
-# Use the default local repo (e.g.~/.m2/repository) as a "remote" repo
-org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=false
-
-#
-# Comma separated list of repositories scanned when resolving an artifact.
-# The default list includes the following repositories containing releases:
-# http://repo1.maven.org/maven2
-# http://repository.apache.org/content/groups/snapshots-group
-# http://svn.apache.org/repos/asf/servicemix/m2-repo
-# http://repository.springsource.com/maven/bundles/release
-# http://repository.springsource.com/maven/bundles/external
-# To add repositories to the default ones, prepend '+' to the list of repositories
-# to add.
-# A repository url can be appended with zero or more of the following flags:
-# @snapshots : the repository contains snaphots
-# @noreleases : the repository does not contain any released artifacts
-# @id=reponid : the id for the repository, just like in the settings.xml this is optional but recomendet
-#
-# The default list doesn't contain any repository containing snapshots as it can impact the artifacts resolution.
-# You may want to add the following repositories containing snapshots:
-# http://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases
-# http://oss.sonatype.org/content/repositories/snapshots@id=sonatype.snapshots.deploy@snapshots@norelease
-# http://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j.sonatype.snapshots.deploy@snapshots@noreleases
-#
-org.ops4j.pax.url.mvn.repositories= \
- file:${karaf.home}/${karaf.default.repository}@id=system.repository, \
- file:${karaf.data}/kar@id=kar.repository@multi, \
- http://repo1.maven.org/maven2@id=central, \
- http://repository.springsource.com/maven/bundles/release@id=spring.ebr.release, \
- http://repository.springsource.com/maven/bundles/external@id=spring.ebr.external
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-subsystem</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <relativePath>../</relativePath>
- </parent>
- <artifactId>netconf-tools</artifactId>
-
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>${project.artifactId}</name>
-
- <modules>
- <module>netconf-cli</module>
- <module>netconf-testtool</module>
- </modules>
-
- <build>
- <pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <version>${yangtools.version}</version>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <yangFilesRootDir>src/main/yang</yangFilesRootDir>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/site/models</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
-
- </pluginManagement>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <failsOnError>false</failsOnError>
- <failOnViolation>true</failOnViolation>
- <configLocation>checkstyle-logging.xml</configLocation>
- <consoleOutput>true</consoleOutput>
- <includeTestSourceDirectory>true</includeTestSourceDirectory>
- <sourceDirectory>${project.basedir}</sourceDirectory>
- <includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang</includes>
- <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/,**\/netconf\/test\/tool\/Main.java, **\/netconf\/test\/tool\/client\/stress\/StressClient.java</excludes>
- </configuration>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>checkstyle-logging</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
- <executions>
- <execution>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-</project>