From: Ed Warnicke Date: Mon, 28 Apr 2014 12:21:21 +0000 (+0000) Subject: Merge "BUG 652 leafref CCE & BUG 720 colons problem" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~169 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=84248dac9ed8aa37e996e39429c8aa8ece473eaf;hp=874d0e74084fc55af280a97052570c8cccf60821 Merge "BUG 652 leafref CCE & BUG 720 colons problem" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 3839d5b2cb..f30d4b005a 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -15,39 +15,64 @@ + 1.0.0 + 0.4.2-SNAPSHOT + 0.5.2-SNAPSHOT + + 1.50 2.3.7 0.4.2-SNAPSHOT 2.10 0.5.1-SNAPSHOT 0.4.3-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + + 1.7 + 1.2.2 0.1.2-SNAPSHOT 2.4 3.1 + 3.0.1 2.3.2 0.5.2-SNAPSHOT 0.2.5-SNAPSHOT + 0.4.3-SNAPSHOT 0.4.3-SNAPSHOT 0.1.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.2-SNAPSHOT - + 0.0.2-SNAPSHOT 7.0.42 + 0.4.2-SNAPSHOT + 2.5.0 1.3.1 1.26.2 3.0.0 - 0000.0002.0035.0-SNAPSHOT + 0000.0002.0038.0-SNAPSHOT 2.15 + 3.0.1 + 3.1.0 + 3.1.6 + 4.2.0 + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.6.0-SNAPSHOT 2.2.0.RELEASE + 2.2.4 14.0.1 0.5.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT 2010.09.24.4-SNAPSHOT 2013.10.21.2-SNAPSHOT @@ -61,8 +86,11 @@ 1.17 1.17 + 1.3.3 src/main/yang-gen-config 1.1.4 + 2.0.1 + 1.1.1 4.8.1 1.0.9 0.4.2-SNAPSHOT @@ -75,24 +103,34 @@ 0.2.5-SNAPSHOT 4.0.17.Final 0.0.3-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT http://nexus.opendaylight.org/content 2013.08.27.4-SNAPSHOT + 0.0.2-SNAPSHOT + 5.0.0 5.0.0 UTF-8 UTF-8 2.6 - 1.0-alpha-2 0.5.0-SNAPSHOT - 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 2.3.2 + 0.4.2-SNAPSHOT 0.1.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.0.3-SNAPSHOT 0.8.1-SNAPSHOT src/main/yang-gen-sal 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT dav:http://nexus.opendaylight.org/content/sites/site 3.2 1.7.2 @@ -105,14 +143,25 @@ 1.2.1 3.1.3.RELEASE 3.1.3.RELEASE + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.1-SNAPSHOT + 0.4.2-SNAPSHOT 2.15 0.7.1-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT -Xmx1024m -XX:MaxPermSize=256m + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 1.5.0 + 0.4.2-SNAPSHOT + 0.0.2-SNAPSHOT 0.4.2-SNAPSHOT 3.6.0.RELEASE + 0.4.2-SNAPSHOT src/main/xtend-gen 2.4.3 2013.09.07.4-SNAPSHOT @@ -142,37 +191,31 @@ logback-core ${logback.version} - com.fasterxml.jackson.core jackson-annotations ${jackson.version} - com.fasterxml.jackson.core jackson-core ${jackson.version} - com.fasterxml.jackson.core jackson-databind ${jackson.version} - com.fasterxml.jackson.jaxrs jackson-jaxrs-base ${jackson.version} - com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider ${jackson.version} - com.fasterxml.jackson.module jackson-module-jaxb-annotations @@ -181,12 +224,12 @@ com.google.code.findbugs jsr305 - 2.0.1 + ${jsr305.api.version} com.google.code.gson gson - 2.2.4 + ${gson.version} com.google.guava @@ -204,6 +247,11 @@ jersey-core ${jersey.version} + + javax.ws.rs + jsr311-api + ${jsr311.api.version} + com.sun.jersey jersey-server @@ -212,12 +260,12 @@ commons-codec commons-codec - 1.7 + ${commons.codec.version} commons-fileupload commons-fileupload - 1.2.2 + ${commons.fileupload.version} commons-io @@ -227,7 +275,7 @@ commons-net commons-net - 3.0.1 + ${commons.net.version} eclipselink @@ -370,8 +418,7 @@ netty-common ${netty.version} - - + io.netty netty-handler @@ -470,7 +517,7 @@ org.aopalliance com.springsource.org.aopalliance - 1.0.0 + ${aopalliance.version} org.apache.commons @@ -480,46 +527,45 @@ org.apache.felix org.apache.felix.dependencymanager - 3.1.0 + ${felix.dependencymanager.version} org.apache.felix org.apache.felix.dependencymanager.shell - 3.0.1 + ${felix.dependencymanager.shell.version} org.apache.felix org.apache.felix.fileinstall - 3.1.6 + ${felix.fileinstall.version} org.apache.felix org.apache.felix.webconsole - 4.2.0 + ${felix.webconsole.version} all org.bouncycastle bcpkix-jdk15on - 1.50 + ${bouncycastle.version} org.bouncycastle bcprov-jdk15on - 1.50 + ${bouncycastle.version} org.codehaus.enunciate enunciate-core-annotations ${enunciate.version} - org.codehaus.jettison jettison - 1.3.3 + ${jettison.version} @@ -531,17 +577,17 @@ org.eclipse.persistence org.eclipse.persistence.antlr - 2.5.0 + ${eclipse.persistence.version} org.eclipse.persistence org.eclipse.persistence.core - 2.5.0 + ${eclipse.persistence.version} org.eclipse.persistence org.eclipse.persistence.moxy - 2.5.0 + ${eclipse.persistence.version} @@ -568,7 +614,7 @@ org.opendaylight.controller appauth - 0.4.2-SNAPSHOT + ${appauth.version} org.opendaylight.controller @@ -605,7 +651,7 @@ org.opendaylight.controller clustering.test - 0.4.2-SNAPSHOT + ${clustering.test.version} org.opendaylight.controller @@ -617,7 +663,7 @@ org.opendaylight.controller commons.northbound - 0.4.2-SNAPSHOT + ${commmons.northbound.version} org.opendaylight.controller @@ -693,7 +739,7 @@ org.opendaylight.controller configuration.implementation - 0.4.3-SNAPSHOT + ${configuration.implementation.version} org.opendaylight.controller @@ -728,27 +774,27 @@ org.opendaylight.controller containermanager.northbound - 0.4.2-SNAPSHOT + ${containermanager.northbound.version} org.opendaylight.controller controllermanager.northbound - 0.0.2-SNAPSHOT + ${controllermanager.northbound.version} org.opendaylight.controller devices.web - 0.4.2-SNAPSHOT + ${devices.web.version} org.opendaylight.controller flowprogrammer.northbound - 0.4.2-SNAPSHOT + ${flowprogrammer.northbound.version} org.opendaylight.controller flows.web - 0.4.2-SNAPSHOT + ${flows.web.version} org.opendaylight.controller @@ -758,7 +804,7 @@ org.opendaylight.controller forwarding.staticrouting.northbound - 0.4.2-SNAPSHOT + ${forwarding.staticrouting.northbound.version} org.opendaylight.controller @@ -768,7 +814,7 @@ org.opendaylight.controller forwardingrulesmanager.implementation - 0.4.2-SNAPSHOT + ${forwardingrulesmanager.implementation.version} @@ -784,7 +830,7 @@ org.opendaylight.controller hosttracker.northbound - 0.4.2-SNAPSHOT + ${hosttracker.northbound.version} org.opendaylight.controller @@ -897,22 +943,22 @@ org.opendaylight.controller networkconfig.neutron - 0.4.2-SNAPSHOT + ${networkconfig.neutron.version} org.opendaylight.controller networkconfig.neutron.implementation - 0.4.2-SNAPSHOT + ${networkconfig.neutron.implementation.version} org.opendaylight.controller networkconfig.neutron.northbound - 0.4.2-SNAPSHOT + ${networkconfig.neutron.northbound.version} org.opendaylight.controller osgi-brandfragment.web - 0.0.2-SNAPSHOT + ${osgi-brandfragment.web.version} @@ -925,17 +971,17 @@ org.opendaylight.controller protocol_plugins.openflow - 0.4.2-SNAPSHOT + ${protocol_plugins.openflow.version} org.opendaylight.controller protocol_plugins.stub - ${protocol_plugin.stub.version} + ${protocol_plugins.stub.version} org.opendaylight.controller routing.dijkstra_implementation - 0.4.2-SNAPSHOT + ${routing.dijkstra_implementation.version} @@ -1049,7 +1095,7 @@ org.opendaylight.controller sal.implementation - 0.4.2-SNAPSHOT + ${sal.implementation.version} org.opendaylight.controller @@ -1071,12 +1117,12 @@ org.opendaylight.controller samples.loadbalancer.northbound - 0.4.2-SNAPSHOT + ${samples.loadbalancer.northbound.version} org.opendaylight.controller samples.simpleforwarding - 0.4.2-SNAPSHOT + ${samples.simpleforwarding.version} org.opendaylight.controller @@ -1086,7 +1132,7 @@ org.opendaylight.controller security - 0.4.2-SNAPSHOT + ${security.version} @@ -1102,7 +1148,7 @@ org.opendaylight.controller statistics.northbound - 0.4.2-SNAPSHOT + ${statistics.northbound.version} org.opendaylight.controller @@ -1112,12 +1158,12 @@ org.opendaylight.controller statisticsmanager.implementation - 0.4.2-SNAPSHOT + ${statisticsmanager.implementation.version} org.opendaylight.controller subnets.northbound - 0.4.2-SNAPSHOT + ${subnets.northbound.version} org.opendaylight.controller @@ -1127,12 +1173,12 @@ org.opendaylight.controller switchmanager.implementation - 0.4.2-SNAPSHOT + ${switchmanager.implementation.version} org.opendaylight.controller switchmanager.northbound - 0.4.2-SNAPSHOT + ${switchmanager.northbound.version} @@ -1149,12 +1195,12 @@ org.opendaylight.controller topology.northbound - 0.4.2-SNAPSHOT + ${topology.northbound.version} org.opendaylight.controller topology.web - 0.4.2-SNAPSHOT + ${topology.web.version} org.opendaylight.controller @@ -1164,7 +1210,7 @@ org.opendaylight.controller troubleshoot.web - 0.4.2-SNAPSHOT + ${troubleshoot.web.version} org.opendaylight.controller @@ -1174,19 +1220,19 @@ org.opendaylight.controller usermanager.implementation - ${usermanager.version} + ${usermanager.implementation.version} org.opendaylight.controller usermanager.northbound - 0.0.2-SNAPSHOT + ${usermanager.northbound.version} org.opendaylight.controller web - 0.4.2-SNAPSHOT + ${web.version} org.opendaylight.controller @@ -1406,7 +1452,7 @@ org.osgi org.osgi.compendium - ${osgi.core.version} + ${osgi.compendium.version} org.osgi diff --git a/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java b/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java index 1d4139f885..156fa580ce 100644 --- a/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java +++ b/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java @@ -18,4 +18,7 @@ public interface PropertiesProvider { * @return prefix + key as used in getProperty method. */ String getFullKeyForReporting(String key); + + String getPrefix(); + String getPropertyWithoutPrefix(String fullKey); } diff --git a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java index 2df07b114c..3d4757b926 100644 --- a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java +++ b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java @@ -26,4 +26,14 @@ public class PropertiesProviderTest implements PropertiesProvider { public String getFullKeyForReporting(String key) { return null; } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getPropertyWithoutPrefix(String fullKey) { + return null; + } } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java new file mode 100644 index 0000000000..ae6ae67584 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java @@ -0,0 +1,20 @@ +/* +* 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 +*/ +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-dep +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 25 11:50:32 CEST 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory { + +} diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java new file mode 100644 index 0000000000..07012263e1 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java @@ -0,0 +1,20 @@ +/* +* 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 +*/ +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 25 11:50:32 CEST 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory { + +} diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java new file mode 100644 index 0000000000..3baee6c132 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java @@ -0,0 +1,20 @@ +/* +* 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 +*/ +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-netconf +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 25 11:50:32 CEST 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory { + +} diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java new file mode 100644 index 0000000000..6f9118bf92 --- /dev/null +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java @@ -0,0 +1,20 @@ +/* +* 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 +*/ +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 25 11:50:32 CEST 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory { + +} diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml index 2365c700f9..686d363110 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml @@ -1,3 +1,12 @@ + + + urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-clustering.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-clustering.xml index 7853b8681b..c5f99fd0c1 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-clustering.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-clustering.xml @@ -1,3 +1,12 @@ + + + diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/03-toaster-sample.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/03-toaster-sample.xml index c481485c92..6d5d0eb826 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/03-toaster-sample.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/03-toaster-sample.xml @@ -1,3 +1,12 @@ + + + diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml new file mode 100644 index 0000000000..8143a38f34 --- /dev/null +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/04-netconf-connector.xml @@ -0,0 +1,45 @@ + + + + + + + + + prefix:sal-netconf-connector + controller-config + 1830 + admin + + prefix:netty-threadgroup + global-worker-group + +
127.0.0.1
+ false + + prefix:netty-event-executor + global-event-executor + + admin + + prefix:netty-threadgroup + global-boss-group + + + prefix:dom-broker-osgi-registry + dom-broker + +
+
+
+
+ + urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&revision=2013-10-28 + +
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend index 6a9712b1c6..75cbf49ee5 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend @@ -113,6 +113,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie public class MDFlowMapping { @@ -127,7 +128,7 @@ public class MDFlowMapping { hardTimeout = sourceFlow.hardTimeout as int idleTimeout = sourceFlow.idleTimeout as int - cookie = BigInteger.valueOf(sourceFlow.id) + cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) priority = sourceFlow.priority as int val sourceActions = sourceFlow.actions; @@ -150,7 +151,7 @@ public class MDFlowMapping { val it = new FlowBuilder(); hardTimeout = sourceFlow.hardTimeout as int idleTimeout = sourceFlow.idleTimeout as int - cookie = BigInteger.valueOf(sourceFlow.id) + cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) priority = sourceFlow.priority as int id = new FlowId(flowId) @@ -404,7 +405,7 @@ public class MDFlowMapping { hardTimeout = sourceFlow.hardTimeout as int idleTimeout = sourceFlow.idleTimeout as int - cookie = BigInteger.valueOf(sourceFlow.id) + cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) priority = sourceFlow.priority as int val sourceActions = sourceFlow.actions; diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java index cb72896858..74b94c7cba 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java @@ -148,7 +148,7 @@ public class ToSalConversionsUtils { target.setActions(actionFrom(actions, node)); } - target.setId(source.getCookie().longValue()); + target.setId(source.getCookie().getValue().longValue()); return target; } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java index b062b0016d..63c5664a0c 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java @@ -177,7 +177,7 @@ public class TestFromSalConversionsUtils { } private void checkOdFlow(NodeFlow odNodeFlow) { - assertEquals("Cookie is incorrect.", 9223372036854775807L, odNodeFlow.getCookie().longValue()); + assertEquals("Cookie is incorrect.", 9223372036854775807L, odNodeFlow.getCookie().getValue().longValue()); assertEquals("Hard timeout is incorrect.", 32765, odNodeFlow.getHardTimeout().shortValue()); assertEquals("Iddle timeout is incorrect.", 32766, odNodeFlow.getIdleTimeout().shortValue()); assertEquals("Priority is incorrect.", 32767, odNodeFlow.getPriority().shortValue()); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java index ca16c65f56..71f2e94805 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java @@ -105,6 +105,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.addr import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; @@ -347,7 +348,7 @@ public class TestToSalConversionsUtils { private FlowAddedBuilder prepareOdFlowCommon() { FlowAddedBuilder odNodeFlowBuilder = new FlowAddedBuilder(); - odNodeFlowBuilder.setCookie(new BigInteger("9223372036854775807")); + odNodeFlowBuilder.setCookie(new FlowCookie(new BigInteger("9223372036854775807"))); odNodeFlowBuilder.setHardTimeout(32767); odNodeFlowBuilder.setIdleTimeout(32767); odNodeFlowBuilder.setPriority(32767); diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang index 02bdd1a1fa..0d8a0b6f54 100644 --- a/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang +++ b/opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang @@ -15,6 +15,11 @@ module opendaylight-flow-types { type instance-identifier; } + typedef flow-cookie { + description "openflow specific type - flow cookie / flow cookie mask"; + type uint64; + } + typedef output-port-values { type enumeration { enum MAX { @@ -143,7 +148,7 @@ module opendaylight-flow-types { } leaf cookie { - type uint64; + type flow-cookie; } leaf table_id { @@ -167,7 +172,7 @@ module opendaylight-flow-types { } leaf cookie_mask { - type uint64; + type flow-cookie; } leaf buffer_id { diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/node-errors.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/node-errors.yang new file mode 100644 index 0000000000..a8eec26936 --- /dev/null +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/node-errors.yang @@ -0,0 +1,168 @@ +module node-error { + namespace "urn:opendaylight:node:error:service"; + prefix node-error; + + import sal-flow {prefix flow; revision-date "2013-08-19";} + import flow-errors {prefix error;} + import flow-capable-transaction {prefix tr;} + import yang-ext {prefix ext; revision-date "2013-07-09";} + import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} + import opendaylight-flow-types {prefix types;revision-date "2013-10-26";} + import opendaylight-group-types {prefix group-type;revision-date 2013-10-18;} + import opendaylight-meter-types {prefix meter-type;revision-date "2013-09-18";} + + revision "2014-04-10" { + description "Initial revision of errors received from a node"; + } + + notification hello-failed-error-notification { + description "Model for ofp_error-Type=0, Hello protocol failed"; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification bad-request-error-notification { + description "Model for ofp_error-Type=1, Request was not understood."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification bad-action-error-notification { + description "Model for ofp_error-Type=2, Error in action description."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification bad-instruction-error-notification { + description "Model for ofp_error-Type=3, Error in instruction list."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification bad-match-error-notification { + description "Model for ofp_error-Type=4, Error in match."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification flow-mod-error-notification { + description "Model for ofp_error-Type=5 - Problem modifying flow entry."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + uses flow:node-error-reference; + } + + notification group-mod-error-notification { + description "Model for ofp_error-Type=6 - Problem modifying group entry."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification port-mod-error-notification { + description "Model for ofp_error-Type=7 - Port mod request failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification table-mod-error-notification { + description "Model for ofp_error-Type=8 - Table mod request failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification queue-op-error-notification { + description "Model for ofp_error-Type=9 - Queue operation failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification switch-config-error-notification { + description "Model for ofp_error-Type=10 - Switch Config request failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification role-request-error-notification { + description "Model for ofp_error-Type=11 - Controller Role request failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification meter-mod-error-notification { + description "Model for ofp_error-Type=12 - Error in meter."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification table-features-error-notification { + description "Model for ofp_error-Type=13 - Setting table features failed."; + + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } + + notification experimenter-error-notification { + description "Model for ofp_error-Type=65535 - Experimenter Error Messages"; + uses error:error-message; + uses tr:transaction-aware; + uses tr:transaction-metadata; + uses flow:base-node-error-notification; + uses flow:node-error-reference; + } +} + diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang index f3db3181f7..50368e46a6 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang @@ -9,13 +9,14 @@ module packet-processing { import opendaylight-match-types {prefix match-type;revision-date "2013-10-26";} import opendaylight-table-types {prefix table-type;revision-date "2013-10-26";} import opendaylight-action-types {prefix action-type;revision-date "2013-11-12";} + import opendaylight-flow-types {prefix flow-type;revision-date "2013-10-26";} revision "2013-07-09" { description ""; } - typedef cookie { + typedef connection-cookie { type uint32; } @@ -58,8 +59,12 @@ module packet-processing { } notification packet-received { - leaf cookie { - type cookie; + leaf connection-cookie { + type connection-cookie; + } + + leaf flow-cookie { + type flow-type:flow-cookie; } leaf table-id { @@ -83,14 +88,14 @@ module packet-processing { input { uses inv:node-context-ref; - leaf cookie { - type cookie; + leaf connection-cookie { + type connection-cookie; } leaf egress { type inv:node-connector-ref; } - leaf buffer-id { + leaf buffer-id { type uint32; } diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-flow.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-flow.yang index b3e6e450af..4cb1d08917 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-flow.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-flow.yang @@ -38,6 +38,33 @@ module sal-flow { uses types:flow; } + grouping base-node-error-notification { + leaf node { + ext:context-reference "inv:node-context"; + type inv:node-ref; + } + } + + grouping node-error-reference { + choice object-reference { + case flow-ref{ + leaf flow-ref { + type types:flow-ref; + } + } + case group-ref{ + leaf group-ref { + type group-type:group-ref; + } + } + case meter-ref{ + leaf meter-ref { + type meter-type:meter-ref; + } + } + } + } + /** Base configuration structure **/ grouping flow-update { uses "inv:node-context-ref"; @@ -124,28 +151,8 @@ module sal-flow { uses error:error-message; uses tr:transaction-aware; uses tr:transaction-metadata; - choice object-reference { - case flow-ref{ - leaf flow-ref { - type types:flow-ref; - } - } - case group-ref{ - leaf group-ref { - type group-type:group-ref; - } - } - case meter-ref{ - leaf meter-ref { - type meter-type:meter-ref; - } - } - } - leaf node { - ext:context-reference "inv:node-context"; - type inv:node-ref; - } - + uses node-error-reference; + uses base-node-error-notification; } notification node-experimenter-error-notification { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java index 6334457fd4..6bd6e6aaf5 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java @@ -132,7 +132,7 @@ public class AbstractForwardedTransaction queue = new LinkedBlockingQueue() { + @Override + public boolean offer(Runnable r) { + if (size() <= 1) { + // if the queue is empty (or has just 1), no need to rampup the threads + return super.offer(r); + } else { + // if the queue is not empty, force the queue to return false. + // threadpoolexecutor will spawn a new thread if the queue.offer returns false. + return false; + } + } + }; + ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-notification-%d").build(); - ExecutorService executor = new ThreadPoolExecutor(CORE_NOTIFICATION_THREADS, MAX_NOTIFICATION_THREADS, - NOTIFICATION_THREAD_LIFE, TimeUnit.SECONDS, new LinkedBlockingQueue(), factory); + + ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_NOTIFICATION_THREADS, MAX_NOTIFICATION_THREADS, + NOTIFICATION_THREAD_LIFE, TimeUnit.SECONDS, queue , factory, + new RejectedExecutionHandler() { + // if the max threads are met, then it will raise a rejectedExecution. We then push to the queue. + @Override + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { + try { + executor.getQueue().put(r); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }); + NOTIFICATION_EXECUTOR = MoreExecutors.listeningDecorator(executor); } + return NOTIFICATION_EXECUTOR; } diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java new file mode 100644 index 0000000000..61a73d63f4 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java @@ -0,0 +1,60 @@ +/* + * 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.md.sal.binding.data; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.Test; +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest; +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.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public class ConcurrentImplicitCreateTest extends AbstractDataServiceTest { + + private static final NodeKey NODE_FOO_KEY = new NodeKey(new NodeId("foo")); + private static final NodeKey NODE_BAR_KEY = new NodeKey(new NodeId("foo")); + private static InstanceIdentifier NODES_PATH = InstanceIdentifier.builder(Nodes.class).build(); + private static InstanceIdentifier NODE_FOO_PATH = InstanceIdentifier.builder(NODES_PATH) + .child(Node.class, NODE_FOO_KEY).build(); + private static InstanceIdentifier NODE_BAR_PATH = InstanceIdentifier.builder(NODES_PATH) + .child(Node.class, NODE_FOO_KEY).build(); + + @Test + public void testConcurrentCreate() throws InterruptedException, ExecutionException { + + DataModificationTransaction fooTx = baDataService.beginTransaction(); + DataModificationTransaction barTx = baDataService.beginTransaction(); + + fooTx.putOperationalData(NODE_FOO_PATH, new NodeBuilder().setKey(NODE_FOO_KEY).build()); + barTx.putOperationalData(NODE_BAR_PATH, new NodeBuilder().setKey(NODE_BAR_KEY).build()); + + Future> fooFuture = fooTx.commit(); + Future> barFuture = barTx.commit(); + + RpcResult fooResult = fooFuture.get(); + RpcResult barResult = barFuture.get(); + + assertTrue(fooResult.isSuccessful()); + assertTrue(barResult.isSuccessful()); + + assertEquals(TransactionStatus.COMMITED, fooResult.getResult()); + assertEquals(TransactionStatus.COMMITED, barResult.getResult()); + + } +} diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java index b23ceaaf15..9519a2a732 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java @@ -31,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Node import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.opendaylight.yangtools.yang.binding.RpcService; @@ -99,7 +100,7 @@ public class NoficationTest extends AbstractTest { * */ assertEquals(1, listener1.addedFlows.size()); - assertEquals(0, listener1.addedFlows.get(0).getCookie().intValue()); + assertEquals(0, listener1.addedFlows.get(0).getCookie().getValue().intValue()); /** * The registration of the Consumer 2. SalFlowListener is registered @@ -196,7 +197,7 @@ public class NoficationTest extends AbstractTest { */ public static FlowAdded flowAdded(int i) { FlowAddedBuilder ret = new FlowAddedBuilder(); - ret.setCookie(BigInteger.valueOf(i)); + ret.setCookie(new FlowCookie(BigInteger.valueOf(i))); return ret.build(); } diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java index 9c24ca0830..d49d6f0e25 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java @@ -26,6 +26,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; @@ -209,7 +210,7 @@ public class RoutedServiceTest extends AbstractTest { static AddFlowInput createSampleAddFlow(NodeRef node, int cookie) { AddFlowInputBuilder ret = new AddFlowInputBuilder(); ret.setNode(node); - ret.setCookie(BigInteger.valueOf(cookie)); + ret.setCookie(new FlowCookie(BigInteger.valueOf(cookie))); return ret.build(); } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java index 64a5606e3f..608ac9bc68 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java @@ -217,8 +217,7 @@ public class DOMDataBrokerImpl implements DOMDataBroker, AutoCloseable { @Override public void merge(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode data) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Not implemented yet."); + getSubtransaction(store).merge(path,data); } @Override @@ -251,12 +250,6 @@ public class DOMDataBrokerImpl implements DOMDataBroker, AutoCloseable { final InstanceIdentifier path) { return getSubtransaction(store).read(path); } - - @Override - public void merge(final LogicalDatastoreType store, final InstanceIdentifier path, - final NormalizedNode data) { - - } } private final class CommitCoordination implements Callable> { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java index b905d2f673..29f2af511e 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java @@ -32,21 +32,13 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; -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; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.Iterables; import com.google.common.util.concurrent.ListenableFuture; public abstract class BackwardsCompatibleTransaction implements @@ -249,7 +241,7 @@ public abstract class BackwardsCompatibleTransaction parentArgs = parentPath(normalizedPath).getPath(); - if(parentArgs.isEmpty()) { - return false; - } - return Iterables.getLast(parentArgs) instanceof AugmentationIdentifier; - } - - private void ensureParentNode(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath, - final NormalizedNode normalizedData) { - InstanceIdentifier parentPath = parentPath(normalizedPath); - PathArgument parentType = Iterables.getLast(parentPath.getPath()); - if(parentType instanceof AugmentationIdentifier) { - AugmentationNode node = Builders.augmentationBuilder() - .withNodeIdentifier((AugmentationIdentifier) parentType) - .build(); - getDelegate().put(store, parentPath, node); - } - if(normalizedData instanceof MapEntryNode) { - MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build(); - getDelegate().put(store, parentPath, mapNode); - } else if (normalizedData instanceof LeafSetNode){ - LeafSetNode leafNode = Builders.leafSetBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build(); - getDelegate().put(store, parentPath, leafNode); - } - - - } - - private InstanceIdentifier parentPath(final InstanceIdentifier normalizedPath) { - List childArgs = normalizedPath.getPath(); - return new InstanceIdentifier(childArgs.subList(0, childArgs.size() -1)); - } - - private boolean parentNodeDoesNotExists(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath) { - try { - return !getDelegate().read(store, parentPath(normalizedPath)).get().isPresent(); - } catch (InterruptedException | ExecutionException e) { - throw new IllegalStateException(e); - } - } - @Override public void removeConfigurationData(final InstanceIdentifier legacyPath) { checkNotNull(legacyPath, "Path MUST NOT be null."); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index 6c0e5823a4..9bbba1e24d 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -258,6 +258,18 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } } + @Override + public void merge(final InstanceIdentifier path, final NormalizedNode data) { + checkNotReady(); + try { + LOG.trace("Tx: {} Merge: {}:{}",getIdentifier(),path,data); + mutableTree.merge(path, data); + // FIXME: Add checked exception + } catch (Exception e) { + LOG.error("Tx: {}, failed to write {}:{} in {}",getIdentifier(),path,data,mutableTree,e); + } + } + @Override public void delete(final InstanceIdentifier path) { checkNotReady(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java index bc7fe7a2c7..b711163b46 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java @@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,6 +48,24 @@ class MutableDataTree { resolveModificationFor(path).write(value); } + public void merge(final InstanceIdentifier path, final NormalizedNode data) { + checkSealed(); + mergeImpl(resolveModificationFor(path),data); + } + + private void mergeImpl(final OperationWithModification op,final NormalizedNode data) { + + if(data instanceof NormalizedNodeContainer) { + @SuppressWarnings({ "rawtypes", "unchecked" }) + NormalizedNodeContainer> dataContainer = (NormalizedNodeContainer) data; + for(NormalizedNode child : dataContainer.getValue()) { + PathArgument childId = child.getIdentifier(); + mergeImpl(op.forChild(childId), child); + } + } + op.merge(data); + } + public void delete(final InstanceIdentifier path) { checkSealed(); resolveModificationFor(path).delete(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java index eaf01aeecd..35864b6bc2 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java @@ -2,6 +2,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; @@ -10,6 +11,7 @@ import com.google.common.primitives.UnsignedLong; public class OperationWithModification { private final NodeModification modification; + private final ModificationApplyOperation applyOperation; private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) { @@ -28,6 +30,14 @@ public class OperationWithModification { return this; } + public NodeModification getModification() { + return modification; + } + + public ModificationApplyOperation getApplyOperation() { + return applyOperation; + } + public boolean isApplicable(final Optional data) { return applyOperation.isApplicable(modification, data); } @@ -41,4 +51,16 @@ public class OperationWithModification { return new OperationWithModification(operation, modification); } + + public void merge(final NormalizedNode data) { + modification.merge(data); + applyOperation.verifyStructure(modification); + + } + + public OperationWithModification forChild(final PathArgument childId) { + NodeModification childMod = modification.modifyChild(childId); + Optional childOp = applyOperation.getChild(childId); + return from(childOp.get(),childMod); + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index 520bd1ba1d..c62c27dea8 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -308,6 +308,7 @@ public class ResolveDataChangeEventsTask implements Callable current) { + Optional original = modification.getOriginal(); + if (original.isPresent() && current.isPresent()) { + return isNotConflicting(original.get(), current.get()); + } else if (current.isPresent()) { + return true; + } + return true; + } + protected boolean isWriteApplicable(final NodeModification modification, final Optional current) { Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { @@ -174,6 +186,10 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper modification); return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(), subtreeVersion))); + case MERGE: + if(currentMeta.isPresent()) { + return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion))); + } // Fallback to write is intentional - if node is not preexisting merge is same as write case WRITE: return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion))); case UNMODIFIED: @@ -183,6 +199,9 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } } + protected abstract StoreMetadataNode applyMerge(NodeModification modification, + StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); + protected abstract StoreMetadataNode applyWrite(NodeModification modification, Optional currentMeta, UnsignedLong subtreeVersion); @@ -219,14 +238,16 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper + "is leaf type node. Subtree change is not allowed."); } + @Override + protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, + final UnsignedLong subtreeVersion) { + return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); + } + @Override protected StoreMetadataNode applyWrite(final NodeModification modification, final Optional currentMeta, final UnsignedLong subtreeVersion) { UnsignedLong nodeVersion = subtreeVersion; - if (currentMeta.isPresent()) { - nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion()); - } - return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion) .setData(modification.getWritenValue()).build(); } @@ -314,6 +335,13 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } + @Override + protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, + final UnsignedLong subtreeVersion) { + // For Node Containers - merge is same as subtree change - we only replace children. + return applySubtreeChange(modification, currentMeta, subtreeVersion); + } + @Override public StoreMetadataNode applySubtreeChange(final NodeModification modification, final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { @@ -569,7 +597,11 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper entryStrategy = Optional. of(new UnkeyedListItemModificationStrategy(schema)); } - + @Override + protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, + final UnsignedLong subtreeVersion) { + return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); + } @Override protected StoreMetadataNode applySubtreeChange(final NodeModification modification, diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java index 199d90252e..b16e907120 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java @@ -32,5 +32,12 @@ public enum ModificationType { * Tree node is to be deleted. * */ - DELETE + DELETE, + + /** + * + * Tree node is to be merged with existing one. + * + */ + MERGE } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java index 04fb3b7c6c..4f650c1711 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java @@ -20,7 +20,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; import com.google.common.base.Predicate; -import com.google.common.primitives.UnsignedLong; /** * Node Modification Node and Tree @@ -37,7 +36,9 @@ public class NodeModification implements StoreTreeNode, Identi public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { @Override public boolean apply(final NodeModification input) { - return input.getModificationType() == ModificationType.WRITE || input.getModificationType() == ModificationType.DELETE; + return input.getModificationType() == ModificationType.WRITE // + || input.getModificationType() == ModificationType.DELETE // + || input.getModificationType() == ModificationType.MERGE; } }; private final PathArgument identifier; @@ -48,7 +49,6 @@ public class NodeModification implements StoreTreeNode, Identi private NormalizedNode value; - private UnsignedLong subtreeVersion; private Optional snapshotCache; private final Map childModification; @@ -176,6 +176,14 @@ public class NodeModification implements StoreTreeNode, Identi this.value = value; } + public synchronized void merge(final NormalizedNode data) { + checkSealed(); + clearSnapshot(); + updateModificationType(ModificationType.MERGE); + // FIXME: Probably merge with previous value. + this.value = data; + } + @GuardedBy("this") private void checkSealed() { checkState(!sealed, "Node Modification is sealed. No further changes allowed."); diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java index 6761bc1968..ddabbc6c03 100644 --- a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java @@ -33,6 +33,25 @@ public interface DOMStoreWriteTransaction extends DOMStoreTransaction { */ void write(InstanceIdentifier path, NormalizedNode data); + /** + * Store a provided data at specified path. This acts as a add / replace + * operation, which is to say that whole subtree will be replaced by + * specified path. + * + * If you need add or merge of current object with specified use + * {@link #merge(LogicalDatastoreType, Path, Object)} + * + * + * @param path + * @param data + * Data object to be written + * + * @throws IllegalStateException + * if the client code already sealed transaction and invoked + * {@link #ready()} + */ + void merge(InstanceIdentifier path, NormalizedNode data); + /** * * Deletes data and whole subtree located at provided path. diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index 9b701203ce..27d320f03e 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -26,10 +26,6 @@ ${project.groupId} sal-connector-api - - org.eclipse.xtend - org.eclipse.xtend.lib - org.opendaylight.controller ietf-netconf-monitoring @@ -175,11 +171,6 @@ - - org.eclipse.xtend - xtend-maven-plugin - - org.opendaylight.yangtools yang-maven-plugin diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java new file mode 100644 index 0000000000..aa5c6f40a9 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -0,0 +1,512 @@ +/* + * 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 static com.google.common.base.Preconditions.checkState; +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.INVENTORY_CONNECTED; +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.INVENTORY_ID; +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.INVENTORY_NODE; +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.INVENTORY_PATH; +import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.NETCONF_INVENTORY_INITIAL_CAPABILITY; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.CONFIG_SOURCE_RUNNING; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_DATA_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_GET_CONFIG_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_GET_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.toFilterStructure; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.toRpcMessage; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.wrap; + +import java.io.InputStream; +import java.net.InetSocketAddress; +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 java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; + +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.controller.md.sal.common.api.data.DataReader; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration; +import org.opendaylight.controller.sal.core.api.Provider; +import org.opendaylight.controller.sal.core.api.RpcImplementation; +import org.opendaylight.controller.sal.core.api.data.DataBrokerService; +import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.protocol.framework.ReconnectStrategy; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; +import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; +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.util.repo.AbstractCachingSchemaSourceProvider; +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; +import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.ListenableFuture; +import io.netty.util.concurrent.EventExecutor; + +public class NetconfDevice implements Provider, // + DataReader, // + DataCommitHandler, // + RpcImplementation, // + AutoCloseable { + + InetSocketAddress socketAddress; + + MountProvisionInstance mountInstance; + + EventExecutor eventExecutor; + + ExecutorService processingExecutor; + + InstanceIdentifier path; + + ReconnectStrategy reconnectStrategy; + + AbstractCachingSchemaSourceProvider schemaSourceProvider; + + private NetconfDeviceSchemaContextProvider deviceContextProvider; + + protected Logger logger; + + Registration> operReaderReg; + Registration> confReaderReg; + Registration> commitHandlerReg; + List rpcReg; + + String name; + + MountProvisionService mountService; + + NetconfClientDispatcher dispatcher; + + static InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance(); + + SchemaSourceProvider remoteSourceProvider; + + DataBrokerService dataBroker; + + NetconfDeviceListener listener; + + private boolean rollbackSupported; + + + public NetconfDevice(String name) { + this.name = name; + this.logger = LoggerFactory.getLogger(NetconfDevice.class + "#" + name); + this.path = InstanceIdentifier.builder(INVENTORY_PATH) + .nodeWithKey(INVENTORY_NODE, Collections.singletonMap(INVENTORY_ID, name)).toInstance(); + } + + public void start() { + checkState(dispatcher != null, "Dispatcher must be set."); + checkState(schemaSourceProvider != null, "Schema Source Provider must be set."); + checkState(eventExecutor != null, "Event executor must be set."); + + listener = new NetconfDeviceListener(this); + + logger.info("Starting NETCONF Client {} for address {}", name, socketAddress); + + dispatcher.createClient(socketAddress, listener, reconnectStrategy); + } + + Optional getSchemaContext() { + if (deviceContextProvider == null) { + return Optional.absent(); + } + return deviceContextProvider.currentContext; + } + + void bringDown() { + if (rpcReg != null) { + for (RpcRegistration reg : rpcReg) { + reg.close(); + } + rpcReg = null; + } + closeGracefully(confReaderReg); + confReaderReg = null; + closeGracefully(operReaderReg); + operReaderReg = null; + closeGracefully(commitHandlerReg); + commitHandlerReg = null; + + updateDeviceState(false, Collections. emptySet()); + } + + private void closeGracefully(final AutoCloseable resource) { + if (resource != null) { + try { + resource.close(); + } catch (Exception e) { + logger.warn("Ignoring exception while closing {}", resource, e); + } + } + } + + void bringUp(final SchemaSourceProvider delegate, final Set capabilities, final boolean rollbackSupported) { + // This has to be called from separate thread, not from netty thread calling onSessionUp in DeviceListener. + // Reason: delegate.getSchema blocks thread when waiting for response + // however, if the netty thread is blocked, no incoming message can be processed + // ... netty should pick another thread from pool to process incoming message, but it does not http://netty.io/wiki/thread-model.html + // TODO redesign +refactor + processingExecutor.submit(new Runnable() { + @Override + public void run() { + NetconfDevice.this.rollbackSupported = rollbackSupported; + remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate); + deviceContextProvider = new NetconfDeviceSchemaContextProvider(NetconfDevice.this, remoteSourceProvider); + deviceContextProvider.createContextFromCapabilities(capabilities); + if (mountInstance != null && getSchemaContext().isPresent()) { + mountInstance.setSchemaContext(getSchemaContext().get()); + } + + updateDeviceState(true, capabilities); + + if (mountInstance != null) { + confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, NetconfDevice.this); + operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, NetconfDevice.this); + commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, NetconfDevice.this); + + List rpcs = new ArrayList<>(); + // TODO same condition twice + if (mountInstance != null && getSchemaContext().isPresent()) { + for (RpcDefinition rpc : mountInstance.getSchemaContext().getOperations()) { + rpcs.add(mountInstance.addRpcImplementation(rpc.getQName(), NetconfDevice.this)); + } + } + rpcReg = rpcs; + } + } + }); + } + + private void updateDeviceState(boolean up, Set capabilities) { + DataModificationTransaction transaction = dataBroker.beginTransaction(); + + CompositeNodeBuilder it = ImmutableCompositeNode.builder(); + it.setQName(INVENTORY_NODE); + it.addLeaf(INVENTORY_ID, name); + it.addLeaf(INVENTORY_CONNECTED, up); + + logger.debug("Client capabilities {}", capabilities); + for (QName capability : capabilities) { + it.addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability); + } + + logger.debug("Update device state transaction " + transaction.getIdentifier() + + " putting operational data started."); + transaction.removeOperationalData(path); + transaction.putOperationalData(path, it.toInstance()); + logger.debug("Update device state transaction " + transaction.getIdentifier() + + " putting operational data ended."); + + // FIXME: this has to be asynchronous + RpcResult transactionStatus = null; + try { + transactionStatus = transaction.commit().get(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting for response", e); + } catch (ExecutionException e) { + throw new RuntimeException("Read configuration data " + path + " failed", e); + } + // TODO better ex handling + + if (transactionStatus.isSuccessful()) { + logger.debug("Update device state transaction " + transaction.getIdentifier() + " SUCCESSFUL."); + } else { + logger.debug("Update device state transaction " + transaction.getIdentifier() + " FAILED!"); + logger.debug("Update device state transaction status " + transaction.getStatus()); + } + } + + @Override + public CompositeNode readConfigurationData(InstanceIdentifier path) { + RpcResult result = null; + try { + result = this.invokeRpc(NETCONF_GET_CONFIG_QNAME, + wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, toFilterStructure(path))).get(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting for response", e); + } catch (ExecutionException e) { + throw new RuntimeException("Read configuration data " + path + " failed", e); + } + + CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME); + return data == null ? null : (CompositeNode) findNode(data, path); + } + + @Override + public CompositeNode readOperationalData(InstanceIdentifier path) { + RpcResult result = null; + try { + result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, toFilterStructure(path))).get(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting for response", e); + } catch (ExecutionException e) { + throw new RuntimeException("Read configuration data " + path + " failed", e); + } + + CompositeNode data = result.getResult().getFirstCompositeByName(NETCONF_DATA_QNAME); + return (CompositeNode) findNode(data, path); + } + + @Override + public Set getSupportedRpcs() { + return Collections.emptySet(); + } + + @Override + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { + return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()), rpc); + } + + @Override + public Collection getProviderFunctionality() { + return Collections.emptySet(); + } + + @Override + public void onSessionInitiated(ProviderSession session) { + dataBroker = session.getService(DataBrokerService.class); + + DataModificationTransaction transaction = dataBroker.beginTransaction(); + if (operationalNodeNotExisting(transaction)) { + transaction.putOperationalData(path, getNodeWithId()); + } + if (configurationNodeNotExisting(transaction)) { + transaction.putConfigurationData(path, getNodeWithId()); + } + + try { + transaction.commit().get(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting for response", e); + } catch (ExecutionException e) { + throw new RuntimeException("Read configuration data " + path + " failed", e); + } + + mountService = session.getService(MountProvisionService.class); + if (mountService != null) { + mountInstance = mountService.createOrGetMountPoint(path); + } + } + + CompositeNode getNodeWithId() { + SimpleNodeTOImpl id = new SimpleNodeTOImpl(INVENTORY_ID, null, name); + return new CompositeNodeTOImpl(INVENTORY_NODE, null, Collections.> singletonList(id)); + } + + boolean configurationNodeNotExisting(DataModificationTransaction transaction) { + return null == transaction.readConfigurationData(path); + } + + boolean operationalNodeNotExisting(DataModificationTransaction transaction) { + return null == transaction.readOperationalData(path); + } + + static Node findNode(CompositeNode node, InstanceIdentifier identifier) { + + Node current = node; + for (InstanceIdentifier.PathArgument arg : identifier.getPath()) { + if (current instanceof SimpleNode) { + return null; + } else if (current instanceof CompositeNode) { + CompositeNode currentComposite = (CompositeNode) current; + + current = currentComposite.getFirstCompositeByName(arg.getNodeType()); + if (current == null) { + current = currentComposite.getFirstCompositeByName(arg.getNodeType().withoutRevision()); + } + if (current == null) { + current = currentComposite.getFirstSimpleByName(arg.getNodeType()); + } + if (current == null) { + current = currentComposite.getFirstSimpleByName(arg.getNodeType().withoutRevision()); + } + if (current == null) { + return null; + } + } + } + return current; + } + + @Override + public DataCommitTransaction requestCommit( + DataModification modification) { + NetconfDeviceTwoPhaseCommitTransaction twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, + modification, true, rollbackSupported); + try { + twoPhaseCommit.prepare(); + } catch (InterruptedException e) { + throw new RuntimeException("Interrupted while waiting for response", e); + } catch (ExecutionException e) { + throw new RuntimeException("Read configuration data " + path + " failed", e); + } + return twoPhaseCommit; + } + + Set getCapabilities(Collection capabilities) { + return FluentIterable.from(capabilities).filter(new Predicate() { + @Override + public boolean apply(final String capability) { + return capability.contains("?") && capability.contains("module=") && capability.contains("revision="); + } + }).transform(new Function() { + @Override + public QName apply(final String capability) { + String[] parts = capability.split("\\?"); + String namespace = parts[0]; + FluentIterable queryParams = FluentIterable.from(Arrays.asList(parts[1].split("&"))); + + String revision = getStringAndTransform(queryParams, "revision=", "revision="); + + String moduleName = getStringAndTransform(queryParams, "module=", "module="); + + if (revision == null) { + logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision="); + revision = getStringAndTransform(queryParams, "amp;revision==", "revision="); + + if (revision != null) { + logger.warn("Netconf device returned revision incorectly escaped for {}", capability); + } + } + if (revision == null) { + return QName.create(URI.create(namespace), null, moduleName); + } + return QName.create(namespace, revision, moduleName); + } + + private String getStringAndTransform(final Iterable queryParams, final String match, + final String substringToRemove) { + Optional found = Iterables.tryFind(queryParams, new Predicate() { + @Override + public boolean apply(final String input) { + return input.startsWith(match); + } + }); + + return found.isPresent() ? found.get().replaceAll(substringToRemove, "") : null; + } + + }).toSet(); + } + + @Override + public void close() { + bringDown(); + } + + public String getName() { + return name; + } + + public InetSocketAddress getSocketAddress() { + return socketAddress; + } + + public MountProvisionInstance getMountInstance() { + return mountInstance; + } + + public void setReconnectStrategy(final ReconnectStrategy reconnectStrategy) { + this.reconnectStrategy = reconnectStrategy; + } + + public void setProcessingExecutor(final ExecutorService processingExecutor) { + this.processingExecutor = processingExecutor; + } + + public void setSocketAddress(final InetSocketAddress socketAddress) { + this.socketAddress = socketAddress; + } + + public void setEventExecutor(final EventExecutor eventExecutor) { + this.eventExecutor = eventExecutor; + } + + public void setSchemaSourceProvider(final AbstractCachingSchemaSourceProvider schemaSourceProvider) { + this.schemaSourceProvider = schemaSourceProvider; + } + + public void setDispatcher(final NetconfClientDispatcher dispatcher) { + this.dispatcher = dispatcher; + } +} + +class NetconfDeviceSchemaContextProvider { + + NetconfDevice device; + + SchemaSourceProvider sourceProvider; + + Optional currentContext; + + NetconfDeviceSchemaContextProvider(NetconfDevice device, SchemaSourceProvider sourceProvider) { + this.device = device; + this.sourceProvider = sourceProvider; + this.currentContext = Optional.absent(); + } + + void createContextFromCapabilities(Iterable capabilities) { + YangSourceContext sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider); + if (!sourceContext.getMissingSources().isEmpty()) { + device.logger.warn("Sources for following models are missing {}", sourceContext.getMissingSources()); + } + device.logger.debug("Trying to create schema context from {}", sourceContext.getValidSources()); + List modelsToParse = YangSourceContext.getValidInputStreams(sourceContext); + if (!sourceContext.getValidSources().isEmpty()) { + SchemaContext schemaContext = tryToCreateContext(modelsToParse); + currentContext = Optional.fromNullable(schemaContext); + } else { + currentContext = Optional.absent(); + } + if (currentContext.isPresent()) { + device.logger.debug("Schema context successfully created."); + } + } + + SchemaContext tryToCreateContext(List modelsToParse) { + YangParserImpl parser = new YangParserImpl(); + try { + + Set models = parser.parseYangModelsFromStreams(modelsToParse); + return parser.resolveSchemaContext(models); + } catch (Exception e) { + device.logger.debug("Error occured during parsing YANG schemas", e); + return null; + } + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend deleted file mode 100644 index 0b88c66b45..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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.collect.FluentIterable -import io.netty.util.concurrent.EventExecutor -import java.io.InputStream -import java.net.InetSocketAddress -import java.net.URI -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 org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.md.sal.common.api.data.DataReader -import org.opendaylight.controller.netconf.client.NetconfClientDispatcher -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession -import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration -import org.opendaylight.controller.sal.core.api.Provider -import org.opendaylight.controller.sal.core.api.RpcImplementation -import org.opendaylight.controller.sal.core.api.data.DataBrokerService -import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction -import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService -import org.opendaylight.protocol.framework.ReconnectStrategy -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.common.QName -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.yangtools.yang.data.api.Node -import org.opendaylight.yangtools.yang.data.api.SimpleNode -import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl -import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode -import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl -import org.opendaylight.yangtools.yang.model.api.SchemaContext -import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider -import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider -import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl -import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -import static com.google.common.base.Preconditions.* -import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.* - -import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.* - -class NetconfDevice implements Provider, // -DataReader, // -DataCommitHandler, // -RpcImplementation, // -AutoCloseable { - - @Property - var InetSocketAddress socketAddress; - - @Property - var MountProvisionInstance mountInstance; - - @Property - var EventExecutor eventExecutor; - - @Property - var ExecutorService processingExecutor; - - @Property - var InstanceIdentifier path; - - @Property - var ReconnectStrategy reconnectStrategy; - - @Property - var AbstractCachingSchemaSourceProvider schemaSourceProvider; - - @Property - private NetconfDeviceSchemaContextProvider deviceContextProvider - - protected val Logger logger - - Registration> operReaderReg - Registration> confReaderReg - Registration> commitHandlerReg - List rpcReg - - @Property - val String name - - MountProvisionService mountService - - @Property - var NetconfClientDispatcher dispatcher - - static val InstanceIdentifier ROOT_PATH = InstanceIdentifier.builder().toInstance(); - - @Property - var SchemaSourceProvider remoteSourceProvider - - DataBrokerService dataBroker - - var NetconfDeviceListener listener; - - public new(String name) { - this._name = name; - this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name); - this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE, - Collections.singletonMap(INVENTORY_ID, name)).toInstance; - } - - def start() { - checkState(dispatcher != null, "Dispatcher must be set."); - checkState(schemaSourceProvider != null, "Schema Source Provider must be set.") - checkState(eventExecutor != null, "Event executor must be set."); - - listener = new NetconfDeviceListener(this); - - logger.info("Starting NETCONF Client {} for address {}", name, socketAddress); - - dispatcher.createClient(socketAddress, listener, reconnectStrategy); - } - - def Optional getSchemaContext() { - if (deviceContextProvider == null) { - return Optional.absent(); - } - return deviceContextProvider.currentContext; - } - - def bringDown() { - if (rpcReg != null) { - for (reg : rpcReg) { - reg.close() - } - rpcReg = null - } - confReaderReg?.close() - confReaderReg = null - operReaderReg?.close() - operReaderReg = null - commitHandlerReg?.close() - commitHandlerReg = null - - updateDeviceState(false, Collections.emptySet()) - } - - def bringUp(SchemaSourceProvider delegate, Set capabilities) { - remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate); - deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider); - deviceContextProvider.createContextFromCapabilities(capabilities); - if (mountInstance != null && schemaContext.isPresent) { - mountInstance.schemaContext = schemaContext.get(); - } - - updateDeviceState(true, capabilities) - - if (mountInstance != null) { - confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this); - operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this); - commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this); - - val rpcs = new ArrayList(); - if (mountInstance != null && schemaContext.isPresent) { - for (rpc : mountInstance.schemaContext.operations) { - rpcs.add(mountInstance.addRpcImplementation(rpc.QName, this)); - } - } - rpcReg = rpcs - } - } - - private def updateDeviceState(boolean up, Set capabilities) { - val transaction = dataBroker.beginTransaction - - val it = ImmutableCompositeNode.builder - setQName(INVENTORY_NODE) - addLeaf(INVENTORY_ID, name) - addLeaf(INVENTORY_CONNECTED, up) - - logger.debug("Client capabilities {}", capabilities) - for (capability : capabilities) { - addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability) - } - - logger.debug("Update device state transaction " + transaction.identifier + " putting operational data started.") - transaction.removeOperationalData(path) - transaction.putOperationalData(path, it.toInstance) - logger.debug("Update device state transaction " + transaction.identifier + " putting operational data ended.") - - // FIXME: this has to be asynchronous - val transactionStatus = transaction.commit.get; - - if (transactionStatus.successful) { - logger.debug("Update device state transaction " + transaction.identifier + " SUCCESSFUL.") - } else { - logger.debug("Update device state transaction " + transaction.identifier + " FAILED!") - logger.debug("Update device state transaction status " + transaction.status) - } - } - - override readConfigurationData(InstanceIdentifier path) { - val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, - wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())).get(); - val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME); - return data?.findNode(path) as CompositeNode; - } - - override readOperationalData(InstanceIdentifier path) { - val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure())).get(); - val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME); - return data?.findNode(path) as CompositeNode; - } - - override getSupportedRpcs() { - Collections.emptySet; - } - - override invokeRpc(QName rpc, CompositeNode input) { - return listener.sendRequest(rpc.toRpcMessage(input,schemaContext)); - } - - override getProviderFunctionality() { - Collections.emptySet - } - - override onSessionInitiated(ProviderSession session) { - dataBroker = session.getService(DataBrokerService); - - val transaction = dataBroker.beginTransaction - if (transaction.operationalNodeNotExisting) { - transaction.putOperationalData(path, nodeWithId) - } - if (transaction.configurationNodeNotExisting) { - transaction.putConfigurationData(path, nodeWithId) - } - transaction.commit().get(); - mountService = session.getService(MountProvisionService); - mountInstance = mountService?.createOrGetMountPoint(path); - } - - def getNodeWithId() { - val id = new SimpleNodeTOImpl(INVENTORY_ID, null, name); - return new CompositeNodeTOImpl(INVENTORY_NODE, null, Collections.singletonList(id)); - } - - def boolean configurationNodeNotExisting(DataModificationTransaction transaction) { - return null === transaction.readConfigurationData(path); - } - - def boolean operationalNodeNotExisting(DataModificationTransaction transaction) { - return null === transaction.readOperationalData(path); - } - - static def Node findNode(CompositeNode node, InstanceIdentifier identifier) { - - var Node current = node; - for (arg : identifier.path) { - if (current instanceof SimpleNode) { - return null; - } else if (current instanceof CompositeNode) { - val currentComposite = (current as CompositeNode); - - current = currentComposite.getFirstCompositeByName(arg.nodeType); - if(current == null) { - current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision()); - } - if(current == null) { - current = currentComposite.getFirstSimpleByName(arg.nodeType); - } - if (current == null) { - current = currentComposite.getFirstSimpleByName(arg.nodeType.withoutRevision()); - } if (current == null) { - return null; - } - } - } - return current; - } - - override requestCommit(DataModification modification) { - val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification, true); - twoPhaseCommit.prepare() - return twoPhaseCommit; - } - - def getCapabilities(Collection capabilities) { - return FluentIterable.from(capabilities).filter[ - contains("?") && contains("module=") && contains("revision=")].transform [ - val parts = split("\\?"); - val namespace = parts.get(0); - val queryParams = FluentIterable.from(parts.get(1).split("&")); - var revision = queryParams.findFirst[startsWith("revision=")]?.replaceAll("revision=", ""); - val moduleName = queryParams.findFirst[startsWith("module=")]?.replaceAll("module=", ""); - if (revision === null) { - logger.warn("Netconf device was not reporting revision correctly, trying to get amp;revision="); - revision = queryParams.findFirst[startsWith("&revision=")]?.replaceAll("revision=", ""); - if (revision != null) { - logger.warn("Netconf device returned revision incorectly escaped for {}", it) - } - } - if (revision == null) { - return QName.create(URI.create(namespace), null, moduleName); - } - return QName.create(namespace, revision, moduleName); - ].toSet(); - } - - override close() { - bringDown() - } -} - -package class NetconfDeviceSchemaContextProvider { - - @Property - val NetconfDevice device; - - @Property - val SchemaSourceProvider sourceProvider; - - @Property - var Optional currentContext; - - new(NetconfDevice device, SchemaSourceProvider sourceProvider) { - _device = device - _sourceProvider = sourceProvider - _currentContext = Optional.absent(); - } - - def createContextFromCapabilities(Iterable capabilities) { - val sourceContext = YangSourceContext.createFrom(capabilities, sourceProvider) - if (!sourceContext.missingSources.empty) { - device.logger.warn("Sources for following models are missing {}", sourceContext.missingSources); - } - device.logger.debug("Trying to create schema context from {}", sourceContext.validSources) - val modelsToParse = YangSourceContext.getValidInputStreams(sourceContext); - if (!sourceContext.validSources.empty) { - val schemaContext = tryToCreateContext(modelsToParse); - currentContext = Optional.fromNullable(schemaContext); - } else { - currentContext = Optional.absent(); - } - if (currentContext.present) { - device.logger.debug("Schema context successfully created."); - } - - } - - def SchemaContext tryToCreateContext(List modelsToParse) { - val parser = new YangParserImpl(); - try { - - val models = parser.parseYangModelsFromStreams(modelsToParse); - val result = parser.resolveSchemaContext(models); - return result; - } catch (Exception e) { - device.logger.debug("Error occured during parsing YANG schemas", e); - return null; - } - } -} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java index 8c65aa309f..1dfc3b44d3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.sal.connect.netconf; +import com.google.common.collect.Sets; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.FutureListener; @@ -17,12 +18,14 @@ import java.util.Iterator; import java.util.Queue; import java.util.Set; +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.client.NetconfClientSession; import org.opendaylight.controller.netconf.client.NetconfClientSessionListener; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; import org.opendaylight.yangtools.yang.common.QName; @@ -39,13 +42,16 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; class NetconfDeviceListener implements NetconfClientSessionListener { + private static final class Request { final UncancellableFuture> future; final NetconfMessage request; + final QName rpc; - private Request(UncancellableFuture> future, NetconfMessage request) { + private Request(UncancellableFuture> future, NetconfMessage request, final QName rpc) { this.future = future; this.request = request; + this.rpc = rpc; } } @@ -64,6 +70,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener { device.getName(), device.getSocketAddress(), session.getSessionId()); this.session = session; + final Set caps = device.getCapabilities(session.getServerCapabilities()); LOG.trace("Server {} advertized capabilities {}", device.getName(), caps); @@ -71,18 +78,24 @@ class NetconfDeviceListener implements NetconfClientSessionListener { final SchemaSourceProvider delegate; if (NetconfRemoteSchemaSourceProvider.isSupportedFor(caps)) { delegate = new NetconfRemoteSchemaSourceProvider(device); - // FIXME parsed caps contain only module-based capabilities + // FIXME caps do not contain urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring, since it is filtered out in getCapabilitites } else if(session.getServerCapabilities().contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.getNamespace().toString())) { delegate = new NetconfRemoteSchemaSourceProvider(device); } else { LOG.info("Netconf server {} does not support IETF Netconf Monitoring", device.getName()); - delegate = SchemaSourceProviders.noopProvider(); + delegate = SchemaSourceProviders.noopProvider(); } - device.bringUp(delegate, caps); + device.bringUp(delegate, caps, isRollbackSupported(session.getServerCapabilities())); } + private static boolean isRollbackSupported(final Collection serverCapabilities) { + // TODO rollback capability cannot be searched for in Set caps + // since this set does not contain module-less capabilities + return Sets.newHashSet(serverCapabilities).contains(NetconfMapping.NETCONF_ROLLBACK_ON_ERROR_URI.toString()); + } + private synchronized void tearDown(final Exception e) { session = null; @@ -137,17 +150,29 @@ class NetconfDeviceListener implements NetconfClientSessionListener { requests.poll(); LOG.debug("Matched {} to {}", r.request, message); - // FIXME: this can throw exceptions, which should result - // in the future failing - NetconfMapping.checkValidReply(r.request, message); - r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()), - Collections.emptyList())); + try { + NetconfMapping.checkValidReply(r.request, message); + } catch (IllegalStateException e) { + LOG.warn("Invalid request-reply match, reply message contains different message-id", e); + r.future.setException(e); + return; + } + + try { + NetconfMapping.checkSuccessReply(message); + } catch (NetconfDocumentedException | IllegalStateException e) { + LOG.warn("Error reply from remote device", e); + r.future.setException(e); + return; + } + + r.future.set(NetconfMapping.toRpcResult(message, r.rpc, device.getSchemaContext())); } else { LOG.warn("Ignoring unsolicited message", message); } } - synchronized ListenableFuture> sendRequest(final NetconfMessage message) { + synchronized ListenableFuture> sendRequest(final NetconfMessage message, final QName rpc) { if (session == null) { LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message); return Futures.>immediateFuture(new RpcResult() { @@ -169,7 +194,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener { }); } - final Request req = new Request(new UncancellableFuture>(true), message); + final Request req = new Request(new UncancellableFuture>(true), message, rpc); requests.add(req); session.sendMessage(req.request).addListener(new FutureListener() { @@ -177,7 +202,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener { public void operationComplete(final Future future) throws Exception { if (!future.isSuccess()) { // We expect that a session down will occur at this point - LOG.debug("Failed to send request {}", req.request, future.cause()); + LOG.debug("Failed to send request {}", XmlUtil.toString(req.request.getDocument()), future.cause()); req.future.setException(future.cause()); } else { LOG.trace("Finished sending request {}", req.request); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java index 5f14c264ed..8a74b17ac4 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java @@ -11,9 +11,11 @@ import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NET import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_COMMIT_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_CONFIG_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_EDIT_CONFIG_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_ERROR_OPTION_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_OPERATION_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_RUNNING_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_TARGET_QNAME; +import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.ROLLBACK_ON_ERROR_OPTION; import java.util.Collection; import java.util.Collections; @@ -33,6 +35,7 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifie import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,13 +50,15 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction modification; private final NetconfDevice device; private final boolean candidateSupported; + private final boolean rollbackSupported; public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device, DataModification modification, - boolean candidateSupported) { + boolean candidateSupported, boolean rollbackOnErrorSupported) { this.device = Preconditions.checkNotNull(device); this.modification = Preconditions.checkNotNull(modification); this.candidateSupported = candidateSupported; + this.rollbackSupported = rollbackOnErrorSupported; } void prepare() throws InterruptedException, ExecutionException { @@ -91,7 +96,14 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction>of()); } + Node targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.>of(targetNode)); + + if(rollbackSupported) { + LOG.debug("Rollback-on-error supported, setting {} to {}", NETCONF_ERROR_OPTION_QNAME, ROLLBACK_ON_ERROR_OPTION); + ret.addLeaf(NETCONF_ERROR_OPTION_QNAME, ROLLBACK_ON_ERROR_OPTION); + } + ret.add(targetWrapperNode); return ret; } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java new file mode 100644 index 0000000000..f0b711d368 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java @@ -0,0 +1,261 @@ +/* + * 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.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import javax.activation.UnsupportedDataTypeException; +import javax.annotation.Nullable; +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.controller.netconf.util.xml.XmlUtil; +import org.opendaylight.controller.sal.common.util.Rpcs; +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.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; +import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; +import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; +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.w3c.dom.Document; +import org.w3c.dom.Element; + +public class NetconfMapping { + + public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"); + public static String NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring"; + public static URI NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0"); + public static URI NETCONF_ROLLBACK_ON_ERROR_URI = URI.create("urn:ietf:params:netconf:capability:rollback-on-error:1.0"); + + public static QName NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf"); + public static QName NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc"); + public static QName NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get"); + public static QName NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter"); + public static QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type"); + public static QName NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config"); + public static QName NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config"); + public static QName NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config"); + public static QName NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation"); + public static QName NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit"); + + public static QName NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config"); + public static QName NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source"); + public static QName NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target"); + + public static QName NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate"); + public static QName NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running"); + + public static QName NETCONF_ERROR_OPTION_QNAME = QName.create(NETCONF_QNAME, "error-option"); + public static String ROLLBACK_ON_ERROR_OPTION = "rollback-on-error"; + + public static QName NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply"); + public static QName NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok"); + public static QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data"); + public static QName NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI, null, + "create-subscription"); + public static QName NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI, null, + "cancel-subscription"); + public static QName IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04", + "ietf-netconf-monitoring"); + + static List> RUNNING = Collections.> singletonList(new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, + null, null)); + + public static CompositeNode CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING); + + static AtomicInteger messageId = new AtomicInteger(0); + + static Node toFilterStructure(InstanceIdentifier identifier) { + Node previous = null; + if (identifier.getPath().isEmpty()) { + return null; + } + + for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument component : Lists + .reverse(identifier.getPath())) { + previous = toNode(component, previous); + } + return filter("subtree", previous); + } + + static Node toNode(NodeIdentifierWithPredicates argument, Node node) { + List> list = new ArrayList<>(); + for (Map.Entry arg : argument.getKeyValues().entrySet()) { + list.add(new SimpleNodeTOImpl(arg.getKey(), null, arg.getValue())); + } + if (node != null) { + list.add(node); + } + return new CompositeNodeTOImpl(argument.getNodeType(), null, list); + } + + static Node toNode(PathArgument argument, Node node) { + if (node != null) { + return new CompositeNodeTOImpl(argument.getNodeType(), null, Collections.> singletonList(node)); + } else { + return new SimpleNodeTOImpl(argument.getNodeType(), null, null); + } + } + + static CompositeNode toCompositeNode(NetconfMessage message, Optional ctx) { + // TODO: implement general normalization to normalize incoming Netconf + // Message + // for Schema Context counterpart + return null; + } + + static CompositeNode toNotificationNode(NetconfMessage message, Optional ctx) { + if (ctx.isPresent()) { + SchemaContext schemaContext = ctx.get(); + Set notifications = schemaContext.getNotifications(); + Document document = message.getDocument(); + return XmlDocumentUtils.notificationToDomNodes(document, Optional.fromNullable(notifications)); + } + return null; + } + + static NetconfMessage toRpcMessage(QName rpc, CompositeNode node, Optional ctx) { + CompositeNodeTOImpl rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node)); + Document w3cPayload = null; + try { + w3cPayload = XmlDocumentUtils.toDocument(rpcPayload, XmlDocumentUtils.defaultValueCodecProvider()); + } catch (UnsupportedDataTypeException e) { + throw new IllegalArgumentException("Unable to create message", e); + } + w3cPayload.getDocumentElement().setAttribute("message-id", "m-" + messageId.getAndIncrement()); + return new NetconfMessage(w3cPayload); + } + + static CompositeNode flattenInput(final CompositeNode node) { + final QName inputQName = QName.create(node.getNodeType(), "input"); + CompositeNode input = node.getFirstCompositeByName(inputQName); + if (input == null) + return node; + if (input instanceof CompositeNode) { + + List> nodes = ImmutableList.> builder() // + .addAll(input.getChildren()) // + .addAll(Collections2.filter(node.getChildren(), new Predicate>() { + @Override + public boolean apply(@Nullable final Node input) { + return input.getNodeType() != inputQName; + } + })) // + .build(); + + return ImmutableCompositeNode.create(node.getNodeType(), nodes); + } + + return input; + } + + static RpcResult toRpcResult(NetconfMessage message, final QName rpc, Optional context) { + CompositeNode rawRpc; + if (context.isPresent()) + if (isDataRetrieQNameReply(rpc)) { + + Element xmlData = getDataSubtree(message.getDocument()); + + List> dataNodes = XmlDocumentUtils.toDomNodes(xmlData, + Optional.of(context.get().getDataDefinitions())); + + CompositeNodeBuilder it = ImmutableCompositeNode.builder(); + it.setQName(NETCONF_RPC_REPLY_QNAME); + it.add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes)); + + rawRpc = it.toInstance(); + // sys(xmlData) + } else { + rawRpc = (CompositeNode) toCompositeNode(message.getDocument()); + } + else { + rawRpc = (CompositeNode) toCompositeNode(message.getDocument()); + } + // rawRpc. + return Rpcs.getRpcResult(true, rawRpc, Collections. emptySet()); + } + + static Element getDataSubtree(Document doc) { + return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0); + } + + static boolean isDataRetrieQNameReply(QName it) { + return NETCONF_URI == it.getNamespace() + && (it.getLocalName() == NETCONF_GET_CONFIG_QNAME.getLocalName() || it.getLocalName() == NETCONF_GET_QNAME + .getLocalName()); + } + + static CompositeNodeTOImpl wrap(QName name, Node node) { + if (node != null) { + return new CompositeNodeTOImpl(name, null, Collections.> singletonList(node)); + } else { + return new CompositeNodeTOImpl(name, null, Collections.> emptyList()); + } + } + + static CompositeNodeTOImpl wrap(QName name, Node additional, Node node) { + if (node != null) { + return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node)); + } else { + return new CompositeNodeTOImpl(name, null, ImmutableList.> of(additional)); + } + } + + static ImmutableCompositeNode filter(String type, Node node) { + CompositeNodeBuilder it = ImmutableCompositeNode.builder(); // + it.setQName(NETCONF_FILTER_QNAME); + it.setAttribute(NETCONF_TYPE_QNAME, type); + if (node != null) { + return it.add(node).toInstance(); + } else { + return it.toInstance(); + } + } + + public static Node toCompositeNode(Document document) { + return XmlDocumentUtils.toDomNode(document); + } + + public static void checkValidReply(NetconfMessage input, NetconfMessage output) { + String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id"); + String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id"); + + if(inputMsgId.equals(outputMsgId) == false) { + String requestXml = XmlUtil.toString(input.getDocument()); + String responseXml = XmlUtil.toString(output.getDocument()); + throw new IllegalStateException(String.format("Rpc request and reply message IDs must be same. Request: %s, response: %s", requestXml, responseXml)); + } + } + + public static void checkSuccessReply(NetconfMessage output) throws NetconfDocumentedException { + if(NetconfMessageUtil.isErrorMessage(output)) { + throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument()))); + } + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend deleted file mode 100644 index 228a01eb4c..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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 com.google.common.collect.ImmutableList -import java.net.URI -import java.util.ArrayList -import java.util.Collections -import java.util.List -import java.util.Set -import java.util.concurrent.atomic.AtomicInteger -import org.opendaylight.controller.netconf.api.NetconfMessage -import org.opendaylight.controller.sal.common.util.Rpcs -import org.opendaylight.yangtools.yang.common.QName -import org.opendaylight.yangtools.yang.common.RpcResult -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument -import org.opendaylight.yangtools.yang.data.api.Node -import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl -import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode -import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils -import org.opendaylight.yangtools.yang.model.api.NotificationDefinition -import org.opendaylight.yangtools.yang.model.api.SchemaContext -import org.w3c.dom.Document -import org.w3c.dom.Element - -class NetconfMapping { - - public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0") - public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" - public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0") - - - public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf"); - public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc"); - public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get"); - public static val NETCONF_FILTER_QNAME = QName.create(NETCONF_QNAME, "filter"); - public static val NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type"); - public static val NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config"); - public static val NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config"); - public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config"); - public static val NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation"); - public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit"); - - public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config"); - public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source"); - public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target"); - - public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate"); - public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running"); - - - public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply"); - public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok"); - public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data"); - public static val NETCONF_CREATE_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"create-subscription"); - public static val NETCONF_CANCEL_SUBSCRIPTION_QNAME = QName.create(NETCONF_NOTIFICATION_URI,null,"cancel-subscription"); - public static val IETF_NETCONF_MONITORING_MODULE = QName.create(NETCONF_MONITORING_URI, "2010-10-04","ietf-netconf-monitoring"); - - static List> RUNNING = Collections.>singletonList( - new SimpleNodeTOImpl(NETCONF_RUNNING_QNAME, null, null)); - public static val CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING); - - static val messageId = new AtomicInteger(0); - - static def Node toFilterStructure(InstanceIdentifier identifier) { - var Node previous = null; - if(identifier.path.empty) { - return null; - } - - for (component : identifier.path.reverseView) { - val Node current = component.toNode(previous); - previous = current; - } - return filter("subtree",previous); - } - - static def dispatch Node toNode(NodeIdentifierWithPredicates argument, Node node) { - val list = new ArrayList>(); - for (arg : argument.keyValues.entrySet) { - list.add = new SimpleNodeTOImpl(arg.key, null, arg.value); - } - if (node != null) { - list.add(node); - } - return new CompositeNodeTOImpl(argument.nodeType, null, list) - } - - static def dispatch Node toNode(PathArgument argument, Node node) { - if (node != null) { - return new CompositeNodeTOImpl(argument.nodeType, null, Collections.singletonList(node)); - } else { - return new SimpleNodeTOImpl(argument.nodeType, null, null); - } - } - - static def CompositeNode toCompositeNode(NetconfMessage message,Optional ctx) { - //TODO: implement general normalization to normalize incoming Netconf Message - // for Schema Context counterpart - return null - } - - static def CompositeNode toNotificationNode(NetconfMessage message,Optional ctx) { - if (ctx.present) { - val schemaContext = ctx.get - val notifications = schemaContext.notifications - val document = message.document - return XmlDocumentUtils.notificationToDomNodes(document, Optional.>fromNullable(notifications)) - } - return null - } - - static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node,Optional ctx) { - val rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node)) - val w3cPayload = XmlDocumentUtils.toDocument(rpcPayload, XmlDocumentUtils.defaultValueCodecProvider) - w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement) - return new NetconfMessage(w3cPayload); - } - - def static flattenInput(CompositeNode node) { - val inputQName = QName.create(node.nodeType,"input"); - val input = node.getFirstCompositeByName(inputQName); - if(input == null) return node; - if(input instanceof CompositeNode) { - - val nodes = ImmutableList.builder() // - .addAll(input.children) // - .addAll(node.children.filter[nodeType != inputQName]) // - .build() - return ImmutableCompositeNode.create(node.nodeType,nodes); - } - - } - - static def RpcResult toRpcResult(NetconfMessage message,QName rpc,Optional context) { - var CompositeNode rawRpc; - if(context.present) { - if(isDataRetrievalReply(rpc)) { - - val xmlData = message.document.dataSubtree - val dataNodes = XmlDocumentUtils.toDomNodes(xmlData, Optional.of(context.get.dataDefinitions)) - - val it = ImmutableCompositeNode.builder() - setQName(NETCONF_RPC_REPLY_QNAME) - add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes)); - - rawRpc = it.toInstance; - //sys(xmlData) - } else { - val rpcSchema = context.get.operations.findFirst[QName == rpc] - rawRpc = message.document.toCompositeNode() as CompositeNode; - } - } else { - rawRpc = message.document.toCompositeNode() as CompositeNode; - } - //rawRpc. - return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet()); - } - - def static Element getDataSubtree(Document doc) { - doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element - } - - def static boolean isDataRetrievalReply(QName it) { - return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName) - } - - static def wrap(QName name, Node node) { - if (node != null) { - return new CompositeNodeTOImpl(name, null, Collections.singletonList(node)); - } else { - return new CompositeNodeTOImpl(name, null, Collections.emptyList()); - } - } - - static def wrap(QName name, Node additional, Node node) { - if (node != null) { - return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node)); - } else { - return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional)); - } - } - - static def filter(String type, Node node) { - val it = ImmutableCompositeNode.builder(); // - setQName(NETCONF_FILTER_QNAME); - setAttribute(NETCONF_TYPE_QNAME,type); - if (node != null) { - return add(node).toInstance(); - } else { - return toInstance(); - } - } - - public static def Node toCompositeNode(Document document) { - return XmlDocumentUtils.toDomNode(document) as Node - } - - public static def checkValidReply(NetconfMessage input, NetconfMessage output) { - val inputMsgId = input.document.documentElement.getAttribute("message-id") - val outputMsgId = output.document.documentElement.getAttribute("message-id") - Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same."); - - } - -} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java index c734e80d9a..abd935dd63 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java @@ -20,6 +20,8 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider { @@ -30,8 +32,11 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider private final NetconfDevice device; + private final Logger logger; + public NetconfRemoteSchemaSourceProvider(NetconfDevice device) { this.device = Preconditions.checkNotNull(device); + logger = LoggerFactory.getLogger(NetconfDevice.class + "#" + device.getName()); } @Override @@ -44,7 +49,7 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider request.addLeaf("version", revision.get()); } - device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision); + logger.trace("Loading YANG schema source for {}:{}", moduleName, revision); try { RpcResult schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()).get(); if (schemaReply.isSuccessful()) { @@ -54,9 +59,9 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider return Optional.of(schemaBody); } } - device.logger.warn("YANG shcema was not successfully retrieved."); + logger.warn("YANG shcema was not successfully retrieved."); } catch (InterruptedException | ExecutionException e) { - device.logger.warn("YANG shcema was not successfully retrieved.", e); + logger.warn("YANG shcema was not successfully retrieved.", e); } return Optional.absent(); } diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImpl.java b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImpl.java index f49771a953..065d0ee7ba 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImpl.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImpl.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.sample.l2switch.md.flow; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; + import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService; import org.opendaylight.controller.sample.l2switch.md.util.InstanceIdentifierUtils; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; @@ -25,6 +26,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; @@ -261,7 +263,7 @@ public class FlowWriterServiceImpl implements FlowWriterService { .setBufferId(0L) // .setHardTimeout(0) // .setIdleTimeout(0) // - .setCookie(BigInteger.valueOf(flowCookieInc.getAndIncrement())) + .setCookie(new FlowCookie(BigInteger.valueOf(flowCookieInc.getAndIncrement()))) .setFlags(new FlowModFlags(false, false, false, false, false)); return macToMacFlow.build(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java index c4334ab9ff..5ace260251 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java @@ -88,8 +88,12 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo private final TimerTask task = new TimerTask() { @Override public void run() { - requestPeriodicStatistics(); - cleanStaleStatistics(); + try{ + requestPeriodicStatistics(); + cleanStaleStatistics(); + }catch(Exception e){ + logger.warn("Exception occured while sending statistics request : {}",e); + } } }; diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml index 2d003f8079..a51f6c2f9f 100644 --- a/opendaylight/md-sal/topology-lldp-discovery/pom.xml +++ b/opendaylight/md-sal/topology-lldp-discovery/pom.xml @@ -34,10 +34,6 @@ equinoxSDK381 org.eclipse.osgi - - org.eclipse.xtend - org.eclipse.xtend.lib - org.opendaylight.controller sal @@ -82,10 +78,6 @@ ${project.basedir}/META-INF - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java new file mode 100644 index 0000000000..0e003dbe7f --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java @@ -0,0 +1,30 @@ +/** + * 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.md.controller.topology.lldp; + +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.osgi.framework.BundleContext; + +public class LLDPActivator extends AbstractBindingAwareProvider { + private static LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider(); + + public void onSessionInitiated(final ProviderContext session) { + DataProviderService dataService = session.getSALService(DataProviderService.class); + provider.setDataService(dataService); + NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class); + provider.setNotificationService(notificationService); + provider.start(); + } + + protected void stopImpl(final BundleContext context) { + provider.close(); + } +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend deleted file mode 100644 index 674e919cd7..0000000000 --- a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.md.controller.topology.lldp - -import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.osgi.framework.BundleContext - -class LLDPActivator extends AbstractBindingAwareProvider { - - static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider(); - - override onSessionInitiated(ProviderContext session) { - provider.dataService = session.getSALService(DataProviderService) - provider.notificationService = session.getSALService(NotificationProviderService) - provider.start(); - } - - override protected stopImpl(BundleContext context) { - provider.close(); - } - -} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java new file mode 100644 index 0000000000..b219722ba8 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java @@ -0,0 +1,58 @@ +/** + * 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.md.controller.topology.lldp; + +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LLDPDiscoveryProvider implements AutoCloseable { + private final static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider.class); + private DataProviderService dataService; + private NotificationProviderService notificationService; + private final LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(LLDPDiscoveryProvider.this); + private Registration listenerRegistration; + + public DataProviderService getDataService() { + return this.dataService; + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public NotificationProviderService getNotificationService() { + return this.notificationService; + } + + public void setNotificationService(final NotificationProviderService notificationService) { + this.notificationService = notificationService; + } + + public void start() { + Registration registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter); + this.listenerRegistration = registerNotificationListener; + LLDPLinkAger.getInstance().setManager(this); + LOG.info("LLDPDiscoveryListener Started."); + } + + public void close() { + try { + LOG.info("LLDPDiscoveryListener stopped."); + if (this.listenerRegistration!=null) { + this.listenerRegistration.close(); + } + LLDPLinkAger.getInstance().close(); + } catch (Exception e) { + throw new Error(e); + } + } +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend deleted file mode 100644 index fc724ac680..0000000000 --- a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.md.controller.topology.lldp - -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.NotificationListener -import org.slf4j.LoggerFactory - -class LLDPDiscoveryProvider implements AutoCloseable { - - - static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider); - - @Property - DataProviderService dataService; - - @Property - NotificationProviderService notificationService; - - val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this); - - Registration listenerRegistration - - def void start() { - listenerRegistration = notificationService.registerNotificationListener(commiter); - LLDPLinkAger.instance.manager = this; - LOG.info("LLDPDiscoveryListener Started."); - - } - - override close() { - LOG.info("LLDPDiscoveryListener stopped."); - listenerRegistration?.close(); - LLDPLinkAger.instance.close(); - } - -} - - diff --git a/opendaylight/netconf/config-netconf-connector/pom.xml b/opendaylight/netconf/config-netconf-connector/pom.xml index 2a0f0a97f7..c10f0a9089 100644 --- a/opendaylight/netconf/config-netconf-connector/pom.xml +++ b/opendaylight/netconf/config-netconf-connector/pom.xml @@ -105,7 +105,8 @@ org.opendaylight.controller.netconf.confignetconfconnector.transactions, org.opendaylight.controller.netconf.confignetconfconnector.util, org.opendaylight.controller.netconf.confignetconfconnector.osgi, - org.opendaylight.controller.config.util, + org.opendaylight.controller.config.util, + org.opendaylight.controller.netconf.confignetconfconnector.exception, com.google.common.base, com.google.common.collect, javax.annotation, @@ -119,6 +120,7 @@ org.opendaylight.controller.netconf.mapping.api, org.opendaylight.controller.netconf.util.mapping, org.opendaylight.controller.netconf.util.xml, + org.opendaylight.controller.netconf.util.exception, org.opendaylight.yangtools.yang.common, org.opendaylight.yangtools.yang.model.api, org.osgi.framework, @@ -128,7 +130,7 @@ com.google.common.io, org.opendaylight.yangtools.yang.model.api.type, org.opendaylight.yangtools.sal.binding.generator.spi, - org.opendaylight.yangtools.sal.binding.yang.types + org.opendaylight.yangtools.sal.binding.yang.types, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java new file mode 100644 index 0000000000..be44a71e06 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NetconfConfigHandlingException.java @@ -0,0 +1,26 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class NetconfConfigHandlingException extends NetconfDocumentedException { + + public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections.emptyMap()); + } + + public NetconfConfigHandlingException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java new file mode 100644 index 0000000000..ebb8054c71 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/NoTransactionFoundException.java @@ -0,0 +1,27 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class NoTransactionFoundException extends NetconfDocumentedException { + + public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); + } + + public NoTransactionFoundException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } + +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java new file mode 100644 index 0000000000..e0d63c1418 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/exception/OperationNotPermittedException.java @@ -0,0 +1,26 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class OperationNotPermittedException extends NetconfDocumentedException { + + public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); + } + + public OperationNotPermittedException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java index 54d24a4cec..c08be06c9f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; public abstract class AttributeIfcSwitchStatement { - protected AttributeIfc lastAttribute; + private AttributeIfc lastAttribute; public T switchAttribute(AttributeIfc attributeIfc) { @@ -39,8 +39,9 @@ public abstract class AttributeIfcSwitchStatement { return caseJavaUnionAttribute(openType); } else if(((JavaAttribute)attributeIfc).isIdentityRef()) { return caseJavaIdentityRefAttribute(openType); - } else + } else { return caseJavaAttribute(openType); + } } catch (UnknownOpenTypeException e) { throw getIllegalArgumentException(attributeIfc); } @@ -58,6 +59,10 @@ public abstract class AttributeIfcSwitchStatement { throw getIllegalArgumentException(attributeIfc); } + public AttributeIfc getLastAttribute() { + return lastAttribute; + } + protected T caseJavaIdentityRefAttribute(OpenType openType) { return caseJavaAttribute(openType); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java index 7939112628..701e96ecd9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AbstractAttributeReadingStrategy.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import java.util.List; @@ -25,14 +26,14 @@ public abstract class AbstractAttributeReadingStrategy implements AttributeReadi } @Override - public AttributeConfigElement readElement(List configNodes) { - if (configNodes.size() == 0) + public AttributeConfigElement readElement(List configNodes) throws NetconfDocumentedException { + if (configNodes.size() == 0){ return AttributeConfigElement.createNullValue(postprocessNullableDefault(nullableDefault)); - + } return readElementHook(configNodes); } - abstract AttributeConfigElement readElementHook(List configNodes); + abstract AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException; protected Object postprocessNullableDefault(String nullableDefault) { return nullableDefault; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java index 8f56961900..442c504cce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.collect.Lists; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import java.util.List; @@ -27,7 +28,7 @@ public class ArrayAttributeReadingStrategy extends AbstractAttributeReadingStrat } @Override - AttributeConfigElement readElementHook(List configNodes) { + AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { List innerList = Lists.newArrayList(); for (int i = 0; i < configNodes.size(); i++) { innerList.add(innerStrategy.readElement(Lists.newArrayList(configNodes.get(i))).getValue()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index dbc1b48d4f..dcc2fa1543 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.base.Optional; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy; import javax.management.openmbean.OpenType; @@ -39,7 +40,7 @@ public class AttributeConfigElement { } public void resolveValue(AttributeResolvingStrategy> attributeResolvingStrategy, - String attrName) { + String attrName) throws NetconfDocumentedException { resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue); resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java index 6dae839148..4e78370c93 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeReadingStrategy.java @@ -10,10 +10,11 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import java.util.List; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; public interface AttributeReadingStrategy { - public abstract AttributeConfigElement readElement(List element); + public abstract AttributeConfigElement readElement(List element) throws NetconfDocumentedException; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java index fdbfb98e1c..792fb28027 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/CompositeAttributeReadingStrategy.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import java.util.List; @@ -28,7 +29,7 @@ public class CompositeAttributeReadingStrategy extends AbstractAttributeReadingS } @Override - AttributeConfigElement readElementHook(List configNodes) { + AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { Preconditions.checkState(configNodes.size() == 1, "This element should be present only once %s", configNodes); @@ -38,7 +39,8 @@ public class CompositeAttributeReadingStrategy extends AbstractAttributeReadingS List recognisedChildren = Lists.newArrayList(); for (Entry innerAttrEntry : innerStrategies.entrySet()) { - List childItem = complexElement.getChildElementsWithSameNamespace(innerAttrEntry.getKey()); + List childItem = null; + childItem = complexElement.getChildElementsWithSameNamespace(innerAttrEntry.getKey()); recognisedChildren.addAll(childItem); AttributeConfigElement resolvedInner = innerAttrEntry.getValue().readElement(childItem); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java index 7a4ba31255..bf9eee7f26 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java @@ -8,9 +8,12 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.base.Preconditions; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; @@ -18,13 +21,14 @@ import java.util.Map; public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReadingStrategy { private static final Object PREFIX_SEPARATOR = ":"; + private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeReadingStrategy.class); public ObjectNameAttributeReadingStrategy(String nullableDefault) { super(nullableDefault); } @Override - AttributeConfigElement readElementHook(List configNodes) { + AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { XmlElement firstChild = configNodes.get(0); Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + firstChild @@ -34,8 +38,9 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading return AttributeConfigElement.create(getNullableDefault(), resolve(firstChild)); } - private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) { - XmlElement typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) throws NetconfDocumentedException{ + XmlElement typeElement = null; + typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Map.Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); String serviceName = checkPrefixAndExtractServiceName(typeElement, prefixNamespace); @@ -47,10 +52,10 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading dependencyName); } - public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry prefixNamespace) { + public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry prefixNamespace) throws NetconfDocumentedException { String serviceName = typeElement.getTextContent(); - Preconditions.checkState(prefixNamespace.equals("") == false, "Service %s value not prefixed with namespace", + Preconditions.checkState(!prefixNamespace.equals(""), "Service %s value not prefixed with namespace", XmlNetconfConstants.TYPE_KEY); String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR; Preconditions.checkState(serviceName.startsWith(prefix), diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java index 61db74feb5..61ea76bbfe 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java @@ -50,31 +50,31 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { - return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new SimpleBinaryAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType openType) { String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION; - return new SimpleUnionAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey); + return new SimpleUnionAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey); } @Override public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType openType) { - return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override public AttributeReadingStrategy caseJavaArrayAttribute(ArrayType openType) { - SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault()); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault()); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } @Override public AttributeReadingStrategy caseJavaCompositeAttribute(CompositeType openType) { Preconditions.checkState(openType.keySet().size() == 1, "Unexpected number of elements for open type %s, should be 1", openType); String mappingKey = openType.keySet().iterator().next(); - return new SimpleCompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey); + return new SimpleCompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey); } @Override @@ -83,18 +83,18 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement keys = ((CompositeType) openType).keySet(); Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType); String mappingKey = keys.iterator().next(); - return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap); + return new SimpleIdentityRefAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey, identityMap); } @Override protected AttributeReadingStrategy caseDependencyAttribute(SimpleType openType) { - return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new ObjectNameAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override protected AttributeReadingStrategy caseTOAttribute(CompositeType openType) { - Preconditions.checkState(lastAttribute instanceof TOAttribute); - Map inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap(); + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + Map inner = ((TOAttribute)getLastAttribute()).getYangPropertiesToTypesMap(); Map innerStrategies = Maps.newHashMap(); @@ -104,21 +104,21 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) lastAttribute).getInnerAttribute()); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) getLastAttribute()).getInnerAttribute()); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } @Override protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java index 3765a13508..cb8f66081b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java @@ -9,12 +9,12 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.base.Preconditions; +import java.util.List; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; - public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy { private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class); @@ -24,7 +24,7 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra } @Override - AttributeConfigElement readElementHook(List configNodes) { + AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { XmlElement xmlElement = configNodes.get(0); Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement + " but was " + configNodes.size()); @@ -37,12 +37,17 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra logger.warn("Ignoring exception caused by failure to read text element", e); } - Preconditions.checkNotNull(textContent, "This element should contain text %s", xmlElement); + if (null == textContent){ + throw new NetconfDocumentedException(String.format("This element should contain text %s", xmlElement), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()), postprocessParsedValue(textContent)); } - protected String readElementContent(XmlElement xmlElement) { + protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException { return xmlElement.getTextContent(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java index 1205597125..8e7ba708c6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java @@ -15,6 +15,7 @@ import java.util.Map; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.yangtools.yang.common.QName; @@ -32,7 +33,7 @@ public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeRe } @Override - protected String readElementContent(XmlElement xmlElement) { + protected String readElementContent(XmlElement xmlElement) throws NetconfDocumentedException { // TODO test Map.Entry namespaceOfTextContent = xmlElement.findNamespaceOfTextContent(); String content = xmlElement.getTextContent(); @@ -53,9 +54,9 @@ public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeRe revision = date; } } - } else + } else { revision = revisions.keySet().iterator().next(); - + } return QName.create(URI.create(namespace), revision, localName).toString(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java index 30436bb42f..54ffe08cfb 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java @@ -30,8 +30,9 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat @Override public Optional> mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array "); @@ -39,19 +40,11 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat for (int i = 0; i < Array.getLength(value); i++) { Object innerValue = Array.get(value, i); - // String expectedClassName = - // getOpenType().getElementOpenType().getClassName(); - // String realClassName = value.getClass().getName(); - - // Preconditions.checkState(realClassName.contains(expectedClassName), - // "Element in collection/array should be of type " + - // expectedClassName + " but was " - // + realClassName + " for attribute: " + getOpenType()); - Optional mapAttribute = innerElementStrategy.mapAttribute(innerValue); - if (mapAttribute.isPresent()) + if (mapAttribute.isPresent()){ retVal.add(mapAttribute.get()); + } } return Optional.of(retVal); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java index 368e1f12a6..594953e569 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java @@ -35,8 +35,9 @@ public class CompositeAttributeMappingStrategy extends @Override public Optional> mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } Util.checkType(value, CompositeDataSupport.class); @@ -54,8 +55,9 @@ public class CompositeAttributeMappingStrategy extends for (String jmxName : jmxToJavaNameMapping.keySet()) { Optional mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName)); - if(mapped.isPresent()) + if(mapped.isPresent()){ retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get()); + } } return Optional.of(retVal); @@ -66,8 +68,7 @@ public class CompositeAttributeMappingStrategy extends AttributeMappingStrategy> attributeMappingStrategy = innerStrategies .get(jmxName); - Optional mapAttribute = attributeMappingStrategy.mapAttribute(innerValue); - return mapAttribute; + return attributeMappingStrategy.mapAttribute(innerValue); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index 506d7d61c3..01844f27d4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -112,7 +112,7 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseDependencyAttribute( SimpleType openType) { - return new ObjectNameAttributeMappingStrategy(openType, dependencyTracker, + return new ObjectNameAttributeMappingStrategy(openType, serviceNameOfDepAttr, namespaceOfDepAttr); } @@ -120,10 +120,10 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseTOAttribute(CompositeType openType) { Map>> innerStrategies = Maps.newHashMap(); - Preconditions.checkState(lastAttribute instanceof TOAttribute); - TOAttribute lastTO = (TOAttribute) lastAttribute; + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + TOAttribute lastTO = (TOAttribute) getLastAttribute(); - for (Entry innerAttrEntry : ((TOAttribute)lastAttribute).getJmxPropertiesToTypesMap().entrySet()) { + for (Entry innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) { innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue())); } @@ -133,14 +133,14 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseListAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); return new ArrayAttributeMappingStrategy(openType, - prepareStrategy(((ListAttribute) lastAttribute).getInnerAttribute())); + prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute())); } @Override protected AttributeMappingStrategy> caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 83e8086eef..b827a5b039 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,31 +10,28 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; -import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; - import javax.management.ObjectName; import javax.management.openmbean.SimpleType; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - private final ServiceRegistryWrapper tracker; private final String serviceName; private final String namespace; - public ObjectNameAttributeMappingStrategy(SimpleType openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) { + public ObjectNameAttributeMappingStrategy(SimpleType openType, String serviceName, String namespace) { super(openType); - this.tracker = dependencyTracker; this.serviceName = serviceName; this.namespace = namespace; } @Override public Optional mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } String expectedClass = getOpenType().getClassName(); String realClass = value.getClass().getName(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java index d92b7c432d..7dbf4f41bc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java @@ -25,8 +25,9 @@ public class SimpleAttributeMappingStrategy extends AbstractAttributeMappingStra @Override public Optional mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } String expectedClass = getOpenType().getClassName(); String realClass = value.getClass().getName(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java index 81a1e53598..1754fc7e09 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java @@ -26,9 +26,9 @@ public class UnionCompositeAttributeMappingStrategy extends @Override protected Optional mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) { - if(description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION) == false) + if(!description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){ return Optional.absent(); - + } return super.mapInnerAttribute(compositeData, jmxName, description); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java index adee8bec58..f0d7960085 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving; import com.google.common.base.Optional; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); } @@ -45,31 +46,31 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) { innerTypeClass = CompositeDataSupport.class; - } else + } else { try { innerTypeClass = Class.forName(getOpenType().getElementOpenType().getClassName()); } catch (ClassNotFoundException e) { - throw new RuntimeException("Unable to locate class for " + throw new IllegalStateException("Unable to locate class for " + getOpenType().getElementOpenType().getClassName(), e); } + } Object parsedArray = null; if (getOpenType().isPrimitiveArray()) { Class primitiveType = getPrimitiveType(innerTypeClass); parsedArray = Array.newInstance(primitiveType, valueList.size()); - } else + } else { parsedArray = Array.newInstance(innerTypeClass, valueList.size()); + } int i = 0; for (Object innerValue : valueList) { Optional parsedElement = innerTypeResolvingStrategy.parseAttribute(attrName + "_" + i, innerValue); - - if (!parsedElement.isPresent()) + if (!parsedElement.isPresent()){ continue; - + } Array.set(parsedArray, i, parsedElement.get()); - // parsedArray[i] = parsedElement.get(); i++; } @@ -94,7 +95,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt try { return (Class) innerTypeClass.getField("TYPE").get(null); } catch (Exception e) { - throw new RuntimeException("Unable to determine primitive type to " + innerTypeClass); + throw new IllegalStateException("Unable to determine primitive type to " + innerTypeClass); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java index 0bb274ae41..599d81396e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import javax.management.openmbean.OpenType; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; /** * Create real object from String or Map that corresponds to given opentype. @@ -18,5 +19,5 @@ import javax.management.openmbean.OpenType; public interface AttributeResolvingStrategy> { O getOpenType(); - Optional parseAttribute(String attrName, Object value); + Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java index e8e97f990f..83ebf65d7f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,7 +42,7 @@ class CompositeAttributeResolvingStrategy extends } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); @@ -75,7 +76,7 @@ class CompositeAttributeResolvingStrategy extends try { parsedValue = new CompositeDataSupport(getOpenType(), items); } catch (OpenDataException e) { - throw new RuntimeException("An error occured during restoration of composite type " + this + throw new IllegalStateException("An error occured during restoration of composite type " + this + " for attribute " + attrName + " from value " + value, e); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index 82c8c1ec6b..4a4281a55e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -106,8 +106,8 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseTOAttribute(CompositeType openType) { - Preconditions.checkState(lastAttribute instanceof TOAttribute); - TOAttribute toAttribute = (TOAttribute) lastAttribute; + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + TOAttribute toAttribute = (TOAttribute) getLastAttribute(); Map>> innerMap = Maps.newHashMap(); @@ -122,14 +122,14 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseListAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute(); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute(); return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType); } @Override protected AttributeResolvingStrategy> caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java index e1b8ecf17e..26709dbe6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java @@ -10,6 +10,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.collect.Maps; +import java.lang.reflect.InvocationTargetException; +import java.text.ParseException; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +38,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); } @@ -70,32 +73,42 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS } static interface Resolver { - Object resolveObject(Class type, String attrName, String value); + Object resolveObject(Class type, String attrName, String value) throws NetconfDocumentedException; } static class DefaultResolver implements Resolver { @Override - public Object resolveObject(Class type, String attrName, String value) { + public Object resolveObject(Class type, String attrName, String value) throws NetconfDocumentedException { try { - Object parsedValue = parseObject(type, value); - return parsedValue; + return parseObject(type, value); } catch (Exception e) { - throw new RuntimeException("Unable to resolve attribute " + attrName + " from " + value, e); + throw new NetconfDocumentedException("Unable to resolve attribute " + attrName + " from " + value, + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } } - protected Object parseObject(Class type, String value) throws Exception { - Method method = type.getMethod("valueOf", String.class); - Object parsedValue = method.invoke(null, value); - return parsedValue; + protected Object parseObject(Class type, String value) throws NetconfDocumentedException { + Method method = null; + try { + method = type.getMethod("valueOf", String.class); + return method.invoke(null, value); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + logger.trace("Error parsing object {}",e); + throw new NetconfDocumentedException("Error parsing object.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } } static class StringResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return value; } } @@ -103,7 +116,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class BigIntegerResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new BigInteger(value); } } @@ -111,7 +124,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class BigDecimalResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new BigDecimal(value); } } @@ -119,16 +132,23 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class CharResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new Character(value.charAt(0)); } } static class DateResolver extends DefaultResolver { - @Override - protected Object parseObject(Class type, String value) throws Exception { - return Util.readDate(value); + protected Object parseObject(Class type, String value) throws NetconfDocumentedException { + try { + return Util.readDate(value); + } catch (ParseException e) { + logger.trace("Unable parse value {} due to {}",value, e); + throw new NetconfDocumentedException("Unable to parse value "+value+" as date.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java index bc99ecf09a..cdebcfaa34 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java @@ -34,10 +34,11 @@ final class UnionCompositeAttributeResolvingStrategy extends CompositeAttributeR Map newMap = Maps.newHashMap(); for (String key : openType.keySet()) { - if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)) + if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){ newMap.put(key, valueMap.get(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)); - else + } else { newMap.put(key, null); + } } return newMap; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java new file mode 100644 index 0000000000..61465f93e8 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java @@ -0,0 +1,14 @@ +/* + * 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.mapping.attributes.toxml; + +public abstract class AbstractAttributeWritingStrategy { + protected Object preprocess(Object value) { + return value; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java index 051f365086..b17842b8e2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java @@ -20,9 +20,9 @@ import com.google.common.base.Optional; public class CompositeAttributeWritingStrategy implements AttributeWritingStrategy { - protected final String key; - protected final Document document; - protected final Map innerStrats; + private final String key; + private final Document document; + private final Map innerStrats; public CompositeAttributeWritingStrategy(Document document, String key, Map innerStrats) { @@ -49,4 +49,16 @@ public class CompositeAttributeWritingStrategy implements AttributeWritingStrate } parentElement.appendChild(innerNode); } + + public String getKey() { + return key; + } + + public Document getDocument() { + return document; + } + + public Map getInnerStrats() { + return innerStrats; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java index 8d63bb05d8..4e07ec8c31 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java @@ -90,11 +90,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement innerStrats = Maps.newHashMap(); String currentKey = key; - for (Entry innerAttrEntry : ((TOAttribute) lastAttribute).getYangPropertiesToTypesMap().entrySet()) { + for (Entry innerAttrEntry : ((TOAttribute) getLastAttribute()).getYangPropertiesToTypesMap().entrySet()) { AttributeWritingStrategy innerStrategy = prepareWritingStrategy(innerAttrEntry.getKey(), innerAttrEntry.getValue(), document); @@ -106,8 +106,8 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute(); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute(); AttributeWritingStrategy innerStrategy = prepareWritingStrategy(key, innerAttribute, document); return new ArrayAttributeWritingStrategy(innerStrategy); @@ -115,7 +115,7 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); return new ArrayAttributeWritingStrategy(innerStrategy); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java index b2555f712a..a74afd0812 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java @@ -8,15 +8,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml; -import java.util.Map; -import java.util.Map.Entry; - +import com.google.common.base.Optional; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; +import java.util.Map; +import java.util.Map.Entry; public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingStrategy { @@ -36,7 +35,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt public void writeElement(Element parentElement, String namespace, Object value) { Util.checkType(value, Map.class); - Element innerNode = XmlUtil.createElement(document, key, Optional.absent()); + Element innerNode = XmlUtil.createElement(getDocument(), getKey(), Optional.absent()); Map map = (Map) value; @@ -46,7 +45,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt // bean Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class); Map innerMap = (Map) runtimeBeanInstanceMappingEntry.getValue(); - Element runtimeInstanceNode = XmlUtil.createElement(document, "_" + Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_" + (String) runtimeBeanInstanceMappingEntry.getKey(), Optional.absent()); innerNode.appendChild(runtimeInstanceNode); @@ -57,7 +56,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt String innerKey = (String) innerObjectEntry.getKey(); Object innerValue = innerObjectEntry.getValue(); - innerStrats.get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue); + getInnerStrats().get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue); } } parentElement.appendChild(innerNode); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java index 1b15171ca0..12988071ba 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java @@ -43,7 +43,6 @@ public class SimpleAttributeWritingStrategy implements AttributeWritingStrategy typeElement.appendChild(document.createTextNode(value)); return typeElement; } - protected Object preprocess(Object value) { return value; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java index c159e46987..4e92c26e36 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java @@ -25,6 +25,7 @@ public class SimpleBinaryAttributeWritingStrategy extends SimpleAttributeWriting super(document, key); } + @Override protected Object preprocess(Object value) { Util.checkType(value, List.class); BaseEncoding en = BaseEncoding.base64(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java index 68d31ae207..ed3bb2a9d9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java @@ -21,7 +21,6 @@ import com.google.common.base.Preconditions; public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy { - private static final char QNAME_SEPARATOR = ':'; private static final String PREFIX = "prefix"; /** diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index decb091f86..854f99c5c0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -8,44 +8,36 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; - import javax.management.ObjectName; - import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; +import static com.google.common.base.Preconditions.checkState; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; public class Config { - private final Logger logger = LoggerFactory.getLogger(Config.class); private final Map> moduleConfigs; - private final Map moduleNamesToConfigs; private final Map> identityMap; @@ -55,11 +47,6 @@ public class Config { public Config(Map> moduleConfigs, Map> identityMap) { this.moduleConfigs = moduleConfigs; - Map moduleNamesToConfigs = new HashMap<>(); - for (Entry> entry : moduleConfigs.entrySet()) { - moduleNamesToConfigs.putAll(entry.getValue()); - } - this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs); this.identityMap = identityMap; } @@ -81,8 +68,9 @@ public class Config { // TODO, this code does not support same module names from different namespaces // Namespace should be present in ObjectName - if (instances == null) + if (instances == null){ continue; + } innerRetVal.put(moduleName, instances); @@ -103,11 +91,6 @@ public class Config { return retVal; } - // public Element toXml(Set instancesToMap, String namespace, - // Document document) { - // return toXml(instancesToMap, Optional.of(namespace), document); - // } - public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, Element dataElement, ServiceRegistryWrapper serviceTracker) { @@ -147,7 +130,7 @@ public class Config { // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException { Optional modulesElement = getModulesElement(xml); List moduleElements = getModulesElementList(modulesElement); @@ -156,7 +139,7 @@ public class Config { for (XmlElement moduleElement : moduleElements) { ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { @Override - public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { + public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException { return moduleMapping.fromXml(moduleElement, serviceTracker, instanceName, moduleNamespace, defaultStrategy, identityMap); } @@ -171,7 +154,7 @@ public class Config { * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted. */ public Map> fromXmlModulesMap(XmlElement xml, - EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) throws NetconfDocumentedException { Optional modulesElement = getModulesElement(xml); List moduleElements = getModulesElementList(modulesElement); @@ -201,7 +184,7 @@ public class Config { XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - private List getModulesElementList(Optional modulesElement) { + private List getModulesElementList(Optional modulesElement) throws NetconfDocumentedException { List moduleElements; if (modulesElement.isPresent()) { @@ -214,11 +197,13 @@ public class Config { } private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { - XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) throws NetconfDocumentedException { + XmlElement typeElement = null; + typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); - XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); + XmlElement nameElement = null; + nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); String instanceName = nameElement.getTextContent(); String factoryNameWithPrefix = typeElement.getTextContent(); String prefixOrEmptyString = prefixToNamespace.getKey(); @@ -238,7 +223,7 @@ public class Config { innerMap.put(factoryName, resolvedElement); } - public Services fromXmlServices(XmlElement xml) { + public Services fromXmlServices(XmlElement xml) throws NetconfDocumentedException { Optional servicesElement = getServicesElement(xml); Services services; @@ -256,15 +241,17 @@ public class Config { XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - public static void checkUnrecognisedChildren(XmlElement parent) { + public static void checkUnrecognisedChildren(XmlElement parent) throws NetconfDocumentedException { Optional servicesOpt = getServicesElement(parent); Optional modulesOpt = getModulesElement(parent); List recognised = Lists.newArrayList(); - if(servicesOpt.isPresent()) + if(servicesOpt.isPresent()){ recognised.add(servicesOpt.get()); - if(modulesOpt.isPresent()) + } + if(modulesOpt.isPresent()){ recognised.add(modulesOpt.get()); + } parent.checkUnrecognisedElements(recognised); } @@ -272,7 +259,7 @@ public class Config { private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { checkState( factoryNameWithPrefix.startsWith(prefixOrEmptyString), - format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'", + String.format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'", factoryNameWithPrefix, prefixOrEmptyString)); int factoryNameAfterPrefixIndex; @@ -298,6 +285,6 @@ public class Config { private interface ResolvingStrategy { public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, - String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) throws NetconfDocumentedException; } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index a940be7e77..0fe5fad29c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -9,13 +9,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; import com.google.common.base.Optional; -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 org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader; @@ -63,26 +63,24 @@ public final class InstanceConfig { Map toXml = Maps.newHashMap(); for (Entry configDefEntry : jmxToAttrConfig.entrySet()) { - // Skip children runtime beans as they are mapped by InstanceRuntime - if (configDefEntry.getValue() instanceof RuntimeBeanEntry) + if (configDefEntry.getValue() instanceof RuntimeBeanEntry){ continue; - + } Object value = configRegistryClient.getAttributeCurrentValue(on, configDefEntry.getKey()); try { AttributeMappingStrategy> attributeMappingStrategy = mappingStrategies .get(configDefEntry.getKey()); Optional a = attributeMappingStrategy.mapAttribute(value); - if (a.isPresent() == false) + if (!a.isPresent()){ continue; - + } toXml.put(configDefEntry.getValue().getAttributeYangName(), a.get()); } catch (Exception e) { throw new IllegalStateException("Unable to map value " + value + " to attribute " + configDefEntry.getKey(), e); } } - return toXml; } @@ -131,14 +129,16 @@ public final class InstanceConfig { } public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, - EditStrategyType defaultStrategy, Multimap providedServices, Map> identityMap) { + EditStrategyType defaultStrategy, Multimap providedServices, Map> identityMap) throws NetconfDocumentedException { Map retVal = Maps.newHashMap(); Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap); List recognisedChildren = Lists.newArrayList(); - XmlElement type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); - XmlElement name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); + XmlElement type = null; + XmlElement name = null; + type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); List typeAndName = Lists.newArrayList(type, name); for (Entry readStratEntry : strats.entrySet()) { @@ -163,7 +163,7 @@ public final class InstanceConfig { } private List getConfigNodes(XmlElement moduleElement, String moduleNamespace, String name, - List recognisedChildren, List typeAndName) { + List recognisedChildren, List typeAndName) throws NetconfDocumentedException { List foundConfigNodes = moduleElement.getChildElementsWithinNamespace(name, moduleNamespace); if (foundConfigNodes.isEmpty()) { logger.debug("No config nodes {}:{} found in {}", moduleNamespace, name, moduleElement); @@ -181,9 +181,13 @@ public final class InstanceConfig { List foundWithoutNamespaceNodes = moduleElement.getChildElementsWithinNamespace(name, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); foundWithoutNamespaceNodes.removeAll(typeAndName); - Preconditions.checkState(foundWithoutNamespaceNodes.isEmpty(), - "Element %s present multiple times with different namespaces: %s, %s", name, foundConfigNodes, - foundWithoutNamespaceNodes); + if (!foundWithoutNamespaceNodes.isEmpty()){ + throw new NetconfDocumentedException(String.format("Element %s present multiple times with different namespaces: %s, %s", name, foundConfigNodes, + foundWithoutNamespaceNodes), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } } recognisedChildren.addAll(foundConfigNodes); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 0bb4191bf2..c9605af586 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -8,15 +8,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; +import java.util.Map; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; -import java.util.Map; - /** * Parsed xml element containing whole configuration for an instance of some * module. Contains preferred edit strategy type. @@ -27,8 +26,9 @@ public class InstanceConfigElementResolved { private final Map configuration; private final Multimap providedServices; - public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { - EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy); + public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) throws NetconfDocumentedException { + EditStrategyType valueOf = null; + valueOf = parseStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; this.providedServices = providedServices; @@ -41,18 +41,9 @@ public class InstanceConfigElementResolved { } - static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) { + static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) throws OperationNotPermittedException { EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy); - if (defaultStrategy.isEnforcing()) { - Preconditions - .checkArgument( - parsedStrategy == defaultStrategy, - "With " - + defaultStrategy - + " as " - + EditConfigXmlParser.DEFAULT_OPERATION_KEY - + " operations on module elements are not permitted since the default option is restrictive"); - } + EditStrategyType.compareParsedStrategyToDefaultEnforcing(parsedStrategy,defaultStrategy); return parsedStrategy; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index dbaa7895d3..a5a625a2d6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -8,13 +8,11 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -24,9 +22,10 @@ import org.opendaylight.yangtools.yang.common.QName; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.Date; +import java.util.Map; public class ModuleConfig { @@ -63,7 +62,7 @@ public class ModuleConfig { Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.absent()); // Xml.addNamespaceAttr(document, root, namespace); - final String prefix = getPrefix(namespace); + final String prefix = getPrefix(); Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix, moduleName, Optional.of(namespace)); // Xml.addNamespaceAttr(document, typeElement, @@ -81,16 +80,12 @@ public class ModuleConfig { return root; } - private String getPrefix(String namespace) { - // if(namespace.contains(":")==false) + private String getPrefix() { return XmlNetconfConstants.PREFIX; - // return namespace.substring(namespace.lastIndexOf(':') + 1, - // namespace.length()); - } public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, - String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) { + String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) throws NetconfDocumentedException { InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices, identityMap); return new ModuleElementResolved(instanceName, ice); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java index 9111701ba0..b772eee0d7 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -8,10 +8,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ModuleElementDefinition { @@ -20,13 +23,26 @@ public class ModuleElementDefinition { private final String instanceName; private final EditStrategyType editStrategy; + private static final Logger logger = LoggerFactory.getLogger(ModuleElementDefinition.class); public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) { this.instanceName = instanceName; - if (currentStrategy == null || currentStrategy.isEmpty()) + if (currentStrategy == null || currentStrategy.isEmpty()) { this.editStrategy = defaultStrategy; - else - this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } else { + EditStrategyType _edStrategy = null; + try { + _edStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } catch (OperationNotPermittedException e) { + _edStrategy = defaultStrategy; + logger.warn("Operation not permitted on current strategy {} while default strategy is {}. Element definition strategy set to default.", + currentStrategy, + defaultStrategy, + e); + } + this.editStrategy = _edStrategy; + } + } public String getInstanceName() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java index 8d2d149822..1f63555e83 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -35,7 +35,9 @@ public class ServiceRegistryWrapper { public boolean hasRefName(String namespace, String serviceName, ObjectName on) { String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); Map forQName = configServiceRefRegistry.getServiceMapping().get(qname); - if(forQName==null) return false; + if(forQName==null){ + return false; + } return forQName.values().contains(on); } @@ -70,7 +72,7 @@ public class ServiceRegistryWrapper { Map>> retVal = Maps.newHashMap(); Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (String serviceQName : serviceMapping.keySet()) + for (String serviceQName : serviceMapping.keySet()){ for (String refName : serviceMapping.get(serviceQName).keySet()) { ObjectName on = serviceMapping.get(serviceQName).get(refName); @@ -91,11 +93,12 @@ public class ServiceRegistryWrapper { serviceToRefs.put(localName, refsToSis); } - Preconditions.checkState(refsToSis.containsKey(refName) == false, + Preconditions.checkState(!refsToSis.containsKey(refName), "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, localName, on); refsToSis.put(refName, si.toString()); } + } return retVal; } @@ -108,10 +111,11 @@ public class ServiceRegistryWrapper { Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + if(serviceNameToRefNameToInstance == null || !serviceNameToRefNameToInstance.containsKey(serviceName)) { refNameToInstance = Collections.emptyMap(); - } else + } else { refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + } final Set refNamesAsSet = toSet(refNameToInstance.keySet()); if (refNamesAsSet.contains(refName)) { @@ -135,12 +139,13 @@ public class ServiceRegistryWrapper { } private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; + String availableRefName = ""; while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; + availableRefName = refName + "_" + suffix++; + if (!refNamesAsSet.contains(availableRefName)){ + return availableRefName; + } } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 9767b3f056..eb5c018cf3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,32 +8,27 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import javax.management.ObjectName; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public final class Services { - private static final Logger logger = LoggerFactory.getLogger(Services.class); - private static final String PROVIDER_KEY = "provider"; private static final String NAME_KEY = "name"; public static final String TYPE_KEY = "type"; @@ -86,7 +81,7 @@ public final class Services { // TODO support edit strategies on services - public static Services fromXml(XmlElement xml) { + public static Services fromXml(XmlElement xml) throws NetconfDocumentedException { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -97,7 +92,7 @@ public final class Services { XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY); Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); - Preconditions.checkState(prefixNamespace.getKey()!=null && prefixNamespace.getKey().equals("") == false, "Type attribute was not prefixed"); + Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed"); Map> namespaceToServices = retVal.get(prefixNamespace.getValue()); if(namespaceToServices == null) { @@ -168,7 +163,7 @@ public final class Services { public static ServiceInstance fromString(String instanceId) { instanceId = instanceId.trim(); Matcher matcher = p.matcher(instanceId); - if(matcher.matches() == false) { + if(!matcher.matches()) { matcher = pDeprecated.matcher(instanceId); } @@ -236,23 +231,30 @@ public final class Services { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj){ return true; - if (obj == null) + } + if (obj == null){ return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()){ return false; + } ServiceInstance other = (ServiceInstance) obj; if (instanceName == null) { - if (other.instanceName != null) + if (other.instanceName != null){ return false; - } else if (!instanceName.equals(other.instanceName)) + } + } else if (!instanceName.equals(other.instanceName)){ return false; + } if (moduleName == null) { - if (other.moduleName != null) + if (other.moduleName != null){ return false; - } else if (!moduleName.equals(other.moduleName)) + } + } else if (!moduleName.equals(other.moduleName)){ return false; + } return true; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java index b7f5fc780b..d63d8a139d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/InstanceRuntimeRpc.java @@ -12,6 +12,7 @@ import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeReadingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader; @@ -67,7 +68,7 @@ public final class InstanceRuntimeRpc { } } - public Map fromXml(XmlElement configRootNode) { + public Map fromXml(XmlElement configRootNode) throws NetconfDocumentedException { Map retVal = Maps.newHashMap(); // FIXME add identity map to runtime data diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java index a081890d39..28b1417893 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java @@ -17,12 +17,12 @@ import java.util.Map; public final class ModuleRpcs { - Map yangToJavaNames = Maps.newHashMap(); - Map> rpcMapping = Maps.newHashMap(); + private final Map yangToJavaNames = Maps.newHashMap(); + private final Map> rpcMapping = Maps.newHashMap(); public void addNameMapping(RuntimeBeanEntry runtimeEntry) { String yangName = runtimeEntry.getYangName(); - Preconditions.checkState(yangToJavaNames.containsKey(yangName) == false, + Preconditions.checkState(!yangToJavaNames.containsKey(yangName), "RuntimeBean %s found twice in same namespace", yangName); yangToJavaNames.put(yangName, runtimeEntry.getJavaNamePrefix()); } @@ -35,7 +35,7 @@ public final class ModuleRpcs { rpcMapping.put(yangName, map); } - Preconditions.checkState(map.containsKey(rpc.getYangName()) == false, "Rpc %s for runtime bean %s added twice", + Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice", rpc.getYangName(), yangName); map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc)); } @@ -55,4 +55,12 @@ public final class ModuleRpcs { Preconditions.checkState(rpc != null, "No rpc found for runtime bean %s with name %s", rbeName, rpcName); return rpc; } + + public Map getYangToJavaNames() { + return yangToJavaNames; + } + + public Map> getRpcMapping() { + return rpcMapping; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 8c3b35122c..6a49275f26 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -8,22 +8,19 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime; -import java.util.Hashtable; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Sets; +import javax.management.ObjectName; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; public class InstanceRuntime { @@ -48,20 +45,23 @@ public class InstanceRuntime { * root + any number of additional properties */ private Set findChildren(ObjectName innerRootBean, Set childRbeOns) { - final Hashtable wantedProperties = innerRootBean.getKeyPropertyList(); + final Map wantedProperties = innerRootBean.getKeyPropertyList(); return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate() { @Override public boolean apply(ObjectName on) { - Hashtable localProperties = on.getKeyPropertyList(); + Map localProperties = on.getKeyPropertyList(); for (Entry propertyEntry : wantedProperties.entrySet()) { - if (!localProperties.containsKey(propertyEntry.getKey())) + if (!localProperties.containsKey(propertyEntry.getKey())){ return false; - if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())) + } + if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())){ return false; - if (localProperties.size() <= wantedProperties.size()) + } + if (localProperties.size() <= wantedProperties.size()){ return false; + } } return true; } @@ -77,10 +77,12 @@ public class InstanceRuntime { @Override public boolean apply(ObjectName on) { - if (on.getKeyPropertyList().size() != keyListSize + 1) + if (on.getKeyPropertyList().size() != keyListSize + 1){ return false; - if (!on.getKeyPropertyList().containsKey(string)) + } + if (!on.getKeyPropertyList().containsKey(string)){ return false; + } return true; } })); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 4936d1dbcd..59767fec6e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -20,11 +20,9 @@ import java.util.Set; public class ModuleRuntime { - private final String moduleName; private final InstanceRuntime instanceRuntime; public ModuleRuntime(String moduleName, InstanceRuntime instanceRuntime) { - this.moduleName = moduleName; this.instanceRuntime = instanceRuntime; } @@ -34,8 +32,9 @@ public class ModuleRuntime { private ObjectName findRoot(Collection runtimeBeanOns) { for (ObjectName objectName : runtimeBeanOns) { - if (objectName.getKeyPropertyList().size() == 3) + if (objectName.getKeyPropertyList().size() == 3){ return objectName; + } } throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 8fc3ee1423..439dea2a80 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -85,7 +85,7 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); - if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) { + if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) { runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); @@ -101,14 +101,4 @@ public class Runtime { return root; } - private ObjectName findInstance(Collection objectNames, String instanceName) { - for (ObjectName objectName : objectNames) { - String name = ObjectNameUtil.getInstanceName(objectName); - if(name.equals(instanceName)) - return objectName; - } - - throw new UnsupportedOperationException("Unable to find config bean instance under name " + instanceName + " among " + objectNames); - } - } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java index cd99ac4d8d..c4217106ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java @@ -13,11 +13,15 @@ import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOpera public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation { - protected final ConfigRegistryClient configRegistryClient; + private final ConfigRegistryClient configRegistryClient; protected AbstractConfigNetconfOperation(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) { super(netconfSessionIdForReporting); this.configRegistryClient = configRegistryClient; } + + public ConfigRegistryClient getConfigRegistryClient() { + return configRegistryClient; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java index 561aab9052..d49fe1a116 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java @@ -8,17 +8,11 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations; -import java.util.HashMap; -import java.util.Map; - 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.util.ConfigRegistryClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -42,7 +36,7 @@ public class Commit extends AbstractConfigNetconfOperation { this.transactionProvider = transactionProvider; } - private static void checkXml(XmlElement xml) { + private static void checkXml(XmlElement xml) throws NetconfDocumentedException { xml.checkName(XmlNetconfConstants.COMMIT); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); } @@ -54,25 +48,14 @@ public class Commit extends AbstractConfigNetconfOperation { @Override protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { - checkXml(xml); + checkXml(xml); CommitStatus status; try { status = this.transactionProvider.commitTransaction(); - } catch (final IllegalStateException e) { - // TODO Illegal state thrown when no transaction yet for user - // Throw other exception type, or create transaction automatically - logger.warn("Commit failed: ", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.operation_failed.name(), - "Operation failed. Use 'get-config' or 'edit-config' before triggering 'commit' operation"); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed, - ErrorSeverity.error, errorInfo); - } catch (ValidationException e) { + logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status); + } catch (ConflictingVersionException | ValidationException e) { throw NetconfDocumentedException.wrap(e); - } catch (ConflictingVersionException e) { - throw NetconfDocumentedException.wrap(e); - } logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java index 639d4dac72..96a43b104d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java @@ -6,11 +6,9 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.netconf.confignetconfconnector.operations; - -import java.util.HashMap; -import java.util.Map; + package org.opendaylight.controller.netconf.confignetconfconnector.operations; +import com.google.common.base.Optional; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; @@ -25,7 +23,9 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; +import java.util.HashMap; +import java.util.Map; + public class DiscardChanges extends AbstractConfigNetconfOperation { @@ -41,7 +41,7 @@ public class DiscardChanges extends AbstractConfigNetconfOperation { this.transactionProvider = transactionProvider; } - private static void fromXml(XmlElement xml) { + private static void fromXml(XmlElement xml) throws NetconfDocumentedException { xml.checkName(DISCARD); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); } @@ -53,21 +53,10 @@ public class DiscardChanges extends AbstractConfigNetconfOperation { @Override protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { - try { - fromXml(xml); - } catch (final IllegalArgumentException e) { - //FIXME where can IllegalStateException be thrown? - logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute, - ErrorSeverity.error, errorInfo); - } - + fromXml(xml); try { this.transactionProvider.abortTransaction(); } catch (final IllegalStateException e) { - //FIXME where can IllegalStateException be thrown? logger.warn("Abort failed: ", e); final Map errorInfo = new HashMap<>(); errorInfo @@ -78,6 +67,7 @@ public class DiscardChanges extends AbstractConfigNetconfOperation { } logger.trace("Changes discarded successfully from datastore {}", Datastore.candidate); + return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.absent()); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java index 642c4456a8..1a7d50e5fa 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java @@ -8,9 +8,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations; -import java.util.HashMap; -import java.util.Map; - +import com.google.common.base.Optional; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; @@ -26,8 +24,8 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; +import java.util.HashMap; +import java.util.Map; public class Validate extends AbstractConfigNetconfOperation { @@ -43,7 +41,7 @@ public class Validate extends AbstractConfigNetconfOperation { this.transactionProvider = transactionProvider; } - private void checkXml(XmlElement xml) { + private void checkXml(XmlElement xml) throws NetconfDocumentedException { xml.checkName(VALIDATE); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); @@ -55,8 +53,10 @@ public class Validate extends AbstractConfigNetconfOperation { String datastoreValue = sourceChildNode.getName(); Datastore sourceDatastore = Datastore.valueOf(datastoreValue); - Preconditions.checkState(sourceDatastore == Datastore.candidate, "Only " + Datastore.candidate - + " is supported as source for " + VALIDATE + " but was " + datastoreValue); + if (sourceDatastore != Datastore.candidate){ + throw new NetconfDocumentedException( "Only " + Datastore.candidate + + " is supported as source for " + VALIDATE + " but was " + datastoreValue,ErrorType.application,ErrorTag.data_missing,ErrorSeverity.error); + } } @Override @@ -66,24 +66,7 @@ public class Validate extends AbstractConfigNetconfOperation { @Override protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { - try { - checkXml(xml); - } catch (IllegalStateException e) { - //FIXME where can IllegalStateException be thrown? I see precondition that guards for programming bugs.. - logger.warn("Rpc error: {}", ErrorTag.missing_attribute, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.missing_attribute.name(), "Missing value of datastore attribute"); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.missing_attribute, - ErrorSeverity.error, errorInfo); - } catch (final IllegalArgumentException e) { - // FIXME use checked exception if it has domain meaning - logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute, - ErrorSeverity.error, errorInfo); - } - + checkXml(xml); try { transactionProvider.validateTransaction(); } catch (ValidationException e) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java index 1d37fcd493..820f8ff772 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; @@ -24,7 +25,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, ServiceRegistryWrapper services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { try { ObjectName on = ta.lookupConfigBean(module, instance); @@ -40,9 +41,9 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { // edit configs should not handle missing abstract void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services); + String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException; abstract void executeStrategy(Map configuration, ConfigTransactionClient ta, - ObjectName objectName, ServiceRegistryWrapper services); + ObjectName objectName, ServiceRegistryWrapper services) throws NetconfConfigHandlingException; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index 13e8c30211..c5fadb097f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -8,45 +8,42 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import java.util.Map; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Map; - public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(DeleteEditConfigStrategy.class); - private final Multimap providedServices; - - public DeleteEditConfigStrategy() { - this.providedServices = HashMultimap.create(); - } - - public DeleteEditConfigStrategy(Multimap providedServices) { - this.providedServices = providedServices; - } @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services) { - throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found"); + String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { + throw new NetconfConfigHandlingException(String.format("Unable to delete %s : %s , ServiceInstance not found", module ,instance), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { try { ta.destroyModule(on); logger.debug("ServiceInstance {} deleted successfully", on); } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to delete " + on, e); + throw new NetconfConfigHandlingException( + String.format("Unable to delete %s because of exception %s" + on, e.getMessage()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 0cc9d1153f..3ea26055f3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -8,15 +8,11 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; - +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; @@ -25,6 +21,7 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; @@ -46,11 +43,12 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; public class EditConfig extends AbstractConfigNetconfOperation { @@ -71,14 +69,14 @@ public class EditConfig extends AbstractConfigNetconfOperation { @VisibleForTesting Element getResponseInternal(final Document document, - final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException { + final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException, NetconfConfigHandlingException { if (editConfigExecution.shouldTest()) { - executeTests(configRegistryClient, editConfigExecution); + executeTests(getConfigRegistryClient(), editConfigExecution); } if (editConfigExecution.shouldSet()) { - executeSet(configRegistryClient, editConfigExecution); + executeSet(getConfigRegistryClient(), editConfigExecution); } logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG); @@ -88,19 +86,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { private void executeSet(ConfigRegistryClient configRegistryClient, EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException { - try { - set(configRegistryClient, editConfigExecution); - - } catch (IllegalStateException e) { - //FIXME: when can IllegalStateException be thrown? - // JmxAttributeValidationException is wrapped in DynamicWritableWrapper with ValidationException - // ValidationException is not thrown until validate or commit is issued - logger.warn("Set phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage()); - throw new NetconfDocumentedException("Test phase: " + e.getMessage(), e, ErrorType.application, - ErrorTag.operation_failed, ErrorSeverity.error, errorInfo); - } + set(configRegistryClient, editConfigExecution); logger.debug("Set phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG); } @@ -108,8 +94,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { EditConfigExecution editConfigExecution) throws NetconfDocumentedException { try { test(configRegistryClient, editConfigExecution, editConfigExecution.getDefaultStrategy()); - } catch (IllegalStateException | ValidationException e) { - //FIXME: when can IllegalStateException be thrown? + } catch (final ValidationException e) { logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e); final Map errorInfo = new HashMap<>(); errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage()); @@ -120,10 +105,9 @@ public class EditConfig extends AbstractConfigNetconfOperation { } private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution, - EditStrategyType editStrategyType) throws ValidationException { + EditStrategyType editStrategyType) throws ValidationException, NetconfDocumentedException { ObjectName taON = transactionProvider.getTestTransaction(); try { - // default strategy = replace wipes config if (editStrategyType == EditStrategyType.replace) { transactionProvider.wipeTestTransaction(taON); @@ -141,7 +125,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { } private void set(ConfigRegistryClient configRegistryClient, - EditConfigXmlParser.EditConfigExecution editConfigExecution) { + EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException { ObjectName taON = transactionProvider.getOrCreateTransaction(); // default strategy = replace wipes config @@ -156,7 +140,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { setOnTransaction(ta, editConfigExecution); } - private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException { Services services = execution.getServices(); @@ -177,7 +161,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService, on, refName, saved); } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e); + throw new NetconfDocumentedException(String.format("Unable to save ref name " + refName + " for instance " + on, e), + ErrorType.application, + ErrorTag.operation_failed, + ErrorSeverity.error); } } } @@ -188,11 +175,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { return ta.getServiceInterfaceName(namespace, serviceName); } - private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) throws NetconfDocumentedException { for (Multimap modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - for (Entry moduleToResolved : modulesToResolved.entries()) { + for (Map.Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); ModuleElementResolved moduleElementResolved = moduleToResolved.getValue(); @@ -206,10 +193,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { } private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta, - EditConfigExecution execution) { + EditConfigExecution execution) throws NetconfDocumentedException { for (Multimap modulesToResolved : execution.getModulesDefinition(ta).values()) { - for (Entry moduleToResolved : modulesToResolved.entries()) { + for (Map.Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue(); @@ -237,7 +224,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { void addIdSchemaNode(IdentitySchemaNode node) { String name = node.getQName().getLocalName(); - Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false); + Preconditions.checkState(!identityNameToSchemaNode.containsKey(name)); identityNameToSchemaNode.put(name, node); } @@ -263,7 +250,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { } Date revision = module.getRevision(); - Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false, + Preconditions.checkState(!revisionsByNamespace.containsKey(revision), "Duplicate revision %s for namespace %s", revision, namespace); IdentityMapping identityMapping = revisionsByNamespace.get(revision); @@ -289,7 +276,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { Map> namespaceToModuleNameToModuleConfig = Maps.newHashMap(); for (String namespace : mBeanEntries.keySet()) { - for (Entry moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) { + for (Map.Entry moduleNameToMbe : mBeanEntries.get(namespace).entrySet()) { String moduleName = moduleNameToMbe.getKey(); ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue(); @@ -319,30 +306,12 @@ public class EditConfig extends AbstractConfigNetconfOperation { protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { EditConfigXmlParser.EditConfigExecution editConfigExecution; - Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot); - try { - editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient); - } catch (IllegalStateException e) { - logger.warn("Error parsing xml", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.missing_attribute.name(), "Error parsing xml: " + e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), ErrorType.rpc, ErrorTag.missing_attribute, - ErrorSeverity.error, errorInfo); - } catch (final IllegalArgumentException e) { - logger.warn("Error parsing xml", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), ErrorType.rpc, ErrorTag.bad_attribute, - ErrorSeverity.error, errorInfo); - } catch (final UnsupportedOperationException e) { - logger.warn("Unsupported", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for 'edit-config'"); - throw new NetconfDocumentedException(e.getMessage(), ErrorType.application, - ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo); - } + Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot); + editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, getConfigRegistryClient()); - return getResponseInternal(document, editConfigExecution); + Element responseInternal; + responseInternal = getResponseInternal(document, editConfigExecution); + return responseInternal; } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java index cebcb0239b..8538e40bcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; @@ -17,6 +18,6 @@ import java.util.Map; public interface EditConfigStrategy { void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, ServiceRegistryWrapper services); + ConfigTransactionClient ta, ServiceRegistryWrapper services) throws NetconfConfigHandlingException; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index e481bbe57f..547ffcda3d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -10,7 +10,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; -import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.util.ConfigRegistryClient; @@ -22,6 +21,8 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; @@ -55,15 +56,30 @@ public class EditConfigXmlParser { xml.checkName(EditConfigXmlParser.EDIT_CONFIG); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); - XmlElement targetElement = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY); - XmlElement targetChildNode = targetElement.getOnlyChildElementWithSameNamespace(); + + XmlElement targetElement = null; + XmlElement targetChildNode = null; + try { + targetElement = xml.getOnlyChildElementWithSameNamespace(EditConfigXmlParser.TARGET_KEY); + targetChildNode = targetElement.getOnlyChildElementWithSameNamespace(); + } catch (final MissingNameSpaceException | UnexpectedNamespaceException e) { + logger.trace("Can't get only child element with same namespace due to {}",e); + throw NetconfDocumentedException.wrap(e); + } String datastoreValue = targetChildNode.getName(); Datastore targetDatastore = Datastore.valueOf(datastoreValue); logger.debug("Setting {} to '{}'", EditConfigXmlParser.TARGET_KEY, targetDatastore); // check target - Preconditions.checkArgument(targetDatastore == Datastore.candidate, - "Only %s datastore supported for edit config but was: %s", Datastore.candidate, targetDatastore); + if (targetDatastore != Datastore.candidate){ + throw new NetconfDocumentedException(String.format( + "Only %s datastore supported for edit config but was: %s", + Datastore.candidate, + targetDatastore), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } // Test option TestOption testOption; @@ -82,9 +98,10 @@ public class EditConfigXmlParser { .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.ERROR_OPTION_KEY); if (errorOptionElement.isPresent()) { String errorOptionParsed = errorOptionElement.get().getTextContent(); - if (false == errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)) + 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 @@ -96,7 +113,13 @@ public class EditConfigXmlParser { editStrategyType = EditStrategyType.valueOf(mergeStrategyString); } - XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); + XmlElement configElement = null; + try { + configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); + } catch (MissingNameSpaceException e) { + logger.trace("Can't get only child element with same namespace due to {}",e); + throw NetconfDocumentedException.wrap(e); + } return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType); } @@ -134,7 +157,7 @@ public class EditConfigXmlParser { private final Config configResolver; private final XmlElement configElement; - EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) { + EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) throws NetconfDocumentedException { Config.checkUnrecognisedChildren(configElement); this.configResolver = configResolver; this.configElement = configElement; @@ -151,7 +174,7 @@ public class EditConfigXmlParser { return testOption == TestOption.set || testOption == TestOption.testThenSet; } - Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) { + Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException { return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } @@ -160,7 +183,7 @@ public class EditConfigXmlParser { return new ServiceRegistryWrapper(serviceRegistry); } - Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) { + Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) throws NetconfDocumentedException { return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 06560b2d27..6b81603dcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -9,6 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; import com.google.common.collect.Multimap; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; import java.util.EnumSet; import java.util.Set; @@ -40,7 +42,22 @@ public enum EditStrategyType { + this); } } + public static void compareParsedStrategyToDefaultEnforcing(EditStrategyType parsedStrategy, + EditStrategyType defaultStrategy) throws OperationNotPermittedException { + if (defaultStrategy.isEnforcing()) { + if (parsedStrategy != defaultStrategy){ + throw new OperationNotPermittedException(String.format("With " + + defaultStrategy + + " as " + + EditConfigXmlParser.DEFAULT_OPERATION_KEY + + " operations on module elements are not permitted since the default option is restrictive"), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } + } + } public EditConfigStrategy getFittingStrategy(Multimap providedServices) { switch (this) { case merge: @@ -48,7 +65,7 @@ public enum EditStrategyType { case replace: return new ReplaceEditConfigStrategy(providedServices); case delete: - return new DeleteEditConfigStrategy(providedServices); + return new DeleteEditConfigStrategy(); case remove: return new RemoveEditConfigStrategy(); case none: diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index f2e2b193a8..3e5707cf6d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -12,6 +12,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; @@ -38,18 +40,23 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services) { - throw new IllegalStateException( - "Unable to handle missing instance, no missing instances should appear at this point, missing: " - + module + ":" + instance); + String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { + throw new NetconfConfigHandlingException( + String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ", + module, + instance), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)) + namespaceToService.getValue(), on)){ continue; + } String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); @@ -59,11 +66,14 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { try { addRefNames(services, providedServices, ta, on); } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance was not found.",e), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } for (Entry configAttributeEntry : configuration.entrySet()) { @@ -79,8 +89,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { ta.setAttribute(on, ace.getJmxName(), new Attribute(ace.getJmxName(), value)); logger.debug("Attribute {} set to {} for {}", configAttributeEntry.getKey(), value, on); } catch (Exception e) { - throw new IllegalStateException("Unable to set attributes for " + on + ", Error with attribute " - + configAttributeEntry.getKey() + ":" + configAttributeEntry.getValue(), e); + throw new NetconfConfigHandlingException(String.format("Unable to set attributes for %s, Error with attribute %s : %s ", + on, + configAttributeEntry.getKey(), + configAttributeEntry.getValue()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java index 92e30f1617..c431766c4c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -9,6 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; @@ -24,13 +26,16 @@ public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services) { + String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { ObjectName on = null; try { on = ta.createModule(module, instance); logger.trace("New instance for {} {} created under name {}", module, instance, on); } catch (InstanceAlreadyExistsException e1) { - throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); + throw new NetconfConfigHandlingException(String.format("Unable to create instance for %s : %s.", module, instance), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index 4976244eae..bc3082ff50 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -12,6 +12,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; @@ -39,18 +41,23 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, ServiceRegistryWrapper services) { - throw new IllegalStateException( - "Unable to handle missing instance, no missing instances should appear at this point, missing: " - + module + ":" + instance); + String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { + throw new NetconfConfigHandlingException( + String.format("Unable to handle missing instance, no missing instances should appear at this point, missing: %s : %s ", + module, + instance), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)) + namespaceToService.getValue(), on)){ continue; + } String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); @@ -60,11 +67,14 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { try { addRefNames(services, providedServices, ta, on); } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance not found. ",on), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } for (Entry configAttributeEntry : configuration.entrySet()) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index f7fc029fcc..4665c2cc89 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -8,22 +8,12 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.get; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.management.ObjectName; - +import com.google.common.collect.Maps; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; @@ -33,7 +23,11 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtim import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; @@ -41,7 +35,10 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.collect.Maps; +import javax.management.ObjectName; +import java.util.List; +import java.util.Map; +import java.util.Set; public class Get extends AbstractConfigNetconfOperation { @@ -72,12 +69,14 @@ public class Get extends AbstractConfigNetconfOperation { RuntimeBeanEntry root = null; for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) { cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap())); - if (rbe.isRoot()) + if (rbe.isRoot()){ root = rbe; + } } - if (root == null) + if (root == null){ continue; + } InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache); ModuleRuntime moduleRuntime = new ModuleRuntime(module, rootInstanceRuntime); @@ -106,13 +105,14 @@ public class Get extends AbstractConfigNetconfOperation { return jmxToYangNamesForChildRbe; } - private static void checkXml(XmlElement xml) { + private static void checkXml(XmlElement xml) throws UnexpectedElementException, UnexpectedNamespaceException, MissingNameSpaceException { xml.checkName(XmlNetconfConstants.GET); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0) + if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + XmlNetconfConstants.GET); + } } @Override @@ -122,37 +122,23 @@ public class Get extends AbstractConfigNetconfOperation { @Override protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { - try { - checkXml(xml); - } catch (final IllegalArgumentException e) { - logger.warn("Error parsing xml", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute, - ErrorSeverity.error, errorInfo); - } catch (final UnsupportedOperationException e) { - logger.warn("Unsupported", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for 'get'"); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, - ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo); - } + checkXml(xml); - final Set runtimeBeans = configRegistryClient.lookupRuntimeBeans(); + final Set runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans(); //Transaction provider required only for candidate datastore final Set configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, null) - .queryInstances(configRegistryClient); + .queryInstances(getConfigRegistryClient()); - final Map> moduleRuntimes = createModuleRuntimes(configRegistryClient, + final Map> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap()); final Map> moduleConfigs = EditConfig.transformMbeToModuleConfigs( - configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); + getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap()); final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs); ObjectName txOn = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn); + ConfigTransactionClient ta = getConfigRegistryClient().getConfigTransactionClient(txOn); final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); logger.trace("{} operation successful", XmlNetconfConstants.GET); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index 05bba56611..82e07c1e7b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -8,18 +8,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; @@ -27,6 +19,9 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.Dat import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; @@ -35,7 +30,8 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; +import javax.management.ObjectName; +import java.util.Set; public class GetConfig extends AbstractConfigNetconfOperation { @@ -57,7 +53,8 @@ public class GetConfig extends AbstractConfigNetconfOperation { this.transactionProvider = transactionProvider; } - public static Datastore fromXml(XmlElement xml) { + public static Datastore fromXml(XmlElement xml) throws UnexpectedNamespaceException, UnexpectedElementException, MissingNameSpaceException, NetconfDocumentedException { + xml.checkName(GET_CONFIG); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); @@ -69,9 +66,10 @@ public class GetConfig extends AbstractConfigNetconfOperation { Datastore sourceDatastore = Datastore.valueOf(sourceParsed); // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0) + if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + GET_CONFIG); + } return sourceDatastore; @@ -106,27 +104,7 @@ public class GetConfig extends AbstractConfigNetconfOperation { @Override public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { Datastore source; - try { - source = fromXml(xml); - } catch (final IllegalArgumentException e) { - logger.warn("Rpc error: {}", ErrorTag.bad_attribute, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.bad_attribute, - ErrorSeverity.error, errorInfo); - } catch (final IllegalStateException e) { - logger.warn("Rpc error: {}", ErrorTag.missing_attribute, e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.missing_attribute.name(), "Missing datasource attribute value"); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.rpc, ErrorTag.missing_attribute, - ErrorSeverity.error, errorInfo); - } catch (final UnsupportedOperationException e) { - logger.warn("Unsupported", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(ErrorTag.operation_not_supported.name(), "Unsupported option for get"); - throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, - ErrorTag.operation_not_supported, ErrorSeverity.error, errorInfo); - } - return getResponseInternal(document, configRegistryClient, source); + source = fromXml(xml); + return getResponseInternal(document, getConfigRegistryClient(), source); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 8accbd591f..7790e09cee 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -8,11 +8,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc; -import java.util.Map; - -import javax.management.ObjectName; -import javax.management.openmbean.OpenType; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; @@ -31,6 +29,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.Abs import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; @@ -39,9 +38,9 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import javax.management.ObjectName; +import javax.management.openmbean.OpenType; +import java.util.Map; public class RuntimeRpc extends AbstractConfigNetconfOperation { @@ -56,7 +55,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { this.yangStoreSnapshot = yangStoreSnapshot; } - private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) { + private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) throws NetconfDocumentedException { AttributeMappingStrategy> mappingStrategy = new ObjectMapper(null).prepareStrategy(returnType); Optional mappedAttributeOpt = mappingStrategy.mapAttribute(result); Preconditions.checkState(mappedAttributeOpt.isPresent(), "Unable to map return value %s as %s", result, returnType.getOpenType()); @@ -94,7 +93,13 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { } public NetconfOperationExecution fromXml(final XmlElement xml) throws NetconfDocumentedException { - final String namespace = xml.getNamespace(); + final String namespace; + try { + namespace = xml.getNamespace(); + } catch (MissingNameSpaceException e) { + logger.trace("Can't get namespace from xml element due to {}",e); + throw NetconfDocumentedException.wrap(e); + } final XmlElement contextInstanceElement = xml.getOnlyChildElement(CONTEXT_INSTANCE); final String operationName = xml.getName(); @@ -117,18 +122,26 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { } @Override - public HandlingPriority canHandle(Document message) { - XmlElement requestElement = getRequestElementWithCheck(message); + public HandlingPriority canHandle(Document message) throws NetconfDocumentedException { + XmlElement requestElement = null; + requestElement = getRequestElementWithCheck(message); XmlElement operationElement = requestElement.getOnlyChildElement(); final String netconfOperationName = operationElement.getName(); - final String netconfOperationNamespace = operationElement.getNamespace(); + final String netconfOperationNamespace; + try { + netconfOperationNamespace = operationElement.getNamespace(); + } catch (MissingNameSpaceException e) { + logger.debug("Cannot retrieve netconf operation namespace from message due to {}", e); + return HandlingPriority.CANNOT_HANDLE; + } final Optional contextInstanceElement = operationElement .getOnlyChildElementOptionally(CONTEXT_INSTANCE); - if (contextInstanceElement.isPresent() == false) + if (!contextInstanceElement.isPresent()){ return HandlingPriority.CANNOT_HANDLE; + } final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get() .getTextContent(), netconfOperationName, netconfOperationNamespace); @@ -165,15 +178,12 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { @Override protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { - - // TODO exception handling // TODO check for namespaces and unknown elements - final NetconfOperationExecution execution = fromXml(xml); logger.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on, execution.attributes); - final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName, + final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName, execution.attributes); logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName, @@ -216,7 +226,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { for (XmlElement xmlElement : xml.getChildElements()) { final String name = xmlElement.getName(); - if (CONTEXT_INSTANCE.equals(name) == false) { // skip context + if (!CONTEXT_INSTANCE.equals(name)) { // skip context // instance child node // because it // specifies diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java index 0f0b1227a6..5cf7f30abc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java @@ -93,12 +93,12 @@ public final class RuntimeRpcElementResolved { RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint); PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"), - matcher.group("key2"), matcher.group("value2"), matcher.group("additional")); + matcher.group("value2"), matcher.group("additional")); String moduleName = groups.getModuleName(); String instanceName = groups.getInstanceName(); - HashMap additionalAttributes = groups.getAdditionalKeys(elementName, moduleName); + Map additionalAttributes = groups.getAdditionalKeys(elementName, moduleName); return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(), additionalAttributes); @@ -106,15 +106,14 @@ public final class RuntimeRpcElementResolved { private static final class PatternGroupResolver { - private final String key1, key2, value1, value2; + private final String key1, value1, value2; private final String additional; private String runtimeBeanYangName; - PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) { + PatternGroupResolver(String key1, String value1, String value2, String additional) { this.key1 = Preconditions.checkNotNull(key1); this.value1 = Preconditions.checkNotNull(value1); - this.key2 = Preconditions.checkNotNull(key2); this.value2 = Preconditions.checkNotNull(value2); this.additional = Preconditions.checkNotNull(additional); @@ -128,13 +127,14 @@ public final class RuntimeRpcElementResolved { return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2; } - HashMap getAdditionalKeys(String elementName, String moduleName) { + Map getAdditionalKeys(String elementName, String moduleName) { HashMap additionalAttributes = Maps.newHashMap(); runtimeBeanYangName = moduleName; for (String additionalKeyValue : additional.split("/")) { - if (Strings.isNullOrEmpty(additionalKeyValue)) + if (Strings.isNullOrEmpty(additionalKeyValue)){ continue; + } Matcher matcher = additionalPattern.matcher(additionalKeyValue); Preconditions .checkState( diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java index 421870ca36..3ba92b092e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java @@ -73,7 +73,7 @@ public class Activator implements BundleActivator { } @Override - public void stop(BundleContext context) throws Exception { + public void stop(BundleContext context) { if (configRegistryLookup != null) { configRegistryLookup.interrupt(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java index 09966b8c3b..7f4f8fccb5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java @@ -24,17 +24,11 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import java.util.Set; final class NetconfOperationProvider { - private final YangStoreSnapshot yangStoreSnapshot; private final Set operations; - private final ConfigRegistryClient configRegistryClient; - private final TransactionProvider transactionProvider; NetconfOperationProvider(YangStoreSnapshot yangStoreSnapshot, ConfigRegistryClient configRegistryClient, TransactionProvider transactionProvider, String netconfSessionIdForReporting) { - this.yangStoreSnapshot = yangStoreSnapshot; - this.configRegistryClient = configRegistryClient; - this.transactionProvider = transactionProvider; operations = setUpOperations(yangStoreSnapshot, configRegistryClient, transactionProvider, netconfSessionIdForReporting); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java index b8b7fcb47f..12469f66b7 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java @@ -52,7 +52,7 @@ public class NetconfOperationServiceFactoryImpl implements NetconfOperationServi Thread.sleep(ATTEMPT_TIMEOUT_MS); } catch (InterruptedException e1) { Thread.currentThread().interrupt(); - throw new RuntimeException("Interrupted while reattempting connection", e1); + throw new IllegalStateException("Interrupted while reattempting connection", e1); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java index c6248df41b..1069858b47 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java @@ -61,8 +61,9 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { for (Map moduleNameToMBE : moduleMXBeanEntryMap.values()) { for (ModuleMXBeanEntry moduleMXBeanEntry : moduleNameToMBE.values()) { String moduleSeenByYangStore = moduleMXBeanEntry.getYangModuleQName().toString(); - if(modulesSeenByConfig.contains(moduleSeenByYangStore) == false) + if(!modulesSeenByConfig.contains(moduleSeenByYangStore)){ missingModulesFromConfig.add(moduleSeenByYangStore); + } } } @@ -149,7 +150,7 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { } } - private static class YangStoreCapability extends BasicCapability { + private static final class YangStoreCapability extends BasicCapability { private final String content; private final String revision; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java index d7cbf6680d..250af688ea 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java @@ -15,6 +15,8 @@ import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.api.jmx.CommitStatus; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.NoTransactionFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,6 +34,7 @@ public class TransactionProvider implements AutoCloseable { private final String netconfSessionIdForReporting; private ObjectName transaction; private final List allOpenedTransactions = new ArrayList<>(); + private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session "; public TransactionProvider(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) { this.configRegistryClient = configRegistryClient; @@ -54,11 +57,12 @@ public class TransactionProvider implements AutoCloseable { public Optional getTransaction() { - if (transaction == null) + if (transaction == null){ return Optional.absent(); + } // Transaction was already closed somehow - if (isStillOpenTransaction(transaction) == false) { + if (!isStillOpenTransaction(transaction)) { logger.warn("Fixing illegal state: transaction {} was closed in {}", transaction, netconfSessionIdForReporting); transaction = null; @@ -68,8 +72,7 @@ public class TransactionProvider implements AutoCloseable { } private boolean isStillOpenTransaction(ObjectName transaction) { - boolean isStillOpenTransaction = configRegistryClient.getOpenConfigs().contains(transaction); - return isStillOpenTransaction; + return configRegistryClient.getOpenConfigs().contains(transaction); } public synchronized ObjectName getOrCreateTransaction() { @@ -94,9 +97,14 @@ public class TransactionProvider implements AutoCloseable { /** * Commit and notification send must be atomic */ - public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException { + public synchronized CommitStatus commitTransaction() throws ValidationException, ConflictingVersionException, NoTransactionFoundException { + if (!getTransaction().isPresent()){ + throw new NoTransactionFoundException("No transaction found for session " + netconfSessionIdForReporting, + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } final Optional maybeTaON = getTransaction(); - Preconditions.checkState(maybeTaON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); ObjectName taON = maybeTaON.get(); try { CommitStatus status = configRegistryClient.commitConfig(taON); @@ -119,7 +127,7 @@ public class TransactionProvider implements AutoCloseable { public synchronized void abortTransaction() { logger.debug("Aborting current transaction"); Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get()); transactionClient.abortConfig(); @@ -136,7 +144,7 @@ public class TransactionProvider implements AutoCloseable { public void validateTransaction() throws ValidationException { Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get()); transactionClient.validateConfig(); @@ -164,10 +172,11 @@ public class TransactionProvider implements AutoCloseable { try { transactionClient.destroyModule(instance); } catch (InstanceNotFoundException e) { - if (isTest) + if (isTest){ logger.debug("Unable to clean configuration in transactiom {}", taON, e); - else + } else { logger.warn("Unable to clean configuration in transactiom {}", taON, e); + } throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e); } @@ -180,7 +189,7 @@ public class TransactionProvider implements AutoCloseable { public void wipeTransaction() { Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); wipeInternal(taON.get(), false, null); } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index cd38d3babe..f151949abc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -8,39 +8,11 @@ package org.opendaylight.controller.netconf.confignetconfconnector; -import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; -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.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; -import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; - -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.Set; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; @@ -74,7 +46,6 @@ import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMX import org.opendaylight.controller.config.yang.test.impl.Peers; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit; import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; @@ -85,6 +56,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStore import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; @@ -111,11 +83,37 @@ import org.w3c.dom.Text; import org.w3c.dom.traversal.DocumentTraversal; import org.xml.sax.SAXException; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; +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.Set; + +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +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.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; +import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; public class NetconfMappingTest extends AbstractConfigTest { @@ -567,7 +565,7 @@ public class NetconfMappingTest extends AbstractConfigTest { assertThat(string, JUnitMatchers.containsString(substring)); } - private void checkEnum(final Document response) { + private void checkEnum(final Document response) throws NetconfDocumentedException { XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") .getOnlyChildElement("modules"); @@ -591,7 +589,7 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, testingDepsSize); } - private void checkTypeConfigAttribute(Document response) { + private void checkTypeConfigAttribute(Document response) throws NetconfDocumentedException { XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") .getOnlyChildElement("modules"); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index ae5a9930d2..4d9935eafb 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -20,7 +20,6 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; @@ -30,6 +29,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlUtil; @@ -104,7 +104,7 @@ public class EditConfigTest { any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); } - private EditConfigExecution mockExecution(EditConfigStrategy editStrat) { + private EditConfigExecution mockExecution(EditConfigStrategy editStrat) throws NetconfDocumentedException { EditConfigExecution mock = mock(EditConfigExecution.class); doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class)); doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class)); diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java index 1616857949..40a15be706 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java @@ -50,7 +50,7 @@ public class ConfigPersisterNotificationHandler implements Closeable { try { mBeanServerConnection.addNotificationListener(DefaultCommitOperationMXBean.OBJECT_NAME, listener, null, null); } catch (InstanceNotFoundException | IOException e) { - throw new RuntimeException("Cannot register as JMX listener to netconf", e); + throw new IllegalStateException("Cannot register as JMX listener to netconf", e); } } @@ -79,9 +79,8 @@ class ConfigPersisterNotificationListener implements NotificationListener { @Override public void handleNotification(Notification notification, Object handback) { - if (notification instanceof NetconfJMXNotification == false) { + if (!(notification instanceof NetconfJMXNotification)) return; - } // Socket should not be closed at this point // Activator unregisters this as JMX listener before close is called diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java index ed5a3a97a4..44e90270e7 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPusher.java @@ -59,7 +59,7 @@ public class ConfigPusher { this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis; } - public synchronized LinkedHashMap pushConfigs(List configs) { + public synchronized LinkedHashMap pushConfigs(List configs) throws NetconfDocumentedException { logger.debug("Last config snapshots to be pushed to netconf: {}", configs); LinkedHashMap result = new LinkedHashMap<>(); // start pushing snapshots: @@ -78,7 +78,7 @@ public class ConfigPusher { * is caught, whole process is retried - new service instance need to be obtained from the factory. Closes * {@link NetconfOperationService} after each use. */ - private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) { + private synchronized EditAndCommitResponse pushConfigWithConflictingVersionRetries(ConfigSnapshotHolder configSnapshotHolder) throws NetconfDocumentedException { ConflictingVersionException lastException; Stopwatch stopwatch = new Stopwatch().start(); do { @@ -139,7 +139,7 @@ public class ConfigPusher { } else { serviceCandidate.close(); logger.trace("Netconf server did not provide required capabilities for {} " + - "Expected but not found: {}, all expected {}, current {}", + "Expected but not found: {}, all expected {}, current {}", idForReporting, notFoundDiff, expectedCapabilities, serviceCandidate.getCapabilities() ); throw new NotEnoughCapabilitiesException("Not enough capabilities for " + idForReporting + ". Expected but not found: " + notFoundDiff); @@ -177,7 +177,7 @@ public class ConfigPusher { * @throws java.lang.RuntimeException if edit-config or commit fails otherwise */ private synchronized EditAndCommitResponse pushConfig(ConfigSnapshotHolder configSnapshotHolder, NetconfOperationService operationService) - throws ConflictingVersionException { + throws ConflictingVersionException, NetconfDocumentedException { Element xmlToBePersisted; try { @@ -209,7 +209,7 @@ public class ConfigPusher { return new EditAndCommitResponse(editResponseMessage, commitResponseMessage); } - private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) { + private NetconfOperation findOperation(NetconfMessage request, NetconfOperationService operationService) throws NetconfDocumentedException { TreeMap allOperations = new TreeMap<>(); Set netconfOperations = operationService.getNetconfOperations(); if (netconfOperations.isEmpty()) { @@ -228,7 +228,7 @@ public class ConfigPusher { private Document sendRequestGetResponseCheckIsOK(NetconfMessage request, NetconfOperationService operationService, String operationNameForReporting, String configIdForReporting) - throws ConflictingVersionException { + throws ConflictingVersionException, NetconfDocumentedException { NetconfOperation operation = findOperation(request, operationService); Document response; @@ -245,7 +245,7 @@ public class ConfigPusher { } // load editConfig.xml template, populate /rpc/edit-config/config with parameter - private static NetconfMessage createEditConfigMessage(Element dataElement) { + private static NetconfMessage createEditConfigMessage(Element dataElement) throws NetconfDocumentedException { String editConfigResourcePath = "/netconfOp/editConfig.xml"; try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcePath)) { Preconditions.checkNotNull(stream, "Unable to load resource " + editConfigResourcePath); diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java index 31a4f08036..a0e7974b94 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java @@ -9,20 +9,19 @@ package org.opendaylight.controller.netconf.persist.impl; import com.google.common.annotations.VisibleForTesting; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.api.Persister; +import org.opendaylight.controller.config.persist.api.PropertiesProvider; import org.opendaylight.controller.config.persist.api.StorageAdapter; import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator; -import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.ListIterator; - /** * {@link Persister} implementation that delegates persisting functionality to * underlying {@link Persister} storages. Each storage has unique id, class, readonly value. @@ -88,7 +87,7 @@ public final class PersisterAggregator implements Persister { } } - private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProviderBaseImpl propertiesProvider) { + private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProvider propertiesProvider) { String classKey = index + "." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX; String storageAdapterClass = propertiesProvider.getProperty(classKey); @@ -102,7 +101,7 @@ public final class PersisterAggregator implements Persister { try { Class clazz = Class.forName(storageAdapterClass); boolean implementsCorrectIfc = StorageAdapter.class.isAssignableFrom(clazz); - if (implementsCorrectIfc == false) { + if (!implementsCorrectIfc) { throw new IllegalArgumentException("Storage adapter " + clazz + " does not implement " + StorageAdapter.class); } storageAdapter = StorageAdapter.class.cast(clazz.newInstance()); @@ -131,10 +130,10 @@ public final class PersisterAggregator implements Persister { } - public static PersisterAggregator createFromProperties(PropertiesProviderBaseImpl propertiesProvider) { + public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) { List persisterWithConfigurations = new ArrayList<>(); String prefixes = propertiesProvider.getProperty("active"); - if (prefixes!=null && prefixes.isEmpty() == false) { + if (prefixes!=null && !prefixes.isEmpty()) { String [] keys = prefixes.split(","); for (String index: keys) { persisterWithConfigurations.add(PersisterAggregator.loadConfiguration(index, propertiesProvider)); @@ -169,7 +168,7 @@ public final class PersisterAggregator implements Persister { } catch (IOException e) { throw new RuntimeException("Error while calling loadLastConfig on " + persisterWithConfiguration, e); } - if (configs.isEmpty() == false) { + if (!configs.isEmpty()) { logger.debug("Found non empty configs using {}:{}", persisterWithConfiguration, configs); return configs; } diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java index d9466ff00b..238661f638 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java @@ -8,13 +8,12 @@ package org.opendaylight.controller.netconf.persist.impl; import org.opendaylight.controller.config.persist.api.PropertiesProvider; -import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl; public class PropertiesProviderAdapterImpl implements PropertiesProvider { - private final PropertiesProviderBaseImpl inner; + private final PropertiesProvider inner; private final String index; - public PropertiesProviderAdapterImpl(PropertiesProviderBaseImpl inner, String index) { + public PropertiesProviderAdapterImpl(PropertiesProvider inner, String index) { this.inner = inner; this.index = index; } @@ -29,6 +28,12 @@ public class PropertiesProviderAdapterImpl implements PropertiesProvider { return inner.getPrefix() + "." + index + ".properties"; } + @Override + public String getPropertyWithoutPrefix(String fullKey) { + return inner.getPropertyWithoutPrefix(fullKey); + } + + @Override public String getFullKeyForReporting(String key) { return getPrefix() + "." + key; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java index 0cc55719e1..1a261da323 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java @@ -10,6 +10,7 @@ package org.opendaylight.controller.netconf.persist.impl.osgi; import com.google.common.annotations.VisibleForTesting; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; @@ -151,7 +152,12 @@ public class ConfigPersisterActivator implements BundleActivator { final Thread pushingThread = new Thread(new Runnable() { @Override public void run() { - configPusher.pushConfigs(configs); + try { + configPusher.pushConfigs(configs); + } catch (NetconfDocumentedException e) { + logger.error("Error pushing configs {}",configs); + throw new IllegalStateException(e); + } logger.info("Configuration Persister initialization completed."); ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator); synchronized (ConfigPersisterActivator.this) { diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java index b1bf232928..e02e27a745 100644 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java +++ b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java @@ -81,7 +81,7 @@ public class ConfigPersisterTest { // this means pushing of config was successful public void assertCannotRegisterAsJMXListener_pushWasSuccessful() { - handler.assertException(RuntimeException.class, "Cannot register as JMX listener to netconf"); + handler.assertException(IllegalStateException.class, "Cannot register as JMX listener to netconf"); } public NetconfOperationService getWorkingService(Document document) throws SAXException, IOException, NetconfDocumentedException { diff --git a/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java index 0a084b0ff6..8e62a147d2 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java +++ b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java @@ -13,7 +13,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.mon /** **/ -public class LocationBuilder { +public final class LocationBuilder { public static Location getDefaultInstance(String defaultValue) { return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri( diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java index ceeca51def..57bd3dd620 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java @@ -90,6 +90,12 @@ public class NetconfDocumentedException extends Exception { this.errorInfo = errorInfo; } + public static NetconfDocumentedException wrap(E exception) throws NetconfDocumentedException { + final Map errorInfo = new HashMap<>(); + errorInfo.put(ErrorTag.operation_failed.name(), "Exception thrown"); + throw new NetconfDocumentedException(exception.getMessage(), exception, ErrorType.application, ErrorTag.operation_failed, + ErrorSeverity.error, errorInfo); + } public static NetconfDocumentedException wrap(ValidationException e) throws NetconfDocumentedException { final Map errorInfo = new HashMap<>(); errorInfo.put(ErrorTag.operation_failed.name(), "Validation failed"); diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java new file mode 100644 index 0000000000..d98211d0dd --- /dev/null +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java @@ -0,0 +1,171 @@ +/* + * 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.util.concurrent.Future; +import io.netty.util.concurrent.GlobalEventExecutor; + +import java.io.Closeable; +import java.io.IOException; +import java.net.InetSocketAddress; +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.protocol.framework.NeverReconnectStrategy; +import org.opendaylight.protocol.framework.ReconnectStrategy; +import org.opendaylight.protocol.framework.TimedReconnectStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Sets; + +/** + * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead. + */ +@Deprecated +public class NetconfClient implements Closeable { + + private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class); + + public static final int DEFAULT_CONNECT_TIMEOUT = 5000; + private final NetconfClientDispatcher dispatch; + private final String label; + private final NetconfClientSession clientSession; + private final NetconfClientSessionListener sessionListener; + private final long sessionId; + private final InetSocketAddress address; + + // TODO test reconnecting constructor + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts, + int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout), + netconfClientDispatcher); + } + + private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this.label = clientLabelForLogging; + dispatch = netconfClientDispatcher; + sessionListener = new SimpleNetconfClientSessionListener(); + Future clientFuture = dispatch.createClient(address, sessionListener, strat); + this.address = address; + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + + private NetconfClientSession get(Future 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 static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher); + } + + public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, + ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException { + return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, + new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, + DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, + NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{ + this.label = clientLabelForLogging; + dispatch = netconfClientDispatcher; + sessionListener = listener; + Future clientFuture = dispatch.createClient(address, sessionListener, strategy); + this.address = address; + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + + public Future sendRequest(NetconfMessage message) { + return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message); + } + + /** + * @deprecated Use {@link sendRequest} instead + */ + @Deprecated + public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException { + return sendMessage(message, 5, 1000); + } + + /** + * @deprecated Use {@link sendRequest} instead + */ + @Deprecated + public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException { + final Stopwatch stopwatch = new Stopwatch().start(); + + try { + return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS); + } finally { + stopwatch.stop(); + logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS)); + } + } + + @Override + public void close() throws IOException { + clientSession.close(); + } + + public NetconfClientDispatcher getNetconfClientDispatcher() { + return dispatch; + } + + private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) { + return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null, + Long.valueOf(connectionAttempts), null); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("NetconfClient{"); + sb.append("label=").append(label); + sb.append(", sessionId=").append(sessionId); + sb.append('}'); + return sb.toString(); + } + + public long getSessionId() { + return sessionId; + } + + public Set getCapabilities() { + Preconditions.checkState(clientSession != null, "Client was not initialized successfully"); + return Sets.newHashSet(clientSession.getServerCapabilities()); + } + + public NetconfClientSession getClientSession() { + return clientSession; + } +} diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java index 20da6aa869..c7c723cb27 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java @@ -79,7 +79,7 @@ public class NetconfClientDispatcher extends AbstractDispatcher { + private static final class ClientChannelInitializer extends AbstractChannelInitializer { private final NetconfClientSessionNegotiatorFactory negotiatorFactory; private final NetconfClientSessionListener sessionListener; diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java index 83f49b2635..f8f73fc8e5 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiator.java @@ -8,10 +8,15 @@ package org.opendaylight.controller.netconf.client; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; - +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 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.util.AbstractChannelInitializer; import org.opendaylight.controller.netconf.util.AbstractNetconfSessionNegotiator; @@ -26,13 +31,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -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 javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; public class NetconfClientSessionNegotiator extends AbstractNetconfSessionNegotiator @@ -54,14 +54,14 @@ public class NetconfClientSessionNegotiator extends } @Override - protected void handleMessage(NetconfHelloMessage netconfMessage) { + protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { NetconfClientSession session = super.getSessionForHelloMessage(netconfMessage); if (shouldUseExi(netconfMessage.getDocument())){ - logger.info("Netconf session: {} should use exi.", session); + logger.debug("Netconf session: {} should use exi.", session); tryToStartExi(session); } else { - logger.info("Netconf session {} isn't capable using exi.", session); + logger.debug("Netconf session {} isn't capable using exi.", session); negotiationSuccessful(session); } } @@ -109,7 +109,7 @@ public class NetconfClientSessionNegotiator extends } @Override - protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) { + protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException { return new NetconfClientSession(sessionListener, channel, extractSessionId(message.getDocument()), NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument())); } diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java index 07e088e117..7af1f01a08 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java @@ -8,7 +8,14 @@ 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.Channel; +import io.netty.util.Timer; +import io.netty.util.concurrent.Promise; 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.util.messages.NetconfHelloMessage; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader; @@ -20,20 +27,14 @@ 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 com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; - -import io.netty.channel.Channel; -import io.netty.util.Timer; -import io.netty.util.concurrent.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory { public static final java.util.Set CLIENT_CAPABILITIES = Sets.newHashSet( - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1, + 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 static final String START_EXI_MESSAGE_ID = "default-start-exi"; @@ -42,6 +43,7 @@ public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorF private final long connectionTimeoutMillis; private final Timer timer; private final EXIOptions options; + private static final Logger logger = LoggerFactory.getLogger(NetconfClientSessionNegotiatorFactory.class); public NetconfClientSessionNegotiatorFactory(Timer timer, Optional additionalHeader, @@ -64,7 +66,13 @@ public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorF Promise promise) { NetconfMessage startExiMessage = NetconfStartExiMessage.create(options, START_EXI_MESSAGE_ID); - NetconfHelloMessage helloMessage = NetconfHelloMessage.createClientHello(CLIENT_CAPABILITIES, additionalHeader); + NetconfHelloMessage helloMessage = null; + try { + helloMessage = NetconfHelloMessage.createClientHello(CLIENT_CAPABILITIES, additionalHeader); + } catch (NetconfDocumentedException e) { + logger.error("Unable to create client hello message with capabilities {} and additional handler {}",CLIENT_CAPABILITIES,additionalHeader); + throw new IllegalStateException(e); + } NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage,startExiMessage); return new NetconfClientSessionNegotiator(proposal, promise, channel, timer, diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java index 504e4c9949..524f0b52b7 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java @@ -26,8 +26,8 @@ import com.google.common.base.Preconditions; public class SimpleNetconfClientSessionListener implements NetconfClientSessionListener { private static final class RequestEntry { - final Promise promise; - final NetconfMessage request; + private final Promise promise; + private final NetconfMessage request; public RequestEntry(Promise future, NetconfMessage request) { this.promise = Preconditions.checkNotNull(future); diff --git a/opendaylight/netconf/netconf-impl/pom.xml b/opendaylight/netconf/netconf-impl/pom.xml index 9694a90c49..c62a85aae6 100644 --- a/opendaylight/netconf/netconf-impl/pom.xml +++ b/opendaylight/netconf/netconf-impl/pom.xml @@ -129,6 +129,7 @@ org.opendaylight.controller.netconf.util.mapping, org.opendaylight.controller.netconf.util.osgi, org.opendaylight.controller.netconf.util.xml, + org.opendaylight.controller.netconf.util.exception, org.opendaylight.controller.netconf.util.handler, org.opendaylight.protocol.framework, org.osgi.framework, diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 6a86ecd21f..91385bab33 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -68,12 +68,11 @@ public class CapabilityProviderImpl implements CapabilityProvider { final Set caps = netconfOperationService.getCapabilities(); for (Capability cap : caps) { - if (cap.getModuleName().isPresent() == false) - continue; - if (cap.getRevision().isPresent() == false) - continue; - if (cap.getCapabilitySchema().isPresent() == false) + if (!cap.getModuleName().isPresent() + || !cap.getRevision().isPresent() + || !cap.getCapabilitySchema().isPresent()){ continue; + } final String currentModuleName = cap.getModuleName().get(); Map revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java index 4461054437..6c7f9d9b2a 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java @@ -42,7 +42,7 @@ public class DefaultCommitNotificationProducer extends NotificationBroadcasterSu try { mbs.registerMBean(instance, on); } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) { - throw new RuntimeException("Unable to register " + instance + " as " + on, e); + throw new IllegalStateException("Unable to register " + instance + " as " + on, e); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index b3245fff2b..75be1f8fe0 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -9,6 +9,8 @@ package org.opendaylight.controller.netconf.impl; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; @@ -26,9 +28,6 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; - public class NetconfServerSessionListener implements NetconfSessionListener { static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class); @@ -97,8 +96,9 @@ public class NetconfServerSessionListener implements NetconfSessionListener { - private static final Set DEFAULT_CAPABILITIES = Sets.newHashSet( - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, - XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0); + private static final Set DEFAULT_BASE_CAPABILITIES = ImmutableSet.of( + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0 + // FIXME, Chunk framing causes ConcurrentClientsTest to fail, investigate +// XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1, + // FIXME, EXI causing issues with sal-netconf-connector, investigate +// XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 + ); private final Timer timer; @@ -42,10 +50,13 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF private final long connectionTimeoutMillis; private final DefaultCommitNotificationProducer commitNotificationProducer; private final SessionMonitoringService monitoringService; + private static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class); + // TODO too many params, refactor public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider, SessionIdProvider idProvider, long connectionTimeoutMillis, - DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) { + DefaultCommitNotificationProducer commitNot, + SessionMonitoringService monitoringService) { this.timer = timer; this.netconfOperationProvider = netconfOperationProvider; this.idProvider = idProvider; @@ -71,8 +82,14 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF getNetconfSessionIdForReporting(sessionId)); CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot); - NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences( - createHelloMessage(sessionId, capabilityProvider), sessionId); + NetconfServerSessionPreferences proposal = null; + try { + proposal = new NetconfServerSessionPreferences( + createHelloMessage(sessionId, capabilityProvider), sessionId); + } catch (NetconfDocumentedException e) { + logger.error("Unable to create hello mesage for session {} with capability provider {}", sessionId,capabilityProvider); + throw new IllegalStateException(e); + } NetconfServerSessionListenerFactory sessionListenerFactory = new NetconfServerSessionListenerFactory( commitNotificationProducer, monitoringService, @@ -82,8 +99,8 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF sessionListenerFactory.getSessionListener(), connectionTimeoutMillis); } - private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) { - return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_CAPABILITIES), sessionId); + private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) throws NetconfDocumentedException { + return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_BASE_CAPABILITIES), sessionId); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java index 1a9f5d7393..d4545430b4 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java @@ -8,9 +8,7 @@ package org.opendaylight.controller.netconf.impl.mapping.operations; -import java.io.InputStream; -import java.util.Map; - +import com.google.common.base.Preconditions; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; @@ -26,8 +24,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import java.io.InputStream; public class DefaultCommit extends AbstractNetconfOperation { @@ -67,14 +64,14 @@ public class DefaultCommit extends AbstractNetconfOperation { @Override public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false, + Preconditions.checkArgument(!subsequentOperation.isExecutionTermination(), "Subsequent netconf operation expected by %s", this); if (isCommitWithoutNotification(requestMessage)) { logger.debug("Skipping commit notification"); } else { // Send commit notification if commit was not issued by persister - requestMessage = removePersisterAttributes(requestMessage); + removePersisterAttributes(requestMessage); Element cfgSnapshot = getConfigSnapshot(operationRouter); logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot); notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities()); @@ -93,21 +90,25 @@ public class DefaultCommit extends AbstractNetconfOperation { return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1); } - private Document removePersisterAttributes(Document message) { - final Element documentElement = message.getDocumentElement(); - documentElement.removeAttribute(NOTIFY_ATTR); - return message; + private void removePersisterAttributes(Document message) { + message.getDocumentElement().removeAttribute(NOTIFY_ATTR); } private boolean isCommitWithoutNotification(Document message) { - XmlElement xmlElement = XmlElement.fromDomElementWithExpected(message.getDocumentElement(), - XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + XmlElement xmlElement = null; + try { + xmlElement = XmlElement.fromDomElementWithExpected(message.getDocumentElement(), + XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + } catch (NetconfDocumentedException e) { + logger.trace("Commit operation is not valid due to {}",e); + return false; + } String attr = xmlElement.getAttribute(NOTIFY_ATTR); - if (attr == null || attr.equals("")) + if (attr == null || attr.equals("")){ return false; - else if (attr.equals(Boolean.toString(false))) { + } else if (attr.equals(Boolean.toString(false))) { logger.debug("Commit operation received with notify=false attribute {}", message); return true; } else { @@ -120,20 +121,9 @@ public class DefaultCommit extends AbstractNetconfOperation { getConfigMessage, null); XmlElement dataElement; - try { - XmlElement xmlElement = XmlElement.fromDomElementWithExpected(responseDocument.getDocumentElement(), - XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); - dataElement = xmlElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY); - } catch (IllegalArgumentException e) { - final String msg = "Unexpected response from get-config operation"; - logger.warn(msg, e); - Map info = Maps.newHashMap(); - info.put(NetconfDocumentedException.ErrorTag.operation_failed.toString(), e.getMessage()); - throw new NetconfDocumentedException(msg, e, NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.operation_failed, - NetconfDocumentedException.ErrorSeverity.error, info); - } - + XmlElement xmlElement = XmlElement.fromDomElementWithExpected(responseDocument.getDocumentElement(), + XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + dataElement = xmlElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY); return dataElement.getDomElement(); } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java index f50dd3e706..beceb8d008 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java @@ -8,11 +8,11 @@ package org.opendaylight.controller.netconf.impl.mapping.operations; -import java.util.HashMap; -import java.util.Map; - +import com.google.common.base.Optional; +import com.google.common.collect.Maps; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -22,8 +22,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.collect.Maps; +import java.util.Map; public final class DefaultGetSchema extends AbstractLastNetconfOperation { public static final String GET_SCHEMA = "get-schema"; @@ -52,23 +51,7 @@ public final class DefaultGetSchema extends AbstractLastNetconfOperation { protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { GetSchemaEntry entry; - try { - entry = new GetSchemaEntry(xml); - } catch (final IllegalArgumentException e) { - logger.warn("Error parsing xml", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(NetconfDocumentedException.ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, NetconfDocumentedException.ErrorType.rpc, - NetconfDocumentedException.ErrorTag.bad_attribute, NetconfDocumentedException.ErrorSeverity.error, - errorInfo); - } catch (final IllegalStateException e) { - logger.warn("Error parsing xml", e); - final Map errorInfo = new HashMap<>(); - errorInfo.put(NetconfDocumentedException.ErrorTag.bad_attribute.name(), e.getMessage()); - throw new NetconfDocumentedException(e.getMessage(), e, NetconfDocumentedException.ErrorType.rpc, - NetconfDocumentedException.ErrorTag.bad_attribute, NetconfDocumentedException.ErrorSeverity.error, - errorInfo); - } + entry = new GetSchemaEntry(xml); String schema; try { @@ -94,11 +77,17 @@ public final class DefaultGetSchema extends AbstractLastNetconfOperation { private final String identifier; private final Optional version; - GetSchemaEntry(XmlElement getSchemaElement) { + GetSchemaEntry(XmlElement getSchemaElement) throws NetconfDocumentedException { getSchemaElement.checkName(GET_SCHEMA); getSchemaElement.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING); - XmlElement identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER); + XmlElement identifierElement = null; + try { + identifierElement = getSchemaElement.getOnlyChildElementWithSameNamespace(IDENTIFIER); + } catch (MissingNameSpaceException e) { + logger.trace("Can't get identifier element as only child element with same namespace due to {}",e); + throw NetconfDocumentedException.wrap(e); + } identifier = identifierElement.getTextContent(); Optional versionElement = getSchemaElement .getOnlyChildElementWithSameNamespaceOptionally(VERSION); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java index bbd07e42bf..303047df12 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java @@ -39,7 +39,7 @@ public class NetconfImplActivator implements BundleActivator { private ServiceRegistration regMonitoring; @Override - public void start(final BundleContext context) throws Exception { + public void start(final BundleContext context) { InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context, "TCP is not configured, netconf not available.", false); @@ -85,7 +85,7 @@ public class NetconfImplActivator implements BundleActivator { } @Override - public void stop(final BundleContext context) throws Exception { + public void stop(final BundleContext context) { logger.info("Shutting down netconf because YangStoreService service was removed"); commitNot.close(); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index a7560fadb6..81fac5f12f 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -51,7 +51,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public void onSessionUp(NetconfManagementSession session) { logger.debug("Session {} up", session); - Preconditions.checkState(sessions.contains(session) == false, "Session %s was already added", session); + Preconditions.checkState(!sessions.contains(session), "Session %s was already added", session); sessions.add(session); } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index bb4c76a4b8..ff96ad779f 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -17,9 +17,9 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultGetSchema; +import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStartExi; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopExi; -import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; @@ -33,6 +33,7 @@ import org.w3c.dom.Document; import java.util.Collections; import java.util.HashSet; import java.util.Map; +import java.util.NavigableMap; import java.util.Set; import java.util.TreeMap; @@ -83,7 +84,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) { final Set netOpsFromService = netconfOperationService.getNetconfOperations(); for (NetconfOperation netconfOperation : netOpsFromService) { - Preconditions.checkState(result.contains(netconfOperation) == false, + Preconditions.checkState(!result.contains(netconfOperation), "Netconf operation %s already present", netconfOperation); result.add(netconfOperation); } @@ -97,9 +98,10 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly"); NetconfOperationExecution netconfOperationExecution; - String messageAsString = XmlUtil.toString(message); + String messageAsString = ""; try { + messageAsString = XmlUtil.toString(message); netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session); } catch (IllegalArgumentException | IllegalStateException e) { logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e); @@ -153,9 +155,9 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } private NetconfOperationExecution getNetconfOperationWithHighestPriority( - Document message, NetconfServerSession session) { + Document message, NetconfServerSession session) throws NetconfDocumentedException { - TreeMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( + NavigableMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( message, session); Preconditions.checkArgument(sortedByPriority.isEmpty() == false, @@ -166,7 +168,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } private TreeMap getSortedNetconfOperationsWithCanHandle(Document message, - NetconfServerSession session) { + NetconfServerSession session) throws NetconfDocumentedException { TreeMap sortedPriority = Maps.newTreeMap(); for (NetconfOperation netconfOperation : allNetconfOperations) { @@ -174,9 +176,9 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { if (netconfOperation instanceof DefaultNetconfOperation) { ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session); } - if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) { + if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) { - Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false, + Preconditions.checkState(!sortedPriority.containsKey(handlingPriority), "Multiple %s available to handle message %s with priority %s", NetconfOperation.class.getName(), message, handlingPriority); sortedPriority.put(handlingPriority, netconfOperation); @@ -185,6 +187,21 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { return sortedPriority; } + public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() { + @Override + public boolean isExecutionTermination() { + return true; + } + + @Override + public Document execute(Document requestMessage) throws NetconfDocumentedException { + throw new NetconfDocumentedException("This execution represents the termination point in operation execution and cannot be executed itself", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } + }; + private static class NetconfOperationExecution implements NetconfOperationChainedExecution { private final NetconfOperation netconfOperation; private NetconfOperationChainedExecution subsequentExecution; @@ -205,7 +222,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } public static NetconfOperationExecution createExecutionChain( - TreeMap sortedByPriority, HandlingPriority handlingPriority) { + NavigableMap sortedByPriority, HandlingPriority handlingPriority) { NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority); HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java index db5a359d7a..02889b62a5 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java @@ -8,20 +8,31 @@ package org.opendaylight.controller.netconf.impl; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; -import io.netty.channel.ChannelFuture; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.util.HashedWheelTimer; +import static com.google.common.base.Preconditions.checkNotNull; +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 java.io.DataOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.management.ManagementFactory; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; @@ -31,28 +42,20 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader; +import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import java.io.DataOutputStream; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; -import static com.google.common.base.Preconditions.checkNotNull; -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 io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.util.HashedWheelTimer; public class ConcurrentClientsTest { @@ -90,13 +93,12 @@ public class ConcurrentClientsTest { SessionIdProvider idProvider = new SessionIdProvider(); hashedWheelTimer = new HashedWheelTimer(); + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService()); commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - - NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory); dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup); @@ -125,7 +127,9 @@ public class ConcurrentClientsTest { return Sets. newHashSet(new NetconfOperation() { @Override public HandlingPriority canHandle(Document message) { - return HandlingPriority.getHandlingPriority(Integer.MAX_VALUE); + return XmlUtil.toString(message).contains(NetconfStartExiMessage.START_EXI) ? + HandlingPriority.CANNOT_HANDLE : + HandlingPriority.HANDLE_WITH_MAX_PRIORITY; } @Override @@ -152,7 +156,7 @@ public class ConcurrentClientsTest { commitNot.close(); } - @Test + @Test(timeout = 30 * 1000) public void multipleClients() throws Exception { List threads = new ArrayList<>(); @@ -173,12 +177,12 @@ public class ConcurrentClientsTest { } } - @Test + @Test(timeout = 30 * 1000) public void synchronizationTest() throws Exception { new BlockingThread("foo").run2(); } - @Test + @Test(timeout = 30 * 1000) public void multipleBlockingClients() throws Exception { List threads = new ArrayList<>(); for (int i = 0; i < CONCURRENCY; i++) { diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index d169858d35..634a18f852 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -22,16 +22,17 @@ import org.junit.Test; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory; 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.TestImplModuleFactory; import org.opendaylight.controller.netconf.StubUserManager; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; @@ -321,17 +322,17 @@ public class NetconfITTest extends AbstractNetconfConfigTest { } } - private void assertIsOK(final Document rpcReply) { + private void assertIsOK(final Document rpcReply) throws NetconfDocumentedException { assertEquals("rpc-reply", rpcReply.getDocumentElement().getLocalName()); assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName()); } - private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException { + private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException { return assertGetConfigWorks(netconfClient, this.getConfig); } private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage) - throws InterruptedException, ExecutionException, TimeoutException { + throws InterruptedException, ExecutionException, TimeoutException, NetconfDocumentedException { final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage); assertNotNull(rpcReply); assertEquals("data", XmlElement.fromDomDocument(rpcReply.getDocument()).getOnlyChildElement().getName()); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 92caea17d5..8d9e839ee7 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -17,12 +17,12 @@ import org.junit.Test; import org.mockito.Mock; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java index 05122be4d2..c08db906df 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java @@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.mapping.api; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -public class HandlingPriority implements Comparable { +public final class HandlingPriority implements Comparable { public static final HandlingPriority CANNOT_HANDLE = new HandlingPriority(); public static final HandlingPriority HANDLE_WITH_DEFAULT_PRIORITY = new HandlingPriority(Integer.MIN_VALUE); @@ -51,34 +51,42 @@ public class HandlingPriority implements Comparable { @Override public int compareTo(HandlingPriority o) { - if (this == o) + if (this == o){ return 0; - if (this == CANNOT_HANDLE) + } + if (this.equals(CANNOT_HANDLE)){ return -1; - if (o == CANNOT_HANDLE) + } + if (o.equals(CANNOT_HANDLE)){ return 1; + } - if (priority > o.priority) + if (priority > o.priority){ return 1; - if (priority == o.priority) + } + if (priority.equals(o.priority)){ return 0; - if (priority < o.priority) + } + if (priority < o.priority){ return -1; - + } throw new IllegalStateException("Unexpected state"); } @Override public boolean equals(Object o) { - if (this == o) + if (this == o){ return true; - if (!(o instanceof HandlingPriority)) + } + if (!(o instanceof HandlingPriority)){ return false; + } HandlingPriority that = (HandlingPriority) o; - if (priority != null ? !priority.equals(that.priority) : that.priority != null) + if (priority != null ? !priority.equals(that.priority) : that.priority != null){ return false; + } return true; } diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java index b70f8dbd39..c7298cbf1e 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java @@ -33,7 +33,7 @@ public interface NetconfOperation { * @param requestMessage * @return */ - HandlingPriority canHandle(Document requestMessage); + HandlingPriority canHandle(Document message) throws NetconfDocumentedException; /** * Execute current netconf operation and trigger execution of subsequent diff --git a/opendaylight/netconf/netconf-monitoring/pom.xml b/opendaylight/netconf/netconf-monitoring/pom.xml index 6730ccbb54..03193b8492 100644 --- a/opendaylight/netconf/netconf-monitoring/pom.xml +++ b/opendaylight/netconf/netconf-monitoring/pom.xml @@ -58,6 +58,7 @@ org.opendaylight.controller.netconf.api, org.opendaylight.controller.netconf.mapping.api, org.opendaylight.controller.netconf.util.mapping, + org.opendaylight.controller.netconf.util.exception, org.osgi.framework, org.slf4j, org.w3c.dom, diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java index 08da36148f..c277e20553 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java @@ -7,8 +7,7 @@ */ package org.opendaylight.controller.netconf.monitoring; -import java.util.Map; - +import com.google.common.collect.Maps; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; @@ -24,8 +23,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import java.util.Map; public class Get extends AbstractNetconfOperation { @@ -37,10 +35,11 @@ public class Get extends AbstractNetconfOperation { this.netconfMonitor = netconfMonitor; } - private Element getPlaceholder(Document innerResult) { + private Element getPlaceholder(Document innerResult) throws NetconfDocumentedException { try { - XmlElement rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(), - XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + XmlElement rootElement = null; + rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(), + XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE); return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement(); } catch (RuntimeException e) { throw new IllegalArgumentException(String.format( @@ -63,8 +62,12 @@ public class Get extends AbstractNetconfOperation { @Override public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false, - "Subsequent netconf operation expected by %s", this); + if (subsequentOperation.isExecutionTermination()){ + throw new NetconfDocumentedException(String.format("Subsequent netconf operation expected by %s", this), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } try { Document innerResult = subsequentOperation.execute(requestMessage); diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java index 200cd344a6..d14464d667 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java @@ -7,8 +7,11 @@ */ package org.opendaylight.controller.netconf.monitoring; -public class MonitoringConstants { +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"; diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java index de04484d13..14c47352a8 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java @@ -21,14 +21,14 @@ public class NetconfMonitoringActivator implements BundleActivator { private NetconfMonitoringServiceTracker monitor; @Override - public void start(final BundleContext context) throws Exception { + public void start(final BundleContext context) { monitor = new NetconfMonitoringServiceTracker(context); monitor.open(); } @Override - public void stop(final BundleContext context) throws Exception { + public void stop(final BundleContext context) { if(monitor!=null) { try { monitor.close(); diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java index a42bc09591..731aad6d1a 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java @@ -7,30 +7,20 @@ */ package org.opendaylight.controller.netconf.monitoring.osgi; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.HashSet; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import java.util.List; import java.util.Set; - import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; 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.MonitoringConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas; - -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; -import com.google.common.io.Files; public class NetconfMonitoringOperationService implements NetconfOperationService { - public static final HashSet CAPABILITIES = Sets.newHashSet(new Capability() { + public static final Set CAPABILITIES = Sets.newHashSet(new Capability() { @Override public String getCapabilityUri() { @@ -69,18 +59,6 @@ public class NetconfMonitoringOperationService implements NetconfOperationServic this.monitor = monitor; } - private static String readSchema() { - String schemaLocation = "/META-INF/yang/ietf-netconf-monitoring.yang"; - URL resource = Schemas.class.getClassLoader().getResource(schemaLocation); - Preconditions.checkNotNull(resource, "Unable to read schema content from %s", schemaLocation); - File file = new File(resource.getFile()); - try { - return Files.toString(file, Charsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException("Unable to load schema from " + schemaLocation, e); - } - } - @Override public Set getCapabilities() { return CAPABILITIES; diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java index 45807a8333..51054dd938 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java @@ -7,19 +7,20 @@ */ package org.opendaylight.controller.netconf.ssh; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.util.concurrent.atomic.AtomicLong; -import javax.annotation.concurrent.ThreadSafe; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; import org.opendaylight.controller.netconf.ssh.threads.SocketThread; import org.opendaylight.controller.usermanager.IUserManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.concurrent.ThreadSafe; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.concurrent.atomic.AtomicLong; + @ThreadSafe -public class NetconfSSHServer implements Runnable { +public final class NetconfSSHServer implements Runnable { private ServerSocket ss = null; private static final Logger logger = LoggerFactory.getLogger(NetconfSSHServer.class); @@ -28,12 +29,12 @@ public class NetconfSSHServer implements Runnable { private final AuthProvider authProvider; private boolean up = false; - private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{ + private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException { logger.trace("Creating SSH server socket on port {}",serverPort); this.ss = new ServerSocket(serverPort); if (!ss.isBound()){ - throw new Exception("Socket can't be bound to requested port :"+serverPort); + throw new IllegalStateException("Socket can't be bound to requested port :"+serverPort); } logger.trace("Server socket created."); this.clientAddress = clientAddress; @@ -41,11 +42,11 @@ public class NetconfSSHServer implements Runnable { this.up = true; } - public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception { + public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws IllegalStateException, IOException { return new NetconfSSHServer(serverPort, clientAddress,authProvider); } - public void stop() throws Exception { + public void stop() throws IOException { up = false; logger.trace("Closing SSH server socket."); ss.close(); @@ -69,7 +70,7 @@ public class NetconfSSHServer implements Runnable { try { SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(),authProvider); } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + logger.error("Exception occurred during socket thread initialization {}",e); } } } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index 2d380482ba..6ddc8ebb55 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -38,9 +38,9 @@ public class AuthProvider implements AuthProviderInterface { } @Override - public boolean authenticated(String username, String password) throws Exception { + public boolean authenticated(String username, String password) { if (AuthProvider.um == null) { - throw new Exception("No usermanager service available."); + throw new IllegalStateException("No usermanager service available."); } AuthResultEnum authResult = AuthProvider.um.authenticate(username, password); return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java index 8e40578a0e..fad0f79a4e 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java @@ -12,7 +12,7 @@ import org.opendaylight.controller.usermanager.IUserManager; public interface AuthProviderInterface { - public boolean authenticated(String username, String password) throws Exception; + public boolean authenticated(String username, String password) throws IllegalStateException; public char[] getPEMAsCharArray() throws Exception; public void removeUserManagerService(); public void addUserManagerService(IUserManager userManagerService); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java index 112bf67f69..5b8803001c 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java @@ -45,7 +45,7 @@ public class NetconfSSHActivator implements BundleActivator{ private IUserManager iUserManager; private BundleContext context = null; - ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ + private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ @Override public IUserManager addingService(ServiceReference reference) { logger.trace("Service {} added, let there be SSH bridge.", reference); @@ -72,19 +72,19 @@ public class NetconfSSHActivator implements BundleActivator{ @Override - public void start(BundleContext context) throws Exception { + public void start(BundleContext context) { this.context = context; listenForManagerService(); } @Override - public void stop(BundleContext context) throws Exception { + public void stop(BundleContext context) throws IOException { if (server != null){ server.stop(); logger.trace("Netconf SSH bridge is down ..."); } } - private void startSSHServer() throws Exception { + private void startSSHServer() throws IllegalStateException, IOException { logger.trace("Starting netconf SSH bridge."); Optional sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE); InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context, @@ -94,14 +94,18 @@ public class NetconfSSHActivator implements BundleActivator{ String path = NetconfConfigUtil.getPrivateKeyPath(context); path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator? if (path.equals("")){ - throw new Exception("Missing netconf.ssh.pk.path key in configuration file."); + throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file."); } File privateKeyFile = new File(path); - String privateKeyPEMString; + String privateKeyPEMString = null; if (privateKeyFile.exists() == false) { // generate & save to file - privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); + try { + privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); + } catch (Exception e) { + logger.error("Exception occured while generating PEM string {}",e); + } } else { // read from file try (FileInputStream fis = new FileInputStream(path)) { @@ -111,7 +115,12 @@ public class NetconfSSHActivator implements BundleActivator{ throw new IllegalStateException("Error reading RSA key from file " + path); } } - AuthProvider authProvider = new AuthProvider(iUserManager, privateKeyPEMString); + AuthProvider authProvider = null; + try { + authProvider = new AuthProvider(iUserManager, privateKeyPEMString); + } catch (Exception e) { + logger.error("Error instantiating AuthProvider {}",e); + } this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider); Thread serverThread = new Thread(server,"netconf SSH server thread"); @@ -120,10 +129,10 @@ public class NetconfSSHActivator implements BundleActivator{ logger.trace("Netconf SSH bridge up and running."); } else { logger.trace("No valid connection configuration for SSH bridge found."); - throw new Exception("No valid connection configuration for SSH bridge found."); + throw new IllegalStateException("No valid connection configuration for SSH bridge found."); } } - private void onUserManagerFound(IUserManager userManager) throws Exception{ + private void onUserManagerFound(IUserManager userManager) throws IOException { if (server!=null && server.isUp()){ server.addUserManagerService(userManager); } else { diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java index ce26910b97..d6566c8ffa 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java @@ -112,18 +112,18 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser if (netconf_ssh_input != null) { netconf_ssh_input.join(); } - } catch (InterruptedException e) { + } catch (InterruptedException e1) { Thread.currentThread().interrupt(); - logger.error("netconf_ssh_input join error ", e); + logger.error("netconf_ssh_input join error ", e1); } try { if (netconf_ssh_output != null) { netconf_ssh_output.join(); } - } catch (InterruptedException e) { + } catch (InterruptedException e2) { Thread.currentThread().interrupt(); - logger.error("netconf_ssh_output join error ", e); + logger.error("netconf_ssh_output join error ", e2); } } } else { diff --git a/opendaylight/netconf/netconf-util/pom.xml b/opendaylight/netconf/netconf-util/pom.xml index 25db5f3f42..65d2954afd 100644 --- a/opendaylight/netconf/netconf-util/pom.xml +++ b/opendaylight/netconf/netconf-util/pom.xml @@ -77,7 +77,8 @@ org.opendaylight.controller.netconf.util.mapping, org.opendaylight.controller.netconf.util.messages, org.opendaylight.controller.netconf.util.handler, - org.opendaylight.controller.netconf.util.handler.*, + org.opendaylight.controller.netconf.util.handler.*, + org.opendaylight.controller.netconf.util.exception, com.google.common.base, com.google.common.collect, ch.ethz.ssh2, diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java index 270af3505f..aa1afc025d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java @@ -61,7 +61,7 @@ public abstract class AbstractNetconfSession { } @Override - protected void handleMessage(NetconfHelloMessage netconfMessage) { - S session = getSessionForHelloMessage(netconfMessage); + protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { + S session = getSessionForHelloMessage(netconfMessage) ; negotiationSuccessful(session); } - protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) { + protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { Preconditions.checkNotNull(netconfMessage, "netconfMessage"); final Document doc = netconfMessage.getDocument(); @@ -180,7 +181,7 @@ extends AbstractSessionNegotiator { return channel.pipeline().replace(handlerKey, handlerKey, decoder); } - protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message); + protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException; protected synchronized void changeState(final State newState) { logger.debug("Changing state from : {} to : {}", state, newState); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java index 29f40ce624..9443f93f92 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/NetconfUtil.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.util; import com.google.common.base.Preconditions; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -52,11 +53,7 @@ public final class NetconfUtil { return (doc == null) ? null : new NetconfMessage(doc); } - public static Document checkIsMessageOk(NetconfMessage responseMessage) { - return checkIsMessageOk(responseMessage.getDocument()); - } - - public static Document checkIsMessageOk(Document response) { + public static Document checkIsMessageOk(Document response) throws NetconfDocumentedException { XmlElement element = XmlElement.fromDomDocument(response); Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY)); element = element.getOnlyChildElement(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java new file mode 100644 index 0000000000..0a3e0b3ec3 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/MissingNameSpaceException.java @@ -0,0 +1,26 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class MissingNameSpaceException extends NetconfDocumentedException { + + public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); + } + + public MissingNameSpaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } +} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java new file mode 100644 index 0000000000..b470ce13a8 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedElementException.java @@ -0,0 +1,26 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class UnexpectedElementException extends NetconfDocumentedException { + + public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); + } + + public UnexpectedElementException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } +} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java new file mode 100644 index 0000000000..50d7670780 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/exception/UnexpectedNamespaceException.java @@ -0,0 +1,26 @@ +/* + * 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.exception; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; + +import java.util.Collections; +import java.util.Map; + +public class UnexpectedNamespaceException extends NetconfDocumentedException { + + public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity) { + this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); + } + + public UnexpectedNamespaceException(final String message, final ErrorType errorType, final ErrorTag errorTag, + final ErrorSeverity errorSeverity, final Map errorInfo){ + super(message,errorType,errorTag,errorSeverity,errorInfo); + } +} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java index ccc80a7b71..8f4590cbb1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java @@ -40,7 +40,7 @@ public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder chunkSize) { ByteBuf chunk = Unpooled.buffer(chunkSize); chunk.writeBytes(createChunkHeader(chunkSize)); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java index a3efe8a16b..8df62a6702 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java @@ -16,7 +16,7 @@ import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants public class EOMFramingMechanismEncoder extends MessageToByteEncoder { @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { out.writeBytes(msg); out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java index 1f7a32dc70..bac83e49d3 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java @@ -15,11 +15,13 @@ import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.MessageToByteEncoder; -public class FramingMechanismHandlerFactory { +public final class FramingMechanismHandlerFactory { private static final Logger logger = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class); - private FramingMechanismHandlerFactory() {} + private FramingMechanismHandlerFactory() { + // not called - private constructor for utility class + } public static MessageToByteEncoder createHandler(FramingMechanism framingMechanism) { logger.debug("{} framing mechanism was selected.", framingMechanism); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java index 219e92c3f1..9f9f4191f7 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java @@ -21,6 +21,8 @@ import io.netty.handler.codec.ByteToMessageDecoder; public class NetconfChunkAggregator extends ByteToMessageDecoder { private final static Logger logger = 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 { @@ -40,17 +42,35 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { private long chunkSize; private CompositeByteBuf chunk; + private void checkNewLine(byte b,String errorMessage){ + if (b != '\n') { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n'); + throw new IllegalStateException(errorMessage); + } + } + + private void checkHash(byte b,String errorMessage){ + if (b != '#') { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#'); + throw new IllegalStateException(errorMessage); + } + } + + private void checkChunkSize(){ + if (chunkSize > maxChunkSize) { + logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize); + throw new IllegalStateException("Maximum chunk size exceeded"); + } + + } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IllegalStateException { while (in.isReadable()) { switch (state) { case HEADER_ONE: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk header encountered (byte 0)"); - } + checkNewLine(b, "Malformed chunk header encountered (byte 0)"); state = State.HEADER_TWO; @@ -60,10 +80,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { case HEADER_TWO: { final byte b = in.readByte(); - if (b != '#') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'#'); - throw new IllegalStateException("Malformed chunk header encountered (byte 1)"); - } + checkHash(b, "Malformed chunk header encountered (byte 1)"); state = State.HEADER_LENGTH_FIRST; break; @@ -84,17 +101,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { } if (b < '0' || b > '9') { - logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'0', (byte)'9'); + logger.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'; - - if (chunkSize > maxChunkSize) { - logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize); - throw new IllegalStateException("Maximum chunk size exceeded"); - } + checkChunkSize(); break; } case DATA: @@ -109,18 +122,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { in.discardReadBytes(); return; } - aggregateChunks(in.readBytes((int) chunkSize)); state = State.FOOTER_ONE; break; case FOOTER_ONE: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 0)"); - } - + checkNewLine(b,"Malformed chunk footer encountered (byte 0)"); state = State.FOOTER_TWO; chunkSize = 0; break; @@ -128,12 +136,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { case FOOTER_TWO: { final byte b = in.readByte(); - - if (b != '#') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'#'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 1)"); - } - + checkHash(b,"Malformed chunk footer encountered (byte 1)"); state = State.FOOTER_THREE; break; } @@ -144,28 +147,14 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { // In this state, either header-of-new-chunk or message-end is expected // Depends on the next character - 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 { - logger.debug("Got byte {} while waiting for {} or {}-{}", b, (byte) '#', (byte) '1', (byte) '9'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 2)"); - } + extractNewChunkOrMessageEnd(b); break; } case FOOTER_FOUR: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 3)"); - } - + checkNewLine(b,"Malformed chunk footer encountered (byte 3)"); state = State.HEADER_ONE; out.add(chunk); chunk = null; @@ -177,6 +166,20 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { in.discardReadBytes(); } + private void extractNewChunkOrMessageEnd(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 { + logger.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(); } @@ -189,8 +192,8 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { } private static int processHeaderLengthFirst(byte b) { - if (isHeaderLengthFirst(b) == false) { - logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'1', (byte)'9'); + if (!isHeaderLengthFirst(b)) { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9'); throw new IllegalStateException("Invalid chunk size encountered (byte 0)"); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java index 9435e6ff73..8b1bb3601d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java @@ -24,7 +24,7 @@ public class NetconfEOMAggregator extends ByteToMessageDecoder { private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class); @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE); if (index == -1) { logger.debug("Message is not complete, read again."); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToEXIEncoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToEXIEncoder.java index 5edec0d1bd..8425ce0779 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToEXIEncoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToEXIEncoder.java @@ -7,28 +7,27 @@ */ package org.opendaylight.controller.netconf.util.handler; -import java.io.ByteArrayInputStream; +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.OutputStream; - +import javax.xml.transform.Transformer; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.sax.SAXTransformerFactory; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.openexi.sax.Transmogrifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.xml.sax.InputSource; - -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; public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder { private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToEXIEncoder.class); - //private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); + private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); private final NetconfEXICodec codec; public NetconfMessageToEXIEncoder(final NetconfEXICodec codec) { @@ -43,10 +42,8 @@ public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder out) throws Exception { + public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IOException, SAXException, NetconfDocumentedException { if (in.readableBytes() == 0) { LOG.debug("No more content in incoming buffer."); return; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java index 06a4dc7207..89f76f39e5 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java @@ -13,6 +13,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; +import java.io.IOException; import java.util.List; import org.opendaylight.controller.netconf.api.NetconfMessage; @@ -21,13 +22,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; +import org.xml.sax.SAXException; public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder { private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class); @Override @VisibleForTesting - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IOException, SAXException { if (in.readableBytes() != 0) { LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in)); out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in)))); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java index 4aa274c6df..c482e77735 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java @@ -29,7 +29,7 @@ public class LoginPassword extends AuthenticationHandler { public void authenticate(Connection connection) throws IOException { boolean isAuthenticated = connection.authenticateWithPassword(username, password); - if (isAuthenticated == false) { + if (!isAuthenticated) { throw new IOException("Authentication failed."); } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java index 7beee649ab..50f44054c1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java @@ -58,8 +58,9 @@ public class SshClient { } public void close() { - for (SshSession session : openSessions.values()) + for (SshSession session : openSessions.values()){ closeSession(session); + } openSessions.clear(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java index 6350dd1544..244bcc0041 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java @@ -64,7 +64,7 @@ public class SshClientAdapter implements Runnable { } } - while (stopRequested.get() == false) { + while (!stopRequested.get()) { byte[] readBuff = new byte[BUFFER_SIZE]; int c = stdOut.read(readBuff); if (c == -1) { @@ -82,7 +82,7 @@ public class SshClientAdapter implements Runnable { // Netty closed connection prematurely. // Just pass and move on. } catch (Exception e) { - throw new RuntimeException(e); + throw new IllegalStateException(e); } finally { sshClient.close(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java index 313ea93241..b8f13699ba 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java @@ -12,7 +12,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandler; - import java.io.IOException; import java.io.InputStream; @@ -60,7 +59,7 @@ public class ChannelInputStream extends InputStream implements ChannelInboundHan lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new IllegalStateException(e); } } return this.bb.readByte() & 0xFF; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java index d6d57c50ac..c40bf3909a 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java @@ -14,8 +14,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Preconditions; - public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperation { protected AbstractLastNetconfOperation(String netconfSessionIdForReporting) { @@ -25,8 +23,12 @@ public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperat @Override protected Element handle(Document document, XmlElement operationElement, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - Preconditions.checkArgument(subsequentOperation.isExecutionTermination(), - "No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation); + if (!subsequentOperation.isExecutionTermination()){ + throw new NetconfDocumentedException(String.format("No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.malformed_message, + NetconfDocumentedException.ErrorSeverity.error); + } return handleWithNoSubsequentOperations(document, operationElement); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java index b7bbd3c6a7..65ca1b7c4b 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java @@ -17,6 +17,8 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -26,6 +28,7 @@ import com.google.common.base.Optional; public abstract class AbstractNetconfOperation implements NetconfOperation { private final String netconfSessionIdForReporting; + private static final Logger logger = LoggerFactory.getLogger(AbstractNetconfOperation.class); protected AbstractNetconfOperation(String netconfSessionIdForReporting) { this.netconfSessionIdForReporting = netconfSessionIdForReporting; @@ -36,16 +39,18 @@ public abstract class AbstractNetconfOperation implements NetconfOperation { } @Override - public HandlingPriority canHandle(Document message) { - OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(message); + public HandlingPriority canHandle(Document message) throws NetconfDocumentedException { + OperationNameAndNamespace operationNameAndNamespace = null; + operationNameAndNamespace = new OperationNameAndNamespace(message); return canHandle(operationNameAndNamespace.getOperationName(), operationNameAndNamespace.getNamespace()); } public static final class OperationNameAndNamespace { private final String operationName, namespace; - public OperationNameAndNamespace(Document message) { - XmlElement requestElement = getRequestElementWithCheck(message); + public OperationNameAndNamespace(Document message) throws NetconfDocumentedException { + XmlElement requestElement = null; + requestElement = getRequestElementWithCheck(message); XmlElement operationElement = requestElement.getOnlyChildElement(); operationName = operationElement.getName(); @@ -61,7 +66,7 @@ public abstract class AbstractNetconfOperation implements NetconfOperation { } } - protected static XmlElement getRequestElementWithCheck(Document message) { + protected static XmlElement getRequestElementWithCheck(Document message) throws NetconfDocumentedException { return XmlElement.fromDomElementWithExpected(message.getDocumentElement(), XmlNetconfConstants.RPC_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java index e3eb450704..3fd25e814d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java @@ -8,8 +8,9 @@ package org.opendaylight.controller.netconf.util.messages; -import java.util.Set; - +import com.google.common.base.Optional; +import com.google.common.collect.Sets; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -17,8 +18,7 @@ import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; +import java.util.Set; /** * NetconfMessage that can carry additional header with session metadata. See {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader} @@ -29,13 +29,13 @@ public final class NetconfHelloMessage extends NetconfMessage { private final NetconfHelloMessageAdditionalHeader additionalHeader; - public NetconfHelloMessage(Document doc, NetconfHelloMessageAdditionalHeader additionalHeader) { + public NetconfHelloMessage(Document doc, NetconfHelloMessageAdditionalHeader additionalHeader) throws NetconfDocumentedException { super(doc); checkHelloMessage(doc); this.additionalHeader = additionalHeader; } - public NetconfHelloMessage(Document doc) { + public NetconfHelloMessage(Document doc) throws NetconfDocumentedException { this(doc, null); } @@ -43,20 +43,14 @@ public final class NetconfHelloMessage extends NetconfMessage { return additionalHeader== null ? Optional.absent() : Optional.of(additionalHeader); } - private static void checkHelloMessage(Document doc) { - try { - XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG, - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + private static void checkHelloMessage(Document doc) throws NetconfDocumentedException { + XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG, + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); - } catch (IllegalArgumentException | IllegalStateException e) { - throw new IllegalArgumentException(String.format( - "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)), e); - } } public static NetconfHelloMessage createClientHello(Iterable capabilities, - Optional additionalHeaderOptional) { + Optional additionalHeaderOptional) throws NetconfDocumentedException { Document doc = createHelloMessageDoc(capabilities); return additionalHeaderOptional.isPresent() ? new NetconfHelloMessage(doc, additionalHeaderOptional.get()) : new NetconfHelloMessage(doc); @@ -80,7 +74,7 @@ public final class NetconfHelloMessage extends NetconfMessage { return doc; } - public static NetconfHelloMessage createServerHello(Set capabilities, long sessionId) { + public static NetconfHelloMessage createServerHello(Set capabilities, long sessionId) throws NetconfDocumentedException { Document doc = createHelloMessageDoc(capabilities); Element sessionIdElement = doc.createElement(XmlNetconfConstants.SESSION_ID); sessionIdElement.setTextContent(Long.toString(sessionId)); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java index 8bd6b88659..5c2770a8c1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java @@ -10,7 +10,9 @@ package org.opendaylight.controller.netconf.util.messages; import com.google.common.base.Charsets; -public class NetconfMessageConstants { +public final class NetconfMessageConstants { + + private NetconfMessageConstants(){} /** * The NETCONF 1.0 old-style message separator. This is framing mechanism * is used by default. @@ -26,4 +28,5 @@ public class NetconfMessageConstants { public static final int MAX_HEADER_LENGTH = 13; public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8); + } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java index e4d97cf65a..49395d53d2 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageUtil.java @@ -10,9 +10,12 @@ package org.opendaylight.controller.netconf.util.messages; import com.google.common.base.Function; import com.google.common.collect.Collections2; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import javax.annotation.Nullable; @@ -21,39 +24,41 @@ import java.util.List; public final class NetconfMessageUtil { + private static final Logger logger = LoggerFactory.getLogger(NetconfMessageUtil.class); + private NetconfMessageUtil() {} - public static boolean isOKMessage(NetconfMessage message) { + public static boolean isOKMessage(NetconfMessage message) throws NetconfDocumentedException { return isOKMessage(message.getDocument()); } - public static boolean isOKMessage(Document document) { + public static boolean isOKMessage(Document document) throws NetconfDocumentedException { return isOKMessage(XmlElement.fromDomDocument(document)); } - public static boolean isOKMessage(XmlElement xmlElement) { + public static boolean isOKMessage(XmlElement xmlElement) throws NetconfDocumentedException { if(xmlElement.getChildElements().size() != 1) { return false; } return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.OK); } - public static boolean isErrorMessage(NetconfMessage message) { + public static boolean isErrorMessage(NetconfMessage message) throws NetconfDocumentedException { return isErrorMessage(message.getDocument()); } - public static boolean isErrorMessage(Document document) { + public static boolean isErrorMessage(Document document) throws NetconfDocumentedException { return isErrorMessage(XmlElement.fromDomDocument(document)); } - public static boolean isErrorMessage(XmlElement xmlElement) { + public static boolean isErrorMessage(XmlElement xmlElement) throws NetconfDocumentedException { if(xmlElement.getChildElements().size() != 1) { return false; } return xmlElement.getOnlyChildElement().getName().equals(XmlNetconfConstants.RPC_ERROR); } - public static Collection extractCapabilitiesFromHello(Document doc) { + public static Collection extractCapabilitiesFromHello(Document doc) throws NetconfDocumentedException { XmlElement responseElement = XmlElement.fromDomDocument(doc); XmlElement capabilitiesElement = responseElement .getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CAPABILITIES); @@ -64,7 +69,12 @@ public final class NetconfMessageUtil { @Override public String apply(@Nullable XmlElement input) { // Trim possible leading/tailing whitespace - return input.getTextContent().trim(); + try { + return input.getTextContent().trim(); + } catch (NetconfDocumentedException e) { + logger.trace("Error fetching inpit text content becauese {}",e); + return null; + } } }); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java index de2d6d7e0c..5b9707f2b5 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java @@ -112,7 +112,7 @@ public final class SendErrorExceptionUtil { XPathConstants.NODE); errorSeverityNode.setTextContent(sendErrorException.getErrorSeverity().getTagValue()); - if (sendErrorException.getErrorInfo() != null && sendErrorException.getErrorInfo().isEmpty() == false) { + if (sendErrorException.getErrorInfo() != null && !sendErrorException.getErrorInfo().isEmpty()) { /* * message-id * rpc diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index 80eaa26de1..b23a2d6697 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -54,7 +54,7 @@ public final class NetconfConfigUtil { Optional inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp, exceptionMessageIfNotFound, forClient); - if (inetSocketAddressOptional.isPresent() == false) { + if (!inetSocketAddressOptional.isPresent()) { throw new IllegalStateException("Netconf tcp address not found." + exceptionMessageIfNotFound); } InetSocketAddress inetSocketAddress = inetSocketAddressOptional.get(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index 1fbae1ee2d..66603fb6c2 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -9,11 +9,16 @@ package org.opendaylight.controller.netconf.util.xml; 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.Lists; import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; +import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -34,6 +39,7 @@ import java.util.Map; public final class XmlElement { private final Element element; + private static final Logger logger = LoggerFactory.getLogger(XmlElement.class); private XmlElement(Element element) { this.element = element; @@ -47,27 +53,27 @@ public final class XmlElement { return new XmlElement(xml.getDocumentElement()); } - public static XmlElement fromString(String s) { + public static XmlElement fromString(String s) throws NetconfDocumentedException { try { return new XmlElement(XmlUtil.readXmlToElement(s)); } catch (IOException | SAXException e) { - throw new IllegalArgumentException("Unable to create from " + s, e); + throw NetconfDocumentedException.wrap(e); } } - public static XmlElement fromDomElementWithExpected(Element element, String expectedName) { + public static XmlElement fromDomElementWithExpected(Element element, String expectedName) throws NetconfDocumentedException { XmlElement xmlElement = XmlElement.fromDomElement(element); xmlElement.checkName(expectedName); return xmlElement; } - public static XmlElement fromDomElementWithExpected(Element element, String expectedName, String expectedNamespace) { + public static XmlElement fromDomElementWithExpected(Element element, String expectedName, String expectedNamespace) throws NetconfDocumentedException { XmlElement xmlElement = XmlElement.fromDomElementWithExpected(element, expectedName); xmlElement.checkNamespace(expectedNamespace); return xmlElement; } - private static Map extractNamespaces(Element typeElement) { + private static Map extractNamespaces(Element typeElement) throws NetconfDocumentedException { Map namespaces = new HashMap<>(); NamedNodeMap attributes = typeElement.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { @@ -78,7 +84,12 @@ public final class XmlElement { if (attribKey.equals(XmlUtil.XMLNS_ATTRIBUTE_KEY)) { prefix = ""; } else { - Preconditions.checkState(attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY + ":")); + if (!attribKey.startsWith(XmlUtil.XMLNS_ATTRIBUTE_KEY + ":")){ + throw new NetconfDocumentedException("Attribute doesn't start with :", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } prefix = attribKey.substring(XmlUtil.XMLNS_ATTRIBUTE_KEY.length() + 1); } namespaces.put(prefix, attribute.getNodeValue()); @@ -87,19 +98,38 @@ public final class XmlElement { return namespaces; } - public void checkName(String expectedName) { - Preconditions.checkArgument(getName().equals(expectedName), "Expected %s xml element but was %s", expectedName, - getName()); + public void checkName(String expectedName) throws UnexpectedElementException { + if (!getName().equals(expectedName)){ + throw new UnexpectedElementException(String.format("Expected %s xml element but was %s", expectedName, + getName()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } - public void checkNamespaceAttribute(String expectedNamespace) { - Preconditions.checkArgument(getNamespaceAttribute().equals(expectedNamespace), - "Unexpected namespace %s for element %s, should be %s", getNamespaceAttribute(), expectedNamespace); + public void checkNamespaceAttribute(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { + if (!getNamespaceAttribute().equals(expectedNamespace)) + { + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + getNamespaceAttribute(), + expectedNamespace), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } - public void checkNamespace(String expectedNamespace) { - Preconditions.checkArgument(getNamespace().equals(expectedNamespace), - "Unexpected namespace %s for element %s, should be %s", getNamespace(), expectedNamespace); + public void checkNamespace(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { + if (!getNamespace().equals(expectedNamespace)) + { + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + getNamespace(), + expectedNamespace), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } public String getName() { @@ -150,7 +180,7 @@ public final class XmlElement { final List result = new ArrayList<>(); for (int i = 0; i < childNodes.getLength(); i++) { Node item = childNodes.item(i); - if (item instanceof Element == false) { + if (!(item instanceof Element)) { continue; } if (strat.accept((Element) item)) { @@ -184,7 +214,11 @@ public final class XmlElement { return getChildElementsInternal(new ElementFilteringStrategy() { @Override public boolean accept(Element e) { - return XmlElement.fromDomElement(e).getNamespace().equals(namespace); + try { + return XmlElement.fromDomElement(e).getNamespace().equals(namespace); + } catch (MissingNameSpaceException e1) { + return false; + } } }); @@ -199,9 +233,14 @@ public final class XmlElement { }); } - public XmlElement getOnlyChildElement(String childName) { + public XmlElement getOnlyChildElement(String childName) throws NetconfDocumentedException { List nameElements = getChildElements(childName); - Preconditions.checkState(nameElements.size() == 1, "One element " + childName + " expected in " + toString()); + if (nameElements.size() != 1){ + throw new NetconfDocumentedException("One element " + childName + " expected in " + toString(), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } return nameElements.get(0); } @@ -221,7 +260,7 @@ public final class XmlElement { } } - public XmlElement getOnlyChildElementWithSameNamespace(String childName) { + public XmlElement getOnlyChildElementWithSameNamespace(String childName) throws NetconfDocumentedException { return getOnlyChildElement(childName, getNamespace()); } @@ -233,7 +272,7 @@ public final class XmlElement { } } - public XmlElement getOnlyChildElementWithSameNamespace() { + public XmlElement getOnlyChildElementWithSameNamespace() throws NetconfDocumentedException { XmlElement childElement = getOnlyChildElement(); childElement.checkNamespace(getNamespace()); return childElement; @@ -249,7 +288,7 @@ public final class XmlElement { } } - public XmlElement getOnlyChildElement(final String childName, String namespace) { + public XmlElement getOnlyChildElement(final String childName, String namespace) throws NetconfDocumentedException { List children = getChildElementsWithinNamespace(namespace); children = Lists.newArrayList(Collections2.filter(children, new Predicate() { @Override @@ -257,38 +296,69 @@ public final class XmlElement { return xmlElement.getName().equals(childName); } })); - Preconditions.checkState(children.size() == 1, "One element %s:%s expected in %s but was %s", namespace, - childName, toString(), children.size()); + if (children.size() != 1){ + throw new NetconfDocumentedException(String.format("One element %s:%s expected in %s but was %s", namespace, + childName, toString(), children.size()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } + return children.get(0); } - public XmlElement getOnlyChildElement() { + public XmlElement getOnlyChildElement() throws NetconfDocumentedException { List children = getChildElements(); - Preconditions.checkState(children.size() == 1, "One element expected in %s but was %s", toString(), - children.size()); + if (children.size() != 1){ + throw new NetconfDocumentedException(String.format( "One element expected in %s but was %s", toString(), + children.size()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } return children.get(0); } - public String getTextContent() { + public String getTextContent() throws NetconfDocumentedException { Node textChild = element.getFirstChild(); - Preconditions.checkNotNull(textChild, "Child node expected, got null for " + getName() + " : " + element); - Preconditions.checkState(textChild instanceof Text, getName() + " should contain text." + - Text.class.getName() + " expected, got " + textChild); + if (null == textChild){ + throw new NetconfDocumentedException(String.format( "Child node expected, got null for " + getName() + " : " + element), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } + if (!(textChild instanceof Text)){ + throw new NetconfDocumentedException(String.format(getName() + " should contain text." + + Text.class.getName() + " expected, got " + textChild), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } String content = textChild.getTextContent(); // Trim needed return content.trim(); } - public String getNamespaceAttribute() { + public String getNamespaceAttribute() throws MissingNameSpaceException { String attribute = element.getAttribute(XmlUtil.XMLNS_ATTRIBUTE_KEY); - Preconditions.checkState(attribute != null && !attribute.equals(""), "Element %s must specify namespace", - toString()); + if (attribute == null || attribute.equals("")){ + throw new MissingNameSpaceException(String.format("Element %s must specify namespace", + toString()), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } return attribute; } - public String getNamespace() { + public String getNamespace() throws MissingNameSpaceException { String namespaceURI = element.getNamespaceURI(); - Preconditions.checkState(namespaceURI != null, "No namespace defined for %s", this); + if (namespaceURI == null || namespaceURI.equals("")){ + throw new MissingNameSpaceException(String.format("No namespace defined for %s", this), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } return namespaceURI; } @@ -297,7 +367,11 @@ public final class XmlElement { final StringBuilder sb = new StringBuilder("XmlElement{"); sb.append("name='").append(getName()).append('\''); if (element.getNamespaceURI() != null) { - sb.append(", namespace='").append(getNamespace()).append('\''); + try { + sb.append(", namespace='").append(getNamespace()).append('\''); + } catch (MissingNameSpaceException e) { + logger.trace("Missing namespace for element."); + } } sb.append('}'); return sb.toString(); @@ -316,7 +390,7 @@ public final class XmlElement { * namespace is returned with empty string as key. If no default namespace * is found value will be null. */ - public Map.Entry findNamespaceOfTextContent() { + public Map.Entry findNamespaceOfTextContent() throws NetconfDocumentedException { Map namespaces = extractNamespaces(element); String textContent = getTextContent(); int indexOfColon = textContent.indexOf(':'); @@ -326,14 +400,14 @@ public final class XmlElement { } else { prefix = ""; } - if (namespaces.containsKey(prefix) == false) { + if (!namespaces.containsKey(prefix)) { throw new IllegalArgumentException("Cannot find namespace for " + XmlUtil.toString(element) + ". Prefix from content is " + prefix + ". Found namespaces " + namespaces); } return Maps.immutableEntry(prefix, namespaces.get(prefix)); } - public List getChildElementsWithSameNamespace(final String childName) { + public List getChildElementsWithSameNamespace(final String childName) throws MissingNameSpaceException { List children = getChildElementsWithinNamespace(getNamespace()); return Lists.newArrayList(Collections2.filter(children, new Predicate() { @Override @@ -344,17 +418,22 @@ public final class XmlElement { } public void checkUnrecognisedElements(List recognisedElements, - XmlElement... additionalRecognisedElements) { + XmlElement... additionalRecognisedElements) throws NetconfDocumentedException { List childElements = getChildElements(); childElements.removeAll(recognisedElements); for (XmlElement additionalRecognisedElement : additionalRecognisedElements) { childElements.remove(additionalRecognisedElement); } - Preconditions.checkState(childElements.isEmpty(), "Unrecognised elements %s in %s", childElements, this); + if (!childElements.isEmpty()){ + throw new NetconfDocumentedException(String.format("Unrecognised elements %s in %s", childElements, this), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error); + } } - public void checkUnrecognisedElements(XmlElement... additionalRecognisedElements) { - checkUnrecognisedElements(Collections. emptyList(), additionalRecognisedElements); + public void checkUnrecognisedElements(XmlElement... additionalRecognisedElements) throws NetconfDocumentedException { + checkUnrecognisedElements(Collections.emptyList(), additionalRecognisedElements); } @Override @@ -383,10 +462,10 @@ public final class XmlElement { public boolean hasNamespace() { try { getNamespaceAttribute(); - } catch (IllegalStateException e) { + } catch (MissingNameSpaceException e) { try { getNamespace(); - } catch (IllegalStateException e1) { + } catch (MissingNameSpaceException e1) { return false; } return true; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java index d0be73843b..708f17cadb 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java @@ -43,8 +43,12 @@ public final class XmlNetconfConstants { public static final String SESSION_ID = "session-id"; // + // TODO duplicate + public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0"; public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0"; - public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1"; +// public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1"; + 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"; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java index d8907424f8..1f81117ca3 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java @@ -8,12 +8,12 @@ package org.opendaylight.controller.netconf.util.xml; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.namespace.QName; @@ -23,7 +23,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; @@ -33,14 +32,12 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -import com.google.common.base.Charsets; -import com.google.common.base.Optional; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; public final class XmlUtil { @@ -81,7 +78,7 @@ public final class XmlUtil { try { dBuilder = BUILDERFACTORY.newDocumentBuilder(); } catch (ParserConfigurationException e) { - throw new RuntimeException("Failed to parse XML document", e); + throw new IllegalStateException("Failed to parse XML document", e); } Document doc = dBuilder.parse(xmlContent); @@ -96,10 +93,9 @@ public final class XmlUtil { public static Document newDocument() { try { DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder(); - Document document = builder.newDocument(); - return document; + return builder.newDocument(); } catch (ParserConfigurationException e) { - throw new RuntimeException("Failed to create document", e); + throw new IllegalStateException("Failed to create document", e); } } @@ -153,8 +149,8 @@ public final class XmlUtil { transformer.transform(source, result); return result.getWriter().toString(); - } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) { - throw new RuntimeException("Unable to serialize xml element " + xml, e); + } catch (Exception | TransformerFactoryConfigurationError e) { + throw new IllegalStateException("Unable to serialize xml element " + xml, e); } } diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java deleted file mode 100644 index 360e8126ae..0000000000 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * 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 java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.StringWriter; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -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.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.sax.SAXTransformerFactory; -import javax.xml.transform.sax.TransformerHandler; -import javax.xml.transform.stream.StreamResult; - -import org.junit.Ignore; -import org.junit.Test; -import org.openexi.proc.common.AlignmentType; -import org.openexi.proc.common.GrammarOptions; -import org.openexi.proc.grammars.GrammarCache; -import org.openexi.sax.EXIReader; -import org.openexi.sax.Transmogrifier; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.xml.sax.InputSource; - -/** - * This test case tests nagasena library used for exi encode/decode. - * - * This library does not work correctly, since it is impossible to encode and then decode DOM xml. - * Encoding DOM using sax Transformer produces invalid xml, that cannot be decoded (Problem seems to be the namespace handling). - * - */ -@Ignore -public class EXILibTest { - - public static final AlignmentType ALIGNMENT_TYPE = AlignmentType.preCompress; - - @Test - public void testExiLibWithSaxTransformer() throws Exception { - final byte[] encode = encodeEXI(getDom2()); - final byte[] encodeWithTransformer = encodeEXITransformer(getDom2()); - - // System.err.println(Arrays.toString(encode)); - // System.err.println(Arrays.toString(encodeWithTransformer)); - - // This works fine (encoded from string) - decodeEXI(encode); - // Error, encoded from Dom with Transformer cannot be decoded, Exception is thrown - // - // either: - // org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. - // - // or: - // java.lang.NullPointerException - // - // depends on GrammarOptions.addNS(go); option set - decodeEXI(encodeWithTransformer); - } - - private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); - - public static byte[] encodeEXITransformer(final Element xml) throws Exception { - final Transmogrifier transmogrifier = new Transmogrifier(); - - transmogrifier.setAlignmentType(ALIGNMENT_TYPE); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - - transmogrifier.setGrammarCache(getGrammarCache()); - - transmogrifier.setOutputStream(out); - - final Transformer transformer = saxTransformerFactory.newTransformer(); - transformer.transform(new DOMSource(xml), new SAXResult(transmogrifier.getSAXTransmogrifier())); - - return out.toByteArray(); - } - - public static byte[] encodeEXI(final Element xml) throws Exception { - final Transmogrifier transmogrifier = new Transmogrifier(); - - transmogrifier.setAlignmentType(ALIGNMENT_TYPE); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - - transmogrifier.setGrammarCache(getGrammarCache()); - - transmogrifier.setOutputStream(out); - - transmogrifier.encode(new InputSource(new ByteArrayInputStream(toString(xml, false).getBytes()))); - - out.flush(); - - return out.toByteArray(); - } - - private static GrammarCache getGrammarCache() { - short go = GrammarOptions.DEFAULT_OPTIONS; - - // This option on or off, nagasena still fails -// go = GrammarOptions.addNS(go); - - return new GrammarCache(null, go); - } - - public static Document decodeEXI(final byte[] input) throws Exception { - - final GrammarCache grammarCache; - final DOMResult domResult = new DOMResult(); - - try(ByteArrayInputStream in = new ByteArrayInputStream(input)) { - - final EXIReader reader = new EXIReader(); - - reader.setAlignmentType(ALIGNMENT_TYPE); - grammarCache = getGrammarCache(); - - reader.setGrammarCache(grammarCache); - - final SAXTransformerFactory transformerFactory - = (SAXTransformerFactory) TransformerFactory.newInstance(); - final TransformerHandler handler = transformerFactory.newTransformerHandler(); - handler.setResult(domResult); - - reader.setContentHandler(handler); - - reader.parse(new InputSource(in)); - } - - return (Document) domResult.getNode(); - } - - public static Element getDom() { - final Element dom; - - final Document d = newDocument(); - - dom = d.createElement("rpc"); - dom.setAttribute("xmlns", "a.b.c"); - dom.setAttribute("message-id", "id"); - dom.appendChild(d.createElement("inner")); - - return dom; - } - - public static Element getDom2() { - final Element dom; - - final Document d = newDocument(); - - dom = d.createElementNS("a.b.c", "rpc"); - dom.setAttribute("message-id", "id"); - dom.appendChild(d.createElement("inner")); - - return dom; - } - - private static final DocumentBuilderFactory BUILDERFACTORY; - - static { - final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setCoalescing(true); - factory.setIgnoringElementContentWhitespace(true); - factory.setIgnoringComments(true); - BUILDERFACTORY = factory; - } - - private static Document newDocument() { - try { - final DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder(); - return builder.newDocument(); - } catch (final ParserConfigurationException e) { - throw new RuntimeException("Failed to create document", e); - } - } - - private static String toString(final Element xml, final boolean addXmlDeclaration) { - try { - final Transformer transformer = TransformerFactory.newInstance().newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, addXmlDeclaration ? "no" : "yes"); - - final StreamResult result = new StreamResult(new StringWriter()); - final DOMSource source = new DOMSource(xml); - transformer.transform(source, result); - - return result.getWriter().toString(); - } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) { - throw new RuntimeException("Unable to serialize xml element " + xml, e); - } - } -} diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java index 85eeb30a07..b8605d8230 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/NetconfUtilTest.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.netconf.util; import org.junit.Test; -import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; @@ -22,7 +21,7 @@ public class NetconfUtilTest { public void testConflictingVersionDetection() throws Exception { Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml")); try{ - NetconfUtil.checkIsMessageOk(new NetconfMessage(document)); + NetconfUtil.checkIsMessageOk(document); fail(); }catch(IllegalStateException e){ assertThat(e.getMessage(), containsString("Optimistic lock failed. Expected parent version 21, was 18")); diff --git a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java index d3cefd41b3..94e67247c8 100644 --- a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java +++ b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java @@ -1010,12 +1010,10 @@ public class SimpleForwardingImpl implements IfNewHostNotify, routing.getRoute(incomingNodeConnector.getNode(), destHost.getnodeconnectorNode()) != null)) { log.trace("Host {} is at {}", dIP, destHost.getnodeConnector()); - HostNodePair key = new HostNodePair(destHost, destHost.getnodeconnectorNode()); // If SimpleForwarding is aware of this host, it will try to install // a path. Forward packet until it's done. - if (dataPacketService != null && this.rulesDB.containsKey(key)) { - + if (dataPacketService != null) { /* * if we know where the host is and there's a path from where this diff --git a/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar b/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar similarity index 85% rename from third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar rename to third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar index 060b171529..1b6a02710a 100644 Binary files a/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar and b/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar differ diff --git a/third-party/org.openexi/nagasena-rta/pom.xml b/third-party/org.openexi/nagasena-rta/pom.xml index 6beba8c28b..98da51aca8 100644 --- a/third-party/org.openexi/nagasena-rta/pom.xml +++ b/third-party/org.openexi/nagasena-rta/pom.xml @@ -13,7 +13,7 @@ org.opendaylight.controller.thirdparty org.openexi - 0000.0002.0035.0-SNAPSHOT + 0000.0002.0038.0-SNAPSHOT org.opendaylight.controller.thirdparty @@ -21,7 +21,7 @@ bundle - nagasena-rta-0000.0002.0035.0.jar + nagasena-rta-0000.0002.0038.0.jar diff --git a/third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar b/third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar similarity index 80% rename from third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar rename to third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar index c566f27d83..ffc28ead4b 100644 Binary files a/third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar and b/third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar differ diff --git a/third-party/org.openexi/nagasena/pom.xml b/third-party/org.openexi/nagasena/pom.xml index 297f15f201..a890431ca6 100644 --- a/third-party/org.openexi/nagasena/pom.xml +++ b/third-party/org.openexi/nagasena/pom.xml @@ -13,7 +13,7 @@ org.opendaylight.controller.thirdparty org.openexi - 0000.0002.0035.0-SNAPSHOT + 0000.0002.0038.0-SNAPSHOT org.opendaylight.controller.thirdparty @@ -21,7 +21,7 @@ bundle - nagasena-0000.0002.0035.0.jar + nagasena-0000.0002.0038.0.jar diff --git a/third-party/org.openexi/pom.xml b/third-party/org.openexi/pom.xml index d623ef8cdc..6369b294ba 100644 --- a/third-party/org.openexi/pom.xml +++ b/third-party/org.openexi/pom.xml @@ -19,7 +19,7 @@ org.opendaylight.controller.thirdparty org.openexi - 0000.0002.0035.0-SNAPSHOT + 0000.0002.0038.0-SNAPSHOT pom 3.0.4