Merge "Bug 1036 - Allow using container in case stmt to preserve uniqueness."
authorTony Tkacik <ttkacik@cisco.com>
Mon, 26 May 2014 19:48:32 +0000 (19:48 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 26 May 2014 19:48:32 +0000 (19:48 +0000)
77 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java
opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java
opendaylight/md-sal/sal-rest-connector/pom.xml
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java
opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java
opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java [new file with mode: 0644]
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java [new file with mode: 0644]
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java [new file with mode: 0644]

index c1dc6ee78948255da57b12f68e176aa8e0b23c25..7c47f3644dcf6b4c9f079d5e5cf7d2150a83f04a 100644 (file)
@@ -78,6 +78,7 @@
     <hosttracker.northbound.version>0.4.2-SNAPSHOT</hosttracker.northbound.version>
     <hosttracker_new.api.version>0.4.2-SNAPSHOT</hosttracker_new.api.version>
     <ietf-inet-types.version>2010.09.24.4-SNAPSHOT</ietf-inet-types.version>
+    <ietf-restconf.version>2013.10.19.1-SNAPSHOT</ietf-restconf.version>
     <ietf-topology.version>2013.10.21.2-SNAPSHOT</ietf-topology.version>
     <ietf-yang-types.version>2010.09.24.4-SNAPSHOT</ietf-yang-types.version>
     <jackson.version>2.3.2</jackson.version>
         <artifactId>ietf-inet-types</artifactId>
         <version>${ietf-inet-types.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools.model</groupId>
+        <artifactId>ietf-restconf</artifactId>
+        <version>${ietf-restconf.version}</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.yangtools.model</groupId>
         <artifactId>ietf-topology</artifactId>
         <artifactId>ietf-yang-types</artifactId>
         <version>${ietf-yang-types.version}</version>
       </dependency>
+      <dependency>
+        <groupId>org.opendaylight.yangtools.model</groupId>
+        <artifactId>ietf-yang-types-20130715</artifactId>
+        <version>2013.07.15.1-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.opendaylight.yangtools.model</groupId>
         <artifactId>opendaylight-l2-types</artifactId>
index 9d0fbd85dc98b0e87b118f2733876673764023eb..ec46219aaf8469e3d8ecadcc9988bb4a47188e3f 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.config.manager.impl.osgi.mapping;
 
 import javassist.ClassPool;
+
 import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
@@ -27,10 +28,8 @@ public class CodecRegistryProvider implements AutoCloseable {
     private final RuntimeGeneratedMappingServiceImpl service;
     private final AutoCloseable registration;
 
-    public CodecRegistryProvider(ClassLoadingStrategy classLoadingStrategy, BundleContext context) {
-        service = new RuntimeGeneratedMappingServiceImpl(classLoadingStrategy);
-        service.setPool(CLASS_POOL);
-        service.init();
+    public CodecRegistryProvider(final ClassLoadingStrategy classLoadingStrategy, final BundleContext context) {
+        service = new RuntimeGeneratedMappingServiceImpl(CLASS_POOL, classLoadingStrategy);
         registration = OsgiRegistrationUtil.registerService(context, service,
                 SchemaServiceListener.class, BindingIndependentMappingService.class);
     }
index 48e661f196370f1497429f805312853d9b7e1bf7..52aa6d276b7337a60bbfc891f32393416cccbd8c 100644 (file)
           <groupId>org.opendaylight.yangtools.model</groupId>
           <artifactId>ietf-inet-types</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools.model</groupId>
+          <artifactId>ietf-restconf</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools.model</groupId>
           <artifactId>ietf-topology</artifactId>
           <groupId>org.opendaylight.yangtools.model</groupId>
           <artifactId>ietf-yang-types</artifactId>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.yangtools.model</groupId>
+          <artifactId>ietf-yang-types-20130715</artifactId>
+        </dependency>
         <dependency>
           <groupId>org.opendaylight.yangtools.model</groupId>
           <artifactId>opendaylight-l2-types</artifactId>
index 9276238e019542d224b45357fffb48a557decbfe..2c95252ac7f6a3e571dcb8cceb03de24dbc2d0c0 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.sal.compatibility;
 
+import java.math.BigInteger;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
@@ -334,8 +335,8 @@ public final class NodeMapping {
 
   public static MacAddress toADMacAddress(final NodeId id) {
     final String nodeId = id.getValue().replaceAll("openflow:", "");
-    long lNodeId = Long.parseLong(nodeId);
-    lNodeId = Long.valueOf(lNodeId).longValue();
+    BigInteger nodeIdRaw = new BigInteger(nodeId);
+    long lNodeId = nodeIdRaw.longValue();
     byte[] bytesFromDpid = ToSalConversionsUtils.bytesFromDpid(lNodeId);
     return new MacAddress(bytesFromDpid);
   }
diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java
new file mode 100644 (file)
index 0000000..b9a2f5b
--- /dev/null
@@ -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.controller.sal.compatibility.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.compatibility.NodeMapping;
+import org.opendaylight.controller.sal.core.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+
+/**
+ * test of {@link NodeMapping} utility class
+ */
+public class NodeMappingTest {
+
+    /**
+     * Test method for
+     * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toADMacAddress(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId)}
+     * .
+     */
+    @Test
+    public void testToADMacAddress() {
+        NodeId[] nodeIds = new NodeId[] {
+                // 0x0000|0000 0000002a (answer to the ultimate question of life, universe and everything)
+                new NodeId("42"),
+                // 0x7fff|ffff ffffffff (max long -> 2**63 - 1)
+                new NodeId("9223372036854775807"),
+                // 0x7fff|7fff ffffffff
+                new NodeId("9223231299366420479"),
+                // 0x8fff|7fff ffffffff (more than biggest positive long)
+                new NodeId("10376152803973267455"),
+                // 0xca13|764a e9ace65a (BUG-770)
+                new NodeId("14561112084339025498")
+        };
+
+        byte[][] expectedMacs = new byte[][] {
+                {0, 0, 0, 0, 0, 0x2a},
+                {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff},
+                {(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff},
+                {(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff},
+                {(byte) 0x76, (byte) 0x4a, (byte) 0xe9, (byte) 0xac, (byte) 0xe6, (byte) 0x5a}
+        };
+        
+        Assert.assertEquals(expectedMacs.length, nodeIds.length);
+
+        for (int i = 0; i < expectedMacs.length; i++) {
+            NodeId nodeId = nodeIds[i];
+            MacAddress mac = NodeMapping.toADMacAddress(nodeId);
+            Assert.assertArrayEquals(expectedMacs[i], mac.getMacAddress());
+        }
+    }
+
+}
index 750defc0e95ac17ad535b299bfad52e4c4a489f2..0f0ce0dc9dd24fb41bc54bde70c196ba2d4d511e 100644 (file)
@@ -26,6 +26,8 @@ import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException;
 import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -36,6 +38,8 @@ import com.google.common.base.Preconditions;
 public final class RuntimeMappingModule extends
         org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModule {
 
+    private static final Logger LOG = LoggerFactory.getLogger(RuntimeMappingModule.class);
+
     private BundleContext bundleContext;
 
     public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
@@ -163,10 +167,17 @@ public final class RuntimeMappingModule extends
         }
 
         @Override
-        public void close() throws Exception {
+        public void close() {
             if(delegate != null) {
                 delegate = null;
-                bundleContext.ungetService(reference);
+
+                try {
+                    bundleContext.ungetService(reference);
+                } catch (IllegalStateException e) {
+                    // Indicates the BundleContext is no longer valid which can happen normally on shutdown.
+                    LOG.debug( "Error unregistering service", e );
+                }
+
                 bundleContext= null;
                 reference = null;
             }
index 33a9869a6b8d9f74605ef1362432cb4f9026f269..f30c8ddcaabf5c8c7cff69744b9ee3e8f936ebf8 100644 (file)
@@ -92,11 +92,11 @@ public class DataNormalizer {
         }
 
         // Write Augmentation data resolution
-        if (legacyData.getChildren().size() == 1) {
+        if (legacyData.getValue().size() == 1) {
             final DataNormalizationOperation<?> potentialOp;
 
             try {
-                final QName childType = legacyData.getChildren().get(0).getNodeType();
+                final QName childType = legacyData.getValue().get(0).getNodeType();
                 potentialOp = currentOp.getChild(childType);
             } catch (DataNormalizationException e) {
                 throw new IllegalArgumentException(String.format("Failed to get child operation for %s", legacyData), e);
index ba7414d42e26cbac61eb97a836cf89343f461969..fd24944018c69b3b9480a7018e0fea1c23986719 100644 (file)
@@ -16,28 +16,29 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-/**
-*
-*/
 public final class SchemaServiceImplSingletonModule extends
-        org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule {
+org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SchemaServiceImplSingletonModule.class);
 
     BundleContext bundleContext;
 
-    public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+    public SchemaServiceImplSingletonModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
 
-    public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
-            org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
-            SchemaServiceImplSingletonModule oldModule, java.lang.AutoCloseable oldInstance) {
+    public SchemaServiceImplSingletonModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
+            final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
+            final SchemaServiceImplSingletonModule oldModule, final java.lang.AutoCloseable oldInstance) {
         super(identifier, dependencyResolver, oldModule, oldInstance);
     }
 
     @Override
-    public boolean canReuseInstance(AbstractSchemaServiceImplSingletonModule oldModule) {
+    public boolean canReuseInstance(final AbstractSchemaServiceImplSingletonModule oldModule) {
         return true;
     }
 
@@ -45,7 +46,7 @@ public final class SchemaServiceImplSingletonModule extends
         return bundleContext;
     }
 
-    public void setBundleContext(BundleContext bundleContext) {
+    public void setBundleContext(final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
 
@@ -61,8 +62,7 @@ public final class SchemaServiceImplSingletonModule extends
             return new GlobalSchemaServiceProxy(getBundleContext(), ref);
         }
 
-        GlobalBundleScanningSchemaServiceImpl newInstance = new GlobalBundleScanningSchemaServiceImpl();
-        newInstance.setContext(getBundleContext());
+        GlobalBundleScanningSchemaServiceImpl newInstance = new GlobalBundleScanningSchemaServiceImpl(getBundleContext());
         newInstance.start();
         return newInstance;
     }
@@ -73,7 +73,7 @@ public final class SchemaServiceImplSingletonModule extends
         private ServiceReference<SchemaService> reference;
         private SchemaService delegate;
 
-        public GlobalSchemaServiceProxy(BundleContext bundleContext, ServiceReference<SchemaService> ref) {
+        public GlobalSchemaServiceProxy(final BundleContext bundleContext, final ServiceReference<SchemaService> ref) {
             this.bundleContext = bundleContext;
             this.reference = ref;
             this.delegate = bundleContext.getService(reference);
@@ -83,29 +83,42 @@ public final class SchemaServiceImplSingletonModule extends
         public void close() throws Exception {
             if (delegate != null) {
                 delegate = null;
-                bundleContext.ungetService(reference);
+
+                try {
+                    bundleContext.ungetService(reference);
+                } catch (IllegalStateException e) {
+                    // Indicates the service was already unregistered which can happen normally
+                    // on shutdown.
+                    LOG.debug( "Error unregistering service", e );
+                }
+
                 reference = null;
                 bundleContext = null;
             }
         }
 
-        public void addModule(Module arg0) {
+        @Override
+        public void addModule(final Module arg0) {
             delegate.addModule(arg0);
         }
 
+        @Override
         public SchemaContext getGlobalContext() {
             return delegate.getGlobalContext();
         }
 
+        @Override
         public SchemaContext getSessionContext() {
             return delegate.getSessionContext();
         }
 
-        public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(SchemaServiceListener arg0) {
+        @Override
+        public ListenerRegistration<SchemaServiceListener> registerSchemaServiceListener(final SchemaServiceListener arg0) {
             return delegate.registerSchemaServiceListener(arg0);
         }
 
-        public void removeModule(Module arg0) {
+        @Override
+        public void removeModule(final Module arg0) {
             delegate.removeModule(arg0);
         }
 
index 827e4ca63d524d94cf9824c2e989bebdb54a9ac8..3de07fc2abee209f0bbab84e822614604aea4bc9 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import com.google.common.collect.Maps;
 
 public abstract class TranslatingDataChangeEvent implements
-        DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
+DataChangeEvent<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> {
 
     private TranslatingDataChangeEvent() {
     }
@@ -98,7 +98,6 @@ public abstract class TranslatingDataChangeEvent implements
         return null;
     }
 
-    @SuppressWarnings({ "rawtypes", "unchecked" })
     private final static class OperationalChangeEvent extends TranslatingDataChangeEvent {
 
         private final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> delegate;
@@ -106,7 +105,7 @@ public abstract class TranslatingDataChangeEvent implements
         private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
 
         public OperationalChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
-                                        final DataNormalizer normalizer) {
+                final DataNormalizer normalizer) {
             this.delegate = change;
             this.normalizer = normalizer;
         }
@@ -179,7 +178,7 @@ public abstract class TranslatingDataChangeEvent implements
         private Map<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> updatedCache;
 
         public ConfigurationChangeEvent(final AsyncDataChangeEvent<InstanceIdentifier, NormalizedNode<?, ?>> change,
-                                        final DataNormalizer normalizer) {
+                final DataNormalizer normalizer) {
             this.delegate = change;
             this.normalizer = normalizer;
         }
index 4e3aa4911365988c916918b19a0accadf38372cd..15479be462ac6580ddc50f2ec19de45ae0b1fd45 100644 (file)
@@ -1,21 +1,27 @@
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import com.google.common.base.Optional;
-import com.google.common.primitives.UnsignedLong;
 
+/**
+ * An implementation of apply operation which fails to do anything,
+ * consistently. An instance of this class is used by the data tree
+ * if it does not have a SchemaContext attached and hence cannot
+ * perform anything meaningful.
+ */
 final class AlwaysFailOperation implements ModificationApplyOperation {
-
     @Override
-    public Optional<StoreMetadataNode> apply(final NodeModification modification,
-            final Optional<StoreMetadataNode> storeMeta, final UnsignedLong subtreeVersion) {
+    public Optional<TreeNode> apply(final ModifiedNode modification,
+            final Optional<TreeNode> storeMeta, final Version subtreeVersion) {
         throw new IllegalStateException("Schema Context is not available.");
     }
 
     @Override
-    public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> storeMetadata) {
+    public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<TreeNode> storeMetadata) {
         throw new IllegalStateException("Schema Context is not available.");
     }
 
@@ -25,7 +31,7 @@ final class AlwaysFailOperation implements ModificationApplyOperation {
     }
 
     @Override
-    public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
+    public void verifyStructure(final ModifiedNode modification) {
         throw new IllegalStateException("Schema Context is not available.");
     }
 }
\ 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/tree/data/DataNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java
new file mode 100644 (file)
index 0000000..dc89148
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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.dom.store.impl.tree.data;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
+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.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+/**
+ * Base strategy for applying changes to a ContainerNode, irrespective of its
+ * actual type.
+ *
+ * @param <T> Type of the container node
+ */
+abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends NormalizedNodeContainerModificationStrategy {
+
+    private final T schema;
+    private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
+            .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {
+
+                @Override
+                public ModificationApplyOperation apply(final PathArgument identifier) {
+                    if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
+                        return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier);
+                    }
+
+                    DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType());
+                    if (child == null) {
+                        return null;
+                    }
+                    return from(child);
+                }
+            }));
+
+    protected DataNodeContainerModificationStrategy(final T schema,
+            final Class<? extends NormalizedNode<?, ?>> nodeClass) {
+        super(nodeClass);
+        this.schema = schema;
+    }
+
+    protected T getSchema() {
+        return schema;
+    }
+
+    @Override
+    public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+        try {
+            return Optional.<ModificationApplyOperation> fromNullable(childCache.get(identifier));
+        } catch (ExecutionException e) {
+            return Optional.absent();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("rawtypes")
+    protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + " [" + schema + "]";
+    }
+
+    public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy<AugmentationSchema> {
+
+        protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
+            super(createAugmentProxy(schema,resolved), AugmentationNode.class);
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof AugmentationNode);
+            return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original);
+        }
+
+
+        private static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
+            Set<DataSchemaNode> realChildSchemas = new HashSet<>();
+            for(DataSchemaNode augChild : schema.getChildNodes()) {
+                realChildSchemas.add(resolved.getDataChildByName(augChild.getQName()));
+            }
+            return new AugmentationSchemaProxy(schema, realChildSchemas);
+        }
+    }
+
+    public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
+
+        public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) {
+            super(schemaNode, ContainerNode.class);
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof ContainerNode);
+            return ImmutableContainerNodeBuilder.create((ContainerNode) original);
+        }
+    }
+
+    public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
+
+        protected ListEntryModificationStrategy(final ListSchemaNode schema) {
+            super(schema, MapEntryNode.class);
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof MapEntryNode);
+            return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
+        }
+    }
+
+    public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
+
+        public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) {
+            super(schemaNode, UnkeyedListEntryNode.class);
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof UnkeyedListEntryNode);
+            return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original);
+        }
+    }
+}
\ No newline at end of file
index f04e379dd95824dd965c0ac8c5c998d9f0dafd83..d3495b542a25f4a05ffa1a2f83e92808c56e6ca3 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
@@ -34,9 +35,9 @@ final class InMemoryDataTree implements DataTree {
     private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
     private ModificationApplyOperation applyOper = new AlwaysFailOperation();
     private SchemaContext currentSchemaContext;
-    private StoreMetadataNode rootNode;
+    private TreeNode rootNode;
 
-    public InMemoryDataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) {
+    public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) {
         this.rootNode = Preconditions.checkNotNull(rootNode);
 
         if (schemaContext != null) {
@@ -80,28 +81,28 @@ final class InMemoryDataTree implements DataTree {
     }
 
     @Override
-    public void validate(DataTreeModification modification) throws DataPreconditionFailedException {
+    public void validate(final DataTreeModification modification) throws DataPreconditionFailedException {
         Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
 
         final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
-        m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode));
+        m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.<TreeNode>of(rootNode));
     }
 
     @Override
-    public synchronized DataTreeCandidate prepare(DataTreeModification modification) {
+    public synchronized DataTreeCandidate prepare(final DataTreeModification modification) {
         Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
 
         final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
-        final NodeModification root = m.getRootModification();
+        final ModifiedNode root = m.getRootModification();
 
-        if (root.getModificationType() == ModificationType.UNMODIFIED) {
+        if (root.getType() == ModificationType.UNMODIFIED) {
             return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
         }
 
         rwLock.writeLock().lock();
         try {
-            // FIXME: rootNode needs to be a read-write snapshot here...
-            final Optional<StoreMetadataNode> newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion()));
+            final Optional<TreeNode> newRoot = m.getStrategy().apply(m.getRootModification(),
+                    Optional.<TreeNode>of(rootNode), rootNode.getSubtreeVersion().next());
             Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
             return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
         } finally {
@@ -110,7 +111,7 @@ final class InMemoryDataTree implements DataTree {
     }
 
     @Override
-    public synchronized void commit(DataTreeCandidate candidate) {
+    public synchronized void commit(final DataTreeCandidate candidate) {
         if (candidate instanceof NoopDataTreeCandidate) {
             return;
         }
@@ -118,7 +119,7 @@ final class InMemoryDataTree implements DataTree {
         Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass());
         final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
 
-        LOG.debug("Updating Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion());
+        LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot());
 
         if (LOG.isTraceEnabled()) {
             LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData()));
index 72562f0a72bd218518a6a2cc0441c1f66af9e4be..bafea6bd9770c25c3e3f74d87cc9a60ebde4e200 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 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;
@@ -13,38 +14,42 @@ import com.google.common.collect.Iterables;
 
 final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
     private static abstract class AbstractNode implements DataTreeCandidateNode {
-        private final StoreMetadataNode newMeta;
-        private final StoreMetadataNode oldMeta;
-        private final NodeModification mod;
+        private final ModifiedNode mod;
+        private final TreeNode newMeta;
+        private final TreeNode oldMeta;
 
-        protected AbstractNode(final NodeModification mod,
-                final StoreMetadataNode oldMeta, final StoreMetadataNode newMeta) {
+        protected AbstractNode(final ModifiedNode mod,
+                final TreeNode oldMeta, final TreeNode newMeta) {
             this.newMeta = newMeta;
             this.oldMeta = oldMeta;
             this.mod = Preconditions.checkNotNull(mod);
         }
 
-        protected final NodeModification getMod() {
+        protected final ModifiedNode getMod() {
             return mod;
         }
 
-        protected final StoreMetadataNode getNewMeta() {
+        protected final TreeNode getNewMeta() {
             return newMeta;
         }
 
-        protected final StoreMetadataNode getOldMeta() {
+        protected final TreeNode getOldMeta() {
             return oldMeta;
         }
 
-        private static final StoreMetadataNode childMeta(final StoreMetadataNode parent, final PathArgument id) {
-            return parent == null ? null : parent.getChild(id).orNull();
+        private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) {
+            if (parent != null) {
+                return parent.getChild(id).orNull();
+            } else {
+                return null;
+            }
         }
 
         @Override
         public Iterable<DataTreeCandidateNode> getChildNodes() {
-            return Iterables.transform(mod.getModifications(), new Function<NodeModification, DataTreeCandidateNode>() {
+            return Iterables.transform(mod.getChildren(), new Function<ModifiedNode, DataTreeCandidateNode>() {
                 @Override
-                public DataTreeCandidateNode apply(final NodeModification input) {
+                public DataTreeCandidateNode apply(final ModifiedNode input) {
                     final PathArgument id = input.getIdentifier();
                     return new ChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id));
                 }
@@ -53,14 +58,15 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
 
         @Override
         public ModificationType getModificationType() {
-            return mod.getModificationType();
+            return mod.getType();
         }
 
-        private Optional<NormalizedNode<?, ?>> optionalData(StoreMetadataNode meta) {
-            if (meta == null) {
+        private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
+            if (meta != null) {
+                return Optional.<NormalizedNode<?,?>>of(meta.getData());
+            } else {
                 return Optional.absent();
             }
-            return Optional.<NormalizedNode<?,?>>of(meta.getData());
         }
 
         @Override
@@ -75,7 +81,7 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
     }
 
     private static final class ChildNode extends AbstractNode {
-        public ChildNode(NodeModification mod, StoreMetadataNode oldMeta, StoreMetadataNode newMeta) {
+        public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
             super(mod, oldMeta, newMeta);
         }
 
@@ -86,7 +92,7 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
     }
 
     private static final class RootNode extends AbstractNode {
-        public RootNode(NodeModification mod, StoreMetadataNode oldMeta, StoreMetadataNode newMeta) {
+        public RootNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
             super(mod, oldMeta, newMeta);
         }
 
@@ -98,17 +104,17 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
 
     private final RootNode root;
 
-    InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot,
-            final StoreMetadataNode oldRoot, final StoreMetadataNode newRoot) {
+    InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot,
+            final TreeNode beforeRoot, final TreeNode afterRoot) {
         super(rootPath);
-        this.root = new RootNode(modificationRoot, oldRoot, newRoot);
+        this.root = new RootNode(modificationRoot, beforeRoot, afterRoot);
     }
 
-    StoreMetadataNode getAfterRoot() {
+    TreeNode getAfterRoot() {
         return root.getNewMeta();
     }
 
-    StoreMetadataNode getBeforeRoot() {
+    TreeNode getBeforeRoot() {
         return root.getOldMeta();
     }
 
index 7614611ab287913e4efa2b2a88e2fe02c393c946..4640be43e71cc431e327e45711ec3999862d73fa 100644 (file)
@@ -1,6 +1,8 @@
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -10,26 +12,26 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  * A factory for creating in-memory data trees.
  */
 public final class InMemoryDataTreeFactory implements DataTreeFactory {
-       private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory();
+    private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory();
 
-       private InMemoryDataTreeFactory() {
-               // Never instantiated externally
-       }
+    private InMemoryDataTreeFactory() {
+        // Never instantiated externally
+    }
 
-       @Override
-       public InMemoryDataTree create() {
-               final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
-               final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
+    @Override
+    public InMemoryDataTree create() {
+        final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
+        final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
 
-               return new InMemoryDataTree(StoreMetadataNode.createEmpty(data), null);
-       }
+        return new InMemoryDataTree(TreeNodeFactory.createTreeNode(data, Version.initial()), null);
+    }
 
-       /**
-        * Get an instance of this factory. This method cannot fail.
-        *
-        * @return Data tree factory instance.
-        */
-       public static final InMemoryDataTreeFactory getInstance() {
-               return INSTANCE;
-       }
+    /**
+     * Get an instance of this factory. This method cannot fail.
+     *
+     * @return Data tree factory instance.
+     */
+    public static final InMemoryDataTreeFactory getInstance() {
+        return INSTANCE;
+    }
 }
index 1540feca661aed15b7a41ffdfa40f6077e9f712d..c05ed4b442d0fa964fa94d88fb9526a5c88673c6 100644 (file)
@@ -7,14 +7,13 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
-import static com.google.common.base.Preconditions.checkState;
-
 import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+import javax.annotation.concurrent.GuardedBy;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 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;
@@ -28,26 +27,20 @@ import com.google.common.base.Preconditions;
 
 final class InMemoryDataTreeModification implements DataTreeModification {
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
-
-    /*
-     * FIXME: the thread safety of concurrent write/delete/read/seal operations
-     *        needs to be evaluated.
-     */
-    private static final AtomicIntegerFieldUpdater<InMemoryDataTreeModification> SEALED_UPDATER =
-            AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed");
-    private volatile int sealed = 0;
-
     private final ModificationApplyOperation strategyTree;
     private final InMemoryDataTreeSnapshot snapshot;
-    private final NodeModification rootNode;
+    private final ModifiedNode rootNode;
+
+    @GuardedBy("this")
+    private boolean sealed = false;
 
     InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) {
         this.snapshot = Preconditions.checkNotNull(snapshot);
         this.strategyTree = Preconditions.checkNotNull(resolver);
-        this.rootNode = NodeModification.createUnmodified(snapshot.getRootNode());
+        this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode());
     }
 
-    NodeModification getRootModification() {
+    ModifiedNode getRootModification() {
         return rootNode;
     }
 
@@ -56,13 +49,13 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> value) {
+    public synchronized void write(final InstanceIdentifier path, final NormalizedNode<?, ?> value) {
         checkSealed();
         resolveModificationFor(path).write(value);
     }
 
     @Override
-    public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+    public synchronized void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
         checkSealed();
         mergeImpl(resolveModificationFor(path),data);
     }
@@ -81,23 +74,23 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public void delete(final InstanceIdentifier path) {
+    public synchronized void delete(final InstanceIdentifier path) {
         checkSealed();
         resolveModificationFor(path).delete();
     }
 
     @Override
-    public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
+    public synchronized Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
         /*
          * Walk the tree from the top, looking for the first node between root and
          * the requested path which has been modified. If no such node exists,
          * we use the node itself.
          */
-        final Entry<InstanceIdentifier, NodeModification> entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, NodeModification.IS_TERMINAL_PREDICATE);
+        final Entry<InstanceIdentifier, ModifiedNode> entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE);
         final InstanceIdentifier key = entry.getKey();
-        final NodeModification mod = entry.getValue();
+        final ModifiedNode mod = entry.getValue();
 
-        final Optional<StoreMetadataNode> result = resolveSnapshot(key, mod);
+        final Optional<TreeNode> result = resolveSnapshot(key, mod);
         if (result.isPresent()) {
             NormalizedNode<?, ?> data = result.get().getData();
             return NormalizedNodeUtils.findNode(key, data, path);
@@ -106,15 +99,16 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         }
     }
 
-    private Optional<StoreMetadataNode> resolveSnapshot(final InstanceIdentifier path,
-            final NodeModification modification) {
+    private Optional<TreeNode> resolveSnapshot(final InstanceIdentifier path,
+            final ModifiedNode modification) {
+        final Optional<Optional<TreeNode>> potentialSnapshot = modification.getSnapshotCache();
+        if(potentialSnapshot.isPresent()) {
+            return potentialSnapshot.get();
+        }
+
         try {
-            Optional<Optional<StoreMetadataNode>> potentialSnapshot = modification.getSnapshotCache();
-            if(potentialSnapshot.isPresent()) {
-                return potentialSnapshot.get();
-            }
             return resolveModificationStrategy(path).apply(modification, modification.getOriginal(),
-                    StoreUtils.increase(snapshot.getRootNode().getSubtreeVersion()));
+                    snapshot.getRootNode().getSubtreeVersion().next());
         } catch (Exception e) {
             LOG.error("Could not create snapshot for {}:{}", path,modification,e);
             throw e;
@@ -127,7 +121,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     private OperationWithModification resolveModificationFor(final InstanceIdentifier path) {
-        NodeModification modification = rootNode;
+        ModifiedNode modification = rootNode;
         // We ensure strategy is present.
         ModificationApplyOperation operation = resolveModificationStrategy(path);
         for (PathArgument pathArg : path.getPath()) {
@@ -137,14 +131,15 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public void seal() {
-        final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1);
-        Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree.");
+    public synchronized void seal() {
+        Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
+        sealed = true;
         rootNode.seal();
     }
 
+    @GuardedBy("this")
     private void checkSealed() {
-        checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
+        Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed.");
     }
 
     @Override
@@ -153,7 +148,9 @@ final class InMemoryDataTreeModification implements DataTreeModification {
     }
 
     @Override
-    public DataTreeModification newModification() {
+    public synchronized DataTreeModification newModification() {
+        Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification");
+
         // FIXME: transaction chaining
         throw new UnsupportedOperationException("Implement this as part of transaction chaining");
     }
index ce2d8c9bd43661e03e0d88cebca24805a62f3786..ee91e625187046f8aef429b756224959c58f3075 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
@@ -12,16 +13,16 @@ import com.google.common.base.Preconditions;
 final class InMemoryDataTreeSnapshot implements DataTreeSnapshot {
     private final ModificationApplyOperation applyOper;
     private final SchemaContext schemaContext;
-    private final StoreMetadataNode rootNode;
+    private final TreeNode rootNode;
 
-    InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode,
+    InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode,
             final ModificationApplyOperation applyOper) {
         this.schemaContext = Preconditions.checkNotNull(schemaContext);
         this.rootNode = Preconditions.checkNotNull(rootNode);
         this.applyOper = Preconditions.checkNotNull(applyOper);
     }
 
-    StoreMetadataNode getRootNode() {
+    TreeNode getRootNode() {
         return rootNode;
     }
 
index 5b4cd565e5cbf5e553fd640777a2a2599ed64b8c..10f39a8cefa045bfce6b356b63d3c1c0b3782c4f 100644 (file)
@@ -9,15 +9,16 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 import com.google.common.base.Optional;
-import com.google.common.primitives.UnsignedLong;
 
 /**
  *
- * Operation responsible for applying {@link NodeModification} on tree.
+ * Operation responsible for applying {@link ModifiedNode} on tree.
  *
  * Operation is composite - operation on top level node consists of
  * suboperations on child nodes. This allows to walk operation hierarchy and
@@ -29,7 +30,7 @@ import com.google.common.primitives.UnsignedLong;
  * Implementations MUST expose all nested suboperations which operates on child
  * nodes expose via {@link #getChild(PathArgument)} method.
  * <li>Same suboperations SHOULD be used when invoked via
- * {@link #apply(NodeModification, Optional)} if applicable.
+ * {@link #apply(ModifiedNode, Optional)} if applicable.
  *
  *
  * Hierarchical composite operation which is responsible for applying
@@ -54,10 +55,10 @@ interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOper
      *             If it is not possible to apply Operation on provided Metadata
      *             node
      * @return new {@link StoreMetadataNode} if operation resulted in updating
-     *         node, {@link Optional#absent()} if {@link NodeModification}
+     *         node, {@link Optional#absent()} if {@link ModifiedNode}
      *         resulted in deletion of this node.
      */
-    Optional<StoreMetadataNode> apply(NodeModification modification, Optional<StoreMetadataNode> storeMeta, UnsignedLong subtreeVersion);
+    Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version subtreeVersion);
 
     /**
      *
@@ -67,7 +68,7 @@ interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOper
      * @param modification to be verified.
      * @throws IllegalArgumentException If provided NodeModification does not adhere to the structure.
      */
-    void verifyStructure(NodeModification modification) throws IllegalArgumentException;
+    void verifyStructure(ModifiedNode modification) throws IllegalArgumentException;
 
     /**
      * Returns a suboperation for specified tree node
@@ -88,5 +89,5 @@ interface ModificationApplyOperation extends StoreTreeNode<ModificationApplyOper
      *         false if modification is no applicable
      * @throws DataPreconditionFailedException
      */
-    void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
+    void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional<TreeNode> current) throws DataPreconditionFailedException;
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java
new file mode 100644 (file)
index 0000000..f83ea1a
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * 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.dom.store.impl.tree.data;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+
+/**
+ * Node Modification Node and Tree
+ *
+ * Tree which structurally resembles data tree and captures client modifications
+ * to the data store tree.
+ *
+ * This tree is lazily created and populated via {@link #modifyChild(PathArgument)}
+ * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}.
+ */
+final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<PathArgument>, NodeModification {
+
+    public static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = new Predicate<ModifiedNode>() {
+        @Override
+        public boolean apply(final ModifiedNode input) {
+            switch (input.getType()) {
+            case DELETE:
+            case MERGE:
+            case WRITE:
+                return true;
+            case SUBTREE_MODIFIED:
+            case UNMODIFIED:
+                return false;
+            }
+
+            throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getType()));
+        }
+    };
+
+    private final Map<PathArgument, ModifiedNode> children = new LinkedHashMap<>();
+    private final Optional<TreeNode> original;
+    private final PathArgument identifier;
+    private ModificationType modificationType = ModificationType.UNMODIFIED;
+    private Optional<TreeNode> snapshotCache;
+    private NormalizedNode<?, ?> value;
+
+    private ModifiedNode(final PathArgument identifier, final Optional<TreeNode> original) {
+        this.identifier = identifier;
+        this.original = original;
+    }
+
+    /**
+     *
+     *
+     * @return
+     */
+    public NormalizedNode<?, ?> getWrittenValue() {
+        return value;
+    }
+
+    @Override
+    public PathArgument getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     *
+     * Returns original store metadata
+     * @return original store metadata
+     */
+    @Override
+    public Optional<TreeNode> getOriginal() {
+        return original;
+    }
+
+    /**
+     * Returns modification type
+     *
+     * @return modification type
+     */
+    @Override
+    public ModificationType getType() {
+        return modificationType;
+    }
+
+    /**
+     *
+     * Returns child modification if child was modified
+     *
+     * @return Child modification if direct child or it's subtree
+     *  was modified.
+     *
+     */
+    @Override
+    public Optional<ModifiedNode> getChild(final PathArgument child) {
+        return Optional.<ModifiedNode> fromNullable(children.get(child));
+    }
+
+    /**
+     *
+     * Returns child modification if child was modified, creates {@link ModifiedNode}
+     * for child otherwise.
+     *
+     * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED}
+     * changes modification type to {@link ModificationType#SUBTREE_MODIFIED}
+     *
+     * @param child
+     * @return {@link ModifiedNode} for specified child, with {@link #getOriginal()}
+     *         containing child metadata if child was present in original data.
+     */
+    public ModifiedNode modifyChild(final PathArgument child) {
+        clearSnapshot();
+        if (modificationType == ModificationType.UNMODIFIED) {
+            updateModificationType(ModificationType.SUBTREE_MODIFIED);
+        }
+        final ModifiedNode potential = children.get(child);
+        if (potential != null) {
+            return potential;
+        }
+
+        final Optional<TreeNode> currentMetadata;
+        if (original.isPresent()) {
+            final TreeNode orig = original.get();
+            currentMetadata = orig.getChild(child);
+        } else {
+            currentMetadata = Optional.absent();
+        }
+
+        ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata);
+        children.put(child, newlyCreated);
+        return newlyCreated;
+    }
+
+    /**
+     *
+     * Returns all recorded direct child modification
+     *
+     * @return all recorded direct child modifications
+     */
+    @Override
+    public Iterable<ModifiedNode> getChildren() {
+        return children.values();
+    }
+
+    /**
+     *
+     * Records a delete for associated node.
+     *
+     */
+    public void delete() {
+        clearSnapshot();
+        updateModificationType(ModificationType.DELETE);
+        children.clear();
+        this.value = null;
+    }
+
+    /**
+     *
+     * Records a write for associated node.
+     *
+     * @param value
+     */
+    public void write(final NormalizedNode<?, ?> value) {
+        clearSnapshot();
+        updateModificationType(ModificationType.WRITE);
+        children.clear();
+        this.value = value;
+    }
+
+    public void merge(final NormalizedNode<?, ?> data) {
+        clearSnapshot();
+        updateModificationType(ModificationType.MERGE);
+        // FIXME: Probably merge with previous value.
+        this.value = data;
+    }
+
+    void seal() {
+        clearSnapshot();
+        for (ModifiedNode child : children.values()) {
+            child.seal();
+        }
+    }
+
+    private void clearSnapshot() {
+        snapshotCache = null;
+    }
+
+    public Optional<TreeNode> storeSnapshot(final Optional<TreeNode> snapshot) {
+        snapshotCache = snapshot;
+        return snapshot;
+    }
+
+    public Optional<Optional<TreeNode>> getSnapshotCache() {
+        return Optional.fromNullable(snapshotCache);
+    }
+
+    @GuardedBy("this")
+    private void updateModificationType(final ModificationType type) {
+        modificationType = type;
+        clearSnapshot();
+    }
+
+    @Override
+    public String toString() {
+        return "NodeModification [identifier=" + identifier + ", modificationType="
+                + modificationType + ", childModification=" + children + "]";
+    }
+
+    public static ModifiedNode createUnmodified(final TreeNode metadataTree) {
+        return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree));
+    }
+}
index f2720b57aebe7267a7ed377a89dc4cf12322aa45..2639d050efe28b8b0903636e987b5c134e79c922 100644 (file)
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import javax.annotation.concurrent.GuardedBy;
-
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-
-/**
- * Node Modification Node and Tree
- *
- * Tree which structurally resembles data tree and captures client modifications
- * to the data store tree.
- *
- * This tree is lazily created and populated via {@link #modifyChild(PathArgument)}
- * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}.
- */
-final class NodeModification implements StoreTreeNode<NodeModification>, Identifiable<PathArgument> {
-
-    public static final Predicate<NodeModification> IS_TERMINAL_PREDICATE = new Predicate<NodeModification>() {
-        @Override
-        public boolean apply(final NodeModification input) {
-            return input.getModificationType() == ModificationType.WRITE //
-                    || input.getModificationType() == ModificationType.DELETE //
-                    || input.getModificationType() == ModificationType.MERGE;
-        }
-    };
-    private final PathArgument identifier;
-    private ModificationType modificationType = ModificationType.UNMODIFIED;
-
-
-    private final Optional<StoreMetadataNode> original;
-
-    private NormalizedNode<?, ?> value;
-
-    private Optional<StoreMetadataNode> snapshotCache;
-
-    private final Map<PathArgument, NodeModification> childModification;
-
-    @GuardedBy("this")
-    private boolean sealed = false;
-
-    protected NodeModification(final PathArgument identifier, final Optional<StoreMetadataNode> original) {
-        this.identifier = identifier;
-        this.original = original;
-        childModification = new LinkedHashMap<>();
-    }
-
-    /**
-     *
-     *
-     * @return
-     */
-    public NormalizedNode<?, ?> getWrittenValue() {
-        return value;
-    }
-
-    @Override
-    public PathArgument getIdentifier() {
-        return identifier;
-    }
-
-    /**
-     *
-     * Returns original store metadata
-     * @return original store metadata
-     */
-    public final Optional<StoreMetadataNode> getOriginal() {
-        return original;
-    }
-
-    /**
-     * Returns modification type
-     *
-     * @return modification type
-     */
-    public final ModificationType getModificationType() {
-        return modificationType;
-    }
-
-    /**
-     *
-     * Returns child modification if child was modified
-     *
-     * @return Child modification if direct child or it's subtree
-     *  was modified.
-     *
-     */
-    @Override
-    public Optional<NodeModification> getChild(final PathArgument child) {
-        return Optional.<NodeModification> fromNullable(childModification.get(child));
-    }
-
-    /**
-     *
-     * Returns child modification if child was modified, creates {@link NodeModification}
-     * for child otherwise.
-     *
-     * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED}
-     * changes modification type to {@link ModificationType#SUBTREE_MODIFIED}
-     *
-     * @param child
-     * @return {@link NodeModification} for specified child, with {@link #getOriginal()}
-     *  containing child metadata if child was present in original data.
-     */
-    public synchronized NodeModification modifyChild(final PathArgument child) {
-        checkSealed();
-        clearSnapshot();
-        if(modificationType == ModificationType.UNMODIFIED) {
-            updateModificationType(ModificationType.SUBTREE_MODIFIED);
-        }
-        final NodeModification potential = childModification.get(child);
-        if (potential != null) {
-            return potential;
-        }
-        Optional<StoreMetadataNode> currentMetadata = Optional.absent();
-        if(original.isPresent()) {
-            currentMetadata = original.get().getChild(child);
-        }
-        NodeModification newlyCreated = new NodeModification(child,currentMetadata);
-        childModification.put(child, newlyCreated);
-        return newlyCreated;
-    }
-
-    /**
-     *
-     * Returns all recorded direct child modification
-     *
-     * @return all recorded direct child modifications
-     */
-    public Iterable<NodeModification> getModifications() {
-        return childModification.values();
-    }
-
-
-    /**
-     *
-     * Records a delete for associated node.
-     *
-     */
-    public synchronized void delete() {
-        checkSealed();
-        clearSnapshot();
-        updateModificationType(ModificationType.DELETE);
-        childModification.clear();
-        this.value = null;
-    }
-
-    /**
-     *
-     * Records a write for associated node.
-     *
-     * @param value
-     */
-    public synchronized void write(final NormalizedNode<?, ?> value) {
-        checkSealed();
-        clearSnapshot();
-        updateModificationType(ModificationType.WRITE);
-        childModification.clear();
-        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.");
-    }
-
-    public synchronized void seal() {
-        sealed = true;
-        clearSnapshot();
-        for(NodeModification child : childModification.values()) {
-            child.seal();
-        }
-    }
-
-    private void clearSnapshot() {
-        snapshotCache = null;
-    }
-
-    public Optional<StoreMetadataNode> storeSnapshot(final Optional<StoreMetadataNode> snapshot) {
-        snapshotCache = snapshot;
-        return snapshot;
-    }
-
-    public Optional<Optional<StoreMetadataNode>> getSnapshotCache() {
-        return Optional.fromNullable(snapshotCache);
-    }
-
-    public boolean hasAdditionalModifications() {
-        return !childModification.isEmpty();
-    }
-
-    @GuardedBy("this")
-    private void updateModificationType(final ModificationType type) {
-        modificationType = type;
-        clearSnapshot();
-    }
-
-    @Override
-    public String toString() {
-        return "NodeModification [identifier=" + identifier + ", modificationType="
-                + modificationType + ", childModification=" + childModification + "]";
-    }
-
-    public static NodeModification createUnmodified(final StoreMetadataNode metadataTree) {
-        return new NodeModification(metadataTree.getIdentifier(), Optional.of(metadataTree));
-    }
 
+interface NodeModification extends Identifiable<PathArgument> {
+    ModificationType getType();
+    Optional<TreeNode> getOriginal();
+    Iterable<? extends NodeModification> getChildren();
 }
index 8a467484141bf9631cd05b26ae09b85f1943d6fd..2ef85cbcb7e548cb6fa1ccd932e7dddbb651ace3 100644 (file)
@@ -46,9 +46,9 @@ final class NoopDataTreeCandidate extends AbstractDataTreeCandidate {
         }
     };
 
-    protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot) {
+    protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot) {
         super(rootPath);
-        Preconditions.checkArgument(modificationRoot.getModificationType() == ModificationType.UNMODIFIED);
+        Preconditions.checkArgument(modificationRoot.getType() == ModificationType.UNMODIFIED);
     }
 
     @Override
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java
new file mode 100644 (file)
index 0000000..3a3af5e
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * 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.dom.store.impl.tree.data;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
+
+    private final Class<? extends NormalizedNode<?, ?>> nodeClass;
+
+    protected NormalizedNodeContainerModificationStrategy(final Class<? extends NormalizedNode<?, ?>> nodeClass) {
+        this.nodeClass = nodeClass;
+    }
+
+    @Override
+    public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException {
+        if (modification.getType() == ModificationType.WRITE) {
+
+        }
+        for (ModifiedNode childModification : modification.getChildren()) {
+            resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification);
+        }
+    }
+
+    @Override
+    protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification,
+            final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        // FIXME: Implement proper write check for replacement of node container
+        //        prerequisite is to have transaction chain available for clients
+        //        otherwise this will break chained writes to same node.
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
+        checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
+        checkArgument(writtenValue instanceof NormalizedNodeContainer);
+
+        NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue;
+        for (Object child : container.getValue()) {
+            checkArgument(child instanceof NormalizedNode);
+
+            /*
+             * FIXME: fail-fast semantics:
+             *
+             * We can validate the data structure here, aborting the commit
+             * before it ever progresses to being committed.
+             */
+        }
+    }
+
+    @Override
+    protected TreeNode applyWrite(final ModifiedNode modification,
+            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+        final Version nodeVersion;
+        if (currentMeta.isPresent()) {
+            nodeVersion = currentMeta.get().getVersion().next();
+        } else {
+            nodeVersion = subtreeVersion;
+        }
+
+        final NormalizedNode<?, ?> newValue = modification.getWrittenValue();
+        final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion);
+
+        if (Iterables.isEmpty(modification.getChildren())) {
+            return newValueMeta;
+        }
+
+        /*
+         * This is where things get interesting. The user has performed a write and
+         * then she applied some more modifications to it. So we need to make sense
+         * of that an apply the operations on top of the written value. We could have
+         * done it during the write, but this operation is potentially expensive, so
+         * we have left it out of the fast path.
+         *
+         * As it turns out, once we materialize the written data, we can share the
+         * code path with the subtree change. So let's create an unsealed TreeNode
+         * and run the common parts on it -- which end with the node being sealed.
+         */
+        final MutableTreeNode mutable = newValueMeta.mutable();
+        mutable.setSubtreeVersion(subtreeVersion);
+
+        @SuppressWarnings("rawtypes")
+        final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
+
+        return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren());
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data,
+            final Version nodeVersion, final Iterable<ModifiedNode> modifications) {
+
+        for (ModifiedNode mod : modifications) {
+            final PathArgument id = mod.getIdentifier();
+            final Optional<TreeNode> cm = meta.getChild(id);
+
+            Optional<TreeNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
+            if (result.isPresent()) {
+                final TreeNode tn = result.get();
+                meta.addChild(tn);
+                data.addChild(tn.getData());
+            } else {
+                meta.removeChild(id);
+                data.removeChild(id);
+            }
+        }
+
+        meta.setData(data.build());
+        return meta.seal();
+    }
+
+    @Override
+    protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+            final Version subtreeVersion) {
+        // For Node Containers - merge is same as subtree change - we only replace children.
+        return applySubtreeChange(modification, currentMeta, subtreeVersion);
+    }
+
+    @Override
+    public TreeNode applySubtreeChange(final ModifiedNode modification,
+            final TreeNode currentMeta, final Version subtreeVersion) {
+        // Bump subtree version to its new target
+        final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next();
+
+        final MutableTreeNode newMeta = currentMeta.mutable();
+        newMeta.setSubtreeVersion(updatedSubtreeVersion);
+
+        @SuppressWarnings("rawtypes")
+        NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
+
+        return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren());
+    }
+
+    @Override
+    protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification,
+            final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction.");
+        checkChildPreconditions(path, modification, current);
+    }
+
+    private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        final TreeNode currentMeta = current.get();
+        for (NodeModification childMod : modification.getChildren()) {
+            final PathArgument childId = childMod.getIdentifier();
+            final Optional<TreeNode> childMeta = currentMeta.getChild(childId);
+
+            InstanceIdentifier childPath = StoreUtils.append(path, childId);
+            resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta);
+        }
+    }
+
+    @Override
+    protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification,
+            final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        if(current.isPresent()) {
+            checkChildPreconditions(path, modification,current);
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
+
+    public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Map<PathArgument, ModificationApplyOperation> childNodes;
+
+        public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
+            super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
+            ImmutableMap.Builder<PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
+
+            for (ChoiceCaseNode caze : schemaNode.getCases()) {
+                for (DataSchemaNode cazeChild : caze.getChildNodes()) {
+                    SchemaAwareApplyOperation childNode = from(cazeChild);
+                    child.put(new NodeIdentifier(cazeChild.getQName()), childNode);
+                }
+            }
+            childNodes = child.build();
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+            return Optional.fromNullable(childNodes.get(child));
+        }
+
+        @Override
+        @SuppressWarnings("rawtypes")
+        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode);
+            return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original);
+        }
+    }
+
+    public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Optional<ModificationApplyOperation> entryStrategy;
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
+            super((Class) LeafSetNode.class);
+            entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof OrderedLeafSetNode<?>);
+            return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>) original);
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+            if (identifier instanceof NodeWithValue) {
+                return entryStrategy;
+            }
+            return Optional.absent();
+        }
+    }
+
+    public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Optional<ModificationApplyOperation> entryStrategy;
+
+        protected OrderedMapModificationStrategy(final ListSchemaNode schema) {
+            super(OrderedMapNode.class);
+            entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof OrderedMapNode);
+            return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original);
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+            if (identifier instanceof NodeIdentifierWithPredicates) {
+                return entryStrategy;
+            }
+            return Optional.absent();
+        }
+
+        @Override
+        public String toString() {
+            return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]";
+        }
+    }
+
+    public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Optional<ModificationApplyOperation> entryStrategy;
+
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
+            super((Class) LeafSetNode.class);
+            entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof LeafSetNode<?>);
+            return ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>) original);
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+            if (identifier instanceof NodeWithValue) {
+                return entryStrategy;
+            }
+            return Optional.absent();
+        }
+    }
+
+    public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
+
+        private final Optional<ModificationApplyOperation> entryStrategy;
+
+        protected UnorderedMapModificationStrategy(final ListSchemaNode schema) {
+            super(MapNode.class);
+            entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
+        }
+
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
+            checkArgument(original instanceof MapNode);
+            return ImmutableMapNodeBuilder.create((MapNode) original);
+        }
+
+        @Override
+        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
+            if (identifier instanceof NodeIdentifierWithPredicates) {
+                return entryStrategy;
+            }
+            return Optional.absent();
+        }
+
+        @Override
+        public String toString() {
+            return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]";
+        }
+    }
+}
index fda8407a95ea842a7dc0c462cf3e7dda217d26c8..ff90d57f49795ef0927e5c7bd00f89684078d004 100644 (file)
@@ -7,19 +7,20 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
-import com.google.common.primitives.UnsignedLong;
 
 final class OperationWithModification {
 
-    private final NodeModification modification;
+    private final ModifiedNode modification;
 
     private final ModificationApplyOperation applyOperation;
 
-    private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) {
+    private OperationWithModification(final ModificationApplyOperation op, final ModifiedNode mod) {
         this.modification = mod;
         this.applyOperation = op;
     }
@@ -35,7 +36,7 @@ final class OperationWithModification {
         return this;
     }
 
-    public NodeModification getModification() {
+    public ModifiedNode getModification() {
         return modification;
     }
 
@@ -43,12 +44,12 @@ final class OperationWithModification {
         return applyOperation;
     }
 
-    public Optional<StoreMetadataNode> apply(final Optional<StoreMetadataNode> data, final UnsignedLong subtreeVersion) {
+    public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version subtreeVersion) {
         return applyOperation.apply(modification, data, subtreeVersion);
     }
 
     public static OperationWithModification from(final ModificationApplyOperation operation,
-            final NodeModification modification) {
+            final ModifiedNode modification) {
         return new OperationWithModification(operation, modification);
 
     }
@@ -60,7 +61,7 @@ final class OperationWithModification {
     }
 
     public OperationWithModification forChild(final PathArgument childId) {
-        NodeModification childMod = modification.modifyChild(childId);
+        ModifiedNode childMod = modification.modifyChild(childId);
         Optional<ModificationApplyOperation> childOp = applyOperation.getChild(childId);
         return from(childOp.get(),childMod);
     }
index 620c00791ca3a338b862ac2cc755aacaba94a1b9..bdf5667b67d92568c5b538d294ee417aabbe76df 100644 (file)
@@ -9,49 +9,28 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
-import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ContainerModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.UnkeyedListItemModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.ChoiceModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedLeafSetModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedMapModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.UnorderedLeafSetModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafModificationStrategy;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.common.QName;
 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.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
 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.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedLeafSetNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -59,17 +38,14 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.primitives.UnsignedLong;
 
 abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
+    private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class);
 
     public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) {
         if (schemaNode instanceof ContainerSchemaNode) {
@@ -86,6 +62,33 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
         throw new IllegalArgumentException("Not supported schema node type for " + schemaNode.getClass());
     }
 
+    public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
+            final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
+        AugmentationSchema augSchema = null;
+
+        allAugments:
+            for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) {
+                for (DataSchemaNode child : potential.getChildNodes()) {
+                    if (identifier.getPossibleChildNames().contains(child.getQName())) {
+                        augSchema = potential;
+                        break allAugments;
+                    }
+                }
+            }
+
+        if (augSchema != null) {
+            return new DataNodeContainerModificationStrategy.AugmentationModificationStrategy(augSchema, resolvedTree);
+        }
+        return null;
+    }
+
+    public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException {
+        if(!condition) {
+            throw new DataPreconditionFailedException(path, message);
+        }
+        return condition;
+    }
+
     private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) {
         List<QName> keyDefinition = schemaNode.getKeyDefinition();
         if (keyDefinition == null || keyDefinition.isEmpty()) {
@@ -95,7 +98,7 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
             return new OrderedMapModificationStrategy(schemaNode);
         }
 
-        return new UnorderedMapModificationStrategy(schemaNode);
+        return new NormalizedNodeContainerModificationStrategy.UnorderedMapModificationStrategy(schemaNode);
     }
 
     private static SchemaAwareApplyOperation fromLeafListSchemaNode(final LeafListSchemaNode schemaNode) {
@@ -106,25 +109,11 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
         }
     }
 
-
-    public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree,
-            final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) {
-        AugmentationSchema augSchema = null;
-
-        allAugments:
-            for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) {
-                for (DataSchemaNode child : potential.getChildNodes()) {
-                    if (identifier.getPossibleChildNames().contains(child.getQName())) {
-                        augSchema = potential;
-                        break allAugments;
-                    }
-                }
-            }
-
-        if (augSchema != null) {
-            return new AugmentationModificationStrategy(augSchema, resolvedTree);
-        }
-        return null;
+    private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws DataPreconditionFailedException {
+        checkDataPrecondition(path, original.getVersion().equals(current.getVersion()),
+                "Node was replaced by other transaction.");
+        checkDataPrecondition(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()),
+                "Node children was modified by other transaction");
     }
 
     protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) {
@@ -134,38 +123,36 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
     }
 
     @Override
-    public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
-        if (modification.getModificationType() == ModificationType.WRITE) {
+    public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException {
+        if (modification.getType() == ModificationType.WRITE) {
             verifyWrittenStructure(modification.getWrittenValue());
         }
     }
 
-    protected abstract void verifyWrittenStructure(NormalizedNode<?, ?> writtenValue);
-
     @Override
-    public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-        switch (modification.getModificationType()) {
+    public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        switch (modification.getType()) {
         case DELETE:
             checkDeleteApplicable(modification, current);
         case SUBTREE_MODIFIED:
-            checkSubtreeModificationApplicable(path,modification, current);
+            checkSubtreeModificationApplicable(path, modification, current);
             return;
         case WRITE:
-            checkWriteApplicable(path,modification, current);
+            checkWriteApplicable(path, modification, current);
             return;
         case MERGE:
-            checkMergeApplicable(path,modification,current);
+            checkMergeApplicable(path, modification, current);
             return;
         case UNMODIFIED:
             return;
         default:
-            throw new UnsupportedOperationException("Suplied modification type "+modification.getModificationType()+ "is not supported.");
+            throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported.");
         }
 
     }
 
-    protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-        Optional<StoreMetadataNode> original = modification.getOriginal();
+    protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        Optional<TreeNode> original = modification.getOriginal();
         if (original.isPresent() && current.isPresent()) {
             /*
              * We need to do conflict detection only and only if the value of leaf changed
@@ -174,39 +161,34 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
              * leads to same data.
              */
             if(!original.get().getData().equals(current.get().getData())) {
-
-                checkNotConflicting(path,original.get(), current.get());
+                checkNotConflicting(path, original.get(), current.get());
             }
         }
     }
 
-    protected void checkWriteApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-        Optional<StoreMetadataNode> original = modification.getOriginal();
+    protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        Optional<TreeNode> original = modification.getOriginal();
         if (original.isPresent() && current.isPresent()) {
-            checkNotConflicting(path,original.get(), current.get());
+            checkNotConflicting(path, original.get(), current.get());
         } else if(original.isPresent()) {
             throw new DataPreconditionFailedException(path,"Node was deleted by other transaction.");
         }
     }
 
-    protected static final void checkNotConflicting(final InstanceIdentifier path,final StoreMetadataNode original, final StoreMetadataNode current) throws DataPreconditionFailedException {
-        checkDataPrecondition(path, original.getNodeVersion().equals(current.getNodeVersion()),"Node was replaced by other transaction.");
-        checkDataPrecondition(path,original.getSubtreeVersion().equals(current.getSubtreeVersion()), "Node children was modified by other transaction");
-    }
-
-    protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification,
-            final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException;
-
-    private void checkDeleteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+    private void checkDeleteApplicable(final NodeModification modification, final Optional<TreeNode> current) {
+        // Delete is always applicable, we do not expose it to subclasses
+        if (current.isPresent()) {
+            LOG.trace("Delete operation turned to no-op on missing node {}", modification);
+        }
     }
 
     @Override
-    public final Optional<StoreMetadataNode> apply(final NodeModification modification,
-            final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
+    public final Optional<TreeNode> apply(final ModifiedNode modification,
+            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
 
-        switch (modification.getModificationType()) {
+        switch (modification.getType()) {
         case DELETE:
-            return modification.storeSnapshot(Optional.<StoreMetadataNode> absent());
+            return modification.storeSnapshot(Optional.<TreeNode> absent());
         case SUBTREE_MODIFIED:
             Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification",
                     modification);
@@ -225,409 +207,19 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
         }
     }
 
-    protected abstract StoreMetadataNode applyMerge(NodeModification modification,
-            StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
-
-    protected abstract StoreMetadataNode applyWrite(NodeModification modification,
-            Optional<StoreMetadataNode> currentMeta, UnsignedLong subtreeVersion);
-
-    protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification,
-            StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
-
-    public static abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends SchemaAwareApplyOperation {
+    protected abstract TreeNode applyMerge(ModifiedNode modification,
+            TreeNode currentMeta, Version subtreeVersion);
 
-        private final T schema;
-        private final Class<? extends NormalizedNode<?, ?>> nodeClass;
-
-        protected ValueNodeModificationStrategy(final T schema, final Class<? extends NormalizedNode<?, ?>> nodeClass) {
-            super();
-            this.schema = schema;
-            this.nodeClass = nodeClass;
-        }
-
-        @Override
-        protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
-            checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
-            throw new UnsupportedOperationException("Node " + schema.getPath()
-                    + "is leaf type node. Child nodes not allowed");
-        }
-
-        @Override
-        protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
-                final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
-            throw new UnsupportedOperationException("Node " + schema.getPath()
-                    + "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);
-        }
+    protected abstract TreeNode applyWrite(ModifiedNode modification,
+            Optional<TreeNode> currentMeta, Version subtreeVersion);
 
-        @Override
-        protected StoreMetadataNode applyWrite(final NodeModification modification,
-                final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
-            return StoreMetadataNode.builder(subtreeVersion).setSubtreeVersion(subtreeVersion)
-                    .setData(modification.getWrittenValue()).build();
-        }
-
-        @Override
-        protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
-                final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-            throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
-        }
-
-    }
-
-    public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy<LeafListSchemaNode> {
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) {
-            super(schema, (Class) LeafSetEntryNode.class);
-        }
-    }
-
-    public static class LeafModificationStrategy extends ValueNodeModificationStrategy<LeafSchemaNode> {
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected LeafModificationStrategy(final LeafSchemaNode schema) {
-            super(schema, (Class) LeafNode.class);
-        }
-    }
-
-    public static abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
-
-        private final Class<? extends NormalizedNode<?, ?>> nodeClass;
-
-        protected NormalizedNodeContainerModificationStrategy(final Class<? extends NormalizedNode<?, ?>> nodeClass) {
-            this.nodeClass = nodeClass;
-        }
-
-        @Override
-        public void verifyStructure(final NodeModification modification) throws IllegalArgumentException {
-            if (modification.getModificationType() == ModificationType.WRITE) {
-
-            }
-            for (NodeModification childModification : modification.getModifications()) {
-                resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification);
-            }
-        }
-
-        @Override
-        protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification,
-                final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-            // FIXME: Implement proper write check for replacement of node container
-            //        prerequisite is to have transaction chain available for clients
-            //        otherwise this will break chained writes to same node.
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
-            checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
-            checkArgument(writtenValue instanceof NormalizedNodeContainer);
-
-            NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue;
-            for (Object child : container.getValue()) {
-                checkArgument(child instanceof NormalizedNode);
-
-                /*
-                 * FIXME: fail-fast semantics:
-                 *
-                 * We can validate the data structure here, aborting the commit
-                 * before it ever progresses to being committed.
-                 */
-            }
-        }
-
-        @Override
-        protected StoreMetadataNode applyWrite(final NodeModification modification,
-                final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
-
-            NormalizedNode<?, ?> newValue = modification.getWrittenValue();
-
-            final UnsignedLong nodeVersion;
-            if (currentMeta.isPresent()) {
-                nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
-            } else {
-                nodeVersion = subtreeVersion;
-            }
-
-            final StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion);
-            if (!modification.hasAdditionalModifications()) {
-                return newValueMeta;
-            }
-
-            @SuppressWarnings("rawtypes")
-            NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue);
-            StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(nodeVersion, dataBuilder) //
-                    .setSubtreeVersion(subtreeVersion);
-
-            return mutateChildren(modification.getModifications(), newValueMeta, builder, nodeVersion);
-        }
-
-        @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) {
-            // Bump subtree version to its new target
-            final UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion());
-
-            @SuppressWarnings("rawtypes")
-            NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData());
-            StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(dataBuilder, currentMeta)
-                    .setIdentifier(modification.getIdentifier())
-                    .setSubtreeVersion(updatedSubtreeVersion);
-
-            return mutateChildren(modification.getModifications(), currentMeta, builder, updatedSubtreeVersion);
-        }
-
-        private StoreMetadataNode mutateChildren(final Iterable<NodeModification> modifications, final StoreMetadataNode meta,
-                final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) {
-
-            for (NodeModification mod : modifications) {
-                final PathArgument id = mod.getIdentifier();
-                final Optional<StoreMetadataNode> cm = meta.getChild(id);
-
-                Optional<StoreMetadataNode> result = resolveChildOperation(id).apply(mod, cm, nodeVersion);
-                if (result.isPresent()) {
-                    builder.add(result.get());
-                } else {
-                    builder.remove(id);
-                }
-            }
-
-            return builder.build();
-        }
-
-        @Override
-        protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
-                final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-            checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction.");
-            checkChildPreconditions(path,modification,current);
-
-        }
-
-        private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-            StoreMetadataNode currentMeta = current.get();
-            for (NodeModification childMod : modification.getModifications()) {
-                PathArgument childId = childMod.getIdentifier();
-                Optional<StoreMetadataNode> childMeta = currentMeta.getChild(childId);
-                InstanceIdentifier childPath = StoreUtils.append(path, childId);
-                resolveChildOperation(childId).checkApplicable(childPath,childMod, childMeta);
-            }
-        }
-
-        @Override
-        protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification,
-                final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
-            if(current.isPresent()) {
-                checkChildPreconditions(path,modification,current);
-            }
-        }
-
-        @SuppressWarnings("rawtypes")
-        protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode<?, ?> original);
-    }
+    protected abstract TreeNode applySubtreeChange(ModifiedNode modification,
+            TreeNode currentMeta, Version subtreeVersion);
 
-    public static abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends NormalizedNodeContainerModificationStrategy {
+    protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification,
+            final Optional<TreeNode> current) throws DataPreconditionFailedException;
 
-        private final T schema;
-        private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
-                .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {
-
-                    @Override
-                    public ModificationApplyOperation apply(final PathArgument identifier) {
-                        if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
-                            return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier);
-                        }
-
-                        DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType());
-                        if (child == null) {
-                            return null;
-                        }
-                        return from(child);
-                    }
-                }));
-
-        protected DataNodeContainerModificationStrategy(final T schema,
-                final Class<? extends NormalizedNode<?, ?>> nodeClass) {
-            super(nodeClass);
-            this.schema = schema;
-        }
-
-        protected T getSchema() {
-            return schema;
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-            try {
-                return Optional.<ModificationApplyOperation> fromNullable(childCache.get(identifier));
-            } catch (ExecutionException e) {
-                return Optional.absent();
-            }
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName() + " [" + schema + "]";
-        }
-
-    }
-
-    public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
-
-        public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) {
-            super(schemaNode, ContainerNode.class);
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof ContainerNode);
-            return ImmutableContainerNodeBuilder.create((ContainerNode) original);
-        }
-    }
-
-    public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
-
-        public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) {
-            super(schemaNode, UnkeyedListEntryNode.class);
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof UnkeyedListEntryNode);
-            return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original);
-        }
-    }
-
-    public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy<AugmentationSchema> {
-
-        protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
-            super(createAugmentProxy(schema,resolved), AugmentationNode.class);
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof AugmentationNode);
-            return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original);
-        }
-    }
-
-    public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
-        private final Map<PathArgument, ModificationApplyOperation> childNodes;
-
-        public ChoiceModificationStrategy(final ChoiceNode schemaNode) {
-            super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class);
-            ImmutableMap.Builder<PathArgument, ModificationApplyOperation> child = ImmutableMap.builder();
-
-            for (ChoiceCaseNode caze : schemaNode.getCases()) {
-                for (DataSchemaNode cazeChild : caze.getChildNodes()) {
-                    SchemaAwareApplyOperation childNode = from(cazeChild);
-                    child.put(new NodeIdentifier(cazeChild.getQName()), childNode);
-                }
-            }
-            childNodes = child.build();
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
-            return Optional.fromNullable(childNodes.get(child));
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode);
-            return ImmutableChoiceNodeBuilder.create((org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode) original);
-        }
-    }
-
-    public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
-
-        protected ListEntryModificationStrategy(final ListSchemaNode schema) {
-            super(schema, MapEntryNode.class);
-        }
-
-        @Override
-        @SuppressWarnings("rawtypes")
-        protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof MapEntryNode);
-            return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
-        }
-    }
-
-    public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
-        private final Optional<ModificationApplyOperation> entryStrategy;
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
-            super((Class) LeafSetNode.class);
-            entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof LeafSetNode<?>);
-            return ImmutableLeafSetNodeBuilder.create((LeafSetNode<?>) original);
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-            if (identifier instanceof NodeWithValue) {
-                return entryStrategy;
-            }
-            return Optional.absent();
-        }
-    }
-
-    public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
-        private final Optional<ModificationApplyOperation> entryStrategy;
-
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) {
-            super((Class) LeafSetNode.class);
-            entryStrategy = Optional.<ModificationApplyOperation> of(new LeafSetEntryModificationStrategy(schema));
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof OrderedLeafSetNode<?>);
-            return ImmutableOrderedLeafSetNodeBuilder.create((OrderedLeafSetNode<?>) original);
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-            if (identifier instanceof NodeWithValue) {
-                return entryStrategy;
-            }
-            return Optional.absent();
-        }
-    }
+    protected abstract void verifyWrittenStructure(NormalizedNode<?, ?> writtenValue);
 
     public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation {
 
@@ -638,21 +230,21 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
         }
 
         @Override
-        protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
-                final UnsignedLong subtreeVersion) {
+        protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+                final Version subtreeVersion) {
             return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
         }
 
         @Override
-        protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
-                final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
+        protected TreeNode applySubtreeChange(final ModifiedNode modification,
+                final TreeNode currentMeta, final Version subtreeVersion) {
             throw new UnsupportedOperationException("UnkeyedList does not support subtree change.");
         }
 
         @Override
-        protected StoreMetadataNode applyWrite(final NodeModification modification,
-                final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
-            return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion);
+        protected TreeNode applyWrite(final ModifiedNode modification,
+                final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+            return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
         }
 
         @Override
@@ -669,86 +261,9 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation {
         }
 
         @Override
-        protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification,
-                final Optional<StoreMetadataNode> current) throws DataPreconditionFailedException {
+        protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification,
+                final Optional<TreeNode> current) throws DataPreconditionFailedException {
             throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
         }
-
-    }
-
-    public static class UnorderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
-        private final Optional<ModificationApplyOperation> entryStrategy;
-
-        protected UnorderedMapModificationStrategy(final ListSchemaNode schema) {
-            super(MapNode.class);
-            entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof MapNode);
-            return ImmutableMapNodeBuilder.create((MapNode) original);
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-            if (identifier instanceof NodeIdentifierWithPredicates) {
-                return entryStrategy;
-            }
-            return Optional.absent();
-        }
-
-        @Override
-        public String toString() {
-            return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]";
-        }
     }
-
-    public static class OrderedMapModificationStrategy extends NormalizedNodeContainerModificationStrategy {
-
-        private final Optional<ModificationApplyOperation> entryStrategy;
-
-        protected OrderedMapModificationStrategy(final ListSchemaNode schema) {
-            super(OrderedMapNode.class);
-            entryStrategy = Optional.<ModificationApplyOperation> of(new ListEntryModificationStrategy(schema));
-        }
-
-        @SuppressWarnings("rawtypes")
-        @Override
-        protected NormalizedNodeContainerBuilder createBuilder(final NormalizedNode<?, ?> original) {
-            checkArgument(original instanceof OrderedMapNode);
-            return ImmutableOrderedMapNodeBuilder.create((OrderedMapNode) original);
-        }
-
-        @Override
-        public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
-            if (identifier instanceof NodeIdentifierWithPredicates) {
-                return entryStrategy;
-            }
-            return Optional.absent();
-        }
-
-        @Override
-        public String toString() {
-            return "OrderedMapModificationStrategy [entry=" + entryStrategy + "]";
-        }
-    }
-
-    public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
-        Set<DataSchemaNode> realChildSchemas = new HashSet<>();
-        for(DataSchemaNode augChild : schema.getChildNodes()) {
-            realChildSchemas.add(resolved.getDataChildByName(augChild.getQName()));
-        }
-        return new AugmentationSchemaProxy(schema, realChildSchemas);
-    }
-
-    public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException {
-        if(!condition) {
-            throw new DataPreconditionFailedException(path, message);
-        }
-        return condition;
-    }
-
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java
deleted file mode 100644 (file)
index 695a1f1..0000000
+++ /dev/null
@@ -1,157 +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.md.sal.dom.store.impl.tree.data;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.concepts.Immutable;
-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 com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedLong;
-
-class StoreMetadataNode implements Immutable, Identifiable<PathArgument> {
-    private final Map<PathArgument, StoreMetadataNode> children;
-    private final UnsignedLong nodeVersion;
-    private final UnsignedLong subtreeVersion;
-    private final NormalizedNode<?, ?> data;
-
-    /**
-     *
-     * @param data
-     * @param nodeVersion
-     * @param subtreeVersion
-     * @param children Map of children, must not be modified externally
-     */
-    private StoreMetadataNode(final NormalizedNode<?, ?> data, final UnsignedLong nodeVersion,
-            final UnsignedLong subtreeVersion, final Map<PathArgument, StoreMetadataNode> children) {
-        this.nodeVersion = Preconditions.checkNotNull(nodeVersion);
-        this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
-        this.data = Preconditions.checkNotNull(data);
-        this.children = Preconditions.checkNotNull(children);
-    }
-
-    public static StoreMetadataNode createEmpty(final NormalizedNode<?, ?> data) {
-        return new StoreMetadataNode(data, UnsignedLong.ZERO, UnsignedLong.ZERO,
-                Collections.<PathArgument, StoreMetadataNode>emptyMap());
-    }
-
-    public static Builder builder(final UnsignedLong version) {
-        return new Builder(version);
-    }
-
-    public static Builder builder(final StoreMetadataNode node) {
-        return new Builder(node);
-    }
-
-    public UnsignedLong getNodeVersion() {
-        return this.nodeVersion;
-    }
-
-    @Override
-    public PathArgument getIdentifier() {
-        return data.getIdentifier();
-    }
-
-    public UnsignedLong getSubtreeVersion() {
-        return subtreeVersion;
-    }
-
-    public NormalizedNode<?, ?> getData() {
-        return this.data;
-    }
-
-    Optional<StoreMetadataNode> getChild(final PathArgument key) {
-        return Optional.fromNullable(children.get(key));
-    }
-
-    @Override
-    public String toString() {
-        return "StoreMetadataNode [identifier=" + getIdentifier() + ", nodeVersion=" + nodeVersion + "]";
-    }
-
-    public static final StoreMetadataNode createRecursively(final NormalizedNode<?, ?> node,
-            final UnsignedLong version) {
-        Builder builder = builder(version) //
-                .setSubtreeVersion(version) //
-                .setData(node);
-        if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
-
-            @SuppressWarnings("unchecked")
-            NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> nodeContainer = (NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>>) node;
-            for (NormalizedNode<?, ?> subNode : nodeContainer.getValue()) {
-                builder.add(createRecursively(subNode, version));
-            }
-        }
-        return builder.build();
-    }
-
-    public static class Builder {
-
-        private final UnsignedLong nodeVersion;
-        private UnsignedLong subtreeVersion;
-        private NormalizedNode<?, ?> data;
-        private Map<PathArgument, StoreMetadataNode> children;
-        private boolean dirty = false;
-
-        private Builder(final UnsignedLong version) {
-            this.nodeVersion = Preconditions.checkNotNull(version);
-            children = new HashMap<>();
-        }
-
-        private Builder(final StoreMetadataNode node) {
-            this.nodeVersion = node.getNodeVersion();
-            children = new HashMap<>(node.children);
-        }
-
-        public Builder setSubtreeVersion(final UnsignedLong version) {
-            this.subtreeVersion = version;
-            return this;
-        }
-
-        public Builder setData(final NormalizedNode<?, ?> data) {
-            this.data = data;
-            return this;
-        }
-
-        public Builder add(final StoreMetadataNode node) {
-            if (dirty) {
-                children = new HashMap<>(children);
-                dirty = false;
-            }
-            children.put(node.getIdentifier(), node);
-            return this;
-        }
-
-        public Builder remove(final PathArgument id) {
-            if (dirty) {
-                children = new HashMap<>(children);
-                dirty = false;
-            }
-            children.remove(id);
-            return this;
-        }
-
-        public StoreMetadataNode build() {
-            checkState(data != null, "Data node should not be null.");
-            checkState(subtreeVersion.compareTo(nodeVersion) >= 0,
-                    "Subtree version must be equals or greater than node version.");
-            dirty = true;
-            return new StoreMetadataNode(data, nodeVersion, subtreeVersion, children);
-        }
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java
deleted file mode 100644 (file)
index 19debbb..0000000
+++ /dev/null
@@ -1,75 +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.md.sal.dom.store.impl.tree.data;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
-
-import com.google.common.base.Preconditions;
-import com.google.common.primitives.UnsignedLong;
-
-/**
- *
- * Helper builder
- *
- *
- */
-@SuppressWarnings("rawtypes")
-class StoreNodeCompositeBuilder {
-
-    private final StoreMetadataNode.Builder metadata;
-
-    private final NormalizedNodeContainerBuilder data;
-
-    private StoreNodeCompositeBuilder(final UnsignedLong version, final NormalizedNodeContainerBuilder nodeBuilder) {
-        this.metadata = StoreMetadataNode.builder(version);
-        this.data = Preconditions.checkNotNull(nodeBuilder);
-    }
-
-    private StoreNodeCompositeBuilder(final NormalizedNodeContainerBuilder nodeBuilder, final StoreMetadataNode currentMeta) {
-        this.metadata = StoreMetadataNode.builder(currentMeta);
-        this.data = Preconditions.checkNotNull(nodeBuilder);
-    }
-
-    @SuppressWarnings("unchecked")
-    public StoreNodeCompositeBuilder add(final StoreMetadataNode node) {
-        metadata.add(node);
-        data.addChild(node.getData());
-        return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public StoreNodeCompositeBuilder remove(final PathArgument id) {
-        metadata.remove(id);
-        data.removeChild(id);
-        return this;
-    }
-
-    public StoreMetadataNode build() {
-        return metadata.setData(data.build()).build();
-    }
-
-    public static StoreNodeCompositeBuilder create(final UnsignedLong version, final NormalizedNodeContainerBuilder nodeBuilder) {
-        return new StoreNodeCompositeBuilder(version, nodeBuilder);
-    }
-
-    public static StoreNodeCompositeBuilder create(final NormalizedNodeContainerBuilder nodeBuilder, final StoreMetadataNode currentMeta) {
-        return new StoreNodeCompositeBuilder(nodeBuilder, currentMeta);
-    }
-
-    @SuppressWarnings("unchecked")
-    public StoreNodeCompositeBuilder setIdentifier(final PathArgument identifier) {
-        data.withNodeIdentifier(identifier);
-        return this;
-    }
-
-    public StoreNodeCompositeBuilder setSubtreeVersion(final UnsignedLong updatedSubtreeVersion) {
-        metadata.setSubtreeVersion(updatedSubtreeVersion);
-        return this;
-    }
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java
new file mode 100644 (file)
index 0000000..5f68782
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.dom.store.impl.tree.data;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
+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.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+
+import com.google.common.base.Optional;
+
+abstract class ValueNodeModificationStrategy<T extends DataSchemaNode> extends SchemaAwareApplyOperation {
+
+    private final T schema;
+    private final Class<? extends NormalizedNode<?, ?>> nodeClass;
+
+    protected ValueNodeModificationStrategy(final T schema, final Class<? extends NormalizedNode<?, ?>> nodeClass) {
+        super();
+        this.schema = schema;
+        this.nodeClass = nodeClass;
+    }
+
+    @Override
+    protected void verifyWrittenStructure(final NormalizedNode<?, ?> writtenValue) {
+        checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass);
+    }
+
+    @Override
+    public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
+        throw new UnsupportedOperationException("Node " + schema.getPath()
+                + "is leaf type node. Child nodes not allowed");
+    }
+
+    @Override
+    protected TreeNode applySubtreeChange(final ModifiedNode modification,
+            final TreeNode currentMeta, final Version subtreeVersion) {
+        throw new UnsupportedOperationException("Node " + schema.getPath()
+                + "is leaf type node. Subtree change is not allowed.");
+    }
+
+    @Override
+    protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta,
+            final Version subtreeVersion) {
+        // Just overwrite whatever was there
+        return applyWrite(modification, null, subtreeVersion);
+    }
+
+    @Override
+    protected TreeNode applyWrite(final ModifiedNode modification,
+            final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+        return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+    }
+
+    @Override
+    protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification,
+            final Optional<TreeNode> current) throws DataPreconditionFailedException {
+        throw new DataPreconditionFailedException(path, "Subtree modification is not allowed.");
+    }
+
+    public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy<LeafListSchemaNode> {
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) {
+            super(schema, (Class) LeafSetEntryNode.class);
+        }
+    }
+
+    public static class LeafModificationStrategy extends ValueNodeModificationStrategy<LeafSchemaNode> {
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        protected LeafModificationStrategy(final LeafSchemaNode schema) {
+            super(schema, (Class) LeafNode.class);
+        }
+    }
+}
\ 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/tree/spi/AbstractTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java
new file mode 100644 (file)
index 0000000..1444f0c
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+import com.google.common.base.Preconditions;
+
+/*
+ * A very basic data tree node.
+ */
+abstract class AbstractTreeNode implements TreeNode {
+    private final NormalizedNode<?, ?> data;
+    private final Version version;
+
+    protected AbstractTreeNode(final NormalizedNode<?, ?> data, final Version version) {
+        this.data = Preconditions.checkNotNull(data);
+        this.version = Preconditions.checkNotNull(version);
+    }
+
+    @Override
+    public PathArgument getIdentifier() {
+        return data.getIdentifier();
+    }
+
+    @Override
+    public final Version getVersion() {
+        return version;
+    }
+
+    @Override
+    public final NormalizedNode<?, ?> getData() {
+        return data;
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java
new file mode 100644 (file)
index 0000000..8f74f60
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+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.api.schema.OrderedNodeContainer;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * A TreeNode capable of holding child nodes. The fact that any of the children
+ * changed is tracked by the subtree version.
+ */
+final class ContainerNode extends AbstractTreeNode {
+    private final Map<PathArgument, TreeNode> children;
+    private final Version subtreeVersion;
+
+    protected ContainerNode(final NormalizedNode<?, ?> data, final Version version,
+            final Map<PathArgument, TreeNode> children, final Version subtreeVersion) {
+        super(data, version);
+        this.children = Preconditions.checkNotNull(children);
+        this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
+    }
+
+    @Override
+    public Version getSubtreeVersion() {
+        return subtreeVersion;
+    }
+
+    @Override
+    public Optional<TreeNode> getChild(final PathArgument key) {
+        return Optional.fromNullable(children.get(key));
+    }
+
+    @Override
+    public MutableTreeNode mutable() {
+        return new Mutable(this);
+    }
+
+    private static final class Mutable implements MutableTreeNode {
+        private final Map<PathArgument, TreeNode> children;
+        private final Version version;
+        private NormalizedNode<?, ?> data;
+        private Version subtreeVersion;
+
+        private Mutable(final ContainerNode parent) {
+            this.data = parent.getData();
+            this.children = new HashMap<>(parent.children);
+            this.subtreeVersion = parent.getSubtreeVersion();
+            this.version = parent.getVersion();
+        }
+
+        @Override
+        public Optional<TreeNode> getChild(final PathArgument child) {
+            return Optional.fromNullable(children.get(child));
+        }
+
+        @Override
+        public void setSubtreeVersion(final Version subtreeVersion) {
+            this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion);
+        }
+
+        @Override
+        public void addChild(final TreeNode child) {
+            children.put(child.getIdentifier(), child);
+        }
+
+        @Override
+        public void removeChild(final PathArgument id) {
+            children.remove(id);
+        }
+
+        @Override
+        public TreeNode seal() {
+            final Map<PathArgument, TreeNode> realChildren;
+
+            if (children.isEmpty()) {
+                realChildren = Collections.emptyMap();
+            } else {
+                realChildren = children;
+            }
+
+            return new ContainerNode(data, version, realChildren, subtreeVersion);
+        }
+
+        @Override
+        public void setData(final NormalizedNode<?, ?> data) {
+            this.data = Preconditions.checkNotNull(data);
+        }
+    }
+
+    private static ContainerNode create(final Version version, final NormalizedNode<?, ?> data,
+            final Iterable<NormalizedNode<?, ?>> children) {
+        final Map<PathArgument, TreeNode> map = new HashMap<>();
+
+        for (NormalizedNode<?, ?> child : children) {
+            map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version));
+        }
+
+        return new ContainerNode(data, version, map, version);
+    }
+
+    public static ContainerNode create(final Version version, final NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> container) {
+        return create(version, container, container.getValue());
+    }
+
+    public static ContainerNode create(final Version version, final OrderedNodeContainer<NormalizedNode<?, ?>> container) {
+        return create(version, container, container.getValue());
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java
new file mode 100644 (file)
index 0000000..dd3672c
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface MutableTreeNode extends StoreTreeNode<TreeNode> {
+    void setData(NormalizedNode<?, ?> data);
+    void setSubtreeVersion(Version subtreeVersion);
+    void addChild(TreeNode child);
+    void removeChild(PathArgument id);
+    TreeNode seal();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java
new file mode 100644 (file)
index 0000000..b0beb81
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/*
+ * A very basic data tree node. It has a version (when it was last modified),
+ * a subtree version (when any of its children were modified) and some read-only
+ * data.
+ */
+public interface TreeNode extends Identifiable<PathArgument>, StoreTreeNode<TreeNode> {
+    /**
+     * Get the data node version.
+     *
+     * @return Current data node version.
+     */
+    Version getVersion();
+
+    /**
+     * Get the subtree version.
+     *
+     * @return Current subtree version.
+     */
+    Version getSubtreeVersion();
+
+    /**
+     * Get a read-only view of the underlying data.
+     *
+     * @return Unmodifiable view of the underlying data.
+     */
+    NormalizedNode<?, ?> getData();
+
+    /**
+     * Get a mutable, isolated copy of the node.
+     *
+     * @return Mutable copy
+     */
+    MutableTreeNode mutable();
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java
new file mode 100644 (file)
index 0000000..c5d174c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer;
+
+public final class TreeNodeFactory {
+    private TreeNodeFactory() {
+        throw new UnsupportedOperationException("Utility class should not be instantiated");
+    }
+
+    /**
+     * Create a new AbstractTreeNode from a data node, descending recursively as needed.
+     * This method should only ever be used for new data.
+     *
+     * @param data data node
+     * @param version data node version
+     * @return new AbstractTreeNode instance, covering the data tree provided
+     */
+    public static final TreeNode createTreeNode(final NormalizedNode<?, ?> data, final Version version) {
+        if (data instanceof NormalizedNodeContainer<?, ?, ?>) {
+            @SuppressWarnings("unchecked")
+            NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>> container = (NormalizedNodeContainer<?, ?, NormalizedNode<?, ?>>) data;
+            return ContainerNode.create(version, container);
+
+        }
+        if (data instanceof OrderedNodeContainer<?>) {
+            @SuppressWarnings("unchecked")
+            OrderedNodeContainer<NormalizedNode<?, ?>> container = (OrderedNodeContainer<NormalizedNode<?, ?>>) data;
+            return ContainerNode.create(version, container);
+        }
+
+        return new ValueNode(data, version);
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java
new file mode 100644 (file)
index 0000000..7194faa
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+final class ValueNode extends AbstractTreeNode {
+    private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class);
+
+    protected ValueNode(final NormalizedNode<?, ?> data, final Version version) {
+        super(data, version);
+    }
+
+    @Override
+    public Optional<TreeNode> getChild(final PathArgument childId) {
+        LOG.warn("Attempted to access child {} of value-node {}", childId, this);
+        return Optional.absent();
+    }
+
+    @Override
+    public Version getSubtreeVersion() {
+        return getVersion();
+    }
+
+    @Override
+    public MutableTreeNode mutable() {
+        /**
+         * Value nodes can only we read/written/delete, which does a straight
+         * replace. That means they don't haver need to be made mutable.
+         */
+        throw new UnsupportedOperationException(String.format("Attempted to mutate value-node %s", this));
+    }
+}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java
new file mode 100644 (file)
index 0000000..09a35d3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.dom.store.impl.tree.spi;
+
+/**
+ * The concept of a version, either node version, or a subtree version. The
+ * only interface contract this class has is that no two versions are the
+ * same.
+ */
+public final class Version {
+    private Version() {
+
+    }
+
+    /**
+     * Create a new version, distinct from any other version.
+     *
+     * @return a new version.
+     */
+    public Version next() {
+        return new Version();
+    }
+
+    /**
+     * Create an initial version.
+     *
+     * @return a new version.
+     */
+    public static final Version initial() {
+        return new Version();
+    }
+}
index dab8fd5cd10bb71f1d9f9df480b3ec509276cd62..430963a884b4fbaa71a7c3c12d5df9356058be0c 100644 (file)
@@ -10,7 +10,10 @@ package org.opendaylight.controller.sal.dom.broker;
 import static com.google.common.base.Preconditions.checkState;
 
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
@@ -33,54 +36,34 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
 
-public class GlobalBundleScanningSchemaServiceImpl implements //
-        SchemaContextProvider, //
-        SchemaService, //
-        ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
-        AutoCloseable {
-    private static final Logger logger = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class);
-
-    private ListenerRegistry<SchemaServiceListener> listeners;
-
-    private BundleContext context;
-    private final BundleScanner scanner = new BundleScanner();
-
-    private BundleTracker<ImmutableSet<Registration<URL>>> bundleTracker;
+public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvider, SchemaService, ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class);
 
+    private final ListenerRegistry<SchemaServiceListener> listeners = new ListenerRegistry<>();
     private final URLSchemaContextResolver contextResolver = new URLSchemaContextResolver();
+    private final BundleScanner scanner = new BundleScanner();
+    private final BundleContext context;
 
     private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
-
+    private BundleTracker<Iterable<Registration<URL>>> bundleTracker;
     private boolean starting = true;
 
-    public ListenerRegistry<SchemaServiceListener> getListeners() {
-        return listeners;
-    }
-
-    public void setListeners(final ListenerRegistry<SchemaServiceListener> listeners) {
-        this.listeners = listeners;
+    public GlobalBundleScanningSchemaServiceImpl(final BundleContext context) {
+        this.context = Preconditions.checkNotNull(context);
     }
 
     public BundleContext getContext() {
         return context;
     }
 
-    public void setContext(final BundleContext context) {
-        this.context = context;
-    }
-
     public void start() {
         checkState(context != null);
-        if (listeners == null) {
-            listeners = new ListenerRegistry<>();
-        }
 
         listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, GlobalBundleScanningSchemaServiceImpl.this);
-        bundleTracker = new BundleTracker<ImmutableSet<Registration<URL>>>(context, BundleEvent.RESOLVED
-                        | BundleEvent.UNRESOLVED, scanner);
+        bundleTracker = new BundleTracker<>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
         bundleTracker.open();
         listenerTracker.open();
         starting = false;
@@ -139,7 +122,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements //
             try {
                 listener.getInstance().onGlobalContextUpdated(snapshot);
             } catch (Exception e) {
-                logger.error("Exception occured during invoking listener", e);
+                LOG.error("Exception occured during invoking listener", e);
             }
         }
         if (services != null) {
@@ -148,37 +131,47 @@ public class GlobalBundleScanningSchemaServiceImpl implements //
                 try {
                     listener.onGlobalContextUpdated(snapshot);
                 } catch (Exception e) {
-                    logger.error("Exception occured during invoking listener", e);
+                    LOG.error("Exception occured during invoking listener {}", listener, e);
                 }
             }
         }
     }
 
-    private class BundleScanner implements BundleTrackerCustomizer<ImmutableSet<Registration<URL>>> {
+    private class BundleScanner implements BundleTrackerCustomizer<Iterable<Registration<URL>>> {
         @Override
-        public ImmutableSet<Registration<URL>> addingBundle(final Bundle bundle, final BundleEvent event) {
+        public Iterable<Registration<URL>> addingBundle(final Bundle bundle, final BundleEvent event) {
 
             if (bundle.getBundleId() == 0) {
-                return ImmutableSet.of();
+                return Collections.emptyList();
             }
 
-            Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
-            Builder<Registration<URL>> builder = ImmutableSet.<Registration<URL>> builder();
-            while (enumeration != null && enumeration.hasMoreElements()) {
-                Registration<URL> reg = contextResolver.registerSource(enumeration.nextElement());
-                builder.add(reg);
+            final Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
+            if (enumeration == null) {
+                return Collections.emptyList();
             }
-            ImmutableSet<Registration<URL>> urls = builder.build();
-            if(urls.isEmpty()) {
-                return urls;
+
+            final List<Registration<URL>> urls = new ArrayList<>();
+            while (enumeration.hasMoreElements()) {
+                final URL u = enumeration.nextElement();
+                try {
+                    urls.add(contextResolver.registerSource(u));
+                    LOG.debug("Registered {}", u);
+                } catch (Exception e) {
+                    LOG.warn("Failed to register {}, ignoring it", e);
+                }
             }
-            tryToUpdateSchemaContext();
-            return urls;
+
+            if (!urls.isEmpty()) {
+                LOG.debug("Loaded {} new URLs, rebuilding schema context", urls.size());
+                tryToUpdateSchemaContext();
+            }
+
+            return ImmutableList.copyOf(urls);
         }
 
         @Override
-        public void modifiedBundle(final Bundle bundle, final BundleEvent event, final ImmutableSet<Registration<URL>> object) {
-            logger.debug("Modified bundle {} {} {}", bundle, event, object);
+        public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration<URL>> object) {
+            LOG.debug("Modified bundle {} {} {}", bundle, event, object);
         }
 
         /**
@@ -188,12 +181,12 @@ public class GlobalBundleScanningSchemaServiceImpl implements //
          */
 
         @Override
-        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final ImmutableSet<Registration<URL>> urls) {
+        public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable<Registration<URL>> urls) {
             for (Registration<URL> url : urls) {
                 try {
                     url.close();
                 } catch (Exception e) {
-                    e.printStackTrace();
+                    LOG.warn("Failed do unregister URL {}, proceeding", url, e);
                 }
             }
             tryToUpdateSchemaContext();
@@ -212,7 +205,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements //
     }
 
     public synchronized void tryToUpdateSchemaContext() {
-        if(starting ) {
+        if (starting) {
             return;
         }
         Optional<SchemaContext> schema = contextResolver.tryToUpdateSchemaContext();
index d8315568bee86ea07ee00b86feddcb0801faaa8e..1a572d157dba9f8272140495b8eabf9669df11bc 100644 (file)
@@ -45,9 +45,9 @@ import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
 
 public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataStore> implements //
-        DataStore, //
-        SchemaContextListener, //
-        AutoCloseable {
+DataStore, //
+SchemaContextListener, //
+AutoCloseable {
 
     private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class);
 
@@ -56,7 +56,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
     private final DataReader<InstanceIdentifier, CompositeNode> reader = new MergeFirstLevelReader();
 
     @Override
-    public boolean containsConfigurationPath(InstanceIdentifier path) {
+    public boolean containsConfigurationPath(final InstanceIdentifier path) {
         try {
             getDelegateReadLock().lock();
             return getDelegate().containsConfigurationPath(path);
@@ -67,7 +67,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
     }
 
     @Override
-    public boolean containsOperationalPath(InstanceIdentifier path) {
+    public boolean containsOperationalPath(final InstanceIdentifier path) {
         try {
             getDelegateReadLock().lock();
             return getDelegate().containsOperationalPath(path);
@@ -100,18 +100,18 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
     }
 
     @Override
-    public CompositeNode readConfigurationData(InstanceIdentifier path) {
+    public CompositeNode readConfigurationData(final InstanceIdentifier path) {
         return reader.readConfigurationData(path);
     }
 
     @Override
-    public CompositeNode readOperationalData(InstanceIdentifier path) {
+    public CompositeNode readOperationalData(final InstanceIdentifier path) {
         return reader.readOperationalData(path);
     }
 
     @Override
     public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier, CompositeNode> requestCommit(
-            DataModification<InstanceIdentifier, CompositeNode> modification) {
+            final DataModification<InstanceIdentifier, CompositeNode> modification) {
         validateAgainstSchema(modification);
         NormalizedDataModification cleanedUp = prepareMergedTransaction(modification);
         cleanedUp.status = TransactionStatus.SUBMITED;
@@ -122,11 +122,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         return validationEnabled;
     }
 
-    public void setValidationEnabled(boolean validationEnabled) {
+    public void setValidationEnabled(final boolean validationEnabled) {
         this.validationEnabled = validationEnabled;
     }
 
-    private void validateAgainstSchema(DataModification<InstanceIdentifier, CompositeNode> modification) {
+    private void validateAgainstSchema(final DataModification<InstanceIdentifier, CompositeNode> modification) {
         if (!validationEnabled) {
             return;
         }
@@ -138,12 +138,12 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
     }
 
     @Override
-    protected void onDelegateChanged(DataStore oldDelegate, DataStore newDelegate) {
+    protected void onDelegateChanged(final DataStore oldDelegate, final DataStore newDelegate) {
         // NOOP
     }
 
     @Override
-    public void onGlobalContextUpdated(SchemaContext context) {
+    public void onGlobalContextUpdated(final SchemaContext context) {
         this.schema = context;
     }
 
@@ -152,8 +152,8 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         this.schema = null;
     }
 
-    protected CompositeNode mergeData(InstanceIdentifier path, CompositeNode stored, CompositeNode modified,
-            boolean config) {
+    protected CompositeNode mergeData(final InstanceIdentifier path, final CompositeNode stored, final CompositeNode modified,
+            final boolean config) {
         // long startTime = System.nanoTime();
         try {
             DataSchemaNode node = schemaNodeFor(path);
@@ -164,13 +164,13 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         }
     }
 
-    private DataSchemaNode schemaNodeFor(InstanceIdentifier path) {
+    private DataSchemaNode schemaNodeFor(final InstanceIdentifier path) {
         checkState(schema != null, "YANG Schema is not available");
         return YangSchemaUtils.getSchemaNode(schema, path);
     }
 
     private NormalizedDataModification prepareMergedTransaction(
-            DataModification<InstanceIdentifier, CompositeNode> original) {
+            final DataModification<InstanceIdentifier, CompositeNode> original) {
         NormalizedDataModification normalized = new NormalizedDataModification(original);
         LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(),
                 original.getRemovedConfigurationData(), original.getRemovedConfigurationData());
@@ -194,7 +194,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         return normalized;
     }
 
-    private Iterable<InstanceIdentifier> getConfigurationSubpaths(InstanceIdentifier entry) {
+    private Iterable<InstanceIdentifier> getConfigurationSubpaths(final InstanceIdentifier entry) {
         // FIXME: This should be replaced by index
         Iterable<InstanceIdentifier> paths = getStoredConfigurationPaths();
 
@@ -202,15 +202,15 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
 
     }
 
-    public Iterable<InstanceIdentifier> getOperationalSubpaths(InstanceIdentifier entry) {
+    public Iterable<InstanceIdentifier> getOperationalSubpaths(final InstanceIdentifier entry) {
         // FIXME: This should be indexed
         Iterable<InstanceIdentifier> paths = getStoredOperationalPaths();
 
         return getChildrenPaths(entry, paths);
     }
 
-    private static final Iterable<InstanceIdentifier> getChildrenPaths(InstanceIdentifier entry,
-            Iterable<InstanceIdentifier> paths) {
+    private static final Iterable<InstanceIdentifier> getChildrenPaths(final InstanceIdentifier entry,
+            final Iterable<InstanceIdentifier> paths) {
         ImmutableSet.Builder<InstanceIdentifier> children = ImmutableSet.builder();
         for (InstanceIdentifier potential : paths) {
             if (entry.contains(potential)) {
@@ -222,7 +222,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
 
     private final Comparator<Entry<InstanceIdentifier, CompositeNode>> preparationComparator = new Comparator<Entry<InstanceIdentifier, CompositeNode>>() {
         @Override
-        public int compare(Entry<InstanceIdentifier, CompositeNode> o1, Entry<InstanceIdentifier, CompositeNode> o2) {
+        public int compare(final Entry<InstanceIdentifier, CompositeNode> o1, final Entry<InstanceIdentifier, CompositeNode> o2) {
             InstanceIdentifier o1Key = o1.getKey();
             InstanceIdentifier o2Key = o2.getKey();
             return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size());
@@ -242,7 +242,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
                 CompositeNode original = getDelegate().readConfigurationData(path);
                 ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
                 if (original != null) {
-                    childNodes.addAll(original.getChildren());
+                    childNodes.addAll(original.getValue());
                     qname = original.getNodeType();
                 } else {
                     qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
@@ -251,7 +251,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
                 FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredConfigurationPaths())
                         .filter(new Predicate<InstanceIdentifier>() {
                             @Override
-                            public boolean apply(InstanceIdentifier input) {
+                            public boolean apply(final InstanceIdentifier input) {
                                 if (path.contains(input)) {
                                     int nesting = input.getPath().size() - path.getPath().size();
                                     if (nesting == 1) {
@@ -285,7 +285,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
                 CompositeNode original = getDelegate().readOperationalData(path);
                 ArrayList<Node<?>> childNodes = new ArrayList<Node<?>>();
                 if (original != null) {
-                    childNodes.addAll(original.getChildren());
+                    childNodes.addAll(original.getValue());
                     qname = original.getNodeType();
                 } else {
                     qname = path.getPath().get(path.getPath().size() - 1).getNodeType();
@@ -294,7 +294,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
                 FluentIterable<InstanceIdentifier> directChildren = FluentIterable.from(getStoredOperationalPaths())
                         .filter(new Predicate<InstanceIdentifier>() {
                             @Override
-                            public boolean apply(InstanceIdentifier input) {
+                            public boolean apply(final InstanceIdentifier input) {
                                 if (path.contains(input)) {
                                     int nesting = input.getPath().size() - path.getPath().size();
                                     if (nesting == 1) {
@@ -326,7 +326,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         private final Object identifier;
         private TransactionStatus status;
 
-        public NormalizedDataModification(DataModification<InstanceIdentifier, CompositeNode> original) {
+        public NormalizedDataModification(final DataModification<InstanceIdentifier, CompositeNode> original) {
             super(getDelegate());
             identifier = original;
             status = TransactionStatus.NEW;
@@ -339,7 +339,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
          *
          * @param entry
          */
-        public void deepRemoveOperationalData(InstanceIdentifier entry) {
+        public void deepRemoveOperationalData(final InstanceIdentifier entry) {
             Iterable<InstanceIdentifier> paths = getOperationalSubpaths(entry);
             removeOperationalData(entry);
             for (InstanceIdentifier potential : paths) {
@@ -347,7 +347,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
             }
         }
 
-        public void deepRemoveConfigurationData(InstanceIdentifier entry) {
+        public void deepRemoveConfigurationData(final InstanceIdentifier entry) {
             Iterable<InstanceIdentifier> paths = getConfigurationSubpaths(entry);
             removeConfigurationData(entry);
             for (InstanceIdentifier potential : paths) {
@@ -355,11 +355,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
             }
         }
 
-        public void putDeepConfigurationData(InstanceIdentifier entryKey, CompositeNode entryData) {
+        public void putDeepConfigurationData(final InstanceIdentifier entryKey, final CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, CONFIGURATIONAL_DATA_STORE_MARKER);
         }
 
-        public void putDeepOperationalData(InstanceIdentifier entryKey, CompositeNode entryData) {
+        public void putDeepOperationalData(final InstanceIdentifier entryKey, final CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, OPERATIONAL_DATA_STORE_MARKER);
         }
 
@@ -379,26 +379,26 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         }
 
         @Override
-        protected CompositeNode mergeConfigurationData(InstanceIdentifier path, CompositeNode stored,
-                CompositeNode modified) {
+        protected CompositeNode mergeConfigurationData(final InstanceIdentifier path, final CompositeNode stored,
+                final CompositeNode modified) {
             return mergeData(path, stored, modified, true);
         }
 
         @Override
-        protected CompositeNode mergeOperationalData(InstanceIdentifier path, CompositeNode stored,
-                CompositeNode modified) {
+        protected CompositeNode mergeOperationalData(final InstanceIdentifier path, final CompositeNode stored,
+                final CompositeNode modified) {
             return mergeData(path, stored, modified, false);
         }
 
-        private void putData(InstanceIdentifier entryKey, CompositeNode entryData, String dataStoreIdentifier) {
+        private void putData(final InstanceIdentifier entryKey, final CompositeNode entryData, final String dataStoreIdentifier) {
             if (dataStoreIdentifier != null && entryKey != null && entryData != null) {
                 switch (dataStoreIdentifier) {
                 case (CONFIGURATIONAL_DATA_STORE_MARKER):
                     this.putConfigurationData(entryKey, entryData);
-                    break;
+                break;
                 case (OPERATIONAL_DATA_STORE_MARKER):
                     this.putOperationalData(entryKey, entryData);
-                    break;
+                break;
 
                 default:
                     LOG.error(dataStoreIdentifier + " is NOT valid DataStore switch marker");
@@ -407,11 +407,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
             }
         }
 
-        private void putCompositeNodeData(InstanceIdentifier entryKey, CompositeNode entryData,
-                String dataStoreIdentifier) {
+        private void putCompositeNodeData(final InstanceIdentifier entryKey, final CompositeNode entryData,
+                final String dataStoreIdentifier) {
             this.putData(entryKey, entryData, dataStoreIdentifier);
 
-            for (Node<?> child : entryData.getChildren()) {
+            for (Node<?> child : entryData.getValue()) {
                 InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType())
                         .toInstance();
                 if (child instanceof CompositeNode) {
@@ -438,7 +438,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
             }
         }
 
-        private Map<QName, Object> getValuesFromListSchema(ListSchemaNode listSchema, CompositeNode entryData) {
+        private Map<QName, Object> getValuesFromListSchema(final ListSchemaNode listSchema, final CompositeNode entryData) {
             List<QName> keyDef = listSchema.getKeyDefinition();
             if (keyDef != null && !keyDef.isEmpty()) {
                 Map<QName, Object> map = new HashMap<QName, Object>();
index 344b3f32763c2fcb9c45047ae7c4e34f0b6e087d..f893f96d18c59e94df9fe7961b8856b214a6f196 100644 (file)
@@ -17,20 +17,19 @@ import org.osgi.framework.ServiceRegistration;
 
 public class SchemaServiceActivator implements BundleActivator {
 
-    
+
     private ServiceRegistration<SchemaService> schemaServiceReg;
     private GlobalBundleScanningSchemaServiceImpl schemaService;
 
     @Override
-    public void start(BundleContext context) throws Exception {
-        schemaService = new GlobalBundleScanningSchemaServiceImpl();
-        schemaService.setContext(context);
+    public void start(final BundleContext context) {
+        schemaService = new GlobalBundleScanningSchemaServiceImpl(context);
         schemaService.start();
         schemaServiceReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String,String>());
     }
-    
+
     @Override
-    public void stop(BundleContext context) throws Exception {
+    public void stop(final BundleContext context) throws Exception {
         schemaServiceReg.unregister();
         schemaService.close();
     }
index 8940e55d321cbd57a6c80e6c1fe0a5c04255569e..4fb190fc8201853e094ac87ec5f1a659ab1e19bf 100644 (file)
@@ -29,6 +29,8 @@ import org.junit.Test;
 import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
@@ -40,7 +42,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 import com.google.common.base.Optional;
-import com.google.common.primitives.UnsignedLong;
 
 /**
  *
@@ -149,7 +150,7 @@ public class ModificationMetadataTreeTest {
     @Test
     public void basicReadWrites() {
         DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext,
-                StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5)), applyOper),
+                TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), applyOper),
                 new SchemaAwareApplyOperationRoot(schemaContext));
         Optional<NormalizedNode<?, ?>> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH);
         assertTrue(originalBarNode.isPresent());
index f2cc5332079448d823bab85167908e9def916540..03ece2f5e03076a8099fcd50d819f276204f03db 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-public class SchemaAwareApplyOperationRoot extends SchemaAwareApplyOperation.DataNodeContainerModificationStrategy<ContainerSchemaNode> {
+public class SchemaAwareApplyOperationRoot extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
     private final SchemaContext context;
 
     public SchemaAwareApplyOperationRoot(final SchemaContext context) {
index 8a74b17ac46449c806f745c48e0892a59ec9374b..34cd9aa47b7f82702a797ddc4bea96ed34f28b7d 100644 (file)
@@ -35,7 +35,6 @@ 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;
@@ -52,9 +51,9 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<In
     private final boolean candidateSupported;
     private final boolean rollbackSupported;
 
-    public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
-            DataModification<InstanceIdentifier, CompositeNode> modification,
-            boolean candidateSupported, boolean rollbackOnErrorSupported) {
+    public NetconfDeviceTwoPhaseCommitTransaction(final NetconfDevice device,
+            final DataModification<InstanceIdentifier, CompositeNode> modification,
+            final boolean candidateSupported, final boolean rollbackOnErrorSupported) {
         this.device = Preconditions.checkNotNull(device);
         this.modification = Preconditions.checkNotNull(modification);
         this.candidateSupported = candidateSupported;
@@ -70,15 +69,15 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<In
         }
     }
 
-    private void sendMerge(InstanceIdentifier key, CompositeNode value) throws InterruptedException, ExecutionException {
+    private void sendMerge(final InstanceIdentifier key, final CompositeNode value) throws InterruptedException, ExecutionException {
         sendEditRpc(createEditStructure(key, Optional.<String>absent(), Optional.of(value)));
     }
 
-    private void sendDelete(InstanceIdentifier toDelete) throws InterruptedException, ExecutionException {
+    private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException {
         sendEditRpc(createEditStructure(toDelete, Optional.of("delete"), Optional.<CompositeNode> absent()));
     }
 
-    private void sendEditRpc(CompositeNode editStructure) throws InterruptedException, ExecutionException {
+    private void sendEditRpc(final CompositeNode editStructure) throws InterruptedException, ExecutionException {
         CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
         builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
         builder.add(editStructure);
@@ -108,8 +107,8 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<In
         return ret;
     }
 
-    private CompositeNode createEditStructure(InstanceIdentifier dataPath, Optional<String> operation,
-            Optional<CompositeNode> lastChildOverride) {
+    private CompositeNode createEditStructure(final InstanceIdentifier dataPath, final Optional<String> operation,
+            final Optional<CompositeNode> lastChildOverride) {
         List<PathArgument> path = dataPath.getPath();
         List<PathArgument> reversed = Lists.reverse(path);
         CompositeNode previous = null;
@@ -130,7 +129,7 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<In
                     builder.setAttribute(NETCONF_OPERATION_QNAME, operation.get());
                 }
                 if (lastChildOverride.isPresent()) {
-                    List<Node<?>> children = lastChildOverride.get().getChildren();
+                    List<Node<?>> children = lastChildOverride.get().getValue();
                     for(Node<?> child : children) {
                         if(!predicates.containsKey(child.getKey())) {
                             builder.add(child);
index f76ec28624e158a3cfa5ad8050c13647b82e2163..2b3a992fc1c3eebaa45a33220731b4c80d2a0181 100644 (file)
@@ -7,12 +7,6 @@
  */
 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;
@@ -20,8 +14,10 @@ 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;
@@ -41,11 +37,16 @@ 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;
 
+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.Lists;
+
 public class NetconfMapping {
 
     public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
@@ -91,7 +92,7 @@ public class NetconfMapping {
 
     static AtomicInteger messageId = new AtomicInteger(0);
 
-    static Node<?> toFilterStructure(InstanceIdentifier identifier) {
+    static Node<?> toFilterStructure(final InstanceIdentifier identifier) {
         Node<?> previous = null;
         if (identifier.getPath().isEmpty()) {
             return null;
@@ -108,7 +109,7 @@ public class NetconfMapping {
         return filter("subtree", previous);
     }
 
-    static Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
+    static Node<?> toNode(final NodeIdentifierWithPredicates argument, final Node<?> node) {
         List<Node<?>> list = new ArrayList<>();
         for (Map.Entry<QName, Object> arg : argument.getKeyValues().entrySet()) {
             list.add(new SimpleNodeTOImpl(arg.getKey(), null, arg.getValue()));
@@ -119,7 +120,7 @@ public class NetconfMapping {
         return new CompositeNodeTOImpl(argument.getNodeType(), null, list);
     }
 
-    static Node<?> toNode(PathArgument argument, Node<?> node) {
+    static Node<?> toNode(final PathArgument argument, final Node<?> node) {
         if (node != null) {
             return new CompositeNodeTOImpl(argument.getNodeType(), null, Collections.<Node<?>> singletonList(node));
         } else {
@@ -127,14 +128,14 @@ public class NetconfMapping {
         }
     }
 
-    static CompositeNode toCompositeNode(NetconfMessage message, Optional<SchemaContext> ctx) {
+    static CompositeNode toCompositeNode(final NetconfMessage message, final Optional<SchemaContext> ctx) {
         // TODO: implement general normalization to normalize incoming Netconf
         // Message
         // for Schema Context counterpart
         return null;
     }
 
-    static CompositeNode toNotificationNode(NetconfMessage message, Optional<SchemaContext> ctx) {
+    static CompositeNode toNotificationNode(final NetconfMessage message, final Optional<SchemaContext> ctx) {
         if (ctx.isPresent()) {
             SchemaContext schemaContext = ctx.get();
             Set<NotificationDefinition> notifications = schemaContext.getNotifications();
@@ -144,7 +145,7 @@ public class NetconfMapping {
         return null;
     }
 
-    static NetconfMessage toRpcMessage(QName rpc, CompositeNode node, Optional<SchemaContext> ctx) {
+    static NetconfMessage toRpcMessage(final QName rpc, final CompositeNode node, final Optional<SchemaContext> ctx) {
         CompositeNodeTOImpl rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node));
         Document w3cPayload = null;
         try {
@@ -164,8 +165,8 @@ public class NetconfMapping {
         if (input instanceof CompositeNode) {
 
             List<Node<?>> nodes = ImmutableList.<Node<?>> builder() //
-                    .addAll(input.getChildren()) //
-                    .addAll(Collections2.filter(node.getChildren(), new Predicate<Node<?>>() {
+                    .addAll(input.getValue()) //
+                    .addAll(Collections2.filter(node.getValue(), new Predicate<Node<?>>() {
                         @Override
                         public boolean apply(@Nullable final Node<?> input) {
                             return input.getNodeType() != inputQName;
@@ -179,7 +180,7 @@ public class NetconfMapping {
         return input;
     }
 
-    static RpcResult<CompositeNode> toRpcResult(NetconfMessage message, final QName rpc, Optional<SchemaContext> context) {
+    static RpcResult<CompositeNode> toRpcResult(final NetconfMessage message, final QName rpc, final Optional<SchemaContext> context) {
         CompositeNode rawRpc;
         if (context.isPresent())
             if (isDataRetrieQNameReply(rpc)) {
@@ -196,7 +197,7 @@ public class NetconfMapping {
                 rawRpc = it.toInstance();
                 // sys(xmlData)
             } else {
-                rawRpc = (CompositeNode) toCompositeNode(message, context);
+                rawRpc = toCompositeNode(message, context);
             }
         else {
             rawRpc = (CompositeNode) toCompositeNode(message.getDocument());
@@ -205,17 +206,17 @@ public class NetconfMapping {
         return Rpcs.getRpcResult(true, rawRpc, Collections.<RpcError> emptySet());
     }
 
-    static Element getDataSubtree(Document doc) {
+    static Element getDataSubtree(final Document doc) {
         return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0);
     }
 
-    static boolean isDataRetrieQNameReply(QName it) {
+    static boolean isDataRetrieQNameReply(final QName it) {
         return NETCONF_URI == it.getNamespace()
                 && (it.getLocalName() == NETCONF_GET_CONFIG_QNAME.getLocalName() || it.getLocalName() == NETCONF_GET_QNAME
-                        .getLocalName());
+                .getLocalName());
     }
 
-    static CompositeNodeTOImpl wrap(QName name, Node<?> node) {
+    static CompositeNodeTOImpl wrap(final QName name, final Node<?> node) {
         if (node != null) {
             return new CompositeNodeTOImpl(name, null, Collections.<Node<?>> singletonList(node));
         } else {
@@ -223,7 +224,7 @@ public class NetconfMapping {
         }
     }
 
-    static CompositeNodeTOImpl wrap(QName name, Node<?> additional, Node<?> node) {
+    static CompositeNodeTOImpl wrap(final QName name, final Node<?> additional, final Node<?> node) {
         if (node != null) {
             return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node));
         } else {
@@ -231,7 +232,7 @@ public class NetconfMapping {
         }
     }
 
-    static ImmutableCompositeNode filter(String type, Node<?> node) {
+    static ImmutableCompositeNode filter(final String type, final Node<?> node) {
         CompositeNodeBuilder<ImmutableCompositeNode> it = ImmutableCompositeNode.builder(); //
         it.setQName(NETCONF_FILTER_QNAME);
         it.setAttribute(NETCONF_TYPE_QNAME, type);
@@ -242,11 +243,11 @@ public class NetconfMapping {
         }
     }
 
-    public static Node<?> toCompositeNode(Document document) {
+    public static Node<?> toCompositeNode(final Document document) {
         return XmlDocumentUtils.toDomNode(document);
     }
 
-    public static void checkValidReply(NetconfMessage input, NetconfMessage output) {
+    public static void checkValidReply(final NetconfMessage input, final NetconfMessage output) {
         String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id");
         String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id");
 
@@ -257,7 +258,7 @@ public class NetconfMapping {
         }
     }
 
-    public static void checkSuccessReply(NetconfMessage output) throws NetconfDocumentedException {
+    public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException {
         if(NetconfMessageUtil.isErrorMessage(output)) {
             throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument())));
         }
index c17a4b70ccc711ad4877500ce0e4799e398ecccb..e4c7c0c64799cb31adb93425301b4ba94a44806e 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-parser-impl</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-restconf</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools.model</groupId>
+      <artifactId>ietf-yang-types-20130715</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
index d1441d7b9d904a202ad90bfcc53d36c794ae993e..ea0f149d296887f4c713ba32e675ee8e4b8fbf54 100644 (file)
@@ -57,7 +57,7 @@ class JsonMapper {
     private MountInstance mountPoint;
     private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
 
-    public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema, MountInstance mountPoint)
+    public void write(final JsonWriter writer, final CompositeNode data, final DataNodeContainer schema, final MountInstance mountPoint)
             throws IOException {
         Preconditions.checkNotNull(writer);
         Preconditions.checkNotNull(data);
@@ -81,12 +81,12 @@ class JsonMapper {
         foundLists.clear();
     }
 
-    private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema)
+    private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema)
             throws IOException {
         checkNotNull(parent);
         checkNotNull(parentSchema);
 
-        for (Node<?> child : parent.getChildren()) {
+        for (Node<?> child : parent.getValue()) {
             DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
 
             if (childSchema == null) {
@@ -122,17 +122,17 @@ class JsonMapper {
             }
         }
 
-        for (Node<?> child : parent.getChildren()) {
+        for (Node<?> child : parent.getValue()) {
             DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes());
             if (childSchema instanceof LeafListSchemaNode) {
-                foundLeafLists.remove((LeafListSchemaNode) childSchema);
+                foundLeafLists.remove(childSchema);
             } else if (childSchema instanceof ListSchemaNode) {
-                foundLists.remove((ListSchemaNode) childSchema);
+                foundLists.remove(childSchema);
             }
         }
     }
 
-    private DataSchemaNode findFirstSchemaForNode(Node<?> node, Set<DataSchemaNode> dataSchemaNode) {
+    private DataSchemaNode findFirstSchemaForNode(final Node<?> node, final Set<DataSchemaNode> dataSchemaNode) {
         for (DataSchemaNode dsn : dataSchemaNode) {
             if (node.getNodeType().equals(dsn.getQName())) {
                 return dsn;
@@ -148,14 +148,14 @@ class JsonMapper {
         return null;
     }
 
-    private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException {
+    private void writeContainer(final JsonWriter writer, final CompositeNode node, final ContainerSchemaNode schema) throws IOException {
         writeName(node, schema, writer);
         writer.beginObject();
         writeChildrenOfParent(writer, node, schema);
         writer.endObject();
     }
 
-    private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema)
+    private void writeList(final JsonWriter writer, final CompositeNode nodeParent, final CompositeNode node, final ListSchemaNode schema)
             throws IOException {
         writeName(node, schema, writer);
         writer.beginArray();
@@ -176,8 +176,8 @@ class JsonMapper {
         writer.endArray();
     }
 
-    private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode<?> node,
-            LeafListSchemaNode schema) throws IOException {
+    private void writeLeafList(final JsonWriter writer, final CompositeNode nodeParent, final SimpleNode<?> node,
+            final LeafListSchemaNode schema) throws IOException {
         writeName(node, schema, writer);
         writer.beginArray();
 
@@ -188,13 +188,13 @@ class JsonMapper {
         writer.endArray();
     }
 
-    private void writeLeaf(JsonWriter writer, SimpleNode<?> node, LeafSchemaNode schema) throws IOException {
+    private void writeLeaf(final JsonWriter writer, final SimpleNode<?> node, final LeafSchemaNode schema) throws IOException {
         writeName(node, schema, writer);
         writeValueOfNodeByType(writer, node, schema.getType(), schema);
     }
 
-    private void writeValueOfNodeByType(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> type,
-            DataSchemaNode schema) throws IOException {
+    private void writeValueOfNodeByType(final JsonWriter writer, final SimpleNode<?> node, final TypeDefinition<?> type,
+            final DataSchemaNode schema) throws IOException {
 
         TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(type);
 
@@ -245,7 +245,7 @@ class JsonMapper {
         }
     }
 
-    private void writeIdentityValuesDTOToJson(JsonWriter writer, IdentityValuesDTO valueDTO) throws IOException {
+    private void writeIdentityValuesDTOToJson(final JsonWriter writer, final IdentityValuesDTO valueDTO) throws IOException {
         StringBuilder result = new StringBuilder();
         for (IdentityValue identityValue : valueDTO.getValuesWithNamespaces()) {
             result.append("/");
@@ -271,7 +271,7 @@ class JsonMapper {
         writer.value(result.toString());
     }
 
-    private void writeModuleNameAndIdentifier(StringBuilder result, IdentityValue identityValue) {
+    private void writeModuleNameAndIdentifier(final StringBuilder result, final IdentityValue identityValue) {
         String moduleName = ControllerContext.getInstance().findModuleNameByNamespace(
                 URI.create(identityValue.getNamespace()));
         if (moduleName != null && !moduleName.isEmpty()) {
@@ -281,8 +281,8 @@ class JsonMapper {
         result.append(identityValue.getValue());
     }
 
-    private void writeStringRepresentation(JsonWriter writer, SimpleNode<?> node, TypeDefinition<?> baseType,
-            Class<?> requiredType) throws IOException {
+    private void writeStringRepresentation(final JsonWriter writer, final SimpleNode<?> node, final TypeDefinition<?> baseType,
+            final Class<?> requiredType) throws IOException {
         Object value = node.getValue();
         logger.debug("Value of " + baseType.getQName().getNamespace() + ":" + baseType.getQName().getLocalName()
                 + " is not instance of " + requiredType.getClass() + " but is " + node.getValue().getClass());
@@ -293,13 +293,13 @@ class JsonMapper {
         }
     }
 
-    private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException {
+    private void writeEmptyDataTypeToJson(final JsonWriter writer) throws IOException {
         writer.beginArray();
         writer.nullValue();
         writer.endArray();
     }
 
-    private void writeName(Node<?> node, DataSchemaNode schema, JsonWriter writer) throws IOException {
+    private void writeName(final Node<?> node, final DataSchemaNode schema, final JsonWriter writer) throws IOException {
         String nameForOutput = node.getNodeType().getLocalName();
         if (schema.isAugmenting()) {
             ControllerContext contContext = ControllerContext.getInstance();
@@ -323,7 +323,7 @@ class JsonMapper {
         private static final long serialVersionUID = -3147729419814417666L;
         private final String value;
 
-        public NumberForJsonWriter(String value) {
+        public NumberForJsonWriter(final String value) {
             this.value = value;
         }
 
index 1870bdf0bf37daf6e5e0acaee273b90ce3c749a5..2abd4b6a3ab5b9a08c56e782257a262db80fbfe2 100644 (file)
@@ -34,7 +34,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack
     private ListenerRegistration<SchemaServiceListener> listenerRegistration;
     private ServiceTracker<Broker, Broker> brokerServiceTrancker;
     private BundleContext bundleContext;
-    private ProviderSession session;
     private Thread webSocketServerThread;
 
     @Override
@@ -70,7 +69,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack
             }
         }
         webSocketServerThread.interrupt();
-        session.close();
         brokerServiceTrancker.close();
     }
 
index e0ae78870394223ca2a662e0d8cbfe3c64193e6f..96ad528a0dd3f9e0591b78b2be702e9b1d004c4c 100644 (file)
@@ -34,21 +34,21 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     private QName name;
     private List<NodeWrapper<?>> values = new ArrayList<>();
 
-    public CompositeNodeWrapper(String localName) {
+    public CompositeNodeWrapper(final String localName) {
         this.localName = Preconditions.checkNotNull(localName);
     }
 
-    public CompositeNodeWrapper(URI namespace, String localName) {
+    public CompositeNodeWrapper(final URI namespace, final String localName) {
         this(localName);
         this.namespace = namespace;
     }
-    
+
     @Override
-    public void setQname(QName name) {
+    public void setQname(final QName name) {
         Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
         this.name = name;
     }
-    
+
     @Override
     public QName getQname() {
         return name;
@@ -71,26 +71,26 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     }
 
     @Override
-    public void setNamespace(URI namespace) {
+    public void setNamespace(final URI namespace) {
         Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
         this.namespace = namespace;
     }
 
-    public void addValue(NodeWrapper<?> value) {
+    public void addValue(final NodeWrapper<?> value) {
         Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
         values.add(value);
     }
 
-    public void removeValue(NodeWrapper<CompositeNode> value) {
+    public void removeValue(final NodeWrapper<CompositeNode> value) {
         Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies.");
         values.remove(value);
     }
-    
+
     public List<NodeWrapper<?>> getValues() {
         Preconditions.checkState(compositeNode == null, "Data can be inconsistent.");
         return Collections.unmodifiableList(values);
     }
-    
+
     @Override
     public boolean isChangeAllowed() {
         return compositeNode == null ? true : false;
@@ -103,13 +103,13 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
                 Preconditions.checkNotNull(namespace);
                 name = new QName(namespace, localName);
             }
-            
+
             List<Node<?>> nodeValues = new ArrayList<>();
             for (NodeWrapper<?> nodeWrapper : values) {
                 nodeValues.add(nodeWrapper.unwrap());
             }
             compositeNode = NodeFactory.createMutableCompositeNode(name, null, nodeValues, null, null);
-            
+
             values = null;
             namespace = null;
             localName = null;
@@ -123,6 +123,7 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
         return unwrap().getNodeType();
     }
 
+    @Deprecated
     @Override
     public CompositeNode getParent() {
         return unwrap().getParent();
@@ -138,38 +139,42 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
         return unwrap().getModificationAction();
     }
 
+    /**
+     * @deprecated Use {@link #getValue()} instead.
+     */
+    @Deprecated
     @Override
     public List<Node<?>> getChildren() {
-        return unwrap().getChildren();
+        return unwrap().getValue();
     }
 
     @Override
-    public List<CompositeNode> getCompositesByName(QName children) {
+    public List<CompositeNode> getCompositesByName(final QName children) {
         return unwrap().getCompositesByName(children);
     }
 
     @Override
-    public List<CompositeNode> getCompositesByName(String children) {
+    public List<CompositeNode> getCompositesByName(final String children) {
         return unwrap().getCompositesByName(children);
     }
 
     @Override
-    public List<SimpleNode<?>> getSimpleNodesByName(QName children) {
+    public List<SimpleNode<?>> getSimpleNodesByName(final QName children) {
         return unwrap().getSimpleNodesByName(children);
     }
 
     @Override
-    public List<SimpleNode<?>> getSimpleNodesByName(String children) {
+    public List<SimpleNode<?>> getSimpleNodesByName(final String children) {
         return unwrap().getSimpleNodesByName(children);
     }
 
     @Override
-    public CompositeNode getFirstCompositeByName(QName container) {
+    public CompositeNode getFirstCompositeByName(final QName container) {
         return unwrap().getFirstCompositeByName(container);
     }
 
     @Override
-    public SimpleNode<?> getFirstSimpleByName(QName leaf) {
+    public SimpleNode<?> getFirstSimpleByName(final QName leaf) {
         return unwrap().getFirstSimpleByName(leaf);
     }
 
@@ -184,7 +189,7 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     }
 
     @Override
-    public List<Node<?>> setValue(List<Node<?>> value) {
+    public List<Node<?>> setValue(final List<Node<?>> value) {
         return unwrap().setValue(value);
     }
 
@@ -199,32 +204,32 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     }
 
     @Override
-    public boolean containsKey(Object key) {
+    public boolean containsKey(final Object key) {
         return unwrap().containsKey(key);
     }
 
     @Override
-    public boolean containsValue(Object value) {
+    public boolean containsValue(final Object value) {
         return unwrap().containsValue(value);
     }
 
     @Override
-    public List<Node<?>> get(Object key) {
+    public List<Node<?>> get(final Object key) {
         return unwrap().get(key);
     }
 
     @Override
-    public List<Node<?>> put(QName key, List<Node<?>> value) {
+    public List<Node<?>> put(final QName key, final List<Node<?>> value) {
         return unwrap().put(key, value);
     }
 
     @Override
-    public List<Node<?>> remove(Object key) {
+    public List<Node<?>> remove(final Object key) {
         return unwrap().remove(key);
     }
 
     @Override
-    public void putAll(Map<? extends QName, ? extends List<Node<?>>> m) {
+    public void putAll(final Map<? extends QName, ? extends List<Node<?>>> m) {
         unwrap().putAll(m);
     }
 
index 874e8b0d1f8f5e7cf151a4c548624b01d72576a5..d978a2f0de25af2f26c106dea7c79a759fea4ce0 100644 (file)
@@ -85,7 +85,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         verifyJsonOutput(jsonOutput);
     }
 
-    private void verifyJsonOutputForEmptyData(String jsonOutput) {
+    private void verifyJsonOutputForEmptyData(final String jsonOutput) {
         assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
@@ -104,7 +104,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertNull("Error during reading Json output: " + exception, exception);
     }
 
-    private void verifyJsonOutput(String jsonOutput) {
+    private void verifyJsonOutput(final String jsonOutput) {
         assertNotNull(jsonOutput);
         StringReader strReader = new StringReader(jsonOutput);
         JsonReader jReader = new JsonReader(strReader);
@@ -123,7 +123,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertNull("Error during reading Json output: " + exception, exception);
     }
 
-    private Cont jsonReadCont1(JsonReader jReader) throws IOException {
+    private Cont jsonReadCont1(final JsonReader jReader) throws IOException {
         jReader.beginObject();
         assertNotNull("cont1 is missing.", jReader.hasNext());
 
@@ -136,7 +136,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private Cont jsonReadCont1Elements(JsonReader jReader, Cont redData) throws IOException {
+    private Cont jsonReadCont1Elements(final JsonReader jReader, final Cont redData) throws IOException {
         jReader.beginObject();
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
@@ -163,7 +163,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private Lst jsonReadLst11(JsonReader jReader, Lst lst) throws IOException {
+    private Lst jsonReadLst11(final JsonReader jReader, final Lst lst) throws IOException {
         jReader.beginArray();
 
         while (jReader.hasNext()) {
@@ -174,7 +174,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lst;
     }
 
-    private LstItem jsonReadLst11Elements(JsonReader jReader) throws IOException {
+    private LstItem jsonReadLst11Elements(final JsonReader jReader) throws IOException {
         LstItem lstItem = new LstItem();
         jReader.beginObject();
         while (jReader.hasNext()) {
@@ -203,7 +203,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lstItem;
     }
 
-    private Lst jsonReadLst112(JsonReader jReader, Lst lst) throws IOException {
+    private Lst jsonReadLst112(final JsonReader jReader, final Lst lst) throws IOException {
         jReader.beginArray();
         while (jReader.hasNext()) {
             LstItem lstItem = jsonReadLst112Elements(jReader);
@@ -213,7 +213,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lst;
     }
 
-    private LstItem jsonReadLst112Elements(JsonReader jReader) throws IOException {
+    private LstItem jsonReadLst112Elements(final JsonReader jReader) throws IOException {
         LstItem lstItem = new LstItem();
         jReader.beginObject();
         if (jReader.hasNext()) {
@@ -227,7 +227,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private Lst jsonReadLst111(JsonReader jReader, Lst lst) throws IOException {
+    private Lst jsonReadLst111(final JsonReader jReader, final Lst lst) throws IOException {
         jReader.beginArray();
         while (jReader.hasNext()) {
             LstItem lstItem = jsonReadLst111Elements(jReader);
@@ -237,7 +237,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lst;
     }
 
-    private LstItem jsonReadLst111Elements(JsonReader jReader) throws IOException {
+    private LstItem jsonReadLst111Elements(final JsonReader jReader) throws IOException {
         LstItem lstItem = new LstItem();
         jReader.beginObject();
         if (jReader.hasNext()) {
@@ -250,7 +250,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lstItem;
     }
 
-    private Object nextValue(JsonReader jReader) throws IOException {
+    private Object nextValue(final JsonReader jReader) throws IOException {
         if (jReader.peek().equals(JsonToken.NULL)) {
             jReader.nextNull();
             return null;
@@ -261,14 +261,14 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         }
     }
 
-    private Cont jsonReadCont111(JsonReader jReader, Cont cont) throws IOException {
+    private Cont jsonReadCont111(final JsonReader jReader, Cont cont) throws IOException {
         jReader.beginObject();
         cont = jsonReadCont111Elements(jReader, cont);
         jReader.endObject();
         return cont;
     }
 
-    private Cont jsonReadCont111Elements(JsonReader jReader, Cont cont) throws IOException {
+    private Cont jsonReadCont111Elements(final JsonReader jReader, final Cont cont) throws IOException {
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf1111")) {
@@ -289,7 +289,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private Lst jsonReadLst1111(JsonReader jReader, Lst lst) throws IOException {
+    private Lst jsonReadLst1111(final JsonReader jReader, final Lst lst) throws IOException {
         jReader.beginArray();
         while (jReader.hasNext()) {
             LstItem lstItem = jsonReadLst1111Elements(jReader);
@@ -299,7 +299,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lst;
     }
 
-    private LstItem jsonReadLst1111Elements(JsonReader jReader) throws IOException {
+    private LstItem jsonReadLst1111Elements(final JsonReader jReader) throws IOException {
         jReader.beginObject();
         LstItem lstItem = new LstItem();
         while (jReader.hasNext()) {
@@ -312,7 +312,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lstItem;
     }
 
-    private LfLst jsonReadLflstValues(JsonReader jReader, LfLst lfLst) throws IOException {
+    private LfLst jsonReadLflstValues(final JsonReader jReader, final LfLst lfLst) throws IOException {
         jReader.beginArray();
         while (jReader.hasNext()) {
             lfLst.addLf(new Lf(nextValue(jReader)));
@@ -321,7 +321,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         return lfLst;
     }
 
-    private void checkDataFromJsonEmpty(Cont dataFromJson) {
+    private void checkDataFromJsonEmpty(final Cont dataFromJson) {
         assertTrue(dataFromJson.getLfs().isEmpty());
         assertTrue(dataFromJson.getLfLsts().isEmpty());
         assertTrue(dataFromJson.getConts().isEmpty());
@@ -357,9 +357,9 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals(1, lst11_1.getLsts().size());
         assertEquals(
                 lst11_1.getLsts().get("lst111"),
-                new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", (int) 35))
-                        .addLstItem(new LstItem().addLf("lf1111", (int) 34)).addLstItem(new LstItem())
-                        .addLstItem(new LstItem()));
+                new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", 35))
+                .addLstItem(new LstItem().addLf("lf1111", 34)).addLstItem(new LstItem())
+                .addLstItem(new LstItem()));
         assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111"));
         // : lst11_1
 
@@ -378,10 +378,10 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals(1, lst11_2_cont111.getLsts().size());
         assertTrue(lst11_2_cont111.getConts().isEmpty());
 
-        assertEquals(new LfLst("lflst1111").addLf((int) 1024).addLf((int) 4096),
+        assertEquals(new LfLst("lflst1111").addLf(1024).addLf(4096),
                 lst11_2_cont111.getLfLsts().get("lflst1111"));
         assertEquals(
-                new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", (int) 4)).addLstItem(
+                new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", 4)).addLstItem(
                         new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111"));
         // :-cont111
         assertEquals(lst11_2.getLsts().get("lst112"), new Lst("lst112").addLstItem(new LstItem()));
@@ -407,7 +407,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private void checkDataFromJson(Cont dataFromJson) {
+    private void checkDataFromJson(final Cont dataFromJson) {
         assertNotNull(dataFromJson.getLfs().get("lf11"));
         assertEquals(dataFromJson.getLfs().get("lf11"), new Lf("lf11", "lf"));
 
@@ -450,7 +450,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         checkLst11_2(lst11_2);
     }
 
-    private void checkLst11_2(LstItem lst11_2) {
+    private void checkLst11_2(final LstItem lst11_2) {
         assertNotNull(lst11_2);
         assertEquals(2, lst11_2.getLfs().size());
         assertEquals(1, lst11_2.getConts().size());
@@ -479,7 +479,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
                 new LstItem().addLf(new Lf("lf1121", "lf1121 str21")));
     }
 
-    private void checkLst11_1(LstItem lst11_1) {
+    private void checkLst11_1(final LstItem lst11_1) {
         assertNotNull(lst11_1);
 
         assertEquals(2, lst11_1.getLfs().size());
@@ -507,7 +507,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         checkLst11x(lst11_1.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str11")));
     }
 
-    private void checkLst11x(Lst lst, LstItem... lstItems) {
+    private void checkLst11x(final Lst lst, final LstItem... lstItems) {
         assertNotNull(lst);
 
         Lst requiredLst = new Lst(lst.getName());
@@ -519,7 +519,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private void checkLst1111(Set<LstItem> lstItems, Lf lf11, Lf lf12, Lf lf21, Lf lf22) {
+    private void checkLst1111(final Set<LstItem> lstItems, final Lf lf11, final Lf lf12, final Lf lf21, final Lf lf22) {
         LstItem lst11_1_cont_lst1111_1 = null;
         LstItem lst11_1_cont_lst1111_2 = null;
         for (LstItem lstItem : lstItems) {
@@ -541,49 +541,49 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         // lst11_1
         MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
                 null, ModifyAction.CREATE, null);
-        cont1.getChildren().add(lst11_1);
+        cont1.getValue().add(lst11_1);
 
         MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_1,
                 (short) 1, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(lf111_1);
+        lst11_1.getValue().add(lf111_1);
 
         // lst111_1_1
         MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
                 lst11_1, null, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(lst111_1_1);
+        lst11_1.getValue().add(lst111_1_1);
         MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"),
-                lst111_1_1, (int) 34, ModifyAction.CREATE, null);
-        lst111_1_1.getChildren().add(lf1111_1_1);
+                lst111_1_1, 34, ModifyAction.CREATE, null);
+        lst111_1_1.getValue().add(lf1111_1_1);
         lst111_1_1.init();
         // :lst111_1_1
 
         // lst111_1_2
         MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
                 lst11_1, null, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(lst111_1_2);
+        lst11_1.getValue().add(lst111_1_2);
         MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"),
-                lst111_1_2, (int) 35, ModifyAction.CREATE, null);
-        lst111_1_2.getChildren().add(lf1111_1_2);
+                lst111_1_2, 35, ModifyAction.CREATE, null);
+        lst111_1_2.getValue().add(lf1111_1_2);
         lst111_1_2.init();
         // :lst111_1_2
 
         // lst111_1_3
         MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
                 lst11_1, null, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(lst111_1_3);
+        lst11_1.getValue().add(lst111_1_3);
         lst111_1_2.init();
         // :lst111_1_3
 
         // lst111_1_4
         MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"),
                 lst11_1, null, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(lst111_1_4);
+        lst11_1.getValue().add(lst111_1_4);
         lst111_1_2.init();
         // :lst111_1_4
 
         MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
                 lst11_1, null, ModifyAction.CREATE, null);
-        lst11_1.getChildren().add(cont111_1);
+        lst11_1.getValue().add(cont111_1);
 
         lst11_1.init();
         // :lst11_1
@@ -591,39 +591,39 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         // lst11_2
         MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
                 null, ModifyAction.CREATE, null);
-        cont1.getChildren().add(lst11_2);
+        cont1.getValue().add(lst11_2);
 
         MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_2,
                 (short) 2, ModifyAction.CREATE, null);
-        lst11_2.getChildren().add(lf111_2);
+        lst11_2.getValue().add(lf111_2);
 
         // cont111_2
         MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
                 lst11_2, null, ModifyAction.CREATE, null);
-        lst11_2.getChildren().add(cont111_2);
+        lst11_2.getValue().add(cont111_2);
 
         MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"),
-                cont111_2, (int) 1024, ModifyAction.CREATE, null);
-        cont111_2.getChildren().add(lflst1111_2_2);
+                cont111_2, 1024, ModifyAction.CREATE, null);
+        cont111_2.getValue().add(lflst1111_2_2);
         MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"),
-                cont111_2, (int) 4096, ModifyAction.CREATE, null);
-        cont111_2.getChildren().add(lflst1111_2_3);
+                cont111_2, 4096, ModifyAction.CREATE, null);
+        cont111_2.getValue().add(lflst1111_2_3);
 
         // lst1111_2
         MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
                 cont111_2, null, ModifyAction.CREATE, null);
-        cont111_2.getChildren().add(lst1111_2_1);
+        cont111_2.getValue().add(lst1111_2_1);
         MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B","simple:yang:types","2013-11-5"),
                 lst1111_2_1, (short) 4, ModifyAction.CREATE, null);
-        lst1111_2_1.getChildren().add(lf1111B_2_1);
+        lst1111_2_1.getValue().add(lf1111B_2_1);
         lst1111_2_1.init();
 
         MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
                 cont111_2, null, ModifyAction.CREATE, null);
-        cont111_2.getChildren().add(lst1111_2_2);
+        cont111_2.getValue().add(lst1111_2_2);
         MutableSimpleNode<?> lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A","simple:yang:types","2013-11-5"),
                 lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null);
-        lst1111_2_2.getChildren().add(lf1111A_2_2);
+        lst1111_2_2.getValue().add(lf1111A_2_2);
         lst1111_2_2.init();
         // :lst1111_2
 
@@ -632,7 +632,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
 
         MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112","simple:yang:types","2013-11-5"), lst11_2,
                 null, ModifyAction.CREATE, null);
-        lst11_2.getChildren().add(lst112_2);
+        lst11_2.getValue().add(lst112_2);
         lst112_2.init();
         lst11_2.init();
 
@@ -641,25 +641,25 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader {
         // lst11_3
         MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1,
                 null, ModifyAction.CREATE, null);
-        cont1.getChildren().add(lst11_3);
+        cont1.getValue().add(lst11_3);
 
         MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_3,
                 (short) 3, ModifyAction.CREATE, null);
-        lst11_3.getChildren().add(lf111_3);
+        lst11_3.getValue().add(lf111_3);
 
         // cont111_3
         MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"),
                 lst11_3, null, ModifyAction.CREATE, null);
-        lst11_3.getChildren().add(cont111_3);
+        lst11_3.getValue().add(cont111_3);
 
         MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
                 cont111_3, null, ModifyAction.CREATE, null);
-        cont111_3.getChildren().add(lst1111_3_1);
+        cont111_3.getValue().add(lst1111_3_1);
         lst1111_3_1.init();
 
         MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"),
                 cont111_3, null, ModifyAction.CREATE, null);
-        cont111_3.getChildren().add(lst1111_3_2);
+        cont111_3.getValue().add(lst1111_3_2);
         lst1111_3_2.init();
 
         cont111_3.init();
index 745f11c210db6c44f90ba97ccacfd6624dc1eb4e..fdd3aa6684303babcabc9c849792e37c6cbf758e 100644 (file)
@@ -73,17 +73,17 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader {
         assertTrue(mtch.matches());
     }
 
-    private CompositeNode prepareCompositeNode(Object value) {
+    private CompositeNode prepareCompositeNode(final Object value) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont","identityref:module","2013-12-2"), null, null,
                 ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1","identityref:module","2013-12-2"), cont, null,
                 ModifyAction.CREATE, null);
-        cont.getChildren().add(cont1);
+        cont.getValue().add(cont1);
 
         MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1","identityref:module","2013-12-2"), cont1, value,
                 ModifyAction.CREATE, null);
 
-        cont1.getChildren().add(lf1);
+        cont1.getValue().add(lf1);
         cont1.init();
         cont.init();
 
index dd1502ba79f5c1325aefbeca443fde34e997da90..42e1e3f739a002259e4b833dd1e9dbafdb373b78 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 import org.slf4j.Logger;
@@ -46,7 +47,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo
         String jsonOutput = null;
         jsonOutput = TestUtils
                 .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
-                        Collections.EMPTY_SET, prepareDataSchemaNode(),
+                        Collections.<Module>emptySet(), prepareDataSchemaNode(),
                         StructuredDataToJsonProvider.INSTANCE);
         assertNotNull(jsonOutput);
         assertTrue(jsonOutput.contains("\"lf1\": \"\""));
@@ -57,7 +58,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo
                 TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
         MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
                 TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
-        cont.getChildren().add(lf1);
+        cont.getValue().add(lf1);
         cont.init();
         return cont;
     }
index 348edbd2945d6d1fb2f86ea0d1e3026a81132c47..052bb1a2be762ffca684a54109f724bd4d188ce9 100644 (file)
@@ -99,32 +99,32 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS
 
         MutableCompositeNode cont_m1 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont_m1", uri1, rev1), data, null, null, null);
-        data.getChildren().add(cont_m1);
+        data.getValue().add(cont_m1);
 
         MutableSimpleNode<?> lf1_m1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m1", uri1, rev1),
                 cont_m1, "lf1 m1 value", null, null);
-        cont_m1.getChildren().add(lf1_m1);
+        cont_m1.getValue().add(lf1_m1);
         cont_m1.init();
 
         MutableCompositeNode contB_m1 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("contB_m1", uri1, rev1), data, null, null, null);
-        data.getChildren().add(contB_m1);
+        data.getValue().add(contB_m1);
         contB_m1.init();
 
         String uri2 = "module:two";
         String rev2 = "2014-01-17";
         MutableCompositeNode cont_m2 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont_m2", uri2, rev2), data, null, null, null);
-        data.getChildren().add(cont_m2);
+        data.getValue().add(cont_m2);
 
         MutableSimpleNode<?> lf1_m2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m2", uri2, rev2),
                 cont_m1, "lf1 m2 value", null, null);
-        cont_m2.getChildren().add(lf1_m2);
+        cont_m2.getValue().add(lf1_m2);
         cont_m2.init();
 
         MutableCompositeNode contB_m2 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("contB_m2", uri2, rev2), data, null, null, null);
-        data.getChildren().add(contB_m2);
+        data.getValue().add(contB_m2);
         contB_m2.init();
 
         data.init();
index f81c1d63f5af572509a76e2fa5b1da05bafa71bb..2ada6e13e9a64c2e62101f693027e3686645d025 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
 import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 import org.slf4j.Logger;
@@ -41,7 +42,7 @@ public class CnSnToXmlNotExistingLeafTypeTest {
         boolean nullPointerExceptionRaised = false;
         try {
             TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(),
-                    Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
+                    Collections.<Module>emptySet(), prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE);
         } catch (WebApplicationException | IOException e) {
             LOG.error("WebApplicationException or IOException was raised");
         } catch (NullPointerException e) {
@@ -56,7 +57,7 @@ public class CnSnToXmlNotExistingLeafTypeTest {
                 TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null);
         MutableSimpleNode<?> lf1 = NodeFactory.createMutableSimpleNode(
                 TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null);
-        cont.getChildren().add(lf1);
+        cont.getValue().add(lf1);
         cont.init();
         return cont;
     }
index 6b4b15325238dd84e39f6745f1d9f6731fb85d2e..fc54795fcce5a468cb0d6e780f561a3052fe2eeb 100644 (file)
@@ -28,11 +28,11 @@ import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
 
 /**
- * 
+ *
  * CnSn = Composite node and Simple node data structure Class contains test of
  * serializing simple nodes data values according data types from YANG schema to
  * XML file
- * 
+ *
  */
 public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
     @BeforeClass
@@ -139,9 +139,9 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
         serializeToXml(
                 prepareCnStructForYangData(
                         TypeDefinitionAwareCodec.BINARY_DEFAULT_CODEC
-                                .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
+                        .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"),
                         elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567</"
-                        + elName + ">");
+                                + elName + ">");
     }
 
     @Test
@@ -198,7 +198,7 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
                         + elName + ">str</" + elName + ">");
     }
 
-    private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation)
+    private void serializeToXml(final CompositeNode compositeNode, final String... xmlRepresentation)
             throws TransformerFactoryConfigurationError {
         String xmlString = "";
         try {
@@ -220,12 +220,12 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) {
+    private CompositeNode prepareIdentityrefData(final String prefix, final boolean valueAsQName) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null);
-        cont.getChildren().add(cont1);
+        cont.getValue().add(cont1);
 
         Object value = null;
         if (valueAsQName) {
@@ -235,20 +235,20 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
         }
         MutableSimpleNode<Object> lf11 = NodeFactory.createMutableSimpleNode(
                 TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null);
-        cont1.getChildren().add(lf11);
+        cont1.getValue().add(lf11);
         cont1.init();
         cont.init();
 
         return cont;
     }
 
-    private CompositeNode prepareCnStructForYangData(Object data, String leafName) {
+    private CompositeNode prepareCnStructForYangData(final Object data, final String leafName) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
 
         MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(leafName), cont, data,
                 ModifyAction.CREATE, null);
-        cont.getChildren().add(lf1);
+        cont.getValue().add(lf1);
         cont.init();
 
         return cont;
@@ -262,8 +262,8 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader {
                 cont, Boolean.TRUE, ModifyAction.CREATE, null);
         MutableSimpleNode<Object> lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont,
                 "true", ModifyAction.CREATE, null);
-        cont.getChildren().add(lfBoolean);
-        cont.getChildren().add(lfLfref);
+        cont.getValue().add(lfBoolean);
+        cont.getValue().add(lfLfref);
         cont.init();
 
         return cont;
index a3e33ce30b6eca4192215a6cc21bc0402abb8897..ac7fe20818f31fc7fbb5bfd24b4399b2113cadee 100644 (file)
@@ -18,15 +18,18 @@ import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.ModifyAction;
+import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
 /**
- * 
+ *
  * CnSn = Composite node and Simple node data structure Class contains test of
  * serializing simple nodes data values according data types from YANG schema to
  * XML file
- * 
+ *
  */
 public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader {
     @BeforeClass
@@ -56,13 +59,13 @@ public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader {
 
     }
 
-    private CompositeNode prepareCnStructForYangData(String lfName, Object data) {
+    private CompositeNode prepareCnStructForYangData(final String lfName, final Object data) {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null,
                 ModifyAction.CREATE, null);
 
         MutableSimpleNode<Object> lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data,
                 ModifyAction.CREATE, null);
-        cont.getChildren().add(lf1);
+        cont.getValue().add(lf1);
         cont.init();
 
         return cont;
index 9e726baf55d29254e41692081fe3f64017247062..0c9e95173fd3f1e309b6e512a90260eaf8bbb899 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import java.util.List;
 
@@ -17,7 +19,9 @@ import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 
 public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -36,13 +40,13 @@ public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        List<Node<?>> childs = compositeNode.getChildren();
+        List<Node<?>> childs = compositeNode.getValue();
         assertEquals(1, childs.size());
         Node<?> nd = childs.iterator().next();
         assertTrue(nd instanceof CompositeNode);
         assertEquals("cont1", nd.getNodeType().getLocalName());
 
-        childs = ((CompositeNode) nd).getChildren();
+        childs = ((CompositeNode) nd).getValue();
         assertEquals(4, childs.size());
         SimpleNode<?> lf11 = null;
         SimpleNode<?> lf12 = null;
index 2030d9125a142032e340b3025eeb078a5434a00d..79dd026fd0dc5cf21b69d7dae886070b009a5999 100644 (file)
@@ -7,14 +7,18 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 
 public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -37,7 +41,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
         SimpleNode<?> lf2 = null;
-        for (Node<?> childNode : compositeNode.getChildren()) {
+        for (Node<?> childNode : compositeNode.getValue()) {
             if (childNode instanceof SimpleNode) {
                 if (childNode.getNodeType().getLocalName().equals("lf2")) {
                     lf2 = (SimpleNode<?>) childNode;
@@ -48,7 +52,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
         assertNotNull(lf2);
         assertTrue(lf2.getValue() instanceof String);
-        assertEquals("121", (String) lf2.getValue());
+        assertEquals("121", lf2.getValue());
 
     }
 
index 8b1dc3475f6f9f986c61658124942e7f1804d234..415d58e53d3f43684aaca2edfde78eee91a033ca 100644 (file)
@@ -58,13 +58,13 @@ public class JsonToCnSnTest {
         CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true,
                 JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
-        assertEquals(3, compositeNode.getChildren().size());
+        assertEquals(3, compositeNode.getValue().size());
 
         boolean lflst1_1 = false;
         boolean lflst1_2 = false;
         boolean lflst1_3 = false;
 
-        for (Node<?> node : compositeNode.getChildren()) {
+        for (Node<?> node : compositeNode.getValue()) {
             assertEquals("lflst1", node.getNodeType().getLocalName());
             assertTrue(node instanceof SimpleNode<?>);
             SimpleNode<?> simpleNode = (SimpleNode<?>) node;
@@ -105,9 +105,9 @@ public class JsonToCnSnTest {
         assertNotNull(compositeNode);
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        assertNotNull(compositeNode.getChildren());
-        assertEquals(1, compositeNode.getChildren().size());
-        Node<?> lfNode = compositeNode.getChildren().iterator().next();
+        assertNotNull(compositeNode.getValue());
+        assertEquals(1, compositeNode.getValue().size());
+        Node<?> lfNode = compositeNode.getValue().iterator().next();
 
         assertTrue(lfNode instanceof SimpleNode<?>);
         assertEquals(null, ((SimpleNode<?>) lfNode).getValue());
@@ -119,7 +119,7 @@ public class JsonToCnSnTest {
         Throwable cause1 = null;
         try {
             TestUtils
-                    .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
+            .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause1 = e;
         }
@@ -134,7 +134,7 @@ public class JsonToCnSnTest {
         Throwable cause2 = null;
         try {
             TestUtils
-                    .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
+            .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause2 = e;
         }
@@ -144,7 +144,7 @@ public class JsonToCnSnTest {
         Throwable cause3 = null;
         try {
             TestUtils
-                    .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
+            .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE);
         } catch (WebApplicationException e) {
             cause3 = e;
         }
@@ -170,7 +170,7 @@ public class JsonToCnSnTest {
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
         assertTrue(compositeNode instanceof CompositeNode);
-        List<Node<?>> children = ((CompositeNode) compositeNode).getChildren();
+        List<Node<?>> children = compositeNode.getValue();
         assertEquals(1, children.size());
         assertEquals("lflst2", children.get(0).getNodeType().getLocalName());
         assertEquals("45", children.get(0).getValue());
@@ -190,7 +190,7 @@ public class JsonToCnSnTest {
      * Tests whether namespace <b>stay unchanged</b> if concrete values are
      * present in composite or simple node and if the method for update is
      * called.
-     * 
+     *
      */
     @Test
     public void notSupplyNamespaceIfAlreadySupplied() {
@@ -233,13 +233,13 @@ public class JsonToCnSnTest {
 
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        List<Node<?>> childs = compositeNode.getChildren();
+        List<Node<?>> childs = compositeNode.getValue();
         assertEquals(1, childs.size());
         Node<?> nd = childs.iterator().next();
         assertTrue(nd instanceof CompositeNode);
         assertEquals("cont1", nd.getNodeType().getLocalName());
 
-        childs = ((CompositeNode) nd).getChildren();
+        childs = ((CompositeNode) nd).getValue();
         assertEquals(4, childs.size());
         SimpleNode<?> lf11 = null;
         SimpleNode<?> lf12 = null;
@@ -274,7 +274,7 @@ public class JsonToCnSnTest {
         assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
         assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
     }
-    
+
     @Ignore
     @Test
     public void loadDataAugmentedSchemaMoreEqualNamesTest() {
@@ -285,17 +285,17 @@ public class JsonToCnSnTest {
         } catch (ResponseException e) {
             exceptionCaught = true;
         }
-        
+
         assertFalse(exceptionCaught);
     }
 
-    private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
-            String moduleName) {
+    private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName, final String namespace,
+            final String moduleName) {
         CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName);
         verifyCompositeNode(compNode, namespace);
     }
 
-    private CompositeNode loadAndNormalizeData(String jsonPath, String yangPath, String topLevelElementName, String moduleName) {
+    private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath, final String topLevelElementName, final String moduleName) {
         CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
@@ -312,8 +312,8 @@ public class JsonToCnSnTest {
         return compNode;
     }
 
-    private void verityMultipleItemsInList(CompositeNode compositeNode) {
-        List<Node<?>> childrenNodes = compositeNode.getChildren();
+    private void verityMultipleItemsInList(final CompositeNode compositeNode) {
+        List<Node<?>> childrenNodes = compositeNode.getValue();
         assertEquals(4, childrenNodes.size());
         boolean lf11Found = false;
         boolean cont11Found = false;
@@ -322,7 +322,7 @@ public class JsonToCnSnTest {
             assertEquals("lst1", lst1Item.getNodeType().getLocalName());
             assertTrue(lst1Item instanceof CompositeNode);
 
-            List<Node<?>> childrenLst1 = ((CompositeNode) lst1Item).getChildren();
+            List<Node<?>> childrenLst1 = ((CompositeNode) lst1Item).getValue();
             assertEquals(1, childrenLst1.size());
             String localName = childrenLst1.get(0).getNodeType().getLocalName();
             if (localName.equals("lf11")) {
@@ -338,7 +338,7 @@ public class JsonToCnSnTest {
             } else if (localName.equals("lst11")) {
                 lst11Found = true;
                 assertTrue(childrenLst1.get(0) instanceof CompositeNode);
-                assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getChildren().size());
+                assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getValue().size());
             }
 
         }
@@ -347,7 +347,7 @@ public class JsonToCnSnTest {
         assertTrue(lst11Found);
     }
 
-    private void verifyCompositeNode(CompositeNode compositeNode, String namespace) {
+    private void verifyCompositeNode(final CompositeNode compositeNode, final String namespace) {
         boolean cont1Found = false;
         boolean lst1Found = false;
         boolean lflst1_1Found = false;
@@ -357,16 +357,16 @@ public class JsonToCnSnTest {
         // assertEquals(namespace,
         // compositeNode.getNodeType().getNamespace().toString());
 
-        for (Node<?> node : compositeNode.getChildren()) {
+        for (Node<?> node : compositeNode.getValue()) {
             if (node.getNodeType().getLocalName().equals("cont1")) {
                 if (node instanceof CompositeNode) {
                     cont1Found = true;
-                    assertEquals(0, ((CompositeNode) node).getChildren().size());
+                    assertEquals(0, ((CompositeNode) node).getValue().size());
                 }
             } else if (node.getNodeType().getLocalName().equals("lst1")) {
                 if (node instanceof CompositeNode) {
                     lst1Found = true;
-                    assertEquals(0, ((CompositeNode) node).getChildren().size());
+                    assertEquals(0, ((CompositeNode) node).getValue().size());
                 }
             } else if (node.getNodeType().getLocalName().equals("lflst1")) {
                 if (node instanceof SimpleNode) {
index 0492b3efd4f1b7a1696c1452a5d69ee9fec07c12..07d781028b99feaa03cd8dc610f499f63a0ca1dc 100644 (file)
@@ -64,7 +64,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
     @Ignore
     @Test
     public void saveCnSnWithLeafListInstIdentifierToXmlTest() throws WebApplicationException, IOException,
-            URISyntaxException, XMLStreamException {
+    URISyntaxException, XMLStreamException {
         CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList());
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToXmlProvider.INSTANCE);
@@ -94,7 +94,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     @Test
     public void saveCnSnWithLeafListInstIdentifierToJsonTest() throws WebApplicationException, IOException,
-            URISyntaxException {
+    URISyntaxException {
         CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList());
         String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode,
                 StructuredDataToJsonProvider.INSTANCE);
@@ -111,7 +111,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
         assertTrue(strInOutput);
     }
 
-    private void validateXmlOutput(String xml) throws XMLStreamException {
+    private void validateXmlOutput(final String xml) throws XMLStreamException {
         XMLInputFactory xmlInFactory = XMLInputFactory.newInstance();
         XMLEventReader eventReader;
 
@@ -152,7 +152,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     }
 
-    private void validateXmlOutputWithLeafList(String xml) throws XMLStreamException {
+    private void validateXmlOutputWithLeafList(final String xml) throws XMLStreamException {
         XMLInputFactory xmlInFactory = XMLInputFactory.newInstance();
         XMLEventReader eventReader;
 
@@ -188,7 +188,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
     }
 
-    private CompositeNode prepareCnSn(InstanceIdentifier instanceIdentifier) throws URISyntaxException {
+    private CompositeNode prepareCnSn(final InstanceIdentifier instanceIdentifier) throws URISyntaxException {
         MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(
                 TestUtils.buildQName("cont", "instance:identifier:module", "2014-01-17"), null, null,null,null);
         MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
@@ -200,13 +200,13 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
                 lst11, instanceIdentifier,null,null);
 
 
-        lst11.getChildren().add(lf111);
+        lst11.getValue().add(lf111);
         lst11.init();
 
-        cont1.getChildren().add(lst11);
+        cont1.getValue().add(lst11);
         cont1.init();
 
-        cont.getChildren().add(cont1);
+        cont.getValue().add(cont1);
         cont.init();
 
         return cont;
index b42178a9c6cfbc965c92957b5e28420d4764c4bf..018a235718323b9c783bbbf0612c96f484de61a1 100644 (file)
@@ -63,7 +63,7 @@ public class InvokeRpcMethodTest {
 
     private class AnswerImpl implements Answer<RpcResult<CompositeNode>> {
         @Override
-        public RpcResult<CompositeNode> answer(InvocationOnMock invocation) throws Throwable {
+        public RpcResult<CompositeNode> answer(final InvocationOnMock invocation) throws Throwable {
             CompositeNode compNode = (CompositeNode) invocation.getArguments()[1];
             return new DummyRpcResult.Builder<CompositeNode>().result(compNode).isSuccessful(true).build();
         }
@@ -123,7 +123,7 @@ public class InvokeRpcMethodTest {
                 TestUtils.buildQName("cont", "nmspc", "2013-12-04"), null, null, ModifyAction.CREATE, null);
         MutableSimpleNode<?> lf = NodeFactory.createMutableSimpleNode(
                 TestUtils.buildQName("lf", "nmspc", "2013-12-04"), cont, "any value", ModifyAction.CREATE, null);
-        cont.getChildren().add(lf);
+        cont.getValue().add(lf);
         cont.init();
 
         return cont;
@@ -150,7 +150,7 @@ public class InvokeRpcMethodTest {
         } catch (ResponseException e) {
             assertEquals(e.getMessage(),
                     Status.INTERNAL_SERVER_ERROR.getStatusCode(), e
-                            .getResponse().getStatus());
+                    .getResponse().getStatus());
         }
     }
 
@@ -216,7 +216,7 @@ public class InvokeRpcMethodTest {
         } catch (ResponseException e) {
             assertEquals(e.getMessage(),
                     Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode(), e
-                            .getResponse().getStatus());
+                    .getResponse().getStatus());
         }
     }
 
@@ -273,8 +273,8 @@ public class InvokeRpcMethodTest {
 
         BrokerFacade brokerFacade = mock(BrokerFacade.class);
         when( brokerFacade.invokeRpc(
-                        eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")),
-                        any( CompositeNode.class ))).thenReturn(rpcResult);
+                eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")),
+                any( CompositeNode.class ))).thenReturn(rpcResult);
 
         restconfImpl.setBroker(brokerFacade);
 
@@ -301,7 +301,7 @@ public class InvokeRpcMethodTest {
 
         MountInstance mockMountPoint = mock( MountInstance.class );
         when( mockMountPoint.rpc( eq( cancelToastQName ), any( CompositeNode.class ) ) )
-                                                                        .thenReturn( mockListener );
+        .thenReturn( mockListener );
 
         InstanceIdWithSchemaNode mockedInstanceId = mock( InstanceIdWithSchemaNode.class );
         when( mockedInstanceId.getMountPoint() ).thenReturn( mockMountPoint );
@@ -315,8 +315,8 @@ public class InvokeRpcMethodTest {
 
         restconfImpl.setControllerContext( mockedContext );
         StructuredData output = restconfImpl.invokeRpc(
-               "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast",
-               "");
+                "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast",
+                "");
         assertEquals(null, output);
 
         //additional validation in the fact that the restconfImpl does not throw an exception.
index 7a949b8f2df962ad9efcf6d93b532296263cb98a..e5b0bf507d03212bf2efedaaa18cc2f28f734567 100644 (file)
@@ -50,13 +50,13 @@ public class XmlLeafrefToCnSnTest {
         verifyCommonPartAOfXml(compNode, "", nameSpace);
     }
 
-    private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) {
+    private void verifyNullAndEmptyStringSingleNode(final CompositeNode compNode, final String nameSpace) {
         assertEquals("cont", compNode.getNodeType().getLocalName());
 
         SimpleNode<?> lf2 = null;
         SimpleNode<?> lf3 = null;
         int found = 0;
-        for (Node<?> child : compNode.getChildren()) {
+        for (Node<?> child : compNode.getValue()) {
             if (found == 0x3)
                 break;
             if (child instanceof SimpleNode<?>) {
@@ -91,11 +91,11 @@ public class XmlLeafrefToCnSnTest {
         String nameSpaceCont = "data:container:yang";
         assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString());
         assertEquals("cont", compNode.getNodeType().getLocalName());
-        assertEquals(3, compNode.getChildren().size());
+        assertEquals(3, compNode.getValue().size());
         CompositeNode lst1_1 = null;
         CompositeNode lst1_2 = null;
         int loopCount = 0;
-        for (Node<?> node : compNode.getChildren()) {
+        for (Node<?> node : compNode.getValue()) {
             if (node.getNodeType().getLocalName().equals("lf1")) {
                 assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString());
                 assertTrue(node instanceof SimpleNode<?>);
@@ -120,7 +120,7 @@ public class XmlLeafrefToCnSnTest {
         // lst1_2
         SimpleNode<?> lflst11 = null;
         CompositeNode cont11 = null;
-        for (Node<?> node : lst1_2.getChildren()) {
+        for (Node<?> node : lst1_2.getValue()) {
             String nodeName = node.getNodeType().getLocalName();
             if (nodeName.equals("lflst11")) {
                 assertTrue(node instanceof SimpleNode<?>);
@@ -134,9 +134,9 @@ public class XmlLeafrefToCnSnTest {
         }
         assertEquals("221", lflst11.getValue());
 
-        assertEquals(1, cont11.getChildren().size());
-        assertTrue(cont11.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getChildren().get(0);
+        assertEquals(1, cont11.getValue().size());
+        assertTrue(cont11.getValue().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont11_lf111 = (SimpleNode<?>) cont11.getValue().get(0);
         assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString());
         assertEquals("lf111", cont11_lf111.getNodeType().getLocalName());
         assertEquals((short) 100, cont11_lf111.getValue());
@@ -154,7 +154,7 @@ public class XmlLeafrefToCnSnTest {
         SimpleNode<?> lflst1_2 = null;
         CompositeNode lst1 = null;
         int lflst1Count = 0;
-        for (Node<?> node : compNode.getChildren()) {
+        for (Node<?> node : compNode.getValue()) {
             if (node.getNodeType().getLocalName().equals("lf1")) {
                 assertTrue(node instanceof SimpleNode<?>);
                 lf1 = (SimpleNode<?>) node;
@@ -183,11 +183,11 @@ public class XmlLeafrefToCnSnTest {
         assertEquals("", lf1.getValue());
         assertEquals("", lflst1_1.getValue());
         assertEquals("", lflst1_2.getValue());
-        assertEquals(1, lst1.getChildren().size());
-        assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName());
+        assertEquals(1, lst1.getValue().size());
+        assertEquals("lf11", lst1.getValue().get(0).getNodeType().getLocalName());
 
-        assertTrue(lst1.getChildren().get(0) instanceof SimpleNode<?>);
-        assertEquals("", lst1.getChildren().get(0).getValue());
+        assertTrue(lst1.getValue().get(0) instanceof SimpleNode<?>);
+        assertEquals("", lst1.getValue().get(0).getValue());
 
     }
 
@@ -201,7 +201,7 @@ public class XmlLeafrefToCnSnTest {
     }
 
     /**
-     * 
+     *
      * Test case like <lf11 xmlns="namespace1"
      * xmlns:x="namespace">identity</lf11>
      */
@@ -213,7 +213,7 @@ public class XmlLeafrefToCnSnTest {
     }
 
     /**
-     * 
+     *
      * Test case like <cont1 xmlns="namespace1"> <lf11
      * xmlns:x="namespace">identity</lf11> </cont1>
      */
@@ -224,7 +224,7 @@ public class XmlLeafrefToCnSnTest {
     }
 
     /**
-     * 
+     *
      * Test case like <cont1 xmlns="namespace1" xmlns:x="namespace">
      * <lf11>x:identity</lf11> </cont1>
      */
@@ -236,7 +236,7 @@ public class XmlLeafrefToCnSnTest {
     }
 
     /**
-     * 
+     *
      * Test case like (without namespace in xml) <cont1> <lf11>x:identity</lf11>
      * </cont1>
      */
@@ -247,7 +247,7 @@ public class XmlLeafrefToCnSnTest {
     }
 
     /**
-     * 
+     *
      * Test case like (without namespace in xml) <cont1> <lf11>identity</lf11>
      * </cont1>
      */
@@ -257,7 +257,7 @@ public class XmlLeafrefToCnSnTest {
                 "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module");
     }
 
-    private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) {
+    private void verifyCommonPartAOfXml(final CompositeNode compNode, final String suf, final String nameSpace) {
         SimpleNode<?> lf1suf = null;
         SimpleNode<?> lflst1suf_1 = null;
         SimpleNode<?> lflst1suf_2 = null;
@@ -267,7 +267,7 @@ public class XmlLeafrefToCnSnTest {
 
         int lflstCount = 0;
 
-        for (Node<?> node : compNode.getChildren()) {
+        for (Node<?> node : compNode.getValue()) {
             String localName = node.getNodeType().getLocalName();
             if (localName.equals("lf1" + suf)) {
                 assertTrue(node instanceof SimpleNode<?>);
@@ -307,23 +307,23 @@ public class XmlLeafrefToCnSnTest {
         assertEquals("131", lflst1suf_2.getValue());
         assertEquals("str1", lflst1suf_3.getValue());
 
-        assertEquals(1, lst1suf.getChildren().size());
+        assertEquals(1, lst1suf.getValue().size());
 
-        assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getChildren().get(0);
+        assertTrue(lst1suf.getValue().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> lst11_lf11 = (SimpleNode<?>) lst1suf.getValue().get(0);
         assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString());
         assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName());
         assertEquals("str2", lst11_lf11.getValue());
 
-        assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode<?>);
-        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getChildren().get(0);
+        assertTrue(cont1suf.getValue().get(0) instanceof SimpleNode<?>);
+        SimpleNode<?> cont1_lf11 = (SimpleNode<?>) cont1suf.getValue().get(0);
         assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString());
         assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName());
         assertEquals((short) 100, cont1_lf11.getValue());
     }
 
-    private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName,
-            int moduleCount, String resultLocalName, String resultNamespace) {
+    private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName, final String schemaName,
+            final int moduleCount, final String resultLocalName, final String resultNamespace) {
         CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE);
         assertNotNull(compositeNode);
 
@@ -339,16 +339,16 @@ public class XmlLeafrefToCnSnTest {
         assertEquals(resultNamespace, qName.getNamespace().toString());
     }
 
-    private SimpleNode<?> getLf11(CompositeNode compositeNode) {
+    private SimpleNode<?> getLf11(final CompositeNode compositeNode) {
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
-        List<Node<?>> childs = compositeNode.getChildren();
+        List<Node<?>> childs = compositeNode.getValue();
         assertEquals(1, childs.size());
         Node<?> nd = childs.iterator().next();
         assertTrue(nd instanceof CompositeNode);
         assertEquals("cont1", nd.getNodeType().getLocalName());
 
-        childs = ((CompositeNode) nd).getChildren();
+        childs = ((CompositeNode) nd).getValue();
         SimpleNode<?> lf11 = null;
         for (Node<?> child : childs) {
             assertTrue(child instanceof SimpleNode);
index f1a18d56a8de60241b64436aa299f2f3c3915de5..5008d28bbfb26ea0e8d9ef8ab2b1814e8736671d 100644 (file)
@@ -7,14 +7,18 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
 import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader;
-import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 
 public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
@@ -34,7 +38,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
         assertEquals("cont", compositeNode.getNodeType().getLocalName());
 
         SimpleNode<?> lf2 = null;
-        for (Node<?> childNode : compositeNode.getChildren()) {
+        for (Node<?> childNode : compositeNode.getValue()) {
             if (childNode instanceof SimpleNode) {
                 if (childNode.getNodeType().getLocalName().equals("lf2")) {
                     lf2 = (SimpleNode<?>) childNode;
@@ -45,7 +49,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader {
 
         assertNotNull(lf2);
         assertTrue(lf2.getValue() instanceof String);
-        assertEquals("121", (String) lf2.getValue());
+        assertEquals("121", lf2.getValue());
     }
 
 }
index ea08f94ebce89eb51553163eee625db100fef746..c2be488d9301f3b759c2f8e7b5a00e4262e8374e 100644 (file)
@@ -28,130 +28,129 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /* InstanceIdentifierUtils provides utility functions related to InstanceIdentifiers.
  */
-public class InstanceIdentifierUtils {
-
-  /**
-   * Creates an Instance Identifier (path) for node with specified id
-   *
-   * @param nodeId
-   * @return
-   */
-  public static final InstanceIdentifier<Node> createNodePath(NodeId nodeId) {
-    return InstanceIdentifier.builder(Nodes.class) //
-        .child(Node.class, new NodeKey(nodeId)) //
-        .build();
-  }
-
-  /**
-   * Shorten's node child path to node path.
-   *
-   * @param nodeChild child of node, from which we want node path.
-   * @return
-   */
-  public static final InstanceIdentifier<Node> getNodePath(InstanceIdentifier<?> nodeChild) {
-    return nodeChild.firstIdentifierOf(Node.class);
-  }
-
-
-  /**
-   * Creates a table path by appending table specific location to node path
-   *
-   * @param nodePath
-   * @param tableKey
-   * @return
-   */
-  public static final InstanceIdentifier<Table> createTablePath(InstanceIdentifier<Node> nodePath, TableKey tableKey) {
-    return InstanceIdentifier.builder(nodePath)
-        .augmentation(FlowCapableNode.class)
-        .child(Table.class, tableKey)
-        .build();
-  }
-
-  /**
-   * Creates a path for particular flow, by appending flow-specific information
-   * to table path.
-   *
-   * @param table
-   * @param flowKey
-   * @return
-   */
-  public static InstanceIdentifier<Flow> createFlowPath(InstanceIdentifier<Table> table, FlowKey flowKey) {
-    return InstanceIdentifier.builder(table)
-        .child(Flow.class, flowKey)
-        .build();
-  }
-
-  /**
-   * Extract table id from table path.
-   *
-   * @param tablePath
-   * @return
-   */
-  public static Short getTableId(InstanceIdentifier<Table> tablePath) {
-    return tablePath.firstKeyOf(Table.class, TableKey.class).getId();
-  }
-
-  /**
-   * Extracts NodeConnectorKey from node connector path.
-   */
-  public static NodeConnectorKey getNodeConnectorKey(InstanceIdentifier<?> nodeConnectorPath) {
-    return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class);
-  }
-
-  /**
-   * Extracts NodeKey from node path.
-   */
-  public static NodeKey getNodeKey(InstanceIdentifier<?> nodePath) {
-    return nodePath.firstKeyOf(Node.class, NodeKey.class);
-  }
-
-
-  //
-  public static final InstanceIdentifier<NodeConnector> createNodeConnectorIdentifier(String nodeIdValue,
-                                                                                      String nodeConnectorIdValue) {
-    return InstanceIdentifier.builder(createNodePath(new NodeId(nodeIdValue))) //
-        .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue))) //
-        .build();
-  }
-
-  /**
-   * @param nodeConnectorRef
-   * @return
-   */
-  public static InstanceIdentifier<Node> generateNodeInstanceIdentifier(NodeConnectorRef nodeConnectorRef) {
-    return nodeConnectorRef.getValue().firstIdentifierOf(Node.class);
-  }
-
-  /**
-   * @param nodeConnectorRef
-   * @param flowTableKey
-   * @return
-   */
-  public static InstanceIdentifier<Table> generateFlowTableInstanceIdentifier(NodeConnectorRef nodeConnectorRef, TableKey flowTableKey) {
-    return InstanceIdentifier.builder(generateNodeInstanceIdentifier(nodeConnectorRef))
-        .augmentation(FlowCapableNode.class)
-        .child(Table.class, flowTableKey)
-        .build();
-  }
-
-  /**
-   * @param nodeConnectorRef
-   * @param flowTableKey
-   * @param flowKey
-   * @return
-   */
-  public static InstanceIdentifier<Flow> generateFlowInstanceIdentifier(NodeConnectorRef nodeConnectorRef,
-                                                                        TableKey flowTableKey,
-                                                                        FlowKey flowKey) {
-    return InstanceIdentifier.builder(generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey))
-        .child(Flow.class, flowKey)
-        .build();
-  }
-
-  public static InstanceIdentifier<Topology> generateTopologyInstanceIdentifier(String topologyId) {
-    return InstanceIdentifier.builder(NetworkTopology.class)
-        .child(Topology.class, new TopologyKey(new TopologyId(topologyId)))
-        .build();
-  }
+public final class InstanceIdentifierUtils {
+
+    private InstanceIdentifierUtils() {
+        throw new UnsupportedOperationException("Utility class should never be instantiated");
+    }
+
+    /**
+     * Creates an Instance Identifier (path) for node with specified id
+     *
+     * @param nodeId
+     * @return
+     */
+    public static final InstanceIdentifier<Node> createNodePath(final NodeId nodeId) {
+        return InstanceIdentifier.builder(Nodes.class) //
+                .child(Node.class, new NodeKey(nodeId)) //
+                .build();
+    }
+
+    /**
+     * Shorten's node child path to node path.
+     *
+     * @param nodeChild child of node, from which we want node path.
+     * @return
+     */
+    public static final InstanceIdentifier<Node> getNodePath(final InstanceIdentifier<?> nodeChild) {
+        return nodeChild.firstIdentifierOf(Node.class);
+    }
+
+
+    /**
+     * Creates a table path by appending table specific location to node path
+     *
+     * @param nodePath
+     * @param tableKey
+     * @return
+     */
+    public static final InstanceIdentifier<Table> createTablePath(final InstanceIdentifier<Node> nodePath, final TableKey tableKey) {
+        return nodePath.builder()
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, tableKey)
+                .build();
+    }
+
+    /**
+     * Creates a path for particular flow, by appending flow-specific information
+     * to table path.
+     *
+     * @param table
+     * @param flowKey
+     * @return
+     */
+    public static InstanceIdentifier<Flow> createFlowPath(final InstanceIdentifier<Table> table, final FlowKey flowKey) {
+        return table.child(Flow.class, flowKey);
+    }
+
+    /**
+     * Extract table id from table path.
+     *
+     * @param tablePath
+     * @return
+     */
+    public static Short getTableId(final InstanceIdentifier<Table> tablePath) {
+        return tablePath.firstKeyOf(Table.class, TableKey.class).getId();
+    }
+
+    /**
+     * Extracts NodeConnectorKey from node connector path.
+     */
+    public static NodeConnectorKey getNodeConnectorKey(final InstanceIdentifier<?> nodeConnectorPath) {
+        return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class);
+    }
+
+    /**
+     * Extracts NodeKey from node path.
+     */
+    public static NodeKey getNodeKey(final InstanceIdentifier<?> nodePath) {
+        return nodePath.firstKeyOf(Node.class, NodeKey.class);
+    }
+
+
+    //
+    public static final InstanceIdentifier<NodeConnector> createNodeConnectorIdentifier(final String nodeIdValue,
+            final String nodeConnectorIdValue) {
+        return createNodePath(new NodeId(nodeIdValue))
+                .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue)));
+    }
+
+    /**
+     * @param nodeConnectorRef
+     * @return
+     */
+    public static InstanceIdentifier<Node> generateNodeInstanceIdentifier(final NodeConnectorRef nodeConnectorRef) {
+        return nodeConnectorRef.getValue().firstIdentifierOf(Node.class);
+    }
+
+    /**
+     * @param nodeConnectorRef
+     * @param flowTableKey
+     * @return
+     */
+    public static InstanceIdentifier<Table> generateFlowTableInstanceIdentifier(final NodeConnectorRef nodeConnectorRef, final TableKey flowTableKey) {
+        return generateNodeInstanceIdentifier(nodeConnectorRef).builder()
+                .augmentation(FlowCapableNode.class)
+                .child(Table.class, flowTableKey)
+                .build();
+    }
+
+    /**
+     * @param nodeConnectorRef
+     * @param flowTableKey
+     * @param flowKey
+     * @return
+     */
+    public static InstanceIdentifier<Flow> generateFlowInstanceIdentifier(final NodeConnectorRef nodeConnectorRef,
+            final TableKey flowTableKey,
+            final FlowKey flowKey) {
+        return generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey).child(Flow.class, flowKey);
+    }
+
+    public static InstanceIdentifier<Topology> generateTopologyInstanceIdentifier(final String topologyId) {
+        return InstanceIdentifier.builder(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(new TopologyId(topologyId)))
+                .build();
+    }
 }
 
index 3520d812d7e1b0a2e591b28f69a29630b61df08b..50f74cc33f99e40c91e3b2241c970ff650391928 100644 (file)
@@ -7,11 +7,19 @@
  */
 package org.opendaylight.controller.sample.l2switch.md.flow;
 
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
@@ -23,128 +31,110 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 /**
  */
 public class FlowWriterServiceImplTest {
-  private DataBrokerService dataBrokerService;
-  private NodeConnectorRef srcNodeConnectorRef;
-  private NodeConnectorRef destNodeConnectorRef;
-  private MacAddress destMacAddress;
-  private MacAddress srcMacAddress;
-  private DataModificationTransaction dataModificationTransaction;
-  private NetworkGraphService networkGraphService;
+    private DataBrokerService dataBrokerService;
+    private NodeConnectorRef srcNodeConnectorRef;
+    private NodeConnectorRef destNodeConnectorRef;
+    private MacAddress destMacAddress;
+    private MacAddress srcMacAddress;
+    private DataModificationTransaction dataModificationTransaction;
+    private NetworkGraphService networkGraphService;
 
-  @Before
-  public void init() {
-    dataBrokerService = mock(DataBrokerService.class);
-    networkGraphService = mock(NetworkGraphService.class);
-    //build source node connector ref
-    InstanceIdentifier<Nodes> srcNodesInstanceIdentifier
-        = InstanceIdentifier.builder(Nodes.class)
-        .build();
-    InstanceIdentifier<Node> srcNodeInstanceIdentifier
-        = InstanceIdentifier.builder(srcNodesInstanceIdentifier)
-        .child(Node.class, new NodeKey(new NodeId("openflow:1")))
-        .build();
-    InstanceIdentifier<NodeConnector> srcNodeConnectorInstanceIdentifier
-        = InstanceIdentifier.builder(srcNodeInstanceIdentifier)
-        .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2")))
-        .build();
-    srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier);
+    @Before
+    public void init() {
+        dataBrokerService = mock(DataBrokerService.class);
+        networkGraphService = mock(NetworkGraphService.class);
+        //build source node connector ref
+        InstanceIdentifier<Nodes> srcNodesInstanceIdentifier = InstanceIdentifier.create(Nodes.class);
+        InstanceIdentifier<Node> srcNodeInstanceIdentifier = srcNodesInstanceIdentifier
+                .child(Node.class, new NodeKey(new NodeId("openflow:1")));
+        InstanceIdentifier<NodeConnector> srcNodeConnectorInstanceIdentifier = srcNodeInstanceIdentifier
+                .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2")));
+        srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier);
 
-    //build dest node connector ref
-    InstanceIdentifier<Nodes> nodesInstanceIdentifier
+        //build dest node connector ref
+        InstanceIdentifier<Nodes> nodesInstanceIdentifier
         = InstanceIdentifier.builder(Nodes.class)
         .build();
-    InstanceIdentifier<Node> nodeInstanceIdentifier
-        = InstanceIdentifier.builder(nodesInstanceIdentifier)
-        .child(Node.class, new NodeKey(new NodeId("openflow:2")))
-        .build();
-    InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier
-        = InstanceIdentifier.builder(nodeInstanceIdentifier)
-        .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2")))
-        .build();
-    destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier);
-    destMacAddress = new MacAddress("00:0a:95:9d:68:16");
-    srcMacAddress = new MacAddress("00:0a:95:8c:97:24");
-    dataModificationTransaction = mock(DataModificationTransaction.class);
-    when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction);
-  }
+        InstanceIdentifier<Node> nodeInstanceIdentifier =
+                nodesInstanceIdentifier.child(Node.class, new NodeKey(new NodeId("openflow:2")));
+        InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifier =
+                nodeInstanceIdentifier.child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2")));
+        destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier);
+        destMacAddress = new MacAddress("00:0a:95:9d:68:16");
+        srcMacAddress = new MacAddress("00:0a:95:8c:97:24");
+        dataModificationTransaction = mock(DataModificationTransaction.class);
+        when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction);
+    }
 
-  @Test
-  public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception {
-    try {
-      new FlowWriterServiceImpl(null, networkGraphService);
-      fail("Expected null pointer exception.");
-    } catch(NullPointerException npe) {
-      assertEquals("dataBrokerService should not be null.", npe.getMessage());
+    @Test
+    public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception {
+        try {
+            new FlowWriterServiceImpl(null, networkGraphService);
+            fail("Expected null pointer exception.");
+        } catch(NullPointerException npe) {
+            assertEquals("dataBrokerService should not be null.", npe.getMessage());
+        }
     }
-  }
 
-  @Test
-  public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    try {
-      flowWriterService.addMacToMacFlow(null, null, null);
-      fail("Expected null pointer exception.");
-    } catch(NullPointerException npe) {
-      assertEquals("Destination mac address should not be null.", npe.getMessage());
+    @Test
+    public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        try {
+            flowWriterService.addMacToMacFlow(null, null, null);
+            fail("Expected null pointer exception.");
+        } catch(NullPointerException npe) {
+            assertEquals("Destination mac address should not be null.", npe.getMessage());
+        }
     }
-  }
 
-  @Test
-  public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    try {
-      flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef);
-      fail("Expected null pointer exception.");
-    } catch(NullPointerException npe) {
-      assertEquals("Destination mac address should not be null.", npe.getMessage());
+    @Test
+    public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        try {
+            flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef);
+            fail("Expected null pointer exception.");
+        } catch(NullPointerException npe) {
+            assertEquals("Destination mac address should not be null.", npe.getMessage());
+        }
     }
-  }
 
-  @Test
-  public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    try {
-      flowWriterService.addMacToMacFlow(null, destMacAddress, null);
-      fail("Expected null pointer exception.");
-    } catch(NullPointerException npe) {
-      assertEquals("Destination port should not be null.", npe.getMessage());
+    @Test
+    public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        try {
+            flowWriterService.addMacToMacFlow(null, destMacAddress, null);
+            fail("Expected null pointer exception.");
+        } catch(NullPointerException npe) {
+            assertEquals("Destination port should not be null.", npe.getMessage());
+        }
     }
-  }
 
-  @Test
-  public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef);
-    verify(dataBrokerService, times(1)).beginTransaction();
-    verify(dataModificationTransaction, times(1)).commit();
-  }
+    @Test
+    public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef);
+        verify(dataBrokerService, times(1)).beginTransaction();
+        verify(dataModificationTransaction, times(1)).commit();
+    }
 
-  @Test
-  public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef);
-    verify(dataBrokerService, never()).beginTransaction();
-    verify(dataModificationTransaction, never()).commit();
+    @Test
+    public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef);
+        verify(dataBrokerService, never()).beginTransaction();
+        verify(dataModificationTransaction, never()).commit();
 
-  }
+    }
 
-  @Test
-  public void testAddMacToMacFlow_SunnyDay() throws Exception {
-    FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
-    flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef);
-    verify(dataBrokerService, times(1)).beginTransaction();
-    verify(dataModificationTransaction, times(1)).commit();
-  }
+    @Test
+    public void testAddMacToMacFlow_SunnyDay() throws Exception {
+        FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService);
+        flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef);
+        verify(dataBrokerService, times(1)).beginTransaction();
+        verify(dataModificationTransaction, times(1)).commit();
+    }
 
 }
index ff950e95e9700289bf9dda3bed79642f1fba096e..c6974d4982db051f1cb6a66d3f67394ee2d57817 100644 (file)
@@ -27,7 +27,7 @@ public final class NetconfSSHServer implements Runnable {
     private static final AtomicLong sesssionId = new AtomicLong();
     private final InetSocketAddress clientAddress;
     private final AuthProvider authProvider;
-    private boolean up = false;
+    private volatile boolean up = false;
 
     private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException {
 
@@ -68,9 +68,17 @@ public final class NetconfSSHServer implements Runnable {
         while (up) {
             logger.trace("Starting new socket thread.");
             try {
-               SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider);
-            } catch (IOException e) {
-                logger.error("Exception occurred during socket thread initialization {}", e);
+                SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider);
+            }
+            catch (IOException e) {
+                if( up ) {
+                    logger.error("Exception occurred during socket thread initialization", e);
+                }
+                else {
+                    // We're shutting down so an exception is expected as the socket's been closed.
+                    // Log to debug.
+                    logger.debug("Shutting down - got expected exception: " + e);
+                }
             }
         }
     }
index c30f65903204df027b582c1c5816d5b106c91239..f1015381961d6b148f55681847280f7011328e72 100644 (file)
@@ -22,6 +22,8 @@ import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 
 public class Activator extends ComponentActivatorAbstractBase {
@@ -163,5 +165,37 @@ public class Activator extends ComponentActivatorAbstractBase {
                     "setConfigurationContainerService",
                     "unsetConfigurationContainerService").setRequired(true));
         }
+        if (imp.equals(NeutronSecurityGroupInterface.class)) {
+            // export the service
+            c.setInterface(
+                new String[] { INeutronSecurityGroupCRUD.class.getName(),
+                    IConfigurationContainerAware.class.getName()}, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                .setService(IClusterContainerServices.class)
+                .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+            c.add(createContainerServiceDependency(containerName).setService(
+                IConfigurationContainerService.class).setCallbacks(
+                "setConfigurationContainerService",
+                "unsetConfigurationContainerService").setRequired(true));
+        }
+        if (imp.equals(NeutronSecurityRuleInterface.class)) {
+            // export the service
+            c.setInterface(
+                new String[] { INeutronSecurityRuleCRUD.class.getName(),
+                    IConfigurationContainerAware.class.getName()}, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                .setService(IClusterContainerServices.class)
+                .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+            c.add(createContainerServiceDependency(containerName).setService(
+                IConfigurationContainerService.class).setCallbacks(
+                "setConfigurationContainerService",
+                "unsetConfigurationContainerService").setRequired(true));
+        }
     }
 }
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java
new file mode 100644 (file)
index 0000000..a991f61
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.ConfigurationObject;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
+import org.opendaylight.controller.configuration.IConfigurationContainerService;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NeutronSecurityGroupInterface implements INeutronSecurityGroupCRUD, IConfigurationContainerAware, IObjectReader {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupInterface.class);
+    private static final String FILE_NAME ="neutron.securitygroup.conf";
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private IConfigurationContainerService configurationService;
+    private ConcurrentMap<String, NeutronSecurityGroup> securityGroupDB;
+
+    // methods needed for creating caches
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            clusterContainerService = null;
+        }
+    }
+
+    public void setConfigurationContainerService(IConfigurationContainerService service) {
+        logger.trace("Configuration service set: {}", service);
+        configurationService = service;
+    }
+
+    public void unsetConfigurationContainerService(IConfigurationContainerService service) {
+        logger.trace("Configuration service removed: {}", service);
+        configurationService = null;
+    }
+
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron Security Groups");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronSecurityGroups",
+                EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron Security Groups -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron Security Groups already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for Neutron Security Groups");
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private void retrieveCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron Security Groups");
+        securityGroupDB = (ConcurrentMap<String, NeutronSecurityGroup>) clusterContainerService
+            .getCache("neutronSecurityGroups");
+        if (securityGroupDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Security Groups");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Security Groups");
+    }
+
+    private void destroyCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for Neutron Security Groups");
+        clusterContainerService.destroyCache("neutronSecurityGroups");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+        loadConfiguration();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean neutronSecurityGroupExists(String uuid) {
+        return securityGroupDB.containsKey(uuid);
+    }
+
+    @Override
+    public NeutronSecurityGroup getNeutronSecurityGroup(String uuid) {
+        if (!neutronSecurityGroupExists(uuid)) {
+            logger.debug("No Security Groups Have Been Defined");
+            return null;
+        }
+        return securityGroupDB.get(uuid);
+    }
+
+    @Override
+    public List<NeutronSecurityGroup> getAllNeutronSecurityGroups() {
+        Set<NeutronSecurityGroup> allSecurityGroups = new HashSet<NeutronSecurityGroup>();
+        for (Entry<String, NeutronSecurityGroup> entry : securityGroupDB.entrySet()) {
+            NeutronSecurityGroup securityGroup = entry.getValue();
+            allSecurityGroups.add(securityGroup);
+        }
+        logger.debug("Exiting getSecurityGroups, Found {} OpenStackSecurityGroup", allSecurityGroups.size());
+        List<NeutronSecurityGroup> ans = new ArrayList<NeutronSecurityGroup>();
+        ans.addAll(allSecurityGroups);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronSecurityGroup(NeutronSecurityGroup input) {
+        if (neutronSecurityGroupExists(input.getSecurityGroupUUID())) {
+            return false;
+        }
+        securityGroupDB.putIfAbsent(input.getSecurityGroupUUID(), input);
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronSecurityGroup(String uuid) {
+        if (!neutronSecurityGroupExists(uuid)) {
+            return false;
+        }
+        securityGroupDB.remove(uuid);
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta) {
+        if (!neutronSecurityGroupExists(uuid)) {
+            return false;
+        }
+        NeutronSecurityGroup target = securityGroupDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    @Override
+    public boolean neutronSecurityGroupInUse(String securityGroupUUID) {
+        return !neutronSecurityGroupExists(securityGroupUUID);
+    }
+
+    private void loadConfiguration() {
+        for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) {
+            NeutronSecurityGroup nn = (NeutronSecurityGroup) conf;
+            securityGroupDB.put(nn.getSecurityGroupUUID(), nn);
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        return configurationService.persistConfiguration(new ArrayList<ConfigurationObject>(securityGroupDB.values()),
+            FILE_NAME);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java
new file mode 100644 (file)
index 0000000..5ca907b
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.configuration.ConfigurationObject;
+import org.opendaylight.controller.configuration.IConfigurationContainerAware;
+import org.opendaylight.controller.configuration.IConfigurationContainerService;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.Status;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class NeutronSecurityRuleInterface implements INeutronSecurityRuleCRUD, IConfigurationContainerAware, IObjectReader {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRuleInterface.class);
+    private static final String FILE_NAME = "neutron.securityrule.conf";
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private IConfigurationContainerService configurationService;
+    private ConcurrentMap<String, NeutronSecurityRule> securityRuleDB;
+
+    // methods needed for creating caches
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            clusterContainerService = null;
+        }
+    }
+
+    public void setConfigurationContainerService(IConfigurationContainerService service) {
+        logger.trace("Configuration service set: {}", service);
+        configurationService = service;
+    }
+
+    public void unsetConfigurationContainerService(IConfigurationContainerService service) {
+        logger.trace("Configuration service removed: {}", service);
+        configurationService = null;
+    }
+
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron Security Rules");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronSecurityRules",
+                EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron Security Rules -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron Security Rules already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for Neutron Security Rules");
+    }
+
+    @SuppressWarnings({"unchecked"})
+    private void retrieveCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron Security Rules");
+        securityRuleDB = (ConcurrentMap<String, NeutronSecurityRule>) clusterContainerService
+            .getCache("neutronSecurityRules");
+        if (securityRuleDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Security Rules");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Security Rules");
+    }
+
+    private void destroyCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for Neutron Security Rules");
+        clusterContainerService.destroyCache("neutronSecurityRules");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+        loadConfiguration();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for (Method toMethod : methods) {
+            if (toMethod.getDeclaringClass().equals(target.getClass())
+                && toMethod.getName().startsWith("set")) {
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[]) null);
+                    if (value != null) {
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean neutronSecurityRuleExists(String uuid) {
+        return securityRuleDB.containsKey(uuid);
+    }
+
+    @Override
+    public NeutronSecurityRule getNeutronSecurityRule(String uuid) {
+        if (!neutronSecurityRuleExists(uuid)) {
+            logger.debug("No Security Rules Have Been Defined");
+            return null;
+        }
+        return securityRuleDB.get(uuid);
+    }
+
+    @Override
+    public List<NeutronSecurityRule> getAllNeutronSecurityRules() {
+        Set<NeutronSecurityRule> allSecurityRules = new HashSet<NeutronSecurityRule>();
+        for (Entry<String, NeutronSecurityRule> entry : securityRuleDB.entrySet()) {
+            NeutronSecurityRule securityRule = entry.getValue();
+            allSecurityRules.add(securityRule);
+        }
+        logger.debug("Exiting getSecurityRule, Found {} OpenStackSecurityRule", allSecurityRules.size());
+        List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
+        ans.addAll(allSecurityRules);
+        return ans;
+    }
+
+    @Override
+    public boolean addNeutronSecurityRule(NeutronSecurityRule input) {
+        if (neutronSecurityRuleExists(input.getSecurityRuleUUID())) {
+            return false;
+        }
+        securityRuleDB.putIfAbsent(input.getSecurityRuleUUID(), input);
+        return true;
+    }
+
+    @Override
+    public boolean removeNeutronSecurityRule(String uuid) {
+        if (!neutronSecurityRuleExists(uuid)) {
+            return false;
+        }
+        securityRuleDB.remove(uuid);
+        return true;
+    }
+
+    @Override
+    public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta) {
+        if (!neutronSecurityRuleExists(uuid)) {
+            return false;
+        }
+        NeutronSecurityRule target = securityRuleDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    @Override
+    public boolean neutronSecurityRuleInUse(String securityRuleUUID) {
+        return !neutronSecurityRuleExists(securityRuleUUID);
+    }
+
+    private void loadConfiguration() {
+        for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) {
+            NeutronSecurityRule nn = (NeutronSecurityRule) conf;
+            securityRuleDB.put(nn.getSecurityRuleUUID(), nn);
+        }
+    }
+
+    @Override
+    public Status saveConfiguration() {
+        return configurationService.persistConfiguration(new ArrayList<ConfigurationObject>(securityRuleDB.values()),
+            FILE_NAME);
+    }
+
+    @Override
+    public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException {
+        return ois.readObject();
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java
new file mode 100644 (file)
index 0000000..0fdf77f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Security Groups needs to implement
+ */
+
+public interface INeutronSecurityGroupAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be created
+     *
+     * @param securityGroup instance of proposed new Neutron Security Group object
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the create operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canCreateNeutronSecurityGroup(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been created
+     *
+     * @param securityGroup instance of new Neutron Security Group object
+     * @return void
+     */
+    public void neutronSecurityGroupCreated(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be changed using the specified
+     * delta
+     *
+     * @param delta    updates to the security group object using patch semantics
+     * @param original instance of the Neutron Security Group object to be updated
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the update operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been updated
+     *
+     * @param securityGroup instance of modified Neutron Security Group object
+     * @return void
+     */
+    public void neutronSecurityGroupUpdated(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method to indicate if the specified security group can be deleted
+     *
+     * @param securityGroup instance of the Neutron Security Group object to be deleted
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the delete operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canDeleteNeutronSecurityGroup(NeutronSecurityGroup securityGroup);
+
+    /**
+     * Services provide this interface method for taking action after a security group has been deleted
+     *
+     * @param securityGroup instance of deleted Neutron Security Group object
+     * @return void
+     */
+    public void neutronSecurityGroupDeleted(NeutronSecurityGroup securityGroup);
+}
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java
new file mode 100644 (file)
index 0000000..a408ef9
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Security Group objects
+ */
+
+public interface INeutronSecurityGroupCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Security Group object exists
+     *
+     * @param uuid UUID of the Security Group object
+     * @return boolean
+     */
+
+    public boolean neutronSecurityGroupExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Security Group object exists
+     *
+     * @param uuid UUID of the Security Group object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup.OpenStackSecurity Groups}
+     * OpenStack Security Group class
+     */
+
+    public NeutronSecurityGroup getNeutronSecurityGroup(String uuid);
+
+    /**
+     * Applications call this interface method to return all Security Group objects
+     *
+     * @return List of OpenStackSecurity Groups objects
+     */
+
+    public List<NeutronSecurityGroup> getAllNeutronSecurityGroups();
+
+    /**
+     * Applications call this interface method to add a Security Group object to the
+     * concurrent map
+     *
+     * @param input OpenStackSecurity Group object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addNeutronSecurityGroup(NeutronSecurityGroup input);
+
+    /**
+     * Applications call this interface method to remove a Neutron Security Group object to the
+     * concurrent map
+     *
+     * @param uuid identifier for the security group object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeNeutronSecurityGroup(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Security Group object
+     *
+     * @param uuid  identifier of the security group object
+     * @param delta OpenStackSecurity Group object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid identifier of the security group object
+     * @return boolean on whether the Security Groups is already in use
+     */
+
+    public boolean neutronSecurityGroupInUse(String uuid);
+
+}
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java
new file mode 100644 (file)
index 0000000..ff2a1c4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods required to be aware of Neutron Security Rules
+ */
+
+public interface INeutronSecurityRuleAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be created
+     *
+     * @param securityRule instance of proposed new Neutron Security Rule object
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the create operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been created
+     *
+     * @param securityRule instance of new Neutron Security Rule object
+     * @return void
+     */
+    public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be changed using the specified
+     * delta
+     *
+     * @param delta    updates to the security rule object using patch semantics
+     * @param original instance of the Neutron Security Rule object to be updated
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the update operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been updated
+     *
+     * @param securityRule instance of modified Neutron Security Rule object
+     * @return void
+     */
+    public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method to indicate if the specified security rule can be deleted
+     *
+     * @param securityRule instance of the Neutron Security Rule object to be deleted
+     * @return integer
+     * the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     * results in the delete operation being interrupted and the returned status value reflected in the
+     * HTTP response.
+     */
+    public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule);
+
+    /**
+     * Services provide this interface method for taking action after a security rule has been deleted
+     *
+     * @param securityRule instance of deleted Neutron Security Rule object
+     * @return void
+     */
+    public void neutronSecurityRuleDeleted(NeutronSecurityRule securityRule);
+}
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java
new file mode 100644 (file)
index 0000000..73b41c7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB OpenStack Security Rule objects
+ */
+
+public interface INeutronSecurityRuleCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Security Rule object exists
+     *
+     * @param uuid UUID of theSecurity Rule object
+     * @return boolean
+     */
+
+    public boolean neutronSecurityRuleExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Security Rule object exists
+     *
+     * @param uuid UUID of the security rule object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule.OpenStackNetworks}
+     * OpenStackSecurity Rule class
+     */
+
+    public NeutronSecurityRule getNeutronSecurityRule(String uuid);
+
+    /**
+     * Applications call this interface method to return all Security Rule objects
+     *
+     * @return List of OpenStack SecurityRules objects
+     */
+
+    public List<NeutronSecurityRule> getAllNeutronSecurityRules();
+
+    /**
+     * Applications call this interface method to add a Security Rule object to the
+     * concurrent map
+     *
+     * @param input OpenStack security rule object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addNeutronSecurityRule(NeutronSecurityRule input);
+
+    /**
+     * Applications call this interface method to remove a Neutron Security Rule object to the
+     * concurrent map
+     *
+     * @param uuid identifier for the security rule object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeNeutronSecurityRule(String uuid);
+
+    /**
+     * Applications call this interface method to edit aSecurity Rule object
+     *
+     * @param uuid  identifier of the security rule object
+     * @param delta OpenStackSecurity Rule object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param uuid identifier of the security rule object
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    public boolean neutronSecurityRuleInUse(String uuid);
+
+}
index aebecfa93e18884d243cfb58227124a98de6d429..21cfdb1305060d1bfa24ff32866f1ce0aa8509b5 100644 (file)
@@ -36,4 +36,14 @@ public class NeutronCRUDInterfaces {
         INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);
         return answer;
     }
-}
+
+    public static INeutronSecurityGroupCRUD getINeutronSecurityGroupCRUD(Object o) {
+        INeutronSecurityGroupCRUD answer = (INeutronSecurityGroupCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityGroupCRUD.class, o);
+        return answer;
+    }
+
+    public static INeutronSecurityRuleCRUD getINeutronSecurityRuleCRUD(Object o) {
+        INeutronSecurityRuleCRUD answer = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, o);
+        return answer;
+    }
+}
\ No newline at end of file
index c8ee4e8cccd3021b3a30deb4eb8ca56b16e17593..680a07453b94b3f56072804b2981006574837f5a 100644 (file)
@@ -61,9 +61,8 @@ public class NeutronPort extends ConfigurationObject implements Serializable {
     @XmlElement (name="tenant_id")
     String tenantID;
 
-    // TODO: add security groups
-    //        @XmlElement (name="security_groups")
-    //        List<String> securityGroups;
+    @XmlElement (name="security_groups")
+    List<NeutronSecurityGroup> securityGroups;
 
     /* this attribute stores the floating IP address assigned to
      * each fixed IP address
@@ -162,6 +161,14 @@ public class NeutronPort extends ConfigurationObject implements Serializable {
         this.tenantID = tenantID;
     }
 
+    public List<NeutronSecurityGroup> getSecurityGroups() {
+        return securityGroups;
+    }
+
+    public void setSecurityGroups(List<NeutronSecurityGroup> securityGroups) {
+        this.securityGroups = securityGroups;
+    }
+
     public NeutronFloatingIP getFloatingIP(String key) {
         if (!floatingIPMap.containsKey(key)) {
             return null;
@@ -259,6 +266,6 @@ public class NeutronPort extends ConfigurationObject implements Serializable {
         return "NeutronPort [portUUID=" + portUUID + ", networkUUID=" + networkUUID + ", name=" + name
                 + ", adminStateUp=" + adminStateUp + ", status=" + status + ", macAddress=" + macAddress
                 + ", fixedIPs=" + fixedIPs + ", deviceID=" + deviceID + ", deviceOwner=" + deviceOwner + ", tenantID="
-                + tenantID + ", floatingIPMap=" + floatingIPMap + "]";
+                + tenantID + ", floatingIPMap=" + floatingIPMap + ", securityGroups=" + securityGroups + "]";
     }
 }
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java
new file mode 100644 (file)
index 0000000..0f0a14c
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import org.opendaylight.controller.configuration.ConfigurationObject;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * OpenStack Neutron v2.0 Security Group bindings.
+ * See OpenStack Network API v2.0 Reference for description of
+ * annotated attributes. The current fields are as follows:
+ * <p/>
+ * id                   uuid-str unique ID for the security group.
+ * name                 String name of the security group.
+ * description          String name of the security group.
+ * tenant_id            uuid-str Owner of security rule..
+ * security_group_rules List<NeutronSecurityRule> nested RO in the sec group.
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityGroup extends ConfigurationObject implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String securityGroupUUID;
+
+    @XmlElement(name = "name")
+    String securityGroupName;
+
+    @XmlElement(name = "description")
+    String securityGroupDescription;
+
+    @XmlElement(name = "tenant_id")
+    String securityGroupTenantID;
+
+    @XmlElement(name = "security_group_rules")
+    List<NeutronSecurityRule> neutronSecurityRule;
+
+    List<NeutronPort> neutronPorts;
+
+    public NeutronSecurityGroup() {
+        neutronPorts = new ArrayList<NeutronPort> ();
+        List<NeutronSecurityRule> securityRules;
+
+    }
+
+    public String getSecurityGroupUUID() {
+        return securityGroupUUID;
+    }
+
+    public void setSecurityGroupUUID(String securityGroupUUID) {
+        this.securityGroupUUID = securityGroupUUID;
+    }
+
+    public String getSecurityGroupName() {
+        return securityGroupName;
+    }
+
+    public void setSecurityGroupName(String securityGroupName) {
+        this.securityGroupName = securityGroupName;
+    }
+
+    public String getSecurityGroupDescription() {
+        return securityGroupDescription;
+    }
+
+    public void setSecurityGroupDescription(String securityGroupDescription) {
+        this.securityGroupDescription = securityGroupDescription;
+    }
+
+    public String getSecurityGroupTenantID() {
+        return securityGroupTenantID;
+    }
+
+    public void setSecurityGroupTenantID(String securityGroupTenantID) {
+        this.securityGroupTenantID = securityGroupTenantID;
+    }
+
+    // Rules In Group
+    public List<NeutronSecurityRule> getSecurityRules() {
+        return neutronSecurityRule;
+    }
+
+    public void setSecurityRules(NeutronSecurityRule neutronSecurityRule) {
+        this.neutronSecurityRule = (List<NeutronSecurityRule>) neutronSecurityRule;
+    }
+
+    public NeutronSecurityGroup extractFields(List<String> fields) {
+        NeutronSecurityGroup ans = new NeutronSecurityGroup ();
+        Iterator<String> i = fields.iterator ();
+        while (i.hasNext ()) {
+            String s = i.next ();
+            if (s.equals ("id")) {
+                ans.setSecurityGroupUUID (this.getSecurityGroupUUID ());
+            }
+            if (s.equals ("name")) {
+                ans.setSecurityGroupName (this.getSecurityGroupName ());
+            }
+            if (s.equals ("description")) {
+                ans.setSecurityGroupDescription (this.getSecurityGroupDescription ());
+            }
+            if (s.equals ("tenant_id")) {
+                ans.setSecurityGroupTenantID (this.getSecurityGroupTenantID ());
+            }
+            if (s.equals ("security_group_rules")) {
+                ans.setSecurityRules ((NeutronSecurityRule) this.getSecurityRules ());
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSecurityGroup{" +
+                "securityGroupUUID='" + securityGroupUUID + '\'' +
+                ", securityGroupName='" + securityGroupName + '\'' +
+                ", securityGroupDescription='" + securityGroupDescription + '\'' +
+                ", securityGroupTenantID='" + securityGroupTenantID + '\'' +
+                ", securityRules=" + neutronSecurityRule + "]";
+    }
+
+    public void initDefaults() {
+        //TODO verify no defaults values are nessecary required.
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java
new file mode 100644 (file)
index 0000000..3fad4fe
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import org.opendaylight.controller.configuration.ConfigurationObject;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * See OpenStack Network API v2.0 Reference for description of
+ * annotated attributes. The current fields are as follows:
+ * <p/>
+ * id                uuid (String) UUID for the security group rule.
+ * security_rule_id  uuid (String) The security group to associate rule.
+ * direction         String Direction the VM traffic  (ingress/egress).
+ * security_group_id The security group to associate rule with.
+ * protocol          String IP Protocol (icmp, tcp, udp, etc).
+ * port_range_min    Integer Port at start of range
+ * port_range_max    Integer Port at end of range
+ * ethertype         String ethertype in L2 packet (IPv4, IPv6, etc)
+ * remote_ip_prefix  String (IP cidr) CIDR for address range.
+ * remote_group_id   uuid-str Source security group to apply to rule.
+ * tenant_id         uuid-str Owner of security rule. Admin only outside tenant.
+ */
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityRule extends ConfigurationObject implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @XmlElement(name = "id")
+    String securityRuleUUID;
+
+    @XmlElement(name = "direction")
+    String securityRuleDirection;
+
+    @XmlElement(name = "protocol")
+    String securityRuleProtocol;
+
+    @XmlElement(name = "port_range_min")
+    Integer securityRulePortMin;
+
+    @XmlElement(name = " port_range_max")
+    Integer securityRulePortMax;
+
+    @XmlElement(name = "ethertype")
+    String securityRuleEthertype;
+
+    @XmlElement(name = "remote_ip_prefix")
+    String securityRuleRemoteIpPrefix;
+
+    @XmlElement(name = "remote_group_id")
+    String securityRemoteGroupID;
+
+    @XmlElement(name = "security_group_id")
+    String securityRuleGroupID;
+
+    @XmlElement(name = "tenant_id")
+    String securityRuleTenantID;
+
+    public NeutronSecurityRule() {
+        List<NeutronSecurityRule> securityRules;
+    }
+
+    public String getSecurityRuleUUID() {
+        return securityRuleUUID;
+    }
+
+    public void setSecurityRuleUUID(String securityRuleUUID) {
+        this.securityRuleUUID = securityRuleUUID;
+    }
+
+    public String getSecurityRuleDirection() {
+        return securityRuleDirection;
+    }
+
+    public void setSecurityRuleDirection(String securityRuleDirection) {
+        this.securityRuleDirection = securityRuleDirection;
+    }
+
+    public String getSecurityRuleProtocol() {
+        return securityRuleProtocol;
+    }
+
+    public void setSecurityRuleProtocol(String securityRuleProtocol) {
+        this.securityRuleProtocol = securityRuleProtocol;
+    }
+
+    public Integer getSecurityRulePortMin() {
+        return securityRulePortMin;
+    }
+
+    public void setSecurityRulePortMin(Integer securityRulePortMin) {
+        this.securityRulePortMin = securityRulePortMin;
+    }
+
+    public Integer getSecurityRulePortMax() {
+        return securityRulePortMax;
+    }
+
+    public void setSecurityRulePortMax(Integer securityRulePortMax) {
+        this.securityRulePortMax = securityRulePortMax;
+    }
+
+    public String getSecurityRuleEthertype() {
+        return securityRuleEthertype;
+    }
+
+    public void setSecurityRuleEthertype(String securityRuleEthertype) {
+        this.securityRuleEthertype = securityRuleEthertype;
+    }
+
+    public String getSecurityRuleRemoteIpPrefix() {
+        return securityRuleRemoteIpPrefix;
+    }
+
+    public void setSecurityRuleRemoteIpPrefix(String securityRuleRemoteIpPrefix) {
+        this.securityRuleRemoteIpPrefix = securityRuleRemoteIpPrefix;
+    }
+
+    public String getSecurityRemoteGroupID() {
+        return securityRemoteGroupID;
+    }
+
+    public void setSecurityRemoteGroupID(String securityRemoteGroupID) {
+        this.securityRemoteGroupID = securityRemoteGroupID;
+    }
+
+    public String getSecurityRuleGroupID() {
+        return securityRuleGroupID;
+    }
+
+    public void setSecurityRuleGroupID(String securityRuleGroupID) {
+        this.securityRuleGroupID = securityRuleGroupID;
+    }
+
+    public String getSecurityRuleTenantID() {
+        return securityRuleTenantID;
+    }
+
+    public void setSecurityRuleTenantID(String securityRuleTenantID) {
+        this.securityRuleTenantID = securityRuleTenantID;
+    }
+
+    public NeutronSecurityRule extractFields(List<String> fields) {
+        NeutronSecurityRule ans = new NeutronSecurityRule();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setSecurityRuleUUID(this.getSecurityRuleUUID());
+            }
+            if (s.equals("direction")) {
+                ans.setSecurityRuleDirection(this.getSecurityRuleDirection());
+            }
+            if (s.equals("protocol")) {
+                ans.setSecurityRuleProtocol(this.getSecurityRuleProtocol());
+            }
+            if (s.equals("port_range_min")) {
+                ans.setSecurityRulePortMin(this.getSecurityRulePortMin());
+            }
+            if (s.equals("port_range_max")) {
+                ans.setSecurityRulePortMax(this.getSecurityRulePortMax());
+            }
+            if (s.equals("ethertype")) {
+                ans.setSecurityRuleEthertype(this.getSecurityRuleEthertype());
+            }
+            if (s.equals("remote_ip_prefix")) {
+                ans.setSecurityRuleRemoteIpPrefix(this.getSecurityRuleRemoteIpPrefix());
+            }
+            if (s.equals("remote_group_id")) {
+                ans.setSecurityRemoteGroupID(this.getSecurityRemoteGroupID());
+            }
+            if (s.equals("security_group_id")) {
+                ans.setSecurityRuleGroupID(this.getSecurityRuleGroupID());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setSecurityRuleTenantID(this.getSecurityRuleTenantID());
+            }
+        }
+        return ans;
+    }
+
+    @Override
+    public String toString() {
+        return "NeutronSecurityRule{" +
+            "securityRuleUUID='" + securityRuleUUID + '\'' +
+            ", securityRuleDirection='" + securityRuleDirection + '\'' +
+            ", securityRuleProtocol='" + securityRuleProtocol + '\'' +
+            ", securityRulePortMin=" + securityRulePortMin +
+            ", securityRulePortMax=" + securityRulePortMax +
+            ", securityRuleEthertype='" + securityRuleEthertype + '\'' +
+            ", securityRuleRemoteIpPrefix='" + securityRuleRemoteIpPrefix + '\'' +
+            ", securityRemoteGroupID=" + securityRemoteGroupID +
+            ", securityRuleGroupID='" + securityRuleGroupID + '\'' +
+            ", securityRuleTenantID='" + securityRuleTenantID + '\'' +
+            '}';
+    }
+
+    public void initDefaults() {
+        //TODO verify no defaults values are nessecary required.
+    }
+}
\ No newline at end of file
index 76c39e4294dd05a0ada503edd05d1243c9b436f5..3fe03a2dac8de2f64d9ee2b9796befe72ab0e8b1 100644 (file)
@@ -32,6 +32,8 @@ public class NeutronNorthboundRSApplication extends Application {
         classes.add(NeutronPortsNorthbound.class);
         classes.add(NeutronRoutersNorthbound.class);
         classes.add(NeutronFloatingIPsNorthbound.class);
+        classes.add(NeutronSecurityGroupsNorthbound.class);
+        classes.add(NeutronSecurityRulesNorthbound.class);
         return classes;
     }
 
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java
new file mode 100644 (file)
index 0000000..6e779d6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType (XmlAccessType.NONE)
+
+public class NeutronSecurityGroupRequest {
+    /**
+    * See OpenStack Network API v2.0 Reference for a
+    * description of annotated attributes and operations
+    */
+
+    @XmlElement (name = "security_group")
+    NeutronSecurityGroup singletonSecurityGroup;
+
+    @XmlElement (name = "security_groups")
+    List<NeutronSecurityGroup> bulkRequest;
+
+    NeutronSecurityGroupRequest() {
+    }
+
+    NeutronSecurityGroupRequest(List<NeutronSecurityGroup> bulk) {
+        bulkRequest = bulk;
+        singletonSecurityGroup = null;
+    }
+
+    NeutronSecurityGroupRequest(NeutronSecurityGroup group) {
+        singletonSecurityGroup = group;
+    }
+
+    public List<NeutronSecurityGroup> getBulk() {
+        return bulkRequest;
+    }
+
+    public NeutronSecurityGroup getSingleton() {
+        return singletonSecurityGroup;
+    }
+
+    public boolean isSingleton() {
+        return (singletonSecurityGroup != null);
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java
new file mode 100644 (file)
index 0000000..5e9a331
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Neutron Northbound REST APIs for Security Group.<br>
+ * This class provides REST APIs for managing neutron Security Group
+ * <p/>
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ */
+@Path ("/security-groups")
+public class NeutronSecurityGroupsNorthbound {
+    static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupsNorthbound.class);
+
+    private NeutronSecurityGroup extractFields(NeutronSecurityGroup o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all Security Groups
+     */
+    @GET
+    @Produces ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+
+    public Response listGroups(
+            // return fields
+            @QueryParam ("fields") List<String> fields,
+            // OpenStack security group attributes
+            @QueryParam ("id") String querySecurityGroupUUID,
+            @QueryParam ("name") String querySecurityGroupName,
+            @QueryParam ("description") String querySecurityDescription,
+            @QueryParam ("tenant_id") String querySecurityTenantID,
+            @QueryParam ("limit") String limit,
+            @QueryParam ("marker") String marker,
+            @QueryParam ("page_reverse") String pageReverse
+    ) {
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronSecurityGroup> allSecurityGroups = securityGroupInterface.getAllNeutronSecurityGroups();
+        List<NeutronSecurityGroup> ans = new ArrayList<NeutronSecurityGroup>();
+        Iterator<NeutronSecurityGroup> i = allSecurityGroups.iterator();
+        while (i.hasNext()) {
+            NeutronSecurityGroup nsg = i.next();
+            if ((querySecurityGroupUUID == null ||
+                    querySecurityGroupUUID.equals(nsg.getSecurityGroupUUID())) &&
+                    (querySecurityGroupName == null ||
+                            querySecurityGroupName.equals(nsg.getSecurityGroupName())) &&
+                    (querySecurityDescription == null ||
+                            querySecurityDescription.equals(nsg.getSecurityGroupDescription())) &&
+                    (querySecurityTenantID == null ||
+                            querySecurityTenantID.equals(nsg.getSecurityGroupTenantID()))) {
+                if (fields.size() > 0) {
+                    ans.add(extractFields(nsg, fields));
+                } else {
+                    ans.add(nsg);
+                }
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronSecurityGroupRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Security Group
+     */
+
+    @Path ("{securityGroupUUID}")
+    @GET
+    @Produces ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response showSecurityGroup(@PathParam ("securityGroupUUID") String securityGroupUUID,
+                                      // return fields
+                                      @QueryParam ("fields") List<String> fields) {
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+            throw new ResourceNotFoundException("Security Group UUID does not exist.");
+        }
+        if (!fields.isEmpty()) {
+            NeutronSecurityGroup ans = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+            return Response.status(200).entity(
+                    new NeutronSecurityGroupRequest(extractFields(ans, fields))).build();
+        } else {
+            return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
+        }
+    }
+
+    /**
+     * Creates new Security Group
+     */
+
+    @POST
+    @Produces ({MediaType.APPLICATION_JSON})
+    @Consumes ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 201, condition = "Created"),
+            @ResponseCode (code = 400, condition = "Bad Request"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 403, condition = "Forbidden"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 409, condition = "Conflict"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response createSecurityGroups(final NeutronSecurityGroupRequest input) {
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        if (input.isSingleton()) {
+            NeutronSecurityGroup singleton = input.getSingleton();
+
+            /*
+             *  Verify that the Security Group doesn't already exist.
+             */
+            if (securityGroupInterface.neutronSecurityGroupExists(singleton.getSecurityGroupUUID())) {
+                throw new BadRequestException("Security Group UUID already exists");
+            }
+
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                    int status = service.canCreateNeutronSecurityGroup(singleton);
+                    if (status < 200 || status > 299) {
+                        return Response.status(status).build();
+                    }
+                }
+            }
+            // Add to Neutron cache
+            securityGroupInterface.addNeutronSecurityGroup(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                    service.neutronSecurityGroupCreated(singleton);
+                }
+            }
+        } else {
+            List<NeutronSecurityGroup> bulk = input.getBulk();
+            Iterator<NeutronSecurityGroup> i = bulk.iterator();
+            HashMap<String, NeutronSecurityGroup> testMap = new HashMap<String, NeutronSecurityGroup>();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+            while (i.hasNext()) {
+                NeutronSecurityGroup test = i.next();
+
+                /*
+                 *  Verify that the security group doesn't already exist
+                 */
+
+                if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) {
+                    throw new BadRequestException("Security Group UUID already is already created");
+                }
+                if (instances != null) for (Object instance : instances) {
+                    INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                    int status = service.canCreateNeutronSecurityGroup(test);
+                    if ((status < 200) || (status > 299)) return Response.status(status).build();
+                }
+            }
+
+            /*
+             * now, each element of the bulk request can be added to the cache
+             */
+            i = bulk.iterator();
+            while (i.hasNext()) {
+                NeutronSecurityGroup test = i.next();
+                securityGroupInterface.addNeutronSecurityGroup(test);
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                        service.neutronSecurityGroupCreated(test);
+                    }
+                }
+            }
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Security Group
+     */
+
+    @Path ("{securityGroupUUID}")
+    @PUT
+    @Produces ({MediaType.APPLICATION_JSON})
+    @Consumes ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 400, condition = "Bad Request"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 403, condition = "Forbidden"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response updateSecurityGroup(
+            @PathParam ("securityGroupUUID") String securityGroupUUID, final NeutronSecurityGroupRequest input) {
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the Security Group exists and there is only one delta provided
+         */
+        if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+            throw new ResourceNotFoundException("Security Group UUID does not exist.");
+        }
+        if (!input.isSingleton()) {
+            throw new BadRequestException("Only singleton edit supported");
+        }
+        NeutronSecurityGroup delta = input.getSingleton();
+        NeutronSecurityGroup original = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+
+        if (delta.getSecurityGroupUUID() != null ||
+                delta.getSecurityGroupTenantID() != null ||
+                delta.getSecurityGroupName() != null ||
+                delta.getSecurityGroupDescription() != null) {
+            throw new BadRequestException("Attribute edit blocked by Neutron");
+        }
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                int status = service.canUpdateNeutronSecurityGroup(delta, original);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * update the object and return it
+         */
+        securityGroupInterface.updateNeutronSecurityGroup(securityGroupUUID, delta);
+        NeutronSecurityGroup updatedSecurityGroup = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                service.neutronSecurityGroupUpdated(updatedSecurityGroup);
+            }
+        }
+        return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build();
+    }
+
+    /**
+     * Deletes a Security Group
+     */
+
+    @Path ("{securityGroupUUID}")
+    @DELETE
+    @StatusCodes ({
+            @ResponseCode (code = 204, condition = "No Content"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 409, condition = "Conflict"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response deleteSecurityGroup(
+            @PathParam ("securityGroupUUID") String securityGroupUUID) {
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the Security Group exists and it isn't currently in use
+         */
+        if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) {
+            throw new ResourceNotFoundException("Security Group UUID does not exist.");
+        }
+        if (securityGroupInterface.neutronSecurityGroupInUse(securityGroupUUID)) {
+            return Response.status(409).build();
+        }
+        NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                int status = service.canDeleteNeutronSecurityGroup(singleton);
+                if ((status < 200) || (status > 299)) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * remove it and return 204 status
+         */
+        securityGroupInterface.removeNeutronSecurityGroup(securityGroupUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance;
+                service.neutronSecurityGroupDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java
new file mode 100644 (file)
index 0000000..b805bd6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.List;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSecurityRuleRequest {
+    /**
+     * See OpenStack Network API v2.0 Reference for a
+     * description of annotated attributes and operations
+     */
+
+    @XmlElement(name="security_group_rule")
+    NeutronSecurityRule singletonSecurityRule;
+
+    @XmlElement(name="security_group_rules")
+    List<NeutronSecurityRule> bulkRequest;
+
+    NeutronSecurityRuleRequest() {
+    }
+
+    NeutronSecurityRuleRequest(List<NeutronSecurityRule> bulk) {
+        bulkRequest = bulk;
+        singletonSecurityRule = null;
+    }
+
+    NeutronSecurityRuleRequest(NeutronSecurityRule rule) {
+        singletonSecurityRule = rule;
+    }
+
+    public NeutronSecurityRule getSingleton() {
+        return singletonSecurityRule;
+    }
+
+    public boolean isSingleton() {
+        return (singletonSecurityRule != null);
+    }
+    public List<NeutronSecurityRule> getBulk() {
+        return bulkRequest;
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java
new file mode 100644 (file)
index 0000000..b2c05e0
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.BadRequestException;
+import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Neutron Northbound REST APIs for Security Rule.<br>
+ * This class provides REST APIs for managing neutron Security Rule
+ * <p/>
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ */
+
+@Path ("/security-group-rules")
+public class NeutronSecurityRulesNorthbound {
+    static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRulesNorthbound.class);
+
+    private NeutronSecurityRule extractFields(NeutronSecurityRule o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all Security Rules
+     */
+    @GET
+    @Produces ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response listRules(
+            // return fields
+            @QueryParam ("fields") List<String> fields,
+            // OpenStack security rule attributes
+            @QueryParam ("id") String querySecurityRuleUUID,
+            @QueryParam ("direction") String querySecurityRuleDirection,
+            @QueryParam ("protocol") String querySecurityRuleProtocol,
+            @QueryParam ("port_range_min") Integer querySecurityRulePortMin,
+            @QueryParam ("port_range_max") Integer querySecurityRulePortMax,
+            @QueryParam ("ethertype") String querySecurityRuleEthertype,
+            @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix,
+            @QueryParam ("remote_group_id") String querySecurityRemoteGroupID,
+            @QueryParam ("security_group_id") String querySecurityRuleGroupID,
+            @QueryParam ("tenant_id") String querySecurityRuleTenantID,
+            @QueryParam ("limit") String limit,
+            @QueryParam ("marker") String marker,
+            @QueryParam ("page_reverse") String pageReverse
+    ) {
+        INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+        if (securityRuleInterface == null) {
+            throw new ServiceUnavailableException("Security Rule CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronSecurityRule> allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules();
+        List<NeutronSecurityRule> ans = new ArrayList<NeutronSecurityRule>();
+        Iterator<NeutronSecurityRule> i = allSecurityRules.iterator();
+        while (i.hasNext()) {
+            NeutronSecurityRule nsr = i.next();
+            if ((querySecurityRuleUUID == null ||
+                    querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) &&
+                    (querySecurityRuleDirection == null ||
+                            querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) &&
+                    (querySecurityRuleProtocol == null ||
+                            querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) &&
+                    (querySecurityRulePortMin == null ||
+                            querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) &&
+                    (querySecurityRulePortMax == null ||
+                            querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) &&
+                    (querySecurityRuleEthertype == null ||
+                            querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) &&
+                    (querySecurityRuleIpPrefix == null ||
+                            querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) &&
+                    (querySecurityRuleGroupID == null ||
+                            querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) &&
+                    (querySecurityRemoteGroupID == null ||
+                            querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) &&
+                    (querySecurityRuleTenantID == null ||
+                            querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) {
+                if (fields.size() > 0) {
+                    ans.add(extractFields(nsr, fields));
+                } else {
+                    ans.add(nsr);
+                }
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronSecurityRuleRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Security Rule
+     */
+
+    @Path ("{securityRuleUUID}")
+    @GET
+    @Produces ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID,
+                                     // return fields
+                                     @QueryParam ("fields") List<String> fields) {
+        INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+        if (securityRuleInterface == null) {
+            throw new ServiceUnavailableException("Security Rule CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+            throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+        }
+        if (!fields.isEmpty()) {
+            NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+            return Response.status(200).entity(
+                    new NeutronSecurityRuleRequest(extractFields(ans, fields))).build();
+        } else {
+            return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
+        }
+    }
+
+    /**
+     * Creates new Security Rule
+     */
+
+    @POST
+    @Produces ({MediaType.APPLICATION_JSON})
+    @Consumes ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 201, condition = "Created"),
+            @ResponseCode (code = 400, condition = "Bad Request"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 403, condition = "Forbidden"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 409, condition = "Conflict"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response createSecurityRules(final NeutronSecurityRuleRequest input) {
+        INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+        if (securityRuleInterface == null) {
+            throw new ServiceUnavailableException("Security Rule CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this);
+        if (securityGroupInterface == null) {
+            throw new ServiceUnavailableException("Security Group CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * Existing entry checks
+        */
+
+        if (input.isSingleton()) {
+            NeutronSecurityRule singleton = input.getSingleton();
+
+            if (securityRuleInterface.neutronSecurityRuleExists(singleton.getSecurityRuleUUID())) {
+                throw new BadRequestException("Security Rule UUID already exists");
+            }
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                    int status = service.canCreateNeutronSecurityRule(singleton);
+                    if ((status < 200) || (status > 299)) {
+                        return Response.status(status).build();
+                    }
+                }
+            }
+
+            // add rule to cache
+            singleton.initDefaults();
+            securityRuleInterface.addNeutronSecurityRule(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                    service.neutronSecurityRuleCreated(singleton);
+                }
+            }
+
+            securityRuleInterface.addNeutronSecurityRule(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                    service.neutronSecurityRuleCreated(singleton);
+                }
+            }
+        } else {
+            List<NeutronSecurityRule> bulk = input.getBulk();
+            Iterator<NeutronSecurityRule> i = bulk.iterator();
+            HashMap<String, NeutronSecurityRule> testMap = new HashMap<String, NeutronSecurityRule>();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+            while (i.hasNext()) {
+                NeutronSecurityRule test = i.next();
+
+                /*
+                 *  Verify that the security rule doesn't already exist
+                 */
+
+                if (securityRuleInterface.neutronSecurityRuleExists(test.getSecurityRuleUUID())) {
+                    throw new BadRequestException("Security Rule UUID already exists");
+                }
+                if (testMap.containsKey(test.getSecurityRuleUUID())) {
+                    throw new BadRequestException("Security Rule UUID already exists");
+                }
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                        int status = service.canCreateNeutronSecurityRule(test);
+                        if ((status < 200) || (status > 299)) {
+                            return Response.status(status).build();
+                        }
+                    }
+                }
+            }
+
+            /*
+             * now, each element of the bulk request can be added to the cache
+             */
+            i = bulk.iterator();
+            while (i.hasNext()) {
+                NeutronSecurityRule test = i.next();
+                securityRuleInterface.addNeutronSecurityRule(test);
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                        service.neutronSecurityRuleCreated(test);
+                    }
+                }
+            }
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Security Rule
+     */
+
+    @Path ("{securityRuleUUID}")
+    @PUT
+    @Produces ({MediaType.APPLICATION_JSON})
+    @Consumes ({MediaType.APPLICATION_JSON})
+    @StatusCodes ({
+            @ResponseCode (code = 200, condition = "Operation successful"),
+            @ResponseCode (code = 400, condition = "Bad Request"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 403, condition = "Forbidden"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response updateSecurityRule(
+            @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) {
+        INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+        if (securityRuleInterface == null) {
+            throw new ServiceUnavailableException("Security Rule CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the Security Rule exists and there is only one delta provided
+         */
+        if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+            throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+        }
+        if (!input.isSingleton()) {
+            throw new BadRequestException("Only singleton edit supported");
+        }
+        NeutronSecurityRule delta = input.getSingleton();
+        NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+
+        /*
+         * updates restricted by Neutron
+         *
+         */
+        if (delta.getSecurityRuleUUID() != null ||
+                delta.getSecurityRuleDirection() != null ||
+                delta.getSecurityRuleProtocol() != null ||
+                delta.getSecurityRulePortMin() != null ||
+                delta.getSecurityRulePortMax() != null ||
+                delta.getSecurityRuleEthertype() != null ||
+                delta.getSecurityRuleRemoteIpPrefix() != null ||
+                delta.getSecurityRuleGroupID() != null ||
+                delta.getSecurityRemoteGroupID() != null ||
+                delta.getSecurityRuleTenantID() != null) {
+            throw new BadRequestException("Attribute edit blocked by Neutron");
+        }
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                int status = service.canUpdateNeutronSecurityRule(delta, original);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * update the object and return it
+         */
+        securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta);
+        NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                service.neutronSecurityRuleUpdated(updatedSecurityRule);
+            }
+        }
+        return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build();
+    }
+
+    /**
+     * Deletes a Security Rule
+     */
+
+    @Path ("{securityRuleUUID}")
+    @DELETE
+    @StatusCodes ({
+            @ResponseCode (code = 204, condition = "No Content"),
+            @ResponseCode (code = 401, condition = "Unauthorized"),
+            @ResponseCode (code = 404, condition = "Not Found"),
+            @ResponseCode (code = 409, condition = "Conflict"),
+            @ResponseCode (code = 501, condition = "Not Implemented")})
+    public Response deleteSecurityRule(
+            @PathParam ("securityRuleUUID") String securityRuleUUID) {
+        INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this);
+        if (securityRuleInterface == null) {
+            throw new ServiceUnavailableException("Security Rule CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the Security Rule exists and it isn't currently in use
+         */
+        if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) {
+            throw new ResourceNotFoundException("Security Rule UUID does not exist.");
+        }
+        if (securityRuleInterface.neutronSecurityRuleInUse(securityRuleUUID)) {
+            return Response.status(409).build();
+        }
+        NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                int status = service.canDeleteNeutronSecurityRule(singleton);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * remove it and return 204 status
+         */
+        securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance;
+                service.neutronSecurityRuleDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
\ No newline at end of file