Merge "Added parsing of namespace in Json"
authorEd Warnicke <eaw@cisco.com>
Sat, 16 Nov 2013 05:11:49 +0000 (05:11 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 16 Nov 2013 05:11:49 +0000 (05:11 +0000)
30 files changed:
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.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/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-statistics/src/main/yang/group-statistics.yang
opendaylight/md-sal/model/model-flow-statistics/src/main/yang/meter-statistics.yang
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/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/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/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

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 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..d17bf8da11dbbeb9f012589c49297faf535b71bf 100644 (file)
@@ -40,6 +40,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Remo
 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 +56,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 +203,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 +243,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 +275,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 +341,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 +488,10 @@ public class FlowConsumerImpl {
         public void onFlowUpdated(FlowUpdated notification) {
             updatedFlows.add(notification);
         }
-        
+
         @Override
         public void onSwitchFlowRemoved(SwitchFlowRemoved notification) {
-            //TODO
+            // TODO
         };
 
     }
@@ -526,10 +551,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 +604,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 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 043b0077f79defd977170a105a3651a13c8f9332..c1740d8abd27fa04c38fc88670cc755501adff65 100644 (file)
@@ -18,10 +18,9 @@ module opendaylight-group-statistics {
     grouping group-stats-response {
         uses "inv:node-context-ref";
 
-        leaf group-stats-id {
-            type group-stats-ref;
+        list group-statistics{
+               uses group-types:group-statistics;
         }
-        uses group-types:group-statistics;
     }
 
     typedef group-features-ref {
@@ -31,9 +30,6 @@ module opendaylight-group-statistics {
     grouping group-features-response {
         uses "inv:node-context-ref";
 
-        leaf group-features-id {
-            type group-features-ref;
-        }
         uses group-types:group-features;
     }
 
@@ -44,10 +40,23 @@ module opendaylight-group-statistics {
     grouping group-desc-response {
         uses "inv:node-context-ref";
 
-        leaf group-desc-id {
-            type group-desc-ref;
+        list group-desc-stats {
+               uses group-types:group-desc-stats;
         }
-        uses group-types:group-desc-stats;
+    }
+    
+    container group-all-statistics {
+       container group-stats {
+               uses group-stats-response;
+       }
+       
+       container group-features {
+                       uses group-features-response;
+               }
+               
+               container group-desc {
+                       uses group-desc-response;
+               }
     }
 
        // RPC calls
@@ -56,9 +65,7 @@ module opendaylight-group-statistics {
             uses inv:node-context-ref;
         }
         output {
-            list group-statistics {
-                uses group-stats-response;
-            }
+               uses group-stats-response;
             uses tr:transaction-aware;
         }
        
@@ -81,9 +88,6 @@ module opendaylight-group-statistics {
        rpc get-group-description {
                input {
             uses inv:node-context-ref;
-            leaf group-id{
-               type group-types:group-id;
-            }
         }
         output {
             uses group-desc-response;
@@ -94,9 +98,6 @@ module opendaylight-group-statistics {
        rpc get-group-features {
                input {
             uses inv:node-context-ref;
-            leaf group-id{
-               type group-types:group-id;
-            }
         }
         output {
             uses group-features-response;
@@ -108,16 +109,28 @@ module opendaylight-group-statistics {
        //Notification calls
        
        notification group-statistics-updated {
+           leaf group-stats-id {
+            type group-stats-ref;
+        }
+               
                uses group-stats-response;
         uses tr:transaction-aware;
        }
        
        notification group-desc-stats-updated {
+               leaf group-desc-id {
+            type group-desc-ref;
+        }
+       
                uses group-desc-response;
         uses tr:transaction-aware;
        }
 
        notification group-features-updated {
+               leaf group-features-id {
+            type group-features-ref;
+        }
+       
                uses group-features-response;
         uses tr:transaction-aware;
        }
index 18dd60d08ddc87a4f8bf45e76b006e7d3d607818..3561e4f33990751d2379e7f08f51c58c5e36c8d8 100644 (file)
@@ -19,10 +19,9 @@ module opendaylight-meter-statistics {
     grouping meter-stats-response {
         uses "inv:node-context-ref";
 
-        leaf meter-stats-id {
-            type meter-stats-ref;
+        list meter-statistics {
+               uses meter-types:meter-statistics;
         }
-        uses meter-types:meter-statistics;
     }
 
     typedef meter-config-ref {
@@ -32,10 +31,9 @@ module opendaylight-meter-statistics {
     grouping meter-config-response {
         uses "inv:node-context-ref";
 
-        leaf meter-config-id {
-            type meter-config-ref;
+        list meter-config-stats {
+               uses meter-types:meter-config-stats;
         }
-        uses meter-types:meter-config-stats;
     }
 
     typedef meter-features-ref {
@@ -45,28 +43,35 @@ module opendaylight-meter-statistics {
     grouping meter-features-response {
         uses "inv:node-context-ref";
 
-        leaf meter-features-id {
-            type meter-features-ref;
-        }
         uses meter-types:meter-features;
     }
 
+       container meter-all-stats {
+               container meter-stats {
+                       uses meter-stats-response;
+               }
+               
+               container meter-config {
+                       uses meter-config-response;
+               }
+               
+               container meter-features {
+                       uses meter-features-response;
+               }
+       }
        // RPC calls
        rpc get-all-meter-statistics {
                input {
             uses inv:node-context-ref;
         }
         output {
-            list meter-statistics {
-                uses meter-stats-response;
-                uses tr:transaction-aware;
-            }
+                       uses meter-stats-response;
+                       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;
             leaf meter-id{
@@ -80,12 +85,9 @@ module opendaylight-meter-statistics {
        
        }
        
-       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;
-            }
         }
         output {
                uses meter-config-response;
@@ -96,9 +98,6 @@ module opendaylight-meter-statistics {
        rpc get-meter-features {
                input {
             uses inv:node-context-ref;
-            leaf meter-id{
-               type meter-types:meter-id;
-               }
         }
         output {
                uses meter-features-response;
@@ -110,16 +109,27 @@ module opendaylight-meter-statistics {
        //Notification calls
        
        notification meter-statistics-updated {
-               uses meter-stats-response;
+           leaf meter-stats-id {
+            type meter-stats-ref;
+        }
+       uses meter-stats-response;
         uses tr:transaction-aware;
        }
        
        notification meter-config-stats-updated {
+               leaf meter-config-id {
+            type meter-config-ref;
+        }
+       
                uses meter-config-response;
         uses tr:transaction-aware;
        }
 
        notification meter-features-updated {
+           leaf meter-features-id {
+            type meter-features-ref;
+        }
+       
                uses meter-features-response;
         uses tr:transaction-aware;
        }
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 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>
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..8507324
--- /dev/null
@@ -0,0 +1,89 @@
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.List;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.desc.response.GroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.stats.response.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.meter.config.response.MeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.meter.stats.response.MeterStatistics;
+
+public class NodeStatistics {
+
+    private NodeRef targetNode;
+    
+    private List<GroupStatistics> groupStatistics;
+    
+    private List<MeterStatistics> meterStatistics;
+    
+    private List<GroupDescStats> groupDescStats;
+    
+    private List<MeterConfigStats> meterConfigStats;
+    
+    private List<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.features.GroupFeatures> groupFeatures;
+    
+    private List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.features.MeterFeatures> meterFeatures;
+    
+    public NodeStatistics(){
+        
+    }
+
+    public NodeRef getTargetNode() {
+        return targetNode;
+    }
+
+    public void setTargetNode(NodeRef targetNode) {
+        this.targetNode = targetNode;
+    }
+
+    public List<GroupStatistics> getGroupStatistics() {
+        return groupStatistics;
+    }
+
+    public void setGroupStatistics(List<GroupStatistics> groupStatistics) {
+        this.groupStatistics = groupStatistics;
+    }
+
+    public List<MeterStatistics> getMeterStatistics() {
+        return meterStatistics;
+    }
+
+    public void setMeterStatistics(List<MeterStatistics> 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 List<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.features.GroupFeatures> getGroupFeatures() {
+        return groupFeatures;
+    }
+
+    public void setGroupFeatures(
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.features.GroupFeatures> groupFeatures) {
+        this.groupFeatures = groupFeatures;
+    }
+
+    public List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.features.MeterFeatures> getMeterFeatures() {
+        return meterFeatures;
+    }
+
+    public void setMeterFeatures(
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.features.MeterFeatures> meterFeatures) {
+        this.meterFeatures = meterFeatures;
+    }
+    
+}
index 073d43ef60df3d944dda0da6512326267be114e5..5c02b6cea069b5266244189990f54e66cddff67f 100644 (file)
@@ -1,13 +1,36 @@
 package org.opendaylight.controller.md.statistics.manager;
 
+import java.util.ArrayList;
+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.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.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 +46,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<NodeRef,NodeStatistics> statisticsCache = 
+            new ConcurrentHashMap<NodeRef,NodeStatistics>();
+    
     public DataProviderService getDataService() {
       return this.dps;
     }
@@ -50,10 +82,28 @@ 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 {
+                        statsRequestSender();
+                        
+                        Thread.sleep(5000);
+                    }catch (Exception e){
+                        spLogger.error("Exception occurred while sending stats request : {}",e.getMessage());
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
         spLogger.info("Statistics Provider started.");
     }
     
@@ -63,6 +113,100 @@ public class StatisticsProvider implements AutoCloseable {
         return dps.beginTransaction();
     }
     
+    private void statsRequestSender(){
+        
+        //Need to call API to receive all the nodes connected to controller.
+        
+        List<NodeRef> targetNodes = new ArrayList<NodeRef>();
+        
+        for (NodeRef targetNode : targetNodes){
+            
+            sendAllGroupStatisticsRequest(targetNode);
+            
+            sendAllMeterStatisticsRequest(targetNode);
+
+            //We need to add check, so see if groups/meters are supported
+            //by the target node.
+            sendGroupDescriptionRequest(targetNode);
+            
+            sendGroupFeaturesRequest(targetNode);
+            
+            sendMeterConfigStatisticsRequest(targetNode);
+            
+            sendMeterFeaturesRequest(targetNode);
+        }
+    }
+    
+    private void sendAllGroupStatisticsRequest(NodeRef targetNode){
+        
+        GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
+        
+        input.setNode(targetNode);
+
+        Future<RpcResult<GetAllGroupStatisticsOutput>> response = 
+                groupStatsService.getAllGroupStatistics(input.build());
+    }
+    
+    private void sendGroupDescriptionRequest(NodeRef targetNode){
+        GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
+        
+        input.setNode(targetNode);
+        
+        Future<RpcResult<GetGroupDescriptionOutput>> response = 
+                groupStatsService.getGroupDescription(input.build());
+    }
+    
+    private void sendGroupFeaturesRequest(NodeRef targetNode){
+        
+        GetGroupFeaturesInputBuilder input = new GetGroupFeaturesInputBuilder();
+        
+        input.setNode(targetNode);
+        
+        Future<RpcResult<GetGroupFeaturesOutput>> response = 
+                groupStatsService.getGroupFeatures(input.build());
+    }
+    
+    private void sendAllMeterStatisticsRequest(NodeRef targenetNode){
+        
+        GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
+        
+        input.setNode(targenetNode);
+        
+        Future<RpcResult<GetAllMeterStatisticsOutput>> response = 
+                meterStatsService.getAllMeterStatistics(input.build());
+    }
+    
+    private void sendMeterConfigStatisticsRequest(NodeRef targetNode){
+        
+        GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
+        
+        input.setNode(targetNode);
+        
+        Future<RpcResult<GetAllMeterConfigStatisticsOutput>> response = 
+                meterStatsService.getAllMeterConfigStatistics(input.build());
+        
+    }
+    private void sendMeterFeaturesRequest(NodeRef targetNode){
+     
+        GetMeterFeaturesInputBuilder input = new GetMeterFeaturesInputBuilder();
+        
+        input.setNode(targetNode);
+        
+        Future<RpcResult<GetMeterFeaturesOutput>> response = 
+                meterStatsService.getMeterFeatures(input.build());
+    }
+    
+    public ConcurrentMap<NodeRef, NodeStatistics> getStatisticsCache() {
+        return statisticsCache;
+    }
+    
+    private List<Node> getAllConnectedNodes(){
+        
+        Nodes nodes = (Nodes) dps.readOperationalData(nodesIdentifier);
+        return nodes.getNode();
+    }
+
+    @SuppressWarnings("deprecation")
     @Override
     public void close(){
         
@@ -71,6 +215,8 @@ public class StatisticsProvider implements AutoCloseable {
             if (this.listenerRegistration != null) {
               
                 this.listenerRegistration.close();
+                
+                this.statisticsRequesterThread.destroy();
             
             }
           } catch (Throwable e) {
index f952124c91e88488ad60134e67e37ad0b12e6e13..cba039f815126a071e2184f397eca2faa7cf92e2 100644 (file)
@@ -1,13 +1,30 @@
 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.GroupDescRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesRef;
 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.GroupStatsRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.all.statistics.GroupDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.all.statistics.GroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.all.statistics.GroupStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesRef;
 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.MeterStatsRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.OpendaylightMeterStatisticsListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.meter.all.stats.MeterConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.meter.all.stats.MeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.meter.all.stats.MeterStatsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsListener,
         OpendaylightMeterStatisticsListener {
@@ -23,35 +40,135 @@ public class StatisticsUpdateCommiter implements OpendaylightGroupStatisticsList
     }
     @Override
     public void onMeterConfigStatsUpdated(MeterConfigStatsUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setMeterConfigStats(notification.getMeterConfigStats());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        MeterConfigRef ref = notification.getMeterConfigId();
+
+        MeterConfigBuilder meterConfig = new MeterConfigBuilder();
+        meterConfig.setNode(notification.getNode());
+        meterConfig.setMeterConfigStats(notification.getMeterConfigStats());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, meterConfig.build());
+        it.commit();
     }
 
     @Override
     public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setMeterStatistics(notification.getMeterStatistics());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        MeterStatsRef ref = notification.getMeterStatsId();
 
+        MeterStatsBuilder meterStats = new MeterStatsBuilder();
+        meterStats.setNode(notification.getNode());
+        meterStats.setMeterStatistics(notification.getMeterStatistics());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, meterStats.build());
+        it.commit();
     }
 
     @Override
     public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
-        // TODO Auto-generated method stub
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setGroupDescStats(notification.getGroupDescStats());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        GroupDescRef ref = notification.getGroupDescId();
 
+        GroupDescBuilder descStats = new GroupDescBuilder();
+        descStats.setNode(notification.getNode());
+        descStats.setGroupDescStats(notification.getGroupDescStats());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, descStats.build());
+        it.commit();
     }
 
     @Override
     public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
-        // TODO Auto-generated method stub
+        
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setGroupStatistics(notification.getGroupStatistics());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        GroupStatsRef ref = notification.getGroupStatsId();
 
+        GroupStatsBuilder groupStats = new GroupStatsBuilder();
+        groupStats.setNode(notification.getNode());
+        groupStats.setGroupStatistics(notification.getGroupStatistics());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, groupStats.build());
+        it.commit();
     }
     @Override
     public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
-        // TODO Auto-generated method stub
+
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setMeterFeatures(notification.getMeterFeatures());
         
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        MeterFeaturesRef ref = notification.getMeterFeaturesId();
+
+        MeterFeaturesBuilder meterFeatures = new MeterFeaturesBuilder();
+        meterFeatures.setNode(notification.getNode());
+        meterFeatures.setMeterFeatures(notification.getMeterFeatures());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, meterFeatures.build());
+        it.commit();
     }
+    
     @Override
     public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
-        // TODO Auto-generated method stub
         
-    }
+        //Add statistics to local cache
+        ConcurrentMap<NodeRef, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+        if(!cache.containsKey(notification.getNode())){
+            cache.put(notification.getNode(), new NodeStatistics());
+        }
+        cache.get(notification.getNode()).setGroupFeatures(notification.getGroupFeatures());
+        
+        //Publish data to configuration data store
+        DataModificationTransaction it = this.statisticsManager.startChange();
+        GroupFeaturesRef ref = notification.getGroupFeaturesId();
 
+        GroupFeaturesBuilder featuresStats = new GroupFeaturesBuilder();
+        featuresStats.setNode(notification.getNode());
+        featuresStats.setGroupFeatures(notification.getGroupFeatures());
+        
+        InstanceIdentifier<? extends Object> refValue = ref.getValue();
+        it.putRuntimeData(refValue, featuresStats.build());
+        it.commit();
+    }
 }
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>