Merge "changed the pom.xml to include proper integration test"
authorGiovanni Meo <gmeo@cisco.com>
Mon, 18 Nov 2013 16:38:36 +0000 (16:38 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 18 Nov 2013 16:38:36 +0000 (16:38 +0000)
55 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java
opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl
opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/FRMUtil.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/FlowConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/GroupConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/IForwardingRulesManager.java [new file with mode: 0644]
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java
opendaylight/md-sal/model/model-flow-base/src/main/yang/action-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-error.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/group-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/CodeGenerationException.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.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/main/java/org/opendaylight/controller/sal/restconf/impl/SimpleNodeWrapper.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicDataTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlToJsonBasicDataTypesTest.java with 97% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/ToJsonBasicYangTypesTest.java [moved from opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/YangAndXmlToJsonBasicYangTypesTest.java with 50% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlProvidersTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/Cont.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/Lf.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LfLst.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/Lst.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/LstItem.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/structures/YangElement.java
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_data.json [moved from opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output.json with 100% similarity]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_empty_data.json [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/empty_data.xml [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/pom.xml
opendaylight/md-sal/statistics-manager/pom.xml
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsManagerActivator.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsProvider.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsUpdateCommiter.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java
opendaylight/northbound/java-client/pom.xml
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java

index 106a7fbb2be8ced7bfb2d054b296b9a86e0462d7..de1a425ce64813f5c783c710367cee51232e66fc 100644 (file)
@@ -37,7 +37,7 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer<
         return null;
     }
 
-    private void blankTransaction() {
+    private synchronized void blankTransaction() {
         // create transaction
         ObjectName tx = configRegistry.beginConfig();
         CommitStatus commitStatus = configRegistry.commitConfig(tx);
index 00f2581ae14ff82ecd6ab29e9a51c72120ad8eef..a331e4e0c1ad95245f838ebee17192e2a7c61c81 100644 (file)
@@ -17,7 +17,12 @@ package ${packageName};
 
     @Override
     public final boolean isModuleImplementingServiceInterface(Class<? extends ${abstractServiceInterfaceType}> serviceInterface) {
-        return serviceIfcs.contains(serviceInterface);
+        for (Class<?> ifc: serviceIfcs) {
+            if (serviceInterface.isAssignableFrom(ifc)){
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
index 282dff0ec621a50e46ba107d73627ca4152e7aba..556abad7af2b9b80f4623cca42c4411f7191e974 100644 (file)
@@ -748,8 +748,10 @@ public class JMXGeneratorTest extends AbstractGeneratorTest {
                 // available if source level is 5.0
                 if (c.getID() == 1610613329)
                     continue;
+                if (c.getID() == 1610613328) // 'for each' statements are only available if source level is 5.0
+                    continue;
                 fail("Error in generated source code " + file + ":"
-                        + c.getSourceLineNumber() + " " + c.toString());
+                        + c.getSourceLineNumber() + " id: " + c.getID() + " message:"  + c.toString());
             }
 
             ASTVisitor visitor = verifiers.get(file.getName());
index 4acaf7b26e8179e2152b01e8b0ffcdfc6b329cf3..9f186642841ea418622bd280875390dfe89c58b2 100644 (file)
@@ -127,7 +127,7 @@ public class FRMUtil {
                 }
             } else if (action instanceof OutputAction) {
                 Integer length = ((OutputAction) action).getMaxLength();
-                List<Uri> outputnodeconnector = ((OutputAction) action).getOutputNodeConnector();
+                Uri outputnodeconnector = ((OutputAction) action).getOutputNodeConnector();
                 if (length < 0 || length > 65294) {
                     logger.error("OutputAction: MaxLength is not valid");
                     return false;
index 372573853cb0bd600f61fe4e10abd93e9c0f6e17..1ff7a98ebb816f07ede8e891c71c152ae46447b2 100644 (file)
@@ -35,11 +35,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddF
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
@@ -54,9 +58,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class FlowConsumerImpl {
+public class FlowConsumerImpl implements IForwardingRulesManager {
     protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class);
-    private FlowEventListener flowEventListener = new FlowEventListener();
+    private final FlowEventListener flowEventListener = new FlowEventListener();
     private Registration<NotificationListener> listener1Reg;
     private SalFlowService flowService;
     // private FlowDataListener listener;
@@ -201,7 +205,7 @@ public class FlowConsumerImpl {
         // updating the staticflow cache
         Integer ordinal = staticFlowsOrdinal.get(0);
         staticFlowsOrdinal.put(0, ++ordinal);
-        staticFlows.put(ordinal, (Flow) dataObject);
+        staticFlows.put(ordinal, dataObject);
 
         // We send flow to the sounthbound plugin
         flowService.addFlow(input.build());
@@ -241,6 +245,29 @@ public class FlowConsumerImpl {
         updateLocalDatabase((NodeFlow) dataObject, false);
     }
 
+    /**
+     * Update flow to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private void updateFlow(InstanceIdentifier<?> path, Flow dataObject) {
+
+        UpdateFlowInputBuilder input = new UpdateFlowInputBuilder();
+        UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder();
+        updatedflowbuilder.fieldsFrom(dataObject);
+        input.setUpdatedFlow(updatedflowbuilder.build());
+
+        // updating the staticflow cache
+        Integer ordinal = staticFlowsOrdinal.get(0);
+        staticFlowsOrdinal.put(0, ++ordinal);
+        staticFlows.put(ordinal, dataObject);
+
+        // We send flow to the sounthbound plugin
+        flowService.updateFlow(input.build());
+        updateLocalDatabase((NodeFlow) dataObject, true);
+    }
+
     @SuppressWarnings("unchecked")
     private void commitToPlugin(internalTransaction transaction) {
         for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.additions.entrySet()) {
@@ -250,7 +277,7 @@ public class FlowConsumerImpl {
         for (@SuppressWarnings("unused")
         Entry<InstanceIdentifier<?>, Flow> entry : transaction.updates.entrySet()) {
             System.out.println("Coming update cc in FlowDatacommitHandler");
-            // updateFlow(entry.getKey(),entry.getValue());
+            updateFlow(entry.getKey(), entry.getValue());
         }
 
         for (Entry<InstanceIdentifier<?>, Flow> entry : transaction.removals.entrySet()) {
@@ -316,7 +343,7 @@ public class FlowConsumerImpl {
                     logger.error(error);
                     return;
                 }
-                if (originalSwView.containsKey((FlowKey) entry)) {
+                if (originalSwView.containsKey(entry)) {
                     logger.warn("Operation Rejected: A flow with same match and priority exists on the target node");
                     logger.trace("Aborting to install {}", entry);
                     continue;
@@ -463,10 +490,23 @@ public class FlowConsumerImpl {
         public void onFlowUpdated(FlowUpdated notification) {
             updatedFlows.add(notification);
         }
-        
+
         @Override
         public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
-            //TODO
+            // TODO
+        }
+
+        @Override
+        public void onNodeErrorNotification(NodeErrorNotification notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        @Override
+        public void onNodeExperimenterErrorNotification(
+                NodeExperimenterErrorNotification notification) {
+            // TODO Auto-generated method stub
+            
         };
 
     }
@@ -526,10 +566,39 @@ public class FlowConsumerImpl {
             FlowConsumerImpl.originalSwView.put((FlowKey) entry, (Flow) entry);
             installedSwView.put((FlowKey) entry, (Flow) entry);
         } else {
-            originalSwView.remove((Flow) entry);
-            installedSwView.remove((FlowKey) entry);
+            originalSwView.remove(entry);
+            installedSwView.remove(entry);
+
+        }
+    }
 
+    @Override
+    public List<DataObject> get() {
+
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        ConcurrentMap<Integer, Flow> flowMap = staticFlows;
+        int maxKey = staticFlowsOrdinal.get(0).intValue();
+        for (int i = 0; i <= maxKey; i++) {
+            Flow entry = flowMap.get(i);
+            if (entry != null) {
+                orderedList.add(entry);
+            }
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, org.opendaylight.controller.sal.core.Node n) {
+        if (this instanceof FlowConsumerImpl) {
+            for (ConcurrentMap.Entry<Integer, Flow> flowEntry : staticFlows.entrySet()) {
+                Flow flow = flowEntry.getValue();
+                if (flow.getNode().equals(n) && flow.getFlowName().equals(name)) {
+
+                    return flowEntry.getValue();
+                }
+            }
         }
+        return null;
     }
 
     /*
@@ -550,7 +619,7 @@ public class FlowConsumerImpl {
         if (add) {
             nodeIndeces.add((Flow) entry);
         } else {
-            nodeIndeces.remove((Flow) entry);
+            nodeIndeces.remove(entry);
         }
 
         // Update cache across cluster
index ce8ee5aaf3564c8a9fb9a7a06d8cce61076670ee..20ab46d4ad5015a71464176ce2299d87ced25ce9 100644 (file)
@@ -1,14 +1,15 @@
 package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -17,8 +18,8 @@ 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.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.Node;
@@ -35,13 +36,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.Gro
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes.GroupType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.Buckets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -51,10 +49,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings("unused")
-public class GroupConsumerImpl {
+public class GroupConsumerImpl implements IForwardingRulesManager {
 
     protected static final Logger logger = LoggerFactory.getLogger(GroupConsumerImpl.class);
-    private GroupEventListener groupEventListener = new GroupEventListener();
+    private final GroupEventListener groupEventListener = new GroupEventListener();
     private Registration<NotificationListener> groupListener;
     private SalGroupService groupService;
     private GroupDataCommitHandler commitHandler;
@@ -69,8 +67,9 @@ public class GroupConsumerImpl {
     private IContainer container;
 
     public GroupConsumerImpl() {
-        
-           InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).node(Group.class).toInstance();
+
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class)
+                .node(Group.class).toInstance();
         groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
 
         clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
@@ -118,32 +117,36 @@ public class GroupConsumerImpl {
 
             clusterGroupContainerService.createCache("frm.nodeGroups",
                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
-            
-//TODO for cluster mode
-           /* clusterGroupContainerService.createCache(WORK_STATUS_CACHE,
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));
-
-            clusterGroupContainerService.createCache(WORK_ORDER_CACHE,
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));*/
-            
-        } catch (CacheConfigException cce) {            
+
+            // TODO for cluster mode
+            /*
+             * clusterGroupContainerService.createCache(WORK_STATUS_CACHE,
+             * EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL,
+             * IClusterServices.cacheMode.ASYNC));
+             *
+             * clusterGroupContainerService.createCache(WORK_ORDER_CACHE,
+             * EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL,
+             * IClusterServices.cacheMode.ASYNC));
+             */
+
+        } catch (CacheConfigException cce) {
             logger.error("Group CacheConfigException");
             return false;
-            
+
         } catch (CacheExistException cce) {
-            logger.error(" Group CacheExistException");           
+            logger.error(" Group CacheExistException");
         }
-        
+
         return true;
     }
-    
+
     private void nonClusterGroupObjectCreate() {
         originalSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
         installedSwGroupView = new ConcurrentHashMap<GroupKey, Group>();
-        nodeGroups = new ConcurrentHashMap<Node, List<Group>>();        
+        nodeGroups = new ConcurrentHashMap<Node, List<Group>>();
         inactiveGroups = new ConcurrentHashMap<GroupKey, Group>();
     }
-    
+
     @SuppressWarnings({ "unchecked" })
     private boolean retrieveGroupCaches() {
         ConcurrentMap<?, ?> map;
@@ -152,7 +155,7 @@ public class GroupConsumerImpl {
             logger.warn("Group: un-initialized clusterGroupContainerService, can't retrieve cache");
             nonClusterGroupObjectCreate();
             return false;
-        }       
+        }
 
         map = clusterGroupContainerService.getCache("frm.originalSwGroupView");
         if (map != null) {
@@ -231,11 +234,11 @@ public class GroupConsumerImpl {
                 logger.error("Group record does not exist");
                 return new Status(StatusCode.BADREQUEST, "Group record does not exist");
             }
-            
-            if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() && 
-                    group.getGroupType().getIntValue() <= GroupType.GroupFf.getIntValue())) {
+
+            if (!(group.getGroupType().getIntValue() >= GroupType.GroupAll.getIntValue() && group.getGroupType()
+                    .getIntValue() <= GroupType.GroupFf.getIntValue())) {
                 logger.error("Invalid Group type %d" + group.getGroupType().getIntValue());
-                return new Status(StatusCode.BADREQUEST, "Invalid Group type");                
+                return new Status(StatusCode.BADREQUEST, "Invalid Group type");
             }
 
             groupBuckets = group.getBuckets();
@@ -279,39 +282,39 @@ public class GroupConsumerImpl {
      * @param dataObject
      */
     private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
-        GroupKey groupKey = groupUpdateDataObject.getKey();        
+        GroupKey groupKey = groupUpdateDataObject.getKey();
         UpdatedGroupBuilder updateGroupBuilder = null;
-        
+
         Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
-        
+
         if (!groupOperationStatus.isSuccess()) {
             logger.error("Group data object validation failed %s" + groupUpdateDataObject.getGroupName());
             return groupOperationStatus;
         }
-         
+
         if (originalSwGroupView.containsKey(groupKey)) {
             originalSwGroupView.remove(groupKey);
             originalSwGroupView.put(groupKey, groupUpdateDataObject);
         }
-        
+
         if (groupUpdateDataObject.isInstall()) {
             UpdateGroupInputBuilder groupData = new UpdateGroupInputBuilder();
             updateGroupBuilder = new UpdatedGroupBuilder();
             updateGroupBuilder.fieldsFrom(groupUpdateDataObject);
             groupData.setUpdatedGroup(updateGroupBuilder.build());
-            //TODO how to get original group and modified group. 
-            
+            // TODO how to get original group and modified group.
+
             if (installedSwGroupView.containsKey(groupKey)) {
                 installedSwGroupView.remove(groupKey);
                 installedSwGroupView.put(groupKey, groupUpdateDataObject);
             }
-            
+
             groupService.updateGroup(groupData.build());
         }
-        
+
         return groupOperationStatus;
     }
-    
+
     /**
      * Adds Group to the southbound plugin and our internal database
      *
@@ -342,26 +345,26 @@ public class GroupConsumerImpl {
 
         return groupOperationStatus;
     }
-    
-       private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
-        for(Entry<InstanceIdentifier<?>, Group> entry :transaction.additions.entrySet()) {
-            
-            if (!addGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+
+    private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+        for (Entry<InstanceIdentifier<?>, Group> entry : transaction.additions.entrySet()) {
+
+            if (!addGroup(entry.getKey(), entry.getValue()).isSuccess()) {
                 transaction.additions.remove(entry.getKey());
                 return Rpcs.getRpcResult(false, null, null);
             }
         }
-        
-        for(Entry<InstanceIdentifier<?>, Group> entry :transaction.updates.entrySet()) {
-           
-            if (!updateGroup(entry.getKey(),entry.getValue()).isSuccess()) {
+
+        for (Entry<InstanceIdentifier<?>, Group> entry : transaction.updates.entrySet()) {
+
+            if (!updateGroup(entry.getKey(), entry.getValue()).isSuccess()) {
                 transaction.updates.remove(entry.getKey());
                 return Rpcs.getRpcResult(false, null, null);
             }
         }
-        
-        for(InstanceIdentifier<?> removal : transaction.removals) {
-           // removeFlow(removal);
+
+        for (InstanceIdentifier<?> removal : transaction.removals) {
+            // removeFlow(removal);
         }
 
         return Rpcs.getRpcResult(true, null, null);
@@ -371,7 +374,8 @@ public class GroupConsumerImpl {
 
         @SuppressWarnings("unchecked")
         @Override
-        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+        public DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
+                DataModification<InstanceIdentifier<?>, DataObject> modification) {
             // We should verify transaction
             System.out.println("Coming in GroupDatacommitHandler");
             internalTransaction transaction = new internalTransaction(modification);
@@ -483,4 +487,31 @@ public class GroupConsumerImpl {
 
         }
     }
+
+    @Override
+    public List<DataObject> get() {
+
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        Collection<Group> groupList = originalSwGroupView.values();
+        for (Iterator<Group> iterator = groupList.iterator(); iterator.hasNext();) {
+            orderedList.add(iterator.next());
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, Node n) {
+
+        if (this instanceof GroupConsumerImpl) {
+            Collection<Group> groupList = originalSwGroupView.values();
+            for (Iterator<Group> iterator = groupList.iterator(); iterator.hasNext();) {
+                Group group = iterator.next();
+                if (group.getNode().equals(n) && group.getGroupName().equals(name)) {
+
+                    return group;
+                }
+            }
+        }
+        return null;
+    }
 }
diff --git a/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/IForwardingRulesManager.java b/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/IForwardingRulesManager.java
new file mode 100644 (file)
index 0000000..fa279bc
--- /dev/null
@@ -0,0 +1,33 @@
+package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+
+import java.util.List;
+
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Interface that describes methods for accessing the flows database.
+ */
+public interface IForwardingRulesManager {
+
+    /**
+     * Returns the specifications of all the flows configured for all the
+     * switches on the current container
+     *
+     * @return the list of flow configurations present in the database
+     */
+    public List<DataObject> get();
+
+    /**
+     * Returns the specification of the flow configured for the given network
+     * node on the current container
+     *
+     * @param name
+     *            the flow name
+     * @param n
+     *            the network node identifier
+     * @return the {@code FlowConfig} object
+     */
+    public DataObject getWithName(String name, Node n);
+
+}
index c69b60bb62f91b3cbb866032b5ede29232145120..34adc28fc5453c8816d4cab752020728d4589ded 100644 (file)
@@ -1,13 +1,15 @@
 package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -16,8 +18,8 @@ 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.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.Node;
@@ -25,6 +27,7 @@ import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
@@ -38,7 +41,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -47,9 +49,9 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class MeterConsumerImpl {
+public class MeterConsumerImpl implements IForwardingRulesManager {
     protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
-    private MeterEventListener meterEventListener = new MeterEventListener();
+    private final MeterEventListener meterEventListener = new MeterEventListener();
     private Registration<NotificationListener> meterListener;
     private SalMeterService meterService;
     private MeterDataCommitHandler commitHandler;
@@ -64,8 +66,9 @@ public class MeterConsumerImpl {
     private IContainer container;
 
     public MeterConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class).node(Meter.class).toInstance();
-        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);        
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class)
+                .node(Meter.class).toInstance();
+        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
         clusterMeterContainerService = FRMConsumerImpl.getClusterContainerService();
 
         container = FRMConsumerImpl.getContainer();
@@ -218,10 +221,9 @@ public class MeterConsumerImpl {
                 originalSwMeterView.put(meterKey, meterAddDataObject);
                 meterService.addMeter(meterBuilder.build());
             }
-            
-            originalSwMeterView.put(meterKey, meterAddDataObject);            
-        }
-        else {
+
+            originalSwMeterView.put(meterKey, meterAddDataObject);
+        } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -235,35 +237,32 @@ public class MeterConsumerImpl {
      *
      * @param dataObject
      */
-    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
+    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
         MeterKey meterKey = meterUpdateDataObject.getKey();
         UpdatedMeterBuilder updateMeterBuilder = null;
-        
-        
-        if (null != meterKey && 
-                validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
-            
+
+        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.UPDATE).isSuccess()) {
+
             if (originalSwMeterView.containsKey(meterKey)) {
                 originalSwMeterView.remove(meterKey);
                 originalSwMeterView.put(meterKey, meterUpdateDataObject);
             }
-            
+
             if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder(); 
+                UpdateMeterInputBuilder updateMeterInputBuilder = new UpdateMeterInputBuilder();
                 updateMeterBuilder = new UpdatedMeterBuilder();
                 updateMeterBuilder.fieldsFrom(meterUpdateDataObject);
                 updateMeterInputBuilder.setUpdatedMeter(updateMeterBuilder.build());
-                
+
                 if (installedSwMeterView.containsKey(meterKey)) {
                     installedSwMeterView.remove(meterKey);
                     installedSwMeterView.put(meterKey, meterUpdateDataObject);
                 }
-                
+
                 meterService.updateMeter(updateMeterInputBuilder.build());
             }
-                        
-        }
-        else {
+
+        } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -277,21 +276,19 @@ public class MeterConsumerImpl {
      *
      * @param dataObject
      */
-    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
+    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {
         MeterKey meterKey = meterUpdateDataObject.getKey();
-        
-        if (null != meterKey && 
-                validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+
+        if (null != meterKey && validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
             if (meterUpdateDataObject.isInstall()) {
-                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();                
-                
+                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();
+
                 installedSwMeterView.put(meterKey, meterUpdateDataObject);
                 meterService.updateMeter(updateMeterBuilder.build());
             }
-            
-            originalSwMeterView.put(meterKey, meterUpdateDataObject);            
-        }
-        else {
+
+            originalSwMeterView.put(meterKey, meterUpdateDataObject);
+        } else {
             return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
         }
 
@@ -525,4 +522,30 @@ public class MeterConsumerImpl {
 
         }
     }
+
+    @Override
+    public List<DataObject> get() {
+
+        List<DataObject> orderedList = new ArrayList<DataObject>();
+        Collection<Meter> meterList = originalSwMeterView.values();
+        for (Iterator<Meter> iterator = meterList.iterator(); iterator.hasNext();) {
+            orderedList.add(iterator.next());
+        }
+        return orderedList;
+    }
+
+    @Override
+    public DataObject getWithName(String name, Node n) {
+        if (this instanceof MeterConsumerImpl) {
+            Collection<Meter> meterList = originalSwMeterView.values();
+            for (Iterator<Meter> iterator = meterList.iterator(); iterator.hasNext();) {
+                Meter meter = iterator.next();
+                if (meter.getNode().equals(n) && meter.getMeterName().equals(name)) {
+
+                    return meter;
+                }
+            }
+        }
+        return null;
+    }
 }
index 15f0685819d0921cdf81f730499ac842271cd59e..2eae511e02975e6aa23f9d2a09091fa186ab3764 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Swit
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification
 import org.opendaylight.yangtools.yang.common.RpcResult
 import org.slf4j.LoggerFactory
 
@@ -137,4 +139,12 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
         // NOOP : Not supported by AD SAL
     }
     
+     override onNodeErrorNotification(NodeErrorNotification notification) {
+        // NOOP : Not supported by AD SAL
+    }
+    
+     override onNodeExperimenterErrorNotification(
+                NodeExperimenterErrorNotification notification) {
+        // NOOP : Not supported by AD SAL
+    }
 }
index 5dd149a99738f2b33fa9e9b024861ee56286835c..1e33481e70a7dae49b1646014f77d422f50648cf 100644 (file)
@@ -190,7 +190,7 @@ public class MDFlowMapping {
     public static dispatch def toAction(Output sourceAction) {
         val actionBuilder = new ActionBuilder();
         val it = new OutputActionBuilder();
-        outputNodeConnector = sourceAction.port.toUriList;
+        outputNodeConnector = sourceAction.port.toUri;
         actionBuilder.action = it.build();
         return actionBuilder.build();
 
@@ -331,7 +331,7 @@ public class MDFlowMapping {
         return it.build()
     }
 
-    public static def List<Uri> toUriList(NodeConnector connector) {
+    public static def Uri toUri(NodeConnector connector) {
         throw new UnsupportedOperationException("TODO: auto-generated method stub")
     }
 
index 96b69618b0db78031a3bf20e2796af99ea42bef2..064b920640fb970afc49c5034554800d6b80f389 100644 (file)
@@ -166,11 +166,11 @@ public class ToSalConversionsUtils {
                 targetAction.add(new Controller());
             } else if (sourceAction instanceof OutputAction) {
 
-                List<Uri> nodeConnectors = ((OutputAction) sourceAction).getOutputNodeConnector();
-                if (nodeConnectors != null) {
-                    for (Uri uri : nodeConnectors) {
-                        targetAction.add(new Output(fromNodeConnectorRef(uri)));
-                    }
+                Uri nodeConnector = ((OutputAction) sourceAction).getOutputNodeConnector();
+                if (nodeConnector != null) {
+                    //for (Uri uri : nodeConnectors) {
+                        targetAction.add(new Output(fromNodeConnectorRef(nodeConnector)));
+                    //}
                 }
             } else if (sourceAction instanceof PopMplsAction) {
                 // TODO: define maping
index e2ae7246063678bca99a9fe9fdce2186323942d1..8108074ed74dc759314238ba7aec9e6836958632 100644 (file)
@@ -175,7 +175,7 @@ public class TestToSalConversionsUtils {
         checkSalAction(actions, FloodAll.class, 1);
         checkSalAction(actions, HwPath.class, 1);
         checkSalAction(actions, Loopback.class, 1);
-        checkSalAction(actions, Output.class, 2, true);
+        checkSalAction(actions, Output.class, 1, true);
         checkSalAction(actions, PopVlan.class, 1);
         checkSalAction(actions, PushVlan.class, 1, true);
         checkSalAction(actions, SetDlDst.class, 1, true);
@@ -451,11 +451,8 @@ public class TestToSalConversionsUtils {
         pushVlanActionBuilder.setTag(0x8100); // 12 bit
     }
 
-    private void prepareActionOutput(OutputActionBuilder outputActionBuilder) {
-        List<Uri> uris = new ArrayList<>();
-        uris.add(new Uri("uri1"));
-        uris.add(new Uri("uri2"));
-        outputActionBuilder.setOutputNodeConnector(uris);
+    private void prepareActionOutput(OutputActionBuilder outputActionBuilder) {       
+        outputActionBuilder.setOutputNodeConnector(new Uri("uri1"));
     }
 
     private Match prepOdMatch(MtchType mt) {
index 3bf7db62976264c9138238b375dfc70c40c1333b..5bfe54e4c32a7132a0fe8e8e9c53908e0e4f6aa0 100644 (file)
@@ -5,6 +5,7 @@ module opendaylight-action-types {
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
     import opendaylight-l2-types {prefix l2t; revision-date "2013-08-27";}
+    import opendaylight-match-types {prefix match; revision-date 2013-10-26";}
     
     revision "2013-11-12" {
         description "Initial revision of action service";
@@ -42,7 +43,7 @@ module opendaylight-action-types {
     grouping action {
         choice action {
             case output-action {
-                leaf-list output-node-connector {
+                leaf output-node-connector {
                     type inet:uri;
                 }
                 
@@ -60,11 +61,21 @@ module opendaylight-action-types {
                     }
                 }
             }
-
+            
+            case set-field {
+                container match {
+                    uses match:match;
+                }
+            }
+            
             case set-queue-action {
                 leaf queue {
                     type string; 
                 }
+                
+                leaf queue-id {
+                    type uint32; 
+                }
             }
 
             case pop-mpls-action {
@@ -168,6 +179,10 @@ module opendaylight-action-types {
                 leaf group {
                     type string;
                 }
+                
+                leaf group-id {
+                    type uint32;
+                }
             }
             
             case set-dl-type-action {
index b5a70ccfe5357a3dec6b91d1ea04aac559a0ec1a..4b50c0ee720488dfd47ead3754099fd05f3ecb10 100644 (file)
@@ -55,6 +55,10 @@ module opendaylight-flow-types {
                 leaf meter {
                     type string;
                 }
+                
+                leaf meter-id {
+                    type uint32;
+                }
             }   
         }
     }
index 685728a88709cac4396294e375f22943113de17c..97ca8b3c71491063d21ac4284b62e537c3b56dd6 100644 (file)
@@ -73,16 +73,6 @@ module opendaylight-group-types {
         }
     }
     
-    grouping group-statistics-request {
-        list group-stats {
-            key "group-id";         
-            
-            leaf group-id {
-                type int32;
-            }           
-        }
-    }
-    
     grouping group-statistics {
             
         leaf group-id {
@@ -128,7 +118,44 @@ module opendaylight-group-types {
         }       
     }
 
+    grouping group-features {
+        uses group-types;
+            
+        leaf capabilities { 
+               type enumeration {
+                enum select-weight;
+                enum select-liveness;
+                enum chaining;
+                enum chaining-checks;
+            }   
+        }
+
+        leaf-list max-groups {
+            type uint32;
+            description "Maximum number of groups for each type";
+            max-elements 4;
+        }
+            
+        leaf-list actions {
+            type uint32;
+            description "Bitmap number OFPAT_* that are supported";
+            max-elements 4;
+        }
+    }
+    
+    grouping group-statistics-request {
+        list group-stats {
+            key "group-id";         
+            
+            leaf group-id {
+                type int32;
+            }           
+        }
+    }
+    
+    
     grouping group-statistics-reply {
+       
         list group-stats {
             key "group-stats-order";
             leaf group-stats-order {
@@ -139,10 +166,10 @@ module opendaylight-group-types {
         }
     }
     
-    grouping group-desc-stats {
+    grouping group-desc-stats-reply {
+       
         list group-desc-stats {
             key "order-id";         
-            
             leaf order-id {
                 type int32;
             }
@@ -151,35 +178,8 @@ module opendaylight-group-types {
         }
     }
     
-    grouping group-features {
-        list group-features {
-            key "order";
-            leaf order {
-                type int32;
-            }
-            
-            uses group-types;
-            
-            leaf capabilities { 
-                type enumeration {
-                    enum select-weight;
-                    enum select-liveness;
-                    enum chaining;
-                    enum chaining-checks;
-                }   
-            }
-
-            leaf-list max-groups {
-                type uint32;
-                description "Maximum number of groups for each type";
-                max-elements 4;
-            }
-            
-            leaf-list actions {
-                type uint32;
-                description "Bitmap number OFPAT_* that are supported";
-                max-elements 4;
-            }
-        }
-    }    
+    grouping group-features-reply {
+       uses group-features;
+    }
+    
 }
\ No newline at end of file
index 148ac9687f5baa8d66fa0fbfb143d91b6fdafb6f..d26ca667996f164f9ca7f8b57c6df25a7c381563 100644 (file)
@@ -119,16 +119,6 @@ module opendaylight-meter-types {
         }
     }
     
-    grouping meter-stats-config-request {
-        list meter-stats {
-            key "meter-id";         
-            
-            leaf meter-id {
-                type int32;
-            }           
-        }
-    }
-    
     grouping meter-statistics {
             
         leaf meter-id {
@@ -174,6 +164,39 @@ module opendaylight-meter-types {
         }
     }
 
+    grouping meter-features {
+                           
+        leaf max_meter {
+            type yang:counter32;
+        }
+           
+        leaf band_types {
+            type yang:counter32;
+        }
+        
+        leaf capabilities {
+            type yang:counter32;
+        }
+        
+        leaf max_bands {
+            type uint8;
+        }
+        
+        leaf max_color {
+            type uint8;
+        }
+    }
+
+    grouping meter-stats-config-request {
+        list meter-stats {
+            key "meter-id";         
+            
+            leaf meter-id {
+                type int32;
+            }           
+        }
+    }
+    
     grouping meter-statistics-reply {
         list meter-stats {
             key "meter-stats-order";
@@ -184,10 +207,9 @@ module opendaylight-meter-types {
         }
     }
     
-    grouping meter-config-stats {
+    grouping meter-config-stats-reply {
         list meter-config-stats {
             key "meter-config-order";
-            
             leaf meter-config-order {
                 type int32;
             }
@@ -196,33 +218,8 @@ module opendaylight-meter-types {
         } 
     }
     
-    grouping meter-features {
-        list meter-features {
-            key "meter-feature-order";
-            
-            leaf meter-feature-order {
-                type yang:counter32;
-            }          
-            
-            leaf max_meter {
-                type yang:counter32;
-            }
-            
-            leaf band_types {
-                type yang:counter32;
-            }
-            
-            leaf capabilities {
-                type yang:counter32;
-            }
-            
-            leaf max_bands {
-                type uint8;
-            }
-            
-            leaf max_color {
-                type uint8;
-            }
-        }
-    }    
+    grouping meter-features-reply {
+       uses meter-features;
+    }
+    
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-error.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-error.yang
new file mode 100644 (file)
index 0000000..171f956
--- /dev/null
@@ -0,0 +1,60 @@
+module flow-errors {
+       namespace "urn:opendaylight:flow:errors";
+    prefix error;
+    
+    revision "2013-11-16" {
+        description "Initial revision of error";
+    }
+
+    typedef error-type {
+        type enumeration {
+            enum hello-failed;
+            enum bad-request;
+            enum bad-action;
+            enum bad-instruction;
+            enum bad-match;
+            enum flow-mod-failed;
+            enum group-mod-failed;
+            enum port-mod-failed;
+            enum table-mod-failed;
+            enum meter-mod-failed;
+            enum queue-op-failed;
+            enum switch-config-failed;
+            enum role-request-failed;
+            enum table-features-failed;
+            enum experimenter;
+        }
+    }
+    
+    grouping error-message {
+        leaf type {
+            type error-type;
+        }
+        
+        leaf code {
+            type uint16;        
+        }
+        
+        leaf data {
+            type string;
+        }
+    }
+    
+    grouping experimenter-error-message {
+        leaf type {
+            type error-type;
+        }
+        
+        leaf exp-type {
+            type uint16;        
+        }
+        
+        leaf experimenter-id {
+            type uint32;        
+        }
+        
+        leaf data {
+            type string;
+        }
+    }   
+}
\ No newline at end of file
index f8589193d7cba41d76789782619c700243fceae9..df0b2527b8731c4036d902d481d7adee1b1e7233 100644 (file)
@@ -7,6 +7,7 @@ module sal-flow {
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import opendaylight-flow-types {prefix types;revision-date "2013-10-26";}
     import flow-capable-transaction {prefix tr;}
+    import flow-errors {prefix error;}
 
     revision "2013-08-19" {
         description "Initial revision of flow service";
@@ -93,4 +94,12 @@ module sal-flow {
     notification switch-flow-removed {
         uses node-flow-removed;
     }
+    
+    notification node-error-notification {
+        uses error:error-message;
+    }
+    
+    notification node-experimenter-error-notification {
+        uses error:experimenter-error-message;
+    }
 }
\ No newline at end of file
index 043b0077f79defd977170a105a3651a13c8f9332..5b565365a5894f9912fde799a5a8f1b56855094b 100644 (file)
@@ -7,58 +7,45 @@ module opendaylight-group-statistics {
     import opendaylight-group-types {prefix group-types;revision-date "2013-10-18";}
     import flow-capable-transaction {prefix tr;}
     
+    contact
+       "Anilkumar Vishnoi
+       Email: avishnoi@in.ibm.com";
+               
     revision "2013-11-11" {
         description "Initial revision of group statistics service";
     }
     
-    typedef group-stats-ref {
-        type instance-identifier;
-    }
-    
-    grouping group-stats-response {
-        uses "inv:node-context-ref";
-
-        leaf group-stats-id {
-            type group-stats-ref;
+    augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-group-statistics";
+        container group-statistics {
+               //config "false";
+               uses group-types:group-statistics-reply;
         }
-        uses group-types:group-statistics;
     }
 
-    typedef group-features-ref {
-        type instance-identifier;
-    }
-    
-    grouping group-features-response {
-        uses "inv:node-context-ref";
-
-        leaf group-features-id {
-            type group-features-ref;
+       augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-group-desc-stats";
+        container group-desc {
+               //config "false";
+               uses group-types:group-desc-stats-reply;
         }
-        uses group-types:group-features;
     }
-
-    typedef group-desc-ref {
-        type instance-identifier;
-    }
-    
-    grouping group-desc-response {
-        uses "inv:node-context-ref";
-
-        leaf group-desc-id {
-            type group-desc-ref;
+       
+       augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-group-features";
+        container group-features {
+               //config "false";
+               uses group-types:group-features-reply;
         }
-        uses group-types:group-desc-stats;
     }
 
        // RPC calls
        rpc get-all-group-statistics {
                input {
-            uses inv:node-context-ref;
+            uses inv:node;
         }
         output {
-            list group-statistics {
-                uses group-stats-response;
-            }
+               uses group-types:group-statistics-reply;
             uses tr:transaction-aware;
         }
        
@@ -66,13 +53,10 @@ module opendaylight-group-statistics {
        
        rpc get-group-statistics {
                input {
-            uses inv:node-context-ref;
-            leaf group-id{
-               type group-types:group-id;
-            }
+            uses inv:node;
         }
         output {
-            uses group-stats-response;
+            uses group-types:group-statistics-reply;
             uses tr:transaction-aware;
         }
        
@@ -80,26 +64,20 @@ module opendaylight-group-statistics {
        
        rpc get-group-description {
                input {
-            uses inv:node-context-ref;
-            leaf group-id{
-               type group-types:group-id;
-            }
+            uses inv:node;
         }
         output {
-            uses group-desc-response;
+            uses group-types:group-desc-stats-reply;
             uses tr:transaction-aware;
         }
        }
        
        rpc get-group-features {
                input {
-            uses inv:node-context-ref;
-            leaf group-id{
-               type group-types:group-id;
-            }
+            uses inv:node;
         }
         output {
-            uses group-features-response;
+            uses group-types:group-features-reply;
             uses tr:transaction-aware;
         }
        }
@@ -108,17 +86,29 @@ module opendaylight-group-statistics {
        //Notification calls
        
        notification group-statistics-updated {
-               uses group-stats-response;
+               leaf moreReplies {
+                       type boolean;
+               }
+               uses inv:node;
+               uses group-types:group-statistics-reply;
         uses tr:transaction-aware;
        }
        
        notification group-desc-stats-updated {
-               uses group-desc-response;
+               leaf moreReplies {
+                       type boolean;
+               }
+               uses inv:node;
+               uses group-types:group-desc-stats-reply;
         uses tr:transaction-aware;
        }
 
        notification group-features-updated {
-               uses group-features-response;
+               leaf moreReplies {
+                       type boolean;
+               }
+               uses inv:node;
+               uses group-types:group-features-reply;
         uses tr:transaction-aware;
        }
 }
index 18dd60d08ddc87a4f8bf45e76b006e7d3d607818..c22bdd3906bb801f1a2432329dff8ef9c9f40292 100644 (file)
@@ -7,101 +7,80 @@ module opendaylight-meter-statistics {
     import opendaylight-meter-types {prefix meter-types;revision-date "2013-09-18";}
     import flow-capable-transaction {prefix tr;}
     
+    contact
+       "Anilkumar Vishnoi
+       Email: avishnoi@in.ibm.com";
 
     revision "2013-11-11" {
         description "Initial revision of meter statistics service";
     }
 
-    typedef meter-stats-ref {
-        type instance-identifier;
-    }
-    
-    grouping meter-stats-response {
-        uses "inv:node-context-ref";
-
-        leaf meter-stats-id {
-            type meter-stats-ref;
+    augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-meter-statistics";
+        container meter-statistics {
+               //config "false";
+               uses meter-types:meter-statistics-reply;
         }
-        uses meter-types:meter-statistics;
     }
 
-    typedef meter-config-ref {
-        type instance-identifier;
-    }
-    
-    grouping meter-config-response {
-        uses "inv:node-context-ref";
-
-        leaf meter-config-id {
-            type meter-config-ref;
+       augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-meter-config-stats";
+        container meter-config-stats {
+               //config "false";
+               uses meter-types:meter-config-stats-reply;
         }
-        uses meter-types:meter-config-stats;
-    }
-
-    typedef meter-features-ref {
-        type instance-identifier;
     }
-    
-    grouping meter-features-response {
-        uses "inv:node-context-ref";
-
-        leaf meter-features-id {
-            type meter-features-ref;
+       
+       augment "/inv:nodes/inv:node" {
+        ext:augment-identifier "node-meter-features";
+        container meter-features {
+               //config "false";
+               uses meter-types:meter-features-reply;
         }
-        uses meter-types:meter-features;
     }
 
        // RPC calls
        rpc get-all-meter-statistics {
                input {
-            uses inv:node-context-ref;
+            uses inv:node;
         }
         output {
-            list meter-statistics {
-                uses meter-stats-response;
-                uses tr:transaction-aware;
-            }
+                       uses meter-types:meter-statistics-reply;
+                       uses tr:transaction-aware;
         }
        
        }
        
        rpc get-meter-statistics {
-               description "RPC Method to send meter statistics request to the give switch for specific meter"; 
                input {
-            uses inv:node-context-ref;
+            uses inv:node;
             leaf meter-id{
                type meter-types:meter-id;
             }
         }
         output {
-            uses meter-stats-response;
+            uses meter-types:meter-statistics-reply;
             uses tr:transaction-aware;
         }
        
        }
        
-       rpc get-meter-config-statistics {
+       rpc get-all-meter-config-statistics {
                input {
-            uses inv:node-context-ref;
-            leaf meter-id{
-               type meter-types:meter-id;
-            }
+            uses inv:node;
         }
         output {
-               uses meter-config-response;
+               uses meter-types:meter-config-stats-reply;
             uses tr:transaction-aware;
         }
        }
        
        rpc get-meter-features {
                input {
-            uses inv:node-context-ref;
-            leaf meter-id{
-               type meter-types:meter-id;
-               }
+            uses inv:node;
         }
         output {
-               uses meter-features-response;
+               uses meter-types:meter-features-reply;
             uses tr:transaction-aware;
         }
        }
@@ -110,17 +89,32 @@ module opendaylight-meter-statistics {
        //Notification calls
        
        notification meter-statistics-updated {
-               uses meter-stats-response;
+               leaf moreReplies {
+                       type boolean;
+               }
+               
+               uses inv:node;
+        uses meter-types:meter-statistics-reply;
         uses tr:transaction-aware;
        }
        
        notification meter-config-stats-updated {
-               uses meter-config-response;
-        uses tr:transaction-aware;
+               leaf moreReplies {
+                       type boolean;
+               }
+           
+        uses inv:node;
+           uses meter-types:meter-config-stats-reply;
+       uses tr:transaction-aware;
        }
 
        notification meter-features-updated {
-               uses meter-features-response;
+               leaf moreReplies {
+                       type boolean;
+               }
+               
+               uses inv:node;
+        uses meter-types:meter-features-reply;
         uses tr:transaction-aware;
        }
 }
index 9e4d3a580c79888da155bd9a5808971862ffed84..c356ff6b0e15258127524119d28f057d9a993755 100644 (file)
             <version>1.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-management</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-impl</artifactId>
             <version>${slf4j.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <version>0.9.9-RC1</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/CodeGenerationException.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/CodeGenerationException.java
new file mode 100644 (file)
index 0000000..1923040
--- /dev/null
@@ -0,0 +1,25 @@
+package org.opendaylight.controller.sal.binding.codegen;
+
+public class CodeGenerationException extends RuntimeException{
+
+    public CodeGenerationException() {
+        super();
+    }
+
+    public CodeGenerationException(String message, Throwable cause, boolean enableSuppression,
+            boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    public CodeGenerationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public CodeGenerationException(String message) {
+        super(message);
+    }
+
+    public CodeGenerationException(Throwable cause) {
+        super(cause);
+    }
+}
index 2d67f11eb2b1b65046890fdfa816283a2c0dc483..2136572aa3240117ced443e180acc8b6c26d68be 100644 (file)
@@ -34,6 +34,10 @@ import org.opendaylight.yangtools.yang.binding.BindingDeserializer
 import org.opendaylight.yangtools.yang.binding.BindingSerializer
 import org.opendaylight.yangtools.yang.binding.BindingCodec
 import org.slf4j.LoggerFactory
+import org.opendaylight.controller.sal.binding.codegen.CodeGenerationException
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import java.security.ProtectionDomain
+import java.io.File
 
 class TransformerGenerator {
 
@@ -53,6 +57,10 @@ class TransformerGenerator {
 
     CtClass ctQName
 
+    @Property
+    var File classFileCapturePath;
+
+
     @Property
     var Map<Type, Type> typeDefinitions;
 
@@ -88,7 +96,7 @@ class TransformerGenerator {
         ]
     }
 
-    def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
+    private def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
         return withClassLoader(inputType.classLoader) [ |
             val transformer = generatedClasses.get(inputType);
             if (transformer != null) {
@@ -111,7 +119,7 @@ class TransformerGenerator {
 
     }
 
-    def Class<?> getValueSerializer(GeneratedTransferObject type) {
+    private def Class<?> getValueSerializer(GeneratedTransferObject type) {
         val cls = loadClassWithTCCL(type.resolvedName);
         val transformer = generatedClasses.get(cls);
         if (transformer !== null) {
@@ -170,18 +178,16 @@ class TransformerGenerator {
                     '''
                 ]
             ]
-            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
             log.info("DOM Codec for {} was generated {}",inputType,ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
-            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
-            exception.addSuppressed(e);
-            throw exception;
+            processException(inputType,e);
+            return null;
         }
     }
 
-    private def <D> Class<? extends BindingCodec<Map<QName, Object>, D>> generateTransformerFor(Class<D> inputType,
+    private def dispatch  Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(Class inputType,
         GeneratedType typeSpec, SchemaNode node) {
         try {
             log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
@@ -209,15 +215,55 @@ class TransformerGenerator {
                 ]
             ]
 
-            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
-            return ret as Class<? extends BindingCodec<Map<QName,Object>, D>>;
+            val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
-            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
-            exception.addSuppressed(e);
-            throw exception;
+            processException(inputType,e);
+            return null;
         }
     }
+    
+    
+    private def dispatch  Class<? extends BindingCodec<Map<QName, Object>, Object>> generateTransformerFor(Class inputType,
+        GeneratedType typeSpec, ChoiceNode node) {
+        try {
+            log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+            val ctCls = createClass(typeSpec.transformatorFqn) [
+                //staticField(Map,"AUGMENTATION_SERIALIZERS");
+                //staticQNameField(inputType);
+                implementsType(ctTransformator)
+                method(Object, "toDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        return null;
+                    '''
+                ]
+                method(Object, "serialize", Object) [
+                    body = '''
+                        return null;
+                    '''
+                ]
+                method(Object, "fromDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        return null;
+                    '''
+                ]
+                method(Object, "deserialize", Object) [
+                    body = '''
+                        return null;
+                    '''
+                ]
+            ]
+
+            val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        } catch (Exception e) {
+            processException(inputType,e);
+            return null;
+        }
+    }
+    
 
     private def keyConstructorList(List<QName> qnames) {
         val names = new TreeSet<String>()
@@ -309,7 +355,7 @@ class TransformerGenerator {
         DataNodeContainer node) {
         val ret = '''
             Â«FOR child : node.childNodes.filter[!augmenting]»
-                Â«val signature = properties.get(child.getterName)»
+                Â«val signature = properties.getFor(child)»
                 Â«deserializeProperty(child, signature.returnType, signature)»
                 _builder.«signature.name.toSetter»(«signature.name»);
             Â«ENDFOR»
@@ -396,7 +442,7 @@ class TransformerGenerator {
             if (returnType == null) {
 
                 val ctCls = createDummyImplementation(inputType, typeSpec);
-                val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+                val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
                 return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
             }
             val ctCls = createClass(typeSpec.transformatorFqn) [
@@ -436,7 +482,7 @@ class TransformerGenerator {
                             if($1 == null) {
                                 return null;
                             }
-                            Â«returnType.name» _simpleValue = Â«deserializeValue(returnType, "$1")»;
+                            Â«returnType.resolvedName» _simpleValue = Â«deserializeValue(returnType, "$1")»;
                             Â«typeSpec.resolvedName» _value = new Â«typeSpec.resolvedName»(_simpleValue);
                             return _value;
                         }
@@ -450,12 +496,12 @@ class TransformerGenerator {
                 ]
             ]
 
-            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
             log.info("DOM Codec for {} was generated {}",inputType,ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
-            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            log.error("Cannot compile DOM Codec for {}",inputType,e);
+            val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
         }
@@ -492,7 +538,7 @@ class TransformerGenerator {
         ]
     }
 
-    def Type getValueReturnType(GeneratedTransferObject object) {
+    private def Type getValueReturnType(GeneratedTransferObject object) {
         for (prop : object.properties) {
             if (prop.name == "value") {
                 return prop.returnType;
@@ -544,16 +590,35 @@ class TransformerGenerator {
                 ]
             ]
 
-            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            val ret = ctCls.toClassImpl(inputType.classLoader, inputType.protectionDomain)
             log.info("DOM Codec for {} was generated {}",inputType,ret)
             return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        } catch (CodeGenerationException e) {
+            throw new CodeGenerationException("Cannot compile Transformator for " + inputType,e);
         } catch (Exception e) {
-            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
-            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            log.error("Cannot compile DOM Codec for {}",inputType,e);
+            val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType);
             exception.addSuppressed(e);
             throw exception;
         }
 
+    }
+    
+    def Class<?> toClassImpl(CtClass newClass, ClassLoader loader, ProtectionDomain domain) {
+        val cls = newClass.toClass(loader,domain);
+        if(classFileCapturePath !== null) {
+            newClass.writeFile(classFileCapturePath.absolutePath);
+        }
+        return cls;
+    }
+    
+    def debugWriteClass(CtClass class1) {
+        val path = class1.name.replace(".","/")+".class"
+        
+        val captureFile = new File(classFileCapturePath,path);
+        captureFile.createNewFile
+        
+        
     }
 
     private def dispatch String deserializeValue(Type type, String domParameter) '''(«type.resolvedName») Â«domParameter»'''
@@ -624,15 +689,47 @@ class TransformerGenerator {
         }
     '''
 
+    private def dispatch String serializeBody(GeneratedType type, ChoiceCaseNode node) '''
+        {
+        Â«QName.name» resultName = Â«QName.name».create($1,QNAME.getLocalName());
+            java.util.List childNodes = new java.util.ArrayList();
+            Â«type.resolvedName» value = («type.resolvedName») $2;
+            Â«transformDataContainerBody(type.allProperties, node)»
+            return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+        }
+    '''
+
+    private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
+        {
+        Â«QName.name» resultName = Â«QName.name».create($1,QNAME.getLocalName());
+            java.util.List childNodes = new java.util.ArrayList();
+            Â«type.resolvedName» value = («type.resolvedName») $2;
+            return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+        }
+    '''
+
+
     private def transformDataContainerBody(Map<String, MethodSignature> properties, DataNodeContainer node) {
         val ret = '''
             Â«FOR child : node.childNodes.filter[!augmenting]»
-                Â«val signature = properties.get(child.getterName)»
+                Â«var signature = properties.getFor(child)»
                 Â«serializeProperty(child, signature.returnType, signature)»
             Â«ENDFOR»
         '''
         return ret;
     }
+    
+    def MethodSignature getFor(Map<String,MethodSignature> map, DataSchemaNode node) {
+        val sig = map.get(node.getterName);
+        if(sig == null) {
+            return map.get(node.booleanGetterName);
+        }
+        return sig;
+    }
+
+    private static def String getBooleanGetterName(DataSchemaNode node) {
+        return "is" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+    }
 
     private static def String getGetterName(DataSchemaNode node) {
         return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
@@ -711,16 +808,12 @@ class TransformerGenerator {
         MethodSignature property) '''
         Â«property.returnType.resolvedName» Â«property.name» = value.«property.name»();
         if(«property.name» != null) {
-            Object domValue = Â«type.serializer».toDomStatic(QNAME,«property.name»);
+            Object domValue = Â«type.serializer.name».toDomStatic(QNAME,«property.name»);
             childNodes.add(domValue);
         }
     '''
 
-    private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
-        {
-            return ($r) java.util.Collections.singletonMap(this.QNAME,null);
-        }
-    '''
+
 
     private def transformatorFqn(GeneratedType typeSpec) {
         return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
@@ -759,6 +852,19 @@ class TransformerGenerator {
         val cls = loadClassWithTCCL(type.fullyQualifiedName)
         return cls.asCtClass;
     }
+    
+    
+    
+    private def dispatch processException(Class<?> inputType,CodeGenerationException e){
+        log.error("Cannot compile DOM Codec for {}. One of it's prerequisites was not generated.",inputType);
+        throw e;
+    }
+    
+    private def dispatch processException(Class<?> inputType,Exception e){
+        log.error("Cannot compile DOM Codec for {}",inputType,e);
+        val exception = new CodeGenerationException("Cannot compile Transformator for " + inputType,e);
+        throw exception;
+    }
 
 }
 
index e2b79203c94dd6db2bb33026dd2ba804b08857a1..a0e1c98237ed0e963a1a3982874f46bbaca463f9 100644 (file)
@@ -55,8 +55,6 @@ import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
 
 class BindingMapping {
 
-
-
     @Property
     val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
     
index 0b91658a187399758e5e8dac99f884749c0d048e..87f31ac5c435820c5ddb5ec505e3dabbab94eba8 100644 (file)
@@ -34,6 +34,10 @@ public class ClassLoaderUtils {
     
     
     public static Class<?> loadClassWithTCCL(String name) throws ClassNotFoundException {
+        if("byte[]".equals(name)) {
+            return byte[].class;
+        }
+        
         return Thread.currentThread().getContextClassLoader().loadClass(name);
     }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/AbstractDataServiceTest.java
new file mode 100644 (file)
index 0000000..27d985b
--- /dev/null
@@ -0,0 +1,107 @@
+package org.opendaylight.controller.sal.binding.test;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Before;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.controller.sal.binding.test.connect.dom.MappingServiceTest;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.reflections.Reflections;
+import org.reflections.scanners.ResourcesScanner;
+
+import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public  abstract class AbstractDataServiceTest {
+    protected DataBrokerService biDataService;
+    protected DataProviderService baDataService;
+    
+    protected RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
+    protected BindingIndependentMappingService mappingService;
+    protected DataBrokerImpl baDataImpl;
+    protected org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
+    protected ListeningExecutorService executor;
+    protected BindingIndependentDataServiceConnector connectorServiceImpl;
+    protected HashMapDataStore dataStore;
+    
+    
+    @Before
+    public void setUp() {
+        executor = MoreExecutors.sameThreadExecutor();
+        baDataImpl = new DataBrokerImpl();
+        baDataService = baDataImpl;
+        baDataImpl.setExecutor(executor);
+        
+        biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
+        biDataService =  biDataImpl;
+        biDataImpl.setExecutor(executor);
+        
+        dataStore = new HashMapDataStore();
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
+        biDataImpl.registerConfigurationReader(treeRoot, dataStore);
+        biDataImpl.registerOperationalReader(treeRoot, dataStore);
+        biDataImpl.registerCommitHandler(treeRoot, dataStore);
+        
+        mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
+        mappingService = mappingServiceImpl;
+        File pathname = new File("target/gen-classes-debug");
+        //System.out.println("Generated classes are captured in " + pathname.getAbsolutePath());
+        mappingServiceImpl.start();
+        //mappingServiceImpl.getBinding().setClassFileCapturePath(pathname);
+        
+        connectorServiceImpl = new BindingIndependentDataServiceConnector();
+        connectorServiceImpl.setBaDataService(baDataService);
+        connectorServiceImpl.setBiDataService(biDataService);
+        connectorServiceImpl.setMappingService(mappingServiceImpl);
+        connectorServiceImpl.start();
+        
+        String[] yangFiles= getModelFilenames();
+        mappingServiceImpl.onGlobalContextUpdated(getContext(yangFiles));
+    }
+
+
+    protected  String[] getModelFilenames() {
+        return getModelFilenamesImpl();
+    }
+    
+    public static String[] getModelFilenamesImpl() {
+        Predicate<String> predicate = new Predicate<String>() {
+            @Override
+            public boolean apply(String input) {
+                return input.endsWith(".yang");
+            }
+        };
+        Reflections reflection= new Reflections("META-INF.yang", new ResourcesScanner());
+        Set<String> result = reflection.getResources(predicate);
+        return (String[]) result.toArray(new String[result.size()]);
+    }
+    
+    public static SchemaContext getContext(String[] yangFiles) {
+
+        ClassLoader loader = AbstractDataServiceTest.class.getClassLoader();
+
+        List<InputStream> streams = new ArrayList<>();
+        for (String string : yangFiles) {
+            InputStream stream = loader.getResourceAsStream(string);
+            streams.add(stream);
+
+        }
+        YangParserImpl parser = new YangParserImpl();
+
+        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+        return parser.resolveSchemaContext(modules);
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/DOMCodecBug01Test.java
new file mode 100644 (file)
index 0000000..70be175
--- /dev/null
@@ -0,0 +1,144 @@
+package org.opendaylight.controller.sal.binding.test.bugfix;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.collect.ImmutableMap;
+
+import static org.junit.Assert.*;
+
+/**
+ * 
+ * Testcase for https://bugs.opendaylight.org/show_bug.cgi?id=144
+ * 
+ * Cannot compile CoDec for org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow
+ * 
+ * @author ttkacik
+ *
+ */
+public class DOMCodecBug01Test extends AbstractDataServiceTest {
+
+    private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+    private static final QName FLOW_ID_QNAME = QName.create(Flow.QNAME, "id");
+    private static final QName FLOW_NODE_QNAME = QName.create(Flow.QNAME, "node");
+    
+    private static final String FLOW_ID = "foo";
+    private static final String NODE_ID = "node:1";
+
+    private static final NodeKey NODE_KEY = new NodeKey(new NodeId(NODE_ID));
+    private static final InstanceIdentifier<Node> NODE_INSTANCE_ID_BA = InstanceIdentifier.builder().node(Nodes.class)
+            .node(Node.class, NODE_KEY).toInstance();
+    
+    
+    private static final Map<QName, Object> NODE_KEY_BI = Collections.<QName, Object> singletonMap(NODE_ID_QNAME,
+            NODE_ID);
+    
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier NODE_INSTANCE_ID_BI = //
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+                    .node(Nodes.QNAME) //
+                    .nodeWithKey(Node.QNAME, NODE_KEY_BI) //
+                    .toInstance();
+    private static final NodeRef NODE_REF = new NodeRef(NODE_INSTANCE_ID_BA);
+    
+    private static final FlowKey FLOW_KEY = new FlowKey(FLOW_ID, NODE_REF);
+
+    private static final Map<QName, Object> FLOW_KEY_BI = //
+            ImmutableMap.<QName,Object>of(FLOW_ID_QNAME, FLOW_ID, FLOW_NODE_QNAME, NODE_REF);
+
+
+    
+
+    private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier FLOW_INSTANCE_ID_BI = //
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder() //
+                    .node(Flows.QNAME) //
+                    .nodeWithKey(Flow.QNAME, FLOW_KEY_BI) //
+                    .toInstance();
+    private static final InstanceIdentifier<? extends DataObject> FLOW_INSTANCE_ID_BA = //
+            InstanceIdentifier.builder() //
+                .node(Flows.class) //
+                .node(Flow.class, FLOW_KEY) //
+                .toInstance();
+    /**
+     * 
+     * When invoking following code in the consumer, user got an
+     * IllegalStateException during creation of mapping between Java DTOs and
+     * data-dom.
+     * 
+     * Exception was compilation error which was caused by incorect generation
+     * of code.
+     * 
+     * 
+     */
+    @Test
+    public void testIndirectGeneration() throws Exception {
+
+        DataModificationTransaction modification = baDataService.beginTransaction();
+
+       FlowBuilder flow = new FlowBuilder();
+        MatchBuilder match = new MatchBuilder();
+        VlanMatchBuilder vlanBuilder = new VlanMatchBuilder();
+        VlanIdBuilder vlanIdBuilder = new VlanIdBuilder();
+        VlanId vlanId = new VlanId(10);
+        vlanBuilder.setVlanId(vlanIdBuilder.setVlanId(vlanId).build());
+        match.setVlanMatch(vlanBuilder.build());
+
+        flow.setKey(FLOW_KEY);
+        flow.setMatch(match.build());
+        flow.setNode(NODE_REF);
+
+        modification.putConfigurationData(FLOW_INSTANCE_ID_BA, flow.build());
+        RpcResult<TransactionStatus> ret = modification.commit().get();
+        assertNotNull(ret);
+        assertEquals(TransactionStatus.COMMITED, ret.getResult());
+        
+        verifyDataAreStoredProperly();
+        
+        
+        DataModificationTransaction modification2 = baDataService.beginTransaction();
+        modification2.removeConfigurationData(FLOW_INSTANCE_ID_BA);
+        
+        DataObject originalData = modification2.getOriginalConfigurationData().get(FLOW_INSTANCE_ID_BA);
+        assertNotNull(originalData);
+        RpcResult<TransactionStatus> ret2 = modification2.commit().get();
+        
+        assertNotNull(ret2);
+        assertEquals(TransactionStatus.COMMITED, ret2.getResult());
+        
+        
+        // Data are not in the store.
+        assertNull(baDataService.readOperationalData(FLOW_INSTANCE_ID_BA));
+        
+        
+    }
+
+    private void verifyDataAreStoredProperly() {
+        CompositeNode biFlow = biDataService.readConfigurationData(FLOW_INSTANCE_ID_BI);
+        assertNotNull(biFlow);
+        CompositeNode biMatch = biFlow.getFirstCompositeByName(QName.create(Flow.QNAME,Match.QNAME.getLocalName()));
+        assertNotNull(biMatch);
+    }
+}
index 0e35ee650e91041a592d6526a186bb9d4580fab3..7706cda750bd342555da2a95dc5b4e635daf6099 100644 (file)
@@ -4,21 +4,16 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 
-import java.util.concurrent.Executors;
+
 import java.util.concurrent.Future;
 
-import org.junit.Before;
+
 import org.junit.Test;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
-import org.opendaylight.controller.sal.binding.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
-import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -29,139 +24,87 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-public class BrokerIntegrationTest {
-
-    DataBrokerService biDataService;
-    DataProviderService baDataService;
-    private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
-    private BindingIndependentMappingService mappingService;
-    private DataBrokerImpl baDataImpl;
-    private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
-    private ListeningExecutorService executor;
-    private BindingIndependentDataServiceConnector connectorServiceImpl;
-    private HashMapDataStore dataStore;
-    
-    
-    @Before
-    public void setUp() {
-        executor = MoreExecutors.sameThreadExecutor();
-        baDataImpl = new DataBrokerImpl();
-        baDataService = baDataImpl;
-        baDataImpl.setExecutor(executor);
-        
-        biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
-        biDataService =  biDataImpl;
-        biDataImpl.setExecutor(executor);
-        
-        dataStore = new HashMapDataStore();
-        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
-        biDataImpl.registerConfigurationReader(treeRoot, dataStore);
-        biDataImpl.registerOperationalReader(treeRoot, dataStore);
-        biDataImpl.registerCommitHandler(treeRoot, dataStore);
-        
-        mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
-        mappingService = mappingServiceImpl;
-        mappingServiceImpl.start();
-        
-        connectorServiceImpl = new BindingIndependentDataServiceConnector();
-        connectorServiceImpl.setBaDataService(baDataService);
-        connectorServiceImpl.setBiDataService(biDataService);
-        connectorServiceImpl.setMappingService(mappingServiceImpl);
-        connectorServiceImpl.start();
-        
-        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
-        "node-inventory.yang" };
-        
-        mappingServiceImpl.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
-        
-    }
-    
+public class BrokerIntegrationTest extends AbstractDataServiceTest {
+
     @Test
     public void simpleModifyOperation() throws Exception {
-        
-        
+
         NodeRef node1 = createNodeRef("0");
-        DataObject  node = baDataService.readConfigurationData(node1.getValue());
+        DataObject node = baDataService.readConfigurationData(node1.getValue());
         assertNull(node);
         Node nodeData1 = createNode("0");
-        
-        
+
         DataModificationTransaction transaction = baDataService.beginTransaction();
         transaction.putConfigurationData(node1.getValue(), nodeData1);
         Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
         assertNotNull(commitResult);
-        
+
         RpcResult<TransactionStatus> result = commitResult.get();
-        
+
         assertNotNull(result);
         assertNotNull(result.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
-        
+
         Node readedData = (Node) baDataService.readConfigurationData(node1.getValue());
         assertNotNull(readedData);
         assertEquals(nodeData1.getKey(), readedData.getKey());
-        
-        
+
         NodeRef nodeFoo = createNodeRef("foo");
         NodeRef nodeBar = createNodeRef("bar");
         Node nodeFooData = createNode("foo");
         Node nodeBarData = createNode("bar");
-        
-        
+
         DataModificationTransaction insertMoreTr = baDataService.beginTransaction();
         insertMoreTr.putConfigurationData(nodeFoo.getValue(), nodeFooData);
         insertMoreTr.putConfigurationData(nodeBar.getValue(), nodeBarData);
         RpcResult<TransactionStatus> result2 = insertMoreTr.commit().get();
-        
+
         assertNotNull(result2);
         assertNotNull(result2.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
-        
-        Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class).toInstance());
+
+        Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class)
+                .toInstance());
         assertNotNull(allNodes);
         assertNotNull(allNodes.getNode());
         assertEquals(3, allNodes.getNode().size());
-        
-        
+
         /**
          * We create transaction no 2
          * 
          */
         DataModificationTransaction removalTransaction = baDataService.beginTransaction();
         assertNotNull(transaction);
-        
+
         /**
          * We remove node 1
          * 
          */
         removalTransaction.removeConfigurationData(node1.getValue());
-        
+
         /**
          * We commit transaction
          */
         Future<RpcResult<TransactionStatus>> commitResult2 = removalTransaction.commit();
         assertNotNull(commitResult2);
-        
+
         RpcResult<TransactionStatus> result3 = commitResult2.get();
-        
+
         assertNotNull(result3);
         assertNotNull(result3.getResult());
         assertEquals(TransactionStatus.COMMITED, result2.getResult());
-    
+
         DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());
         assertNull(readedData2);
     }
-    
+
     private static NodeRef createNodeRef(String string) {
         NodeKey key = new NodeKey(new NodeId(string));
         InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
                 .toInstance();
         return new NodeRef(path);
     }
-    
+
     private static Node createNode(String string) {
         NodeBuilder ret = new NodeBuilder();
         ret.setId(new NodeId(string));
index b0c2e7529ad1edcfd2e8e18104c6613a0e1a227a..e26273e026cf6d098d6e7efb38ef2dd176c9d1e5 100644 (file)
@@ -17,6 +17,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
@@ -48,10 +49,9 @@ public class MappingServiceTest {
     @Test
     public void baDataToBiData() throws Exception {
 
-        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
-                "node-inventory.yang" };
+        String[] yangFiles = AbstractDataServiceTest.getModelFilenamesImpl();
 
-        SchemaContext ctx = getContext(yangFiles);
+        SchemaContext ctx = AbstractDataServiceTest.getContext(yangFiles);
 
         impl.onGlobalContextUpdated(ctx);
 
@@ -73,9 +73,8 @@ public class MappingServiceTest {
     @Test
     public void instanceIdentifierTest() throws Exception {
 
-        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
-                "node-inventory.yang" };
-        SchemaContext ctx = getContext(yangFiles);
+        String[] yangFiles = AbstractDataServiceTest.getModelFilenamesImpl();
+        SchemaContext ctx = AbstractDataServiceTest.getContext(yangFiles);
         impl.onGlobalContextUpdated(ctx);
 
         NodeKey nodeKey = new NodeKey(new NodeId("foo"));
@@ -85,22 +84,6 @@ public class MappingServiceTest {
         assertEquals(2, result.getPath().size());
     }
 
-    public static SchemaContext getContext(String[] yangFiles) {
-
-        ClassLoader loader = MappingServiceTest.class.getClassLoader();
-
-        List<InputStream> streams = new ArrayList<>();
-        for (String string : yangFiles) {
-            InputStream stream = loader.getResourceAsStream("META-INF/yang/" + string);
-            streams.add(stream);
-
-        }
-        YangParserImpl parser = new YangParserImpl();
-
-        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
-        return parser.resolveSchemaContext(modules);
-    }
-
     private Node createChildNode(String id) {
         NodeBuilder node = new NodeBuilder();
         NodeId nodeId = new NodeId(id);
index 1627243267dd5a774cf54f5456c428ff8f09248c..6fec18033f8feeed2df5dd7f040d2ddf622d63ad 100644 (file)
@@ -18,6 +18,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved;
 import org.opendaylight.yangtools.concepts.Registration;
@@ -205,5 +207,18 @@ public class NoficationTest extends AbstractTest {
             
         }
 
+        @Override
+        public void onNodeErrorNotification(NodeErrorNotification notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        @Override
+        public void onNodeExperimenterErrorNotification(
+                NodeExperimenterErrorNotification notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
     }
 }
index fa00908e4d54c41245332ebc5d6dedc8f78492d9..3115994e01575a57661db4bbc73bc81927e9713d 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.sal.rest.impl;
 
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.net.URI;
 import java.util.Map.Entry;
 import java.util.Set;
 
@@ -48,7 +49,8 @@ class JsonReader {
     }
     
     private CompositeNodeWrapper createStructureWithRoot(String rootObjectName, JsonObject rootObject) {
-        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(rootObjectName);
+        CompositeNodeWrapper firstNode = new CompositeNodeWrapper(getNamespaceFrom(rootObjectName),
+                getLocalNameFrom(rootObjectName));
         for (Entry<String, JsonElement> childOfFirstNode : rootObject.entrySet()) {
             addChildToParent(childOfFirstNode.getKey(), childOfFirstNode.getValue(), firstNode);
         }
@@ -57,7 +59,8 @@ class JsonReader {
     
     private void addChildToParent(String childName, JsonElement childType, CompositeNodeWrapper parent) {
         if (childType.isJsonObject()) {
-            CompositeNodeWrapper child = new CompositeNodeWrapper(childName);
+            CompositeNodeWrapper child = new CompositeNodeWrapper(getNamespaceFrom(childName),
+                    getLocalNameFrom(childName));
             parent.addValue(child);
             for (Entry<String, JsonElement> childOfChild : childType.getAsJsonObject().entrySet()) {
                 addChildToParent(childOfChild.getKey(), childOfChild.getValue(), child);
@@ -71,11 +74,28 @@ class JsonReader {
             String value = childPrimitive.getAsString();
             SimpleNodeWrapper child = null;
             if (value.equals("[null]")) {
-                child = new SimpleNodeWrapper(childName, null);
+                child = new SimpleNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName), null);
             } else {
-                child = new SimpleNodeWrapper(childName, value);
+                child = new SimpleNodeWrapper(getNamespaceFrom(childName), getLocalNameFrom(childName), value);
             }
             parent.addValue(child);
         }
     }
+
+    private URI getNamespaceFrom(String jsonElementName) {
+        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
+        if (indexOfDelimeter == -1) {
+            return null;
+        }
+        return URI.create(jsonElementName.substring(0, indexOfDelimeter));
+    }
+
+    private String getLocalNameFrom(String jsonElementName) {
+        int indexOfDelimeter = jsonElementName.lastIndexOf(':');
+        if (indexOfDelimeter == -1) {
+            return jsonElementName;
+        }
+        return jsonElementName.substring(indexOfDelimeter + 1, jsonElementName.length());
+    }
+
 }
index da07bba187a25e185cab8b72211860e0ffd99437..e000c7e29e21c0a39904088351940d6862e3f42d 100644 (file)
@@ -29,6 +29,11 @@ public final class CompositeNodeWrapper implements NodeWrapper<CompositeNode>, C
     public CompositeNodeWrapper(String localName) {
         this.localName = Preconditions.checkNotNull(localName);
     }
+    
+    public CompositeNodeWrapper(URI namespace, String localName) {
+        this(localName);
+        this.namespace = namespace;
+    }
 
     @Override
     public String getLocalName() {
index 50b6ac77e6ee8b3c885efe87869231736ffce2d2..4600d0890bcc41f30f6f43ff0907c978156352a3 100644 (file)
@@ -24,6 +24,11 @@ public final class SimpleNodeWrapper implements NodeWrapper<SimpleNode<?>>, Simp
         this.value = value;
     }
     
+    public SimpleNodeWrapper(URI namespace, String localName, String value) {
+        this(localName, value);
+        this.namespace = namespace;
+    }
+    
     @Override
     public String getLocalName() {
         if (simpleNode != null) {
index e9552ec890895cf7c082161a323cb210ae77d301..532e29df66dbe5962ab246e56b674710fede7622 100644 (file)
@@ -4,6 +4,8 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 
 import java.io.*;
+import java.net.*;
+import java.sql.Date;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -19,10 +21,9 @@ import javax.xml.transform.stream.StreamResult;
 
 import org.opendaylight.controller.sal.rest.impl.*;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.*;
 import org.opendaylight.yangtools.yang.model.api.*;
 import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
@@ -115,24 +116,17 @@ final class TestUtils {
 
     }
 
-    static String convertXmlDataAndYangToJson(String xmlDataPath, String yangPath, String outputPath) {
+    static String convertCompositeNodeDataAndYangToJson(CompositeNode compositeNode, String yangPath, String outputPath) {
         String jsonResult = null;
         Set<Module> modules = null;
 
         try {
-            modules = TestUtils.loadModules(YangAndXmlToJsonBasicDataTypesTest.class.getResource(yangPath).getPath());
+            modules = TestUtils.loadModules(ToJsonBasicDataTypesTest.class.getResource(yangPath).getPath());
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }
         assertNotNull("modules can't be null.", modules);
 
-        InputStream xmlStream = YangAndXmlToJsonBasicDataTypesTest.class.getResourceAsStream(xmlDataPath);
-        CompositeNode compositeNode = null;
-        try {
-            compositeNode = TestUtils.loadCompositeNode(xmlStream);
-        } catch (FileNotFoundException e) {
-            e.printStackTrace();
-        }
         assertNotNull("Composite node can't be null", compositeNode);
 
         StructuredDataToJsonProvider structuredDataToJsonProvider = StructuredDataToJsonProvider.INSTANCE;
@@ -160,10 +154,21 @@ final class TestUtils {
         return jsonResult;
     }
 
+    static CompositeNode loadCompositeNode(String xmlDataPath) {
+        InputStream xmlStream = ToJsonBasicDataTypesTest.class.getResourceAsStream(xmlDataPath);
+        CompositeNode compositeNode = null;
+        try {
+            compositeNode = TestUtils.loadCompositeNode(xmlStream);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        return compositeNode;
+    }
+
     static void outputToFile(ByteArrayOutputStream outputStream, String outputDir) throws IOException {
         FileOutputStream fileOS = null;
         try {
-            String path = YangAndXmlToJsonBasicDataTypesTest.class.getResource(outputDir).getPath();
+            String path = ToJsonBasicDataTypesTest.class.getResource(outputDir).getPath();
             File outFile = new File(path + "/data.json");
             fileOS = new FileOutputStream(outFile);
             try {
@@ -212,7 +217,7 @@ final class TestUtils {
     }
 
     private static FileReader getFileReader(String path) {
-        String fullPath = YangAndXmlToJsonBasicDataTypesTest.class.getResource(path).getPath();
+        String fullPath = ToJsonBasicDataTypesTest.class.getResource(path).getPath();
         assertNotNull("Path to file can't be null.", fullPath);
         File file = new File(fullPath);
         assertNotNull("File can't be null", file);
@@ -244,4 +249,20 @@ final class TestUtils {
         return strBuilder.toString();
     }
 
+    static QName buildQName(String name, String uri, String date) {
+        try {
+            URI u = new URI(uri);
+            Date dt = null;
+            if (date != null) {
+                dt = Date.valueOf(date);
+            }
+            return new QName(u, dt, name);
+        } catch (URISyntaxException e) {
+            return null;
+        }
+    }
+
+    static QName buildQName(String name) {
+        return buildQName(name, "", null);
+    }
 }
@@ -10,9 +10,10 @@ import java.io.*;
 import java.util.*;
 
 import org.junit.Test;
+
 import com.google.gson.stream.*;
 
-public class YangAndXmlToJsonBasicDataTypesTest {
+public class ToJsonBasicDataTypesTest {
 
     @Test
     public void simpleYangDataTest() {
@@ -21,7 +22,8 @@ public class YangAndXmlToJsonBasicDataTypesTest {
         // TestUtils.readJsonFromFile("/yang-to-json-conversion/simple-yang-types/xml/awaited_output.json",
         // false);
 
-        jsonOutput = TestUtils.convertXmlDataAndYangToJson("/yang-to-json-conversion/simple-data-types/xml/data.xml",
+        jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
+                TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-data-types/xml/data.xml"),
                 "/yang-to-json-conversion/simple-data-types", "/yang-to-json-conversion/simple-data-types/xml");
         verifyJsonOutput(jsonOutput);
     }
@@ -1,35 +1,62 @@
 package org.opendaylight.controller.sal.restconf.impl.test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
 
 import java.io.*;
 import java.util.*;
 
-import javax.validation.constraints.AssertFalse;
-
 import org.junit.Test;
 import org.opendaylight.controller.sal.restconf.impl.test.structures.*;
+import org.opendaylight.yangtools.yang.data.api.*;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
 
-import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.*;
 
-public class YangAndXmlToJsonBasicYangTypesTest {
+public class ToJsonBasicYangTypesTest {
 
+    /**
+     * Test of json output when as input are specified composite node with empty
+     * data + YANG file
+     */
     @Test
-    public void simpleYangTypesWithJsonReaderTest() {
-        String jsonOutput;
-        // jsonOutput =
-        // TestUtils.readJsonFromFile("/yang-to-json-conversion/simple-yang-types/xml/awaited_output.json",
-        // false);
-
-        jsonOutput = TestUtils.convertXmlDataAndYangToJson("/yang-to-json-conversion/simple-yang-types/xml/data.xml",
+    public void compositeNodeAndYangWithJsonReaderEmptyDataTest() {
+        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(prepareCompositeNodeWithEmpties(),
                 "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
+        verifyJsonOutputForEmpty(jsonOutput);
+    }
 
+    /**
+     * Test of json output when as input are specified xml file (no empty
+     * elements)and YANG file
+     */
+    @Test
+    public void xmlAndYangTypesWithJsonReaderTest() {
+        String jsonOutput = TestUtils.convertCompositeNodeDataAndYangToJson(
+                TestUtils.loadCompositeNode("/yang-to-json-conversion/simple-yang-types/xml/data.xml"),
+                "/yang-to-json-conversion/simple-yang-types", "/yang-to-json-conversion/simple-yang-types/xml");
         verifyJsonOutput(jsonOutput);
+    }
+
+    private void verifyJsonOutputForEmpty(String jsonOutput) {
+        StringReader strReader = new StringReader(jsonOutput);
+        JsonReader jReader = new JsonReader(strReader);
 
+        String exception = null;
+        Cont dataFromJson = null;
+        try {
+            dataFromJson = jsonReadCont1(jReader);
+        } catch (IOException e) {
+            exception = e.getMessage();
+        }
+
+        assertNotNull("Data structures from json are missing.", dataFromJson);
+        checkDataFromJsonEmpty(dataFromJson);
+
+        assertNull("Error during reading Json output: " + exception, exception);
     }
 
     private void verifyJsonOutput(String jsonOutput) {
@@ -68,7 +95,7 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf11")) {
-                redData.addLf(new Lf(keyName, jReader.nextString()));
+                redData.addLf(new Lf(keyName, nextValue(jReader)));
             } else if (keyName.equals("lflst11")) {
                 LfLst lfLst = new LfLst(keyName);
                 lfLst = jsonReadLflstValues(jReader, lfLst);
@@ -107,9 +134,9 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf111")) {
-                lstItem.addLf(new Lf(keyName, jReader.nextString()));
+                lstItem.addLf(new Lf(keyName, nextValue(jReader)));
             } else if (keyName.equals("lf112")) {
-                lstItem.addLf(new Lf(keyName, jReader.nextString()));
+                lstItem.addLf(new Lf(keyName, nextValue(jReader)));
             } else if (keyName.equals("cont111")) {
                 Cont cont = new Cont(keyName);
                 cont = jsonReadCont111(jReader, cont);
@@ -146,7 +173,7 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         if (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf1121")) {
-                lstItem.addLf(new Lf(keyName, jReader.nextString()));
+                lstItem.addLf(new Lf(keyName, nextValue(jReader)));
             }
         }
         jReader.endObject();
@@ -170,13 +197,22 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         if (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf1111")) {
-                lstItem.addLf(new Lf(keyName, jReader.nextString()));
+                lstItem.addLf(new Lf(keyName, nextValue(jReader)));
             }
         }
         jReader.endObject();
         return lstItem;
     }
 
+    private String nextValue(JsonReader jReader) throws IOException {
+        if (jReader.peek().equals(JsonToken.NULL)) {
+            jReader.nextNull();
+            return null;
+        } else {
+            return jReader.nextString();
+        }
+    }
+
     private Cont jsonReadCont111(JsonReader jReader, Cont cont) throws IOException {
         jReader.beginObject();
         cont = jsonReadCont111Elements(jReader, cont);
@@ -188,7 +224,7 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf1111")) {
-                cont.addLf(new Lf(keyName, jReader.nextString()));
+                cont.addLf(new Lf(keyName, nextValue(jReader)));
             } else if (keyName.equals("lflst1111")) {
                 LfLst lfLst = new LfLst(keyName);
                 lfLst = jsonReadLflstValues(jReader, lfLst);
@@ -221,7 +257,7 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         while (jReader.hasNext()) {
             String keyName = jReader.nextName();
             if (keyName.equals("lf1111A") || keyName.equals("lf1111B")) {
-                lstItem.addLf(new Lf(keyName, jReader.nextString()));
+                lstItem.addLf(new Lf(keyName, nextValue(jReader)));
             }
         }
         jReader.endObject();
@@ -231,12 +267,94 @@ public class YangAndXmlToJsonBasicYangTypesTest {
     private LfLst jsonReadLflstValues(JsonReader jReader, LfLst lfLst) throws IOException {
         jReader.beginArray();
         while (jReader.hasNext()) {
-            lfLst.addLf(new Lf(jReader.nextString()));
+            lfLst.addLf(new Lf(nextValue(jReader)));
         }
         jReader.endArray();
         return lfLst;
     }
 
+    private void checkDataFromJsonEmpty(Cont dataFromJson) {
+        assertTrue(dataFromJson.getLfs().isEmpty());
+        assertTrue(dataFromJson.getLfLsts().isEmpty());
+        assertTrue(dataFromJson.getConts().isEmpty());
+
+        Map<String, Lst> lsts = dataFromJson.getLsts();
+        assertEquals(1, lsts.size());
+        Lst lst11 = lsts.get("lst11");
+        assertNotNull(lst11);
+        Set<LstItem> lstItems = lst11.getLstItems();
+        assertNotNull(lstItems);
+
+        LstItem lst11_1 = null;
+        LstItem lst11_2 = null;
+        LstItem lst11_3 = null;
+        for (LstItem lstItem : lstItems) {
+            if (lstItem.getLfs().get("lf111").getValue().equals("1")) {
+                lst11_1 = lstItem;
+            } else if (lstItem.getLfs().get("lf111").getValue().equals("2")) {
+                lst11_2 = lstItem;
+            } else if (lstItem.getLfs().get("lf111").getValue().equals("3")) {
+                lst11_3 = lstItem;
+            }
+        }
+
+        assertNotNull(lst11_1);
+        assertNotNull(lst11_2);
+        assertNotNull(lst11_3);
+
+        // lst11_1
+        assertTrue(lst11_1.getLfLsts().isEmpty());
+        assertEquals(1, lst11_1.getLfs().size());
+        assertEquals(1, lst11_1.getConts().size());
+        assertEquals(1, lst11_1.getLsts().size());
+        assertEquals(lst11_1.getLsts().get("lst111"), 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
+
+        // lst11_2
+        assertTrue(lst11_2.getLfLsts().isEmpty());
+        assertEquals(1, lst11_2.getLfs().size());
+        assertEquals(1, lst11_2.getConts().size());
+        assertEquals(1, lst11_2.getLsts().size());
+
+        Cont lst11_2_cont111 = lst11_2.getConts().get("cont111");
+
+        // -cont111
+        assertNotNull(lst11_2_cont111);
+        assertTrue(lst11_2_cont111.getLfs().isEmpty());
+        assertEquals(1, lst11_2_cont111.getLfLsts().size());
+        assertEquals(1, lst11_2_cont111.getLsts().size());
+        assertTrue(lst11_2_cont111.getConts().isEmpty());
+
+        assertEquals(new LfLst("lflst1111").addLf("1024").addLf("4096"), lst11_2_cont111.getLfLsts().get("lflst1111"));
+        assertEquals(
+                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()));
+        // : lst11_2
+
+        // lst11_3
+        assertEquals(1, lst11_3.getLfs().size());
+        assertTrue(lst11_3.getLfLsts().isEmpty());
+        assertTrue(lst11_3.getLsts().isEmpty());
+        assertTrue(lst11_3.getLsts().isEmpty());
+
+        // -cont111
+        Cont lst11_3_cont111 = lst11_3.getConts().get("cont111");
+        assertEquals(0, lst11_3_cont111.getLfs().size());
+        assertEquals(0, lst11_3_cont111.getLfLsts().size());
+        assertEquals(1, lst11_3_cont111.getLsts().size());
+        assertTrue(lst11_3_cont111.getConts().isEmpty());
+
+        assertEquals(new Lst("lst1111").addLstItem(new LstItem()).addLstItem(new LstItem()), lst11_3_cont111.getLsts()
+                .get("lst1111"));
+        // :-cont111
+        // : lst11_3
+
+    }
+
     private void checkDataFromJson(Cont dataFromJson) {
         assertNotNull(dataFromJson.getLfs().get("lf11"));
         assertEquals(dataFromJson.getLfs().get("lf11"), new Lf("lf11", "lf"));
@@ -364,4 +482,142 @@ public class YangAndXmlToJsonBasicYangTypesTest {
         assertNotNull(lst11_1_cont_lst1111_2);
     }
 
+    private CompositeNode prepareCompositeNodeWithEmpties() {
+        MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(
+                TestUtils.buildQName("cont1", "simple:yang:types", "2013-11-5"), null, null, ModifyAction.CREATE, null);
+
+        // lst11_1
+        MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1,
+                null, ModifyAction.CREATE, null);
+        cont1.getChildren().add(lst11_1);
+
+        MutableSimpleNode<?> lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_1, "1",
+                ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(lf111_1);
+
+        // lst111_1_1
+        MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"),
+                lst11_1, null, ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(lst111_1_1);
+        MutableSimpleNode<?> lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
+                lst111_1_1, "34", ModifyAction.CREATE, null);
+        lst111_1_1.getChildren().add(lf1111_1_1);
+        lst111_1_1.init();
+        // :lst111_1_1
+
+        // lst111_1_2
+        MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"),
+                lst11_1, null, ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(lst111_1_2);
+        MutableSimpleNode<?> lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111"),
+                lst111_1_2, "35", ModifyAction.CREATE, null);
+        lst111_1_2.getChildren().add(lf1111_1_2);
+        lst111_1_2.init();
+        // :lst111_1_2
+
+        // lst111_1_3
+        MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"),
+                lst11_1, null, ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(lst111_1_3);
+        lst111_1_2.init();
+        // :lst111_1_3
+
+        // lst111_1_4
+        MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111"),
+                lst11_1, null, ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(lst111_1_4);
+        lst111_1_2.init();
+        // :lst111_1_4
+
+        MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"),
+                lst11_1, null, ModifyAction.CREATE, null);
+        lst11_1.getChildren().add(cont111_1);
+
+        lst11_1.init();
+        // :lst11_1
+
+        // lst11_2
+        MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1,
+                null, ModifyAction.CREATE, null);
+        cont1.getChildren().add(lst11_2);
+
+        MutableSimpleNode<?> lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_2, "2",
+                ModifyAction.CREATE, null);
+        lst11_2.getChildren().add(lf111_2);
+
+        // cont111_2
+        MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"),
+                lst11_2, null, ModifyAction.CREATE, null);
+        lst11_2.getChildren().add(cont111_2);
+
+        MutableSimpleNode<?> lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
+                cont111_2, "1024", ModifyAction.CREATE, null);
+        cont111_2.getChildren().add(lflst1111_2_2);
+        MutableSimpleNode<?> lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111"),
+                cont111_2, "4096", ModifyAction.CREATE, null);
+        cont111_2.getChildren().add(lflst1111_2_3);
+
+        // lst1111_2
+        MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
+                cont111_2, null, ModifyAction.CREATE, null);
+        cont111_2.getChildren().add(lst1111_2_1);
+        MutableSimpleNode<?> lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B"),
+                lst1111_2_1, "4", ModifyAction.CREATE, null);
+        lst1111_2_1.getChildren().add(lf1111B_2_1);
+        lst1111_2_1.init();
+
+        MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
+                cont111_2, null, ModifyAction.CREATE, null);
+        cont111_2.getChildren().add(lst1111_2_2);
+        MutableSimpleNode<?> lf1111B_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A"),
+                lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null);
+        lst1111_2_2.getChildren().add(lf1111B_2_2);
+        lst1111_2_2.init();
+        // :lst1111_2
+
+        cont111_2.init();
+        // :cont111_2
+
+        MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112"), lst11_2,
+                null, ModifyAction.CREATE, null);
+        lst11_2.getChildren().add(lst112_2);
+        lst112_2.init();
+        lst11_2.init();
+
+        // :lst11_2
+
+        // lst11_3
+        MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11"), cont1,
+                null, ModifyAction.CREATE, null);
+        cont1.getChildren().add(lst11_3);
+
+        MutableSimpleNode<?> lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111"), lst11_3, "3",
+                ModifyAction.CREATE, null);
+        lst11_3.getChildren().add(lf111_3);
+
+        // cont111_3
+        MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111"),
+                lst11_3, null, ModifyAction.CREATE, null);
+        lst11_3.getChildren().add(cont111_3);
+
+        MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
+                cont111_3, null, ModifyAction.CREATE, null);
+        cont111_3.getChildren().add(lst1111_3_1);
+        lst1111_3_1.init();
+
+        MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111"),
+                cont111_3, null, ModifyAction.CREATE, null);
+        cont111_3.getChildren().add(lst1111_3_2);
+        lst1111_3_2.init();
+
+        cont111_3.init();
+        // :cont111_3
+
+        lst11_3.init();
+        // :lst11_3
+
+        cont1.init();
+        return cont1;
+    }
+
 }
index 0b8b5d48de1d6fe40bafaa5e82b61e854162fed6..9d004362d29d0b64b9a8636f51430ccfa46d8ca3 100644 (file)
@@ -24,6 +24,7 @@ import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
 
+import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
@@ -151,6 +152,21 @@ public class XmlProvidersTest extends JerseyTest {
                 Entity.entity("<SimpleNode>", new MediaType("application", "vnd.yang.api+xml")));
         assertEquals(400, response.getStatus());
     }
+    
+    @Test
+    public void testXmlToCompositeNode404NotFound() {
+        URI uri = null;
+        try {
+            uri = new URI("/datastore/" + URLEncoder.encode("ietf-interfaces:interfaces/interface/eth0", Charsets.US_ASCII.name()).toString());
+        } catch (UnsupportedEncodingException | URISyntaxException e) {
+            e.printStackTrace();
+        }
+        
+        when(brokerFacade.readOperationalData(any(InstanceIdentifier.class))).thenReturn(null);
+        
+        Response response = target(uri.toASCIIString()).request(MediaTypes.API+RestconfService.XML).get();
+        assertEquals(404, response.getStatus());
+    }
 
     @Override
     protected Application configure() {
index a1028ca0327ab58773f91c5c8de0c1b279f1ba60..00783537d8aff029b55ac1c0d9e6f25ec1f941b6 100644 (file)
@@ -24,7 +24,11 @@ public class Cont extends LstItem {
             return false;
         }
         Cont cont = (Cont) obj;
-        if (!this.name.equals(cont.name)) {
+        if (this.name == null) {
+            if (cont.name != null) {
+                return false;
+            }
+        } else if (!this.name.equals(cont.name)) {
             return false;
         }
         return true;
index 66cf1cc6101807b8a6f86aae7dacbb4541353dad..a1e06c3cabfa1d1cbeb207c676da1583cb4643d2 100644 (file)
@@ -2,6 +2,8 @@ package org.opendaylight.controller.sal.restconf.impl.test.structures;
 
 public class Lf extends YangElement {
     private String value;
+    private int numOfEqualItems = 0;
+
 
     public Lf(String name, String value) {
         super(name);
@@ -29,17 +31,30 @@ public class Lf extends YangElement {
             return false;
         }
         Lf lf = (Lf) obj;
-        if (!this.value.equals(lf.value)) {
+        if (this.value == null) {
+            if (lf.value != null) {
+                return false;
+            }
+        } else if (!this.value.equals(lf.value)) {
+            return false;
+        }
+        if (this.numOfEqualItems != lf.numOfEqualItems) {
             return false;
         }
         return true;
     }
+    
+    public void incNumOfEqualItems() {
+        this.numOfEqualItems++;
+    }
+    
 
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
         result = prime * result + ((value == null) ? 0 : value.hashCode());
+        result = prime * result + numOfEqualItems;
         return result;
     }
 
index 7688f2ed22bdf3817785cc368d6bd1cf0f0b7a44..87fed95f6ff15b4a2a3800a0adaa25c1aaf62ba0 100644 (file)
@@ -10,8 +10,16 @@ public class LfLst extends YangElement {
         lfs = new HashSet<>();
     }
 
+    public LfLst addLf(String value) {
+        return addLf(new Lf(value));
+    }
+
+    
     public LfLst addLf(Lf lf) {
-        lfs.add(lf);
+        while (this.lfs.contains(lf)) {
+            lf.incNumOfEqualItems();
+        }
+        this.lfs.add(lf);
         return this;
     }
 
@@ -31,7 +39,11 @@ public class LfLst extends YangElement {
             return false;
         }
         LfLst lfLst = (LfLst) obj;
-        if (!this.lfs.equals(lfLst.lfs)) {
+        if (this.lfs == null) {
+            if (lfLst.lfs != null) {
+                return false;
+            }
+        } else if (!this.lfs.equals(lfLst.lfs)) {
             return false;
         }
         return true;
index f5b3a5446e8f504c29f05989d9992cb2c7c448d1..56928e81e9d8ebdd15ec2442b576f0e1c0f7af3f 100644 (file)
@@ -10,9 +10,13 @@ public class Lst extends YangElement {
         lstItems = new HashSet<>();
     }
 
-    public void addLstItem(LstItem lstItem) {
+    public Lst addLstItem(LstItem lstItem) {
         lstItem.setLstName(name);
+        while (this.lstItems.contains(lstItem)) {
+            lstItem.incNumOfEqualItems();
+        }
         this.lstItems.add(lstItem);
+        return this;
     }
 
     public Set<LstItem> getLstItems() {
@@ -31,7 +35,11 @@ public class Lst extends YangElement {
             return false;
         }
         Lst lst = (Lst) obj;
-        if (!this.lstItems.equals(lst.lstItems)) {
+        if (this.lstItems == null) {
+            if (lst.lstItems != null) {
+                return false;
+            }
+        } else if (!this.lstItems.equals(lst.lstItems)) {
             return false;
         }
         return true;
index 22b1a3adf681a0efd2e38c212024f01255c1b230..9eb58b5344186690484658ffa489fc376df811cd 100644 (file)
@@ -8,6 +8,7 @@ public class LstItem {
     Map<String, LfLst> lfLsts;
     Map<String, Lst> lsts;
     Map<String, Cont> conts;
+    private int numOfEqualItems = 0;
 
     public LstItem() {
         lfs = new HashMap<>();
@@ -41,6 +42,11 @@ public class LstItem {
         return this;
     }
 
+    public LstItem addLf(String name, String value) {
+        lfs.put(name, new Lf(name, value));
+        return this;
+    }
+
     public void addLfLst(LfLst lfLst) {
         lfLsts.put(lfLst.getName(), lfLst);
     }
@@ -53,6 +59,10 @@ public class LstItem {
         conts.put(cont.getName(), cont);
     }
 
+    public void incNumOfEqualItems() {
+        this.numOfEqualItems++;
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -62,16 +72,35 @@ public class LstItem {
             return false;
         }
         LstItem lstItem = (LstItem) obj;
-        if (!this.conts.equals(lstItem.conts)) {
+        if (this.conts == null) {
+            if (lstItem.conts != null) {
+                return false;
+            }
+        } else if (!this.conts.equals(lstItem.conts)) {
+            return false;
+        }
+        if (this.lfs == null) {
+            if (lstItem.lfs != null) {
+                return false;
+            }
+        } else if (!this.lfs.equals(lstItem.lfs)) {
             return false;
         }
-        if (!this.lfs.equals(lstItem.lfs)) {
+        if (this.lfLsts == null) {
+            if (lstItem.lfLsts != null) {
+                return false;
+            }
+        } else if (!this.lfLsts.equals(lstItem.lfLsts)) {
             return false;
         }
-        if (!this.lfLsts.equals(lstItem.lfLsts)) {
+        if (this.lsts == null) {
+            if (lstItem.lsts != null) {
+                return false;
+            }
+        } else if (!this.lsts.equals(lstItem.lsts)) {
             return false;
         }
-        if (!this.lsts.equals(lstItem.lsts)) {
+        if (this.numOfEqualItems != lstItem.numOfEqualItems) {
             return false;
         }
         return true;
@@ -85,6 +114,7 @@ public class LstItem {
         result = prime * result + ((lfLsts == null) ? 0 : lfLsts.hashCode());
         result = prime * result + ((lsts == null) ? 0 : lsts.hashCode());
         result = prime * result + ((conts == null) ? 0 : conts.hashCode());
+        result = prime * result + numOfEqualItems;
         return result;
     }
 
index d10eb342c28e9be2998bb292fd024a592a6fce92..ed234582b8947b6400614b5d854323bc37049993 100644 (file)
@@ -6,7 +6,7 @@ public class YangElement {
     protected YangElement(String name) {
         this.name = name;
     }
-    
+
     public String getName() {
         return name;
     }
@@ -20,7 +20,11 @@ public class YangElement {
             return false;
         }
         YangElement yangElement = (YangElement) obj;
-        if (!this.name.equals(yangElement.name)) {
+        if (this.name == null) {
+            if (yangElement.name != null) {
+                return false;
+            }
+        } else if (!this.name.equals(yangElement.name)) {
             return false;
         }
         return true;
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_empty_data.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/awaited_output_empty_data.json
new file mode 100644 (file)
index 0000000..4b19988
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "cont1": {
+        "lst11": [
+            {
+                "lf111": 1,
+                "lst111": [
+                    {
+                        "lf1111": 34
+                    },
+                    {
+                        "lf1111": 35
+                    },
+                    {},
+                    {}
+                ],
+                "cont111": {}
+            },
+            {
+                "lf111": 2,
+                "cont111": {
+                    "lflst1111": [
+                        1024,
+                        4096
+                    ],
+                    "lst1111": [
+                        {
+                            "lf1111B": 4
+                        },
+                        {
+                            "lf1111A": "lf1111A str12"
+                        }
+                    ]
+                },
+                "lst112": [
+                    {}
+                ]
+            },
+            {
+                "lf111": 3,
+                "cont111": {
+                    "lst1111": [
+                        {},
+                        {}
+                    ]
+                }
+            }
+        ]
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/empty_data.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/yang-to-json-conversion/simple-yang-types/xml/empty_data.xml
new file mode 100644 (file)
index 0000000..68470ea
--- /dev/null
@@ -0,0 +1,40 @@
+<cont1>
+       <lst11>
+               <lf111>1</lf111>
+               <lst111></lst111>       
+               <lst111></lst111>       
+               <lst111>
+                       <lf1111></lf1111>
+               </lst111>       
+               <lst111>
+                       <lf1111>35</lf1111>
+               </lst111>       
+               <cont111></cont111>             
+       </lst11>
+       <lst11>
+               <lf111>2</lf111>
+               <cont111>
+                       <lf1111></lf1111>
+                       <lflst1111></lflst1111>
+                       <lflst1111>1024</lflst1111>
+                       <lflst1111>4096</lflst1111>
+                       <lst1111>
+                               <lf1111B>4</lf1111B>
+                       </lst1111>
+                       <lst1111>
+                               <lf1111A>lf1111A str12</lf1111A>
+                       </lst1111>
+               </cont111>
+               <lst112></lst112>
+       </lst11>
+       <lst11>
+               <lf111>3</lf111>
+               <cont111>
+                       <lf1111></lf1111>
+                       <lflst1111></lflst1111>
+                       <lflst1111></lflst1111>
+                       <lst1111></lst1111>
+                       <lst1111></lst1111>
+               </cont111>
+       </lst11>
+</cont1>
index 72e49be4de49899f111aeb55ffe65426b0eb3d1e..78599087685f9ffcb5b7566c7b0da067e065ab0b 100644 (file)
@@ -20,7 +20,6 @@
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
-        <version>${bundle.plugin.version}</version>
         <extensions>true</extensions>
         <configuration>
           <instructions>
index 3a355d2e4aff4127db68ccf603f642485a66b268..b85fc681c06724b93ec94be6933f85783e37c86e 100644 (file)
                     </instructions>
                 </configuration>
             </plugin>
-            <plugin>
-                <groupId>org.eclipse.xtend</groupId>
-                <artifactId>xtend-maven-plugin</artifactId>
-            </plugin>
             <plugin>
                 <artifactId>maven-clean-plugin</artifactId>
             </plugin>
diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatistics.java
new file mode 100644 (file)
index 0000000..0cc7beb
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse 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.statistics.manager;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.nodes.node.GroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+
+public class NodeStatistics {
+
+    private NodeRef targetNode;
+    
+    private List<GroupStats> groupStatistics;
+    
+    private List<MeterStats> meterStatistics;
+    
+    private List<GroupDescStats> groupDescStats;
+    
+    private List<MeterConfigStats> meterConfigStats;
+    
+    private GroupFeatures groupFeatures;
+    
+    private MeterFeatures meterFeatures;
+    
+    public NodeStatistics(){
+        
+    }
+
+    public NodeRef getTargetNode() {
+        return targetNode;
+    }
+
+    public void setTargetNode(NodeRef targetNode) {
+        this.targetNode = targetNode;
+    }
+
+    public List<GroupStats> getGroupStatistics() {
+        return groupStatistics;
+    }
+
+    public void setGroupStatistics(List<GroupStats> groupStatistics) {
+        this.groupStatistics = groupStatistics;
+    }
+
+    public List<MeterStats> getMeterStatistics() {
+        return meterStatistics;
+    }
+
+    public void setMeterStatistics(List<MeterStats> meterStatistics) {
+        this.meterStatistics = meterStatistics;
+    }
+
+    public List<GroupDescStats> getGroupDescStats() {
+        return groupDescStats;
+    }
+
+    public void setGroupDescStats(List<GroupDescStats> groupDescStats) {
+        this.groupDescStats = groupDescStats;
+    }
+
+    public List<MeterConfigStats> getMeterConfigStats() {
+        return meterConfigStats;
+    }
+
+    public void setMeterConfigStats(List<MeterConfigStats> meterConfigStats) {
+        this.meterConfigStats = meterConfigStats;
+    }
+
+    public GroupFeatures getGroupFeatures() {
+        return groupFeatures;
+    }
+
+    public void setGroupFeatures(GroupFeatures groupFeatures) {
+        this.groupFeatures = groupFeatures;
+    }
+
+    public MeterFeatures getMeterFeatures() {
+        return meterFeatures;
+    }
+
+    public void setMeterFeatures(MeterFeatures meterFeatures) {
+        this.meterFeatures = meterFeatures;
+    }
+    
+}
index 3c5c57994c7fb95ec02300735a98cf7db482e8c3..7cbd2314b60265e04626ba4d2409a4f2912be559 100644 (file)
@@ -1,3 +1,16 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/*
+ * TODO: Handle multipart messages with following flag true 
+ * OFPMPF_REPLY_MORE = 1 << 0
+ * Better accumulate all the messages and update local cache 
+ * and configurational data store
+ */
 package org.opendaylight.controller.md.statistics.manager;
 
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
index 073d43ef60df3d944dda0da6512326267be114e5..5218d051fa2cdb40ec9fa47f58114abf5c334dc6 100644 (file)
@@ -1,13 +1,42 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse 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.statistics.manager;
 
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Future;
+
 import org.eclipse.xtext.xbase.lib.Exceptions;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsService;
 import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -23,6 +52,15 @@ public class StatisticsProvider implements AutoCloseable {
     
     private OpendaylightMeterStatisticsService meterStatsService;
     
+    private Thread statisticsRequesterThread;
+    
+    private final  InstanceIdentifier<Nodes> nodesIdentifier = InstanceIdentifier.builder().node(Nodes.class).toInstance();
+    
+    //Local caching of stats
+    
+    private final ConcurrentMap<NodeId,NodeStatistics> statisticsCache = 
+            new ConcurrentHashMap<NodeId,NodeStatistics>();
+    
     public DataProviderService getDataService() {
       return this.dps;
     }
@@ -50,10 +88,29 @@ public class StatisticsProvider implements AutoCloseable {
         this.listenerRegistration = registerNotificationListener;
         
         // Get Group/Meter statistics service instance
-        groupStatsService = StatisticsManagerActivator.getProviderContext().getRpcService(OpendaylightGroupStatisticsService.class);
+        groupStatsService = StatisticsManagerActivator.getProviderContext().
+                getRpcService(OpendaylightGroupStatisticsService.class);
         
-        meterStatsService = StatisticsManagerActivator.getProviderContext().getRpcService(OpendaylightMeterStatisticsService.class);
+        meterStatsService = StatisticsManagerActivator.getProviderContext().
+                getRpcService(OpendaylightMeterStatisticsService.class);
+
+        statisticsRequesterThread = new Thread( new Runnable(){
 
+            @Override
+            public void run() {
+                while(true){
+                    try {
+                        spLogger.info("Statistics requester thread started with timer interval : {}",5000);
+                        
+                        statsRequestSender();
+                        
+                        Thread.sleep(5000);
+                    }catch (Exception e){
+                        spLogger.error("Exception occurred while sending stats request : {}",e);
+                    }
+                }
+            }
+        });
         spLogger.info("Statistics Provider started.");
     }
     
@@ -63,6 +120,103 @@ public class StatisticsProvider implements AutoCloseable {
         return dps.beginTransaction();
     }
     
+    private void statsRequestSender(){
+        
+        //Need to call API to receive all the nodes connected to controller.
+        List<Node> targetNodes = getAllConnectedNodes();
+
+        for (Node targetNode : targetNodes){
+            spLogger.info("Send request for stats collection to node : {})",targetNode.getId());
+            
+            //We need to add check, so see if groups/meters are supported
+            //by the target node. Below check doesn't look good.
+            if(targetNode.getId().getValue().contains("openflow:")){
+                sendAllGroupStatisticsRequest(targetNode);
+                
+                sendAllMeterStatisticsRequest(targetNode);
+                
+                sendGroupDescriptionRequest(targetNode);
+                
+                sendGroupFeaturesRequest(targetNode);
+                
+                sendMeterConfigStatisticsRequest(targetNode);
+                
+                sendMeterFeaturesRequest(targetNode);
+            }
+        }
+    }
+    
+    private void sendAllGroupStatisticsRequest(Node targetNode){
+        
+        final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
+        
+        input.setId(targetNode.getId());
+
+        Future<RpcResult<GetAllGroupStatisticsOutput>> response = 
+                groupStatsService.getAllGroupStatistics(input.build());
+    }
+    
+    private void sendGroupDescriptionRequest(Node targetNode){
+        final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+        
+        input.setId(targetNode.getId());
+        
+        Future<RpcResult<GetGroupDescriptionOutput>> response = 
+                groupStatsService.getGroupDescription(input.build());
+    }
+    
+    private void sendGroupFeaturesRequest(Node targetNode){
+        
+        GetGroupFeaturesInputBuilder input = new GetGroupFeaturesInputBuilder();
+        
+        input.setId(targetNode.getId());
+        
+        Future<RpcResult<GetGroupFeaturesOutput>> response = 
+                groupStatsService.getGroupFeatures(input.build());
+    }
+    
+    private void sendAllMeterStatisticsRequest(Node targetNode){
+        
+        GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+        
+        input.setId(targetNode.getId());
+        
+        Future<RpcResult<GetAllMeterStatisticsOutput>> response = 
+                meterStatsService.getAllMeterStatistics(input.build());
+    }
+    
+    private void sendMeterConfigStatisticsRequest(Node targetNode){
+        
+        GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+        
+        input.setId(targetNode.getId());
+        
+        Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response = 
+                meterStatsService.getAllMeterConfigStatistics(input.build());
+        
+    }
+    private void sendMeterFeaturesRequest(Node targetNode){
+     
+        GetMeterFeaturesInputBuilder input = new GetMeterFeaturesInputBuilder();
+        
+        input.setId(targetNode.getId());
+        
+        Future<RpcResult<GetMeterFeaturesOutput>> response = 
+                meterStatsService.getMeterFeatures(input.build());
+    }
+    
+    public ConcurrentMap<NodeId, NodeStatistics> getStatisticsCache() {
+        return statisticsCache;
+    }
+    
+    private List<Node> getAllConnectedNodes(){
+        
+        Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier);
+        spLogger.info("Number of connected nodes : {}",nodes.getNode().size());
+        return nodes.getNode();
+    }
+
+    @SuppressWarnings("deprecation")
     @Override
     public void close(){
         
@@ -71,6 +225,8 @@ public class StatisticsProvider implements AutoCloseable {
             if (this.listenerRegistration != null) {
               
                 this.listenerRegistration.close();
+                
+                this.statisticsRequesterThread.destroy();
             
             }
           } catch (Throwable e) {
index f952124c91e88488ad60134e67e37ad0b12e6e13..c207db0478c9696ae68c28b00566b42085e4244b 100644 (file)
@@ -1,13 +1,49 @@
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse 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.statistics.manager;
 
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.nodes.node.GroupDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.nodes.node.GroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.nodes.node.GroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdated;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterConfigStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterStatisticsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
 
 public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsListener,
         OpendaylightMeterStatisticsListener {
@@ -18,40 +54,210 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
 
         this.statisticsManager = manager;
     }
+    
     public StatisticsProvider getStatisticsManager(){
         return statisticsManager;
     }
+   
     @Override
     public void onMeterConfigStatsUpdated(MeterConfigStatsUpdated notification) {
-        // TODO Auto-generated method stub
+
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        cache.get(notification.getId()).setMeterConfigStats(notification.getMeterConfigStats());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
+        
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
+        
+        NodeMeterConfigStatsBuilder meterConfig= new NodeMeterConfigStatsBuilder();
+        MeterConfigStatsBuilder stats = new MeterConfigStatsBuilder();
+        stats.setMeterConfigStats(notification.getMeterConfigStats());
+        meterConfig.setMeterConfigStats(stats.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeMeterConfigStats.class, meterConfig.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
+
     }
 
     @Override
     public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        cache.get(notification.getId()).setMeterStatistics(notification.getMeterStats());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
+        
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
+        
+        NodeMeterStatisticsBuilder meterStats= new NodeMeterStatisticsBuilder();
+        MeterStatisticsBuilder stats = new MeterStatisticsBuilder();
+        stats.setMeterStats(notification.getMeterStats());
+        meterStats.setMeterStatistics(stats.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeMeterStatistics.class, meterStats.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
 
     }
 
     @Override
     public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        cache.get(notification.getId()).setGroupDescStats(notification.getGroupDescStats());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
+        
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
+        
+        NodeGroupDescStatsBuilder groupDesc= new NodeGroupDescStatsBuilder();
+        GroupDescBuilder stats = new GroupDescBuilder();
+        stats.setGroupDescStats(notification.getGroupDescStats());
+        groupDesc.setGroupDesc(stats.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeGroupDescStats.class, groupDesc.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
 
     }
 
     @Override
     public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
-
+        
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        cache.get(notification.getId()).setGroupStatistics(notification.getGroupStats());
+        
+        //Publish data to configuration data store
+        
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
+        
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
+        
+        NodeGroupStatisticsBuilder groupStats = new NodeGroupStatisticsBuilder();
+        GroupStatisticsBuilder stats = new GroupStatisticsBuilder();
+        stats.setGroupStats(notification.getGroupStats());
+        groupStats.setGroupStatistics(stats.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeGroupStatistics.class, groupStats.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
     }
+    
     @Override
     public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
-        // TODO Auto-generated method stub
+
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
+        meterFeature.setBandTypes(notification.getBandTypes());
+        meterFeature.setCapabilities(notification.getCapabilities());
+        meterFeature.setMaxBands(notification.getMaxBands());
+        meterFeature.setMaxColor(notification.getMaxColor());
+        meterFeature.setMaxMeter(notification.getMaxMeter());
+        
+        cache.get(notification.getId()).setMeterFeatures(meterFeature.build());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
+        
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
         
+        NodeMeterFeaturesBuilder nodeMeterFeatures= new NodeMeterFeaturesBuilder();
+        nodeMeterFeatures.setMeterFeatures(meterFeature.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeMeterFeatures.class, nodeMeterFeatures.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
     }
+    
     @Override
     public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getId())){
+            cache.put(notification.getId(), new NodeStatistics());
+        }
+        
+        GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
+        groupFeatures.setActions(notification.getActions());
+        groupFeatures.setCapabilities(notification.getCapabilities());
+        groupFeatures.setGroupType(notification.getGroupType());
+        groupFeatures.setMaxGroups(notification.getMaxGroups());
+        cache.get(notification.getId()).setGroupFeatures(groupFeatures.build());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        NodeKey key = new NodeKey(notification.getId());
+        NodeRef ref = getNodeRef(key);
         
+        final NodeBuilder nodeData = new NodeBuilder(); 
+        nodeData.setKey(key);
+        
+        NodeGroupFeaturesBuilder nodeGroupFeatures= new NodeGroupFeaturesBuilder();
+        nodeGroupFeatures.setGroupFeatures(groupFeatures.build());
+        
+        //Update augmented data
+        nodeData.addAugmentation(NodeGroupFeatures.class, nodeGroupFeatures.build());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, nodeData.build());
+        it.commit();
+    }
+
+    private NodeRef getNodeRef(NodeKey nodeKey){
+        InstanceIdentifierBuilder<?> builder = InstanceIdentifier.builder().node(Nodes.class);
+        return new NodeRef(builder.node(Node.class,nodeKey).toInstance());
     }
 
 }
index ce0036f9afa6024d18282e5e2cfe559b2744cd4a..5055c935838e974125529d814334d1b616057b66 100644 (file)
@@ -72,13 +72,12 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
     private static Set<Capability> setupCapabilities(YangStoreSnapshot yangStoreSnapshot) {
         Set<Capability> capabilities = Sets.newHashSet();
 
+        // [RFC6241] 8.3.  Candidate Configuration Capability
         capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
+        // [RFC6241] 8.5.  Rollback-on-Error Capability
         capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
-        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:operations:1.0"));
-        capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:operations:1.1"));
-        capabilities
-                .add(new BasicCapability(
-                        "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04"));
+        // [RFC6022] get-schema RPC. TODO: implement rest of the RFC
+        capabilities.add(new BasicCapability("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04"));
 
         final Collection<Map.Entry<Module, String>> modulesAndContents = yangStoreSnapshot.getModuleMap().values();
         for (Map.Entry<Module, String> moduleAndContent : modulesAndContents) {
index b6fd29696fee57a74e72bbbba1674a0b6b59a951..78da7bdcc0ad2fd7653dbb5dc7859634dc00685c 100644 (file)
@@ -40,9 +40,9 @@
         <version>1.5</version>
         <executions>
           <execution>
-            <phase>install</phase>
+            <phase>package</phase>
             <goals>
-                <goal>run</goal>
+              <goal>run</goal>
             </goals>
           </execution>
         </executions>
             <!-- generate index.html -->
             <!-- append header -->
             <echo file="${docs.output.dir}/index.html" append="true">
-&lt;![CDATA[
-&lt;html&gt;
-  &lt;head&gt;
-    &lt;title&gt; OpenDaylight REST API Documentation &lt;/title&gt;
-  &lt;/head&gt;
-  &lt;body&gt;
-  &lt;h2&gt;OpenDaylight REST API Documentation&lt;/h2&gt;
-  &lt;p&gt; OpenDaylight supports the following &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Representational State Transfer (REST)&lt;/a&gt; APIs: &lt;/p&gt;
-  &lt;h4&gt;
-]]&gt;
+              &lt;![CDATA[
+              &lt;html&gt;
+              &lt;head&gt;
+              &lt;title&gt; OpenDaylight REST API Documentation &lt;/title&gt;
+              &lt;/head&gt;
+              &lt;body&gt;
+              &lt;h2&gt;OpenDaylight REST API Documentation&lt;/h2&gt;
+              &lt;p&gt; OpenDaylight supports the following &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Representational State Transfer (REST)&lt;/a&gt; APIs: &lt;/p&gt;
+              &lt;h4&gt;
+              ]]&gt;
             </echo>
             <dirset id="nbset" dir="${docs.output.dir}">
               <include name="*"/>
 
             <!-- append footer -->
             <echo file="${docs.output.dir}/index.html" append="true">
-&lt;![CDATA[
-  &lt;/h4&gt;
-  &lt;i&gt;---&lt;/i&gt;
-  &lt;/body&gt;
-&lt;/html&gt;
-]]&gt;
+              &lt;![CDATA[
+              &lt;/h4&gt;
+              &lt;i&gt;---&lt;/i&gt;
+              &lt;/body&gt;
+              &lt;/html&gt;
+              ]]&gt;
             </echo>
             <!-- archive all the docs excluding whatever is not needed -->
             <echo message="======== Archiving enunciate docs ========"/>
       </plugin>
 
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-install-plugin</artifactId>
-        <version>2.5</version>
-        <configuration>
-          <packaging>jar</packaging>
-          <groupId>${project.groupId}</groupId>
-          <version>${project.version}</version>
-        </configuration>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.8</version>
         <executions>
           <execution>
-            <!-- skip default install -->
-            <id>default-install</id>
-            <phase>install</phase>
-            <goals>
-              <goal>install</goal>
-            </goals>
-            <configuration>
-              <skip>true</skip>
-            </configuration>
-          </execution>
-          <execution>
-            <!-- install full java client -->
-            <id>install-full-client</id>
-            <phase>install</phase>
-            <goals>
-              <goal>install-file</goal>
-            </goals>
-            <configuration>
-              <artifactId>${project.artifactId}.full-client</artifactId>
-              <file>${java-client}</file>
-              <sources>${java-client-sources}</sources>
-            </configuration>
-          </execution>
-          <execution>
-            <!-- install full java json client -->
-            <id>install-full-json-client</id>
-            <phase>install</phase>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
             <goals>
-              <goal>install-file</goal>
+              <goal>attach-artifact</goal>
             </goals>
             <configuration>
-              <artifactId>${project.artifactId}.full-json-client</artifactId>
-              <file>${json-client}</file>
-              <sources>${json-client-sources}</sources>
+              <artifacts>
+                <artifact>
+                  <file>${java-client}</file>
+                  <type>jar</type>
+                  <classifier>full-java-client</classifier>
+                </artifact>
+                <artifact>
+                  <file>${java-client-sources}</file>
+                  <type>jar</type>
+                  <classifier>full-java-client-sources</classifier>
+                </artifact>
+                <artifact>
+                  <file>${json-client}</file>
+                  <type>jar</type>
+                  <classifier>full-json-client</classifier>
+                </artifact>
+                <artifact>
+                  <file>${json-client-sources}</file>
+                  <type>jar</type>
+                  <classifier>full-json-client-sources</classifier>
+                </artifact>
+              </artifacts>
             </configuration>
           </execution>
         </executions>
       </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-deploy-plugin</artifactId>
-        <version>2.5</version>
-        <configuration>
-          <packaging>jar</packaging>
-          <generatePom>true</generatePom>
-          <groupId>${project.groupId}</groupId>
-          <version>${project.version}</version>
-          <url>${project.distributionManagement.repository.url}</url>
-        </configuration>
-        <executions>
-          <execution>
-            <!-- skip default deploy -->
-            <id>default-deploy</id>
-            <phase>deploy</phase>
-            <goals>
-              <goal>deploy</goal>
-            </goals>
-            <configuration>
-              <skip>true</skip>
-            </configuration>
-          </execution>
-          <execution>
-            <!-- deploy full java client -->
-            <id>deploy-full-client</id>
-            <phase>deploy</phase>
-            <goals>
-              <goal>deploy-file</goal>
-            </goals>
-            <configuration>
-              <artifactId>${project.artifactId}.full-client</artifactId>
-              <file>${java-client}</file>
-              <sources>${java-client-sources}</sources>
-            </configuration>
-          </execution>
-          <execution>
-            <!-- deploy full java json client -->
-            <id>deploy-full-json-client</id>
-            <phase>deploy</phase>
-            <goals>
-              <goal>deploy-file</goal>
-            </goals>
-            <configuration>
-              <artifactId>${project.artifactId}.full-json-client</artifactId>
-              <file>${json-client}</file>
-              <sources>${json-client-sources}</sources>
-            </configuration>
-          </execution>
-       </executions>
-    </plugin>
-
     </plugins>
   </build>
   <dependencies>
index a410f99ba9c8d619a3c2771be95f09f410b270a3..bb650132c69546c3a963435658a52f0ff651c92b 100644 (file)
@@ -49,6 +49,7 @@ import org.opendaylight.controller.sal.topology.ITopologyService;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.IObjectReader;
+import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.ObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectWriter;
 import org.opendaylight.controller.sal.utils.Status;
@@ -383,6 +384,56 @@ public class TopologyManagerImpl implements
                 || e.getTailNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION));
     }
 
+    /**
+     * This method cross checks the determination of nodeConnector type by Discovery Service
+     * against the information in SwitchManager and updates it accordingly.
+     * @param e
+     *          The edge
+     */
+    private void crossCheckNodeConnectors(Edge e) {
+        NodeConnector nc;
+        if (e.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
+            nc = updateNCTypeFromSwitchMgr(e.getHeadNodeConnector());
+            if (nc != null) {
+                e.setHeadNodeConnector(nc);
+            }
+        }
+        if (e.getTailNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.PRODUCTION)) {
+            nc = updateNCTypeFromSwitchMgr(e.getTailNodeConnector());
+            if (nc != null) {
+                e.setTailNodeConnector(nc);
+            }
+        }
+    }
+
+    /**
+     * A NodeConnector may have been categorized as of type Production by Discovery Service.
+     * But at the time when this determination was made, only OF nodes were known to Discovery
+     * Service. This method checks if the node of nodeConnector is known to SwitchManager. If
+     * so, then it returns a new NodeConnector with correct type.
+     *
+     * @param nc
+     *       NodeConnector as passed on in the edge
+     * @return
+     *       If Node of the NodeConnector is in SwitchManager, then return a new NodeConnector
+     *       with correct type, null otherwise
+     */
+
+    private NodeConnector updateNCTypeFromSwitchMgr(NodeConnector nc) {
+
+        for (Node node : switchManager.getNodes()) {
+            String nodeName = node.getNodeIDString();
+            log.trace("Switch Manager Node Name: {}, NodeConnector Node Name: {}", nodeName,
+                    nc.getNode().getNodeIDString());
+            if (nodeName.equals(nc.getNode().getNodeIDString())) {
+                NodeConnector nodeConnector = NodeConnectorCreator
+                        .createNodeConnector(node.getType(), nc.getID(), node);
+                return nodeConnector;
+            }
+        }
+        return null;
+    }
+
     /**
      * The Map returned is a copy of the current topology hence if the topology
      * changes the copy doesn't
@@ -533,6 +584,10 @@ public class TopologyManagerImpl implements
                 return null;
             }
 
+            // Check if nodeConnectors of the edge were correctly categorized
+            // by OF plugin
+            crossCheckNodeConnectors(e);
+
             // Make sure the props are non-null
             if (props == null) {
                 props = new HashSet<Property>();