Merge "Fixed incorrect help message, converted to more standard format."
authormichal rehak <mirehak@cisco.com>
Tue, 3 Jun 2014 08:49:22 +0000 (08:49 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 3 Jun 2014 08:49:22 +0000 (08:49 +0000)
drop-test/src/main/java/org/opendaylight/openflowplugin/droptest/DropTestRpcSender.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/action/ActionSetNwDstReactor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/action/ActionSetNwSrcReactor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/flowflag/FlowFlagReactor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchReactor.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/queue/MessageSpyCounterImpl.java
test-scripts/crud/odl_flow_test.py
test-scripts/crud/odl_group_tests.py
test-scripts/crud/odl_meter_test.py
test-scripts/odl_crud_tests.py
test-scripts/tools/crud_test_with_param_superclass.py

index 142a769ac4965a57d9193dc5d77a4f49748683a6..7cda5b7da5baaef9b25e674aeb2490836dfe602d 100644 (file)
@@ -7,6 +7,12 @@
  */
 package org.opendaylight.openflowplugin.droptest;
 
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction;
@@ -38,30 +44,30 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
-import java.util.Collections;
-import java.util.List;
-import java.util.Arrays;
-
 @SuppressWarnings("all")
 public class DropTestRpcSender implements PacketProcessingListener {
     private final static Logger LOG = LoggerFactory.getLogger(DropTestProvider.class);
 
     private final DropTestRpcProvider _manager;
     private final SalFlowService _flowService;
-    
-    private int _sent;
-    private int _rcvd;
-    private int _excs;
-    
-    public DropTestStats getStats(){
-       return new DropTestStats(this._sent, this._rcvd, this._excs);
+
+    private static final AtomicIntegerFieldUpdater<DropTestRpcSender> SENT_UPDATER = AtomicIntegerFieldUpdater.newUpdater(DropTestRpcSender.class, "_sent");
+    private volatile int _sent;
+
+    private static final AtomicIntegerFieldUpdater<DropTestRpcSender> RCVD_UPDATER = AtomicIntegerFieldUpdater.newUpdater(DropTestRpcSender.class, "_rcvd");
+    private volatile int _rcvd;
+
+    private static final AtomicIntegerFieldUpdater<DropTestRpcSender> EXCS_UPDATER = AtomicIntegerFieldUpdater.newUpdater(DropTestRpcSender.class, "_excs");
+    private volatile int _excs;
+
+    public DropTestStats getStats() {
+        return new DropTestStats(this._sent, this._rcvd, this._excs);
     }
-    
+
     public void clearStats(){
-       this._sent = 0;
-       this._rcvd = 0;
-       this._excs = 0;
+        this._sent = 0;
+        this._rcvd = 0;
+        this._excs = 0;
    }
 
     public DropTestRpcProvider getManager() {
@@ -78,100 +84,93 @@ public class DropTestRpcSender implements PacketProcessingListener {
     }
 
     @Override
-       public void onPacketReceived(final PacketReceived notification) {
+    public void onPacketReceived(final PacketReceived notification) {
         // LOG.debug("onPacketReceived - Entering - " + notification);
 
-       synchronized(this) {
-               this._rcvd++;
-       }
-       
-       try {
-                       // Get the Ingress nodeConnectorRef
-                       final NodeConnectorRef ncr = notification.getIngress();
-
-                       // Get the instance identifier for the nodeConnectorRef
-                       final InstanceIdentifier<NodeConnector> ncri = (InstanceIdentifier<NodeConnector>) ncr.getValue();
-                       final NodeConnectorKey ncKey = InstanceIdentifier.<NodeConnector, NodeConnectorKey>keyOf(ncri);
-
-                       // Get the instanceID for the Node in the tree above us
-                       final InstanceIdentifier<Node> nodeInstanceId = ncri.<Node>firstIdentifierOf(Node.class);
-                       final NodeKey nodeKey = InstanceIdentifier.<Node, NodeKey>keyOf(nodeInstanceId);
-                       final byte[] rawPacket = notification.getPayload();
-
-                       // LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} payload {}",
-                       //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(rawPacket));
-
-                       final byte[] srcMac = Arrays.copyOfRange(rawPacket, 6, 12);
-
-                       //LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} srcMac {}",
-                       //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(srcMac));
-
-
-                       final MatchBuilder match = new MatchBuilder();
-                       final EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
-                       final EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
-
-                       //TODO: use HEX, use binary form
-                       //Hex.decodeHex("000000000001".toCharArray());
-
-                       ethSourceBuilder.setAddress(new MacAddress(DropTestUtils.macToString(srcMac)));
-                       ethernetMatch.setEthernetSource(ethSourceBuilder.build());
-                       match.setEthernetMatch(ethernetMatch.build());
-                       final DropActionBuilder dab = new DropActionBuilder();
-                       final DropAction dropAction = dab.build();
-                       final ActionBuilder ab = new ActionBuilder();
-                       ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
-
-                       // Add our drop action to a list
-                       final List<Action> actionList = Collections.singletonList(ab.build());
-
-                       // Create an Apply Action
-                       final ApplyActionsBuilder aab = new ApplyActionsBuilder();
-                       aab.setAction(actionList);
-
-                       // Wrap our Apply Action in an Instruction
-                       final InstructionBuilder ib = new InstructionBuilder();
-                       ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-
-                       // Put our Instruction in a list of Instructions
-                       final InstructionsBuilder isb = new InstructionsBuilder();;
-                       final List<Instruction> instructions = Collections.singletonList(ib.build());
-                       isb.setInstruction(instructions);
-
-                       // Finally build our flow
-                       final AddFlowInputBuilder fb = new AddFlowInputBuilder();
-                       fb.setMatch(match.build());
-                       fb.setInstructions(isb.build());
-                       //fb.setId(new FlowId(Long.toString(fb.hashCode)));
-
-                       // Construct the flow instance id
-                       final InstanceIdentifier<Node> flowInstanceId = InstanceIdentifier
-                                       .builder(Nodes.class) // File under nodes
-                                       .child(Node.class, nodeKey).toInstance(); // A particular node identified by nodeKey
-                       fb.setNode(new NodeRef(flowInstanceId));
-
-                       fb.setPriority(4);
-                       fb.setBufferId(0L);
-                       final BigInteger value = new BigInteger("10", 10);
-                       fb.setCookie(new FlowCookie(value));
-                       fb.setCookieMask(new FlowCookie(value));
-                       fb.setTableId(Short.valueOf(((short) 0)));
-                       fb.setHardTimeout(300);
-                       fb.setIdleTimeout(240);
-                       fb.setFlags(new FlowModFlags(false, false, false, false, false));
-
-                       // Add flow
-                       this.getFlowService().addFlow(fb.build());
-
-                       synchronized (this) {
-                               this._sent++;
-                       }
-               } catch (Exception e) {
-                       // TODO Auto-generated catch block
-                       LOG.error("Failed to process packet", e);
-                       synchronized (this) {
-                               this._excs++;
-                       }
-               }
+        RCVD_UPDATER.incrementAndGet(this);
+
+        try {
+            // Get the Ingress nodeConnectorRef
+            final NodeConnectorRef ncr = notification.getIngress();
+
+            // Get the instance identifier for the nodeConnectorRef
+            final InstanceIdentifier<NodeConnector> ncri = (InstanceIdentifier<NodeConnector>) ncr.getValue();
+            final NodeConnectorKey ncKey = InstanceIdentifier.<NodeConnector, NodeConnectorKey>keyOf(ncri);
+
+            // Get the instanceID for the Node in the tree above us
+            final InstanceIdentifier<Node> nodeInstanceId = ncri.<Node>firstIdentifierOf(Node.class);
+            final NodeKey nodeKey = InstanceIdentifier.<Node, NodeKey>keyOf(nodeInstanceId);
+            final byte[] rawPacket = notification.getPayload();
+
+            // LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} payload {}",
+            //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(rawPacket));
+
+            final byte[] srcMac = Arrays.copyOfRange(rawPacket, 6, 12);
+
+            //LOG.debug("onPacketReceived - received Packet on Node {} and NodeConnector {} srcMac {}",
+            //        nodeKey.getId(), ncKey.getId(), Hex.encodeHexString(srcMac));
+
+
+            final MatchBuilder match = new MatchBuilder();
+            final EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+            final EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
+
+            //TODO: use HEX, use binary form
+            //Hex.decodeHex("000000000001".toCharArray());
+
+            ethSourceBuilder.setAddress(new MacAddress(DropTestUtils.macToString(srcMac)));
+            ethernetMatch.setEthernetSource(ethSourceBuilder.build());
+            match.setEthernetMatch(ethernetMatch.build());
+            final DropActionBuilder dab = new DropActionBuilder();
+            final DropAction dropAction = dab.build();
+            final ActionBuilder ab = new ActionBuilder();
+            ab.setAction(new DropActionCaseBuilder().setDropAction(dropAction).build());
+
+            // Add our drop action to a list
+            final List<Action> actionList = Collections.singletonList(ab.build());
+
+            // Create an Apply Action
+            final ApplyActionsBuilder aab = new ApplyActionsBuilder();
+            aab.setAction(actionList);
+
+            // Wrap our Apply Action in an Instruction
+            final InstructionBuilder ib = new InstructionBuilder();
+            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+
+            // Put our Instruction in a list of Instructions
+            final InstructionsBuilder isb = new InstructionsBuilder();;
+            final List<Instruction> instructions = Collections.singletonList(ib.build());
+            isb.setInstruction(instructions);
+
+            // Finally build our flow
+            final AddFlowInputBuilder fb = new AddFlowInputBuilder();
+            fb.setMatch(match.build());
+            fb.setInstructions(isb.build());
+            //fb.setId(new FlowId(Long.toString(fb.hashCode)));
+
+            // Construct the flow instance id
+            final InstanceIdentifier<Node> flowInstanceId = InstanceIdentifier
+                    .builder(Nodes.class) // File under nodes
+                    .child(Node.class, nodeKey).toInstance(); // A particular node identified by nodeKey
+            fb.setNode(new NodeRef(flowInstanceId));
+
+            fb.setPriority(4);
+            fb.setBufferId(0L);
+            final BigInteger value = new BigInteger("10", 10);
+            fb.setCookie(new FlowCookie(value));
+            fb.setCookieMask(new FlowCookie(value));
+            fb.setTableId(Short.valueOf(((short) 0)));
+            fb.setHardTimeout(300);
+            fb.setIdleTimeout(240);
+            fb.setFlags(new FlowModFlags(false, false, false, false, false));
+
+            // Add flow
+            this.getFlowService().addFlow(fb.build());
+            SENT_UPDATER.incrementAndGet(this);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            LOG.error("Failed to process packet", e);
+            EXCS_UPDATER.incrementAndGet(this);
+        }
     }
 }
index 7213335083903a95c67ab9f4e64a733c502cee83..1e5f8637987836eab3bcb44a43bdc8b592d5ae93 100644 (file)
@@ -18,36 +18,33 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Res
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCase;
 
 /**
- * 
+ *
  */
 public class ActionSetNwDstReactor extends ConvertReactor<SetNwDstActionCase> {
-    
-    private static ActionSetNwDstReactor instance;
-    
+
+    private static ActionSetNwDstReactor INSTANCE = new ActionSetNwDstReactor();
+
     private ActionSetNwDstReactor() {
         //NOOP
     }
-    
+
     /**
      * @return singleton
      */
-    public static synchronized ActionSetNwDstReactor getInstance() {
-        if (instance == null) {
-            instance = new ActionSetNwDstReactor();
-        }
-        return instance;
+    public static ActionSetNwDstReactor getInstance() {
+        return INSTANCE;
     }
-    
+
     @Override
-    protected void initMappings(Map<Short, Convertor<SetNwDstActionCase,?>> conversions, 
-            Map<InjectionKey, ResultInjector<?,?>> injections) {
+    protected void initMappings(final Map<Short, Convertor<SetNwDstActionCase,?>> conversions,
+            final Map<InjectionKey, ResultInjector<?,?>> injections) {
         ActionSetNwDstReactorMappingFactory.addSetNwDstConvertors(conversions);
         ActionSetNwDstReactorMappingFactory.addSetNwDstInjectors(injections);
     }
-    
+
     @Override
-    protected InjectionKey buildInjectionKey(short version,
-            Object convertedItem, Object target) {
+    protected InjectionKey buildInjectionKey(final short version,
+            final Object convertedItem, final Object target) {
         InjectionResultTargetKey key = null;
         if (convertedItem != null) {
              key = new InjectionResultTargetKey(version, target.getClass().getName(), convertedItem.getClass().getName());
index ad3ba9c1089543a7379d4051997855b2b721aca4..e9d55f875e2907eb719a1dab41bcdfc3630f0a87 100644 (file)
@@ -18,36 +18,33 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Res
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCase;
 
 /**
- * 
+ *
  */
 public class ActionSetNwSrcReactor extends ConvertReactor<SetNwSrcActionCase> {
-    
-    private static ActionSetNwSrcReactor instance;
-    
+
+    private static ActionSetNwSrcReactor INSTANCE = new ActionSetNwSrcReactor();
+
     private ActionSetNwSrcReactor() {
         //NOOP
     }
-    
+
     /**
      * @return singleton
      */
-    public static synchronized ActionSetNwSrcReactor getInstance() {
-        if (instance == null) {
-            instance = new ActionSetNwSrcReactor();
-        }
-        return instance;
+    public static ActionSetNwSrcReactor getInstance() {
+        return INSTANCE;
     }
-    
+
     @Override
-    protected void initMappings(Map<Short, Convertor<SetNwSrcActionCase,?>> conversions, 
-            Map<InjectionKey, ResultInjector<?,?>> injections) {
+    protected void initMappings(final Map<Short, Convertor<SetNwSrcActionCase,?>> conversions,
+            final Map<InjectionKey, ResultInjector<?,?>> injections) {
         ActionSetNwSrcReactorMappingFactory.addSetNwSrcConvertors(conversions);
         ActionSetNwSrcReactorMappingFactory.addSetNwSrcInjectors(injections);
     }
-    
+
     @Override
-    protected InjectionKey buildInjectionKey(short version,
-            Object convertedItem, Object target) {
+    protected InjectionKey buildInjectionKey(final short version,
+            final Object convertedItem, final Object target) {
         InjectionResultTargetKey key = null;
         if (convertedItem != null) {
              key = new InjectionResultTargetKey(version, target.getClass().getName(), convertedItem.getClass().getName());
index 4d208e8aa5cb0e237ad892af59fe07296921aeba..05f6a5a06414a514713eec183b522a7a4e687bed 100644 (file)
@@ -17,29 +17,26 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Res
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
 
 /**
- * 
+ *
  */
 public class FlowFlagReactor extends ConvertReactor<FlowModFlags> {
-    
-    private static FlowFlagReactor instance;
-    
+
+    private static FlowFlagReactor INSTANCE = new FlowFlagReactor();
+
     private FlowFlagReactor() {
         //NOOP
     }
-    
+
     /**
      * @return singleton
      */
-    public static synchronized FlowFlagReactor getInstance() {
-        if (instance == null) {
-            instance = new FlowFlagReactor();
-        }
-        return instance;
+    public static FlowFlagReactor getInstance() {
+        return INSTANCE;
     }
-    
+
     @Override
-    protected void initMappings(Map<Short, Convertor<FlowModFlags, ?>> conversions, 
-            Map<InjectionKey, ResultInjector<?,?>> injections) {
+    protected void initMappings(final Map<Short, Convertor<FlowModFlags, ?>> conversions,
+            final Map<InjectionKey, ResultInjector<?,?>> injections) {
         FlowFlagReactorMappingFactory.addFlowFlagsConvertors(conversions);
         FlowFlagReactorMappingFactory.addFlowFlagsIjectors(injections);
     }
index 1b27b84748e56622d672ecba206431a2e35b6279..abb5ea0698ddb4fb5b30c57fbb590cfa18a6119f 100644 (file)
@@ -17,31 +17,27 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Res
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
 
 /**
- * 
+ *
  */
 public class MatchReactor extends ConvertReactor<Match> {
-    
-    private static MatchReactor instance;
-    
+
+    private static MatchReactor INSTANCE = new MatchReactor();
+
     private MatchReactor() {
         //NOOP
     }
-    
+
     /**
      * @return singleton
      */
-    public static synchronized MatchReactor getInstance() {
-        if (instance == null) {
-            instance = new MatchReactor();
-        }
-        return instance;
+    public static MatchReactor getInstance() {
+        return INSTANCE;
     }
-    
+
     @Override
-    protected void initMappings(Map<Short, Convertor<Match,?>> conversions, 
-            Map<InjectionKey, ResultInjector<?,?>> injections) {
+    protected void initMappings(final Map<Short, Convertor<Match,?>> conversions,
+            final Map<InjectionKey, ResultInjector<?,?>> injections) {
         MatchReactorMappingFactory.addMatchConvertors(conversions);
         MatchReactorMappingFactory.addMatchIjectors(injections);
     }
-
 }
index 6af42b9065b52fd2c670903fa8ec23ef6237de2d..6890f169cadef194eb3c609c311990d3477f19b2 100644 (file)
@@ -9,12 +9,12 @@
 package org.opendaylight.openflowplugin.openflow.md.queue;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 
 import org.opendaylight.yangtools.yang.binding.DataContainer;
 import org.slf4j.Logger;
@@ -24,16 +24,45 @@ import org.slf4j.LoggerFactory;
  * message counter (by type)
  */
 public class MessageSpyCounterImpl implements MessageObservatory<DataContainer> {
-    
+
     private static final Logger LOG = LoggerFactory
             .getLogger(MessageSpyCounterImpl.class);
-    
-    private Map<STATISTIC_GROUP, Map<Class<? extends DataContainer>, AtomicLong[]>> inputStats = new ConcurrentHashMap<>();
-    
+
+    private static final class MessageCounters {
+        private static final AtomicLongFieldUpdater<MessageCounters> UPDATER = AtomicLongFieldUpdater.newUpdater(MessageCounters.class, "current");
+        private volatile long current;
+        private long cumulative;
+
+        public synchronized long accumulate() {
+            final long inc = UPDATER.getAndSet(this, 0);
+            cumulative += inc;
+            return inc;
+        }
+
+        public synchronized long getCumulative() {
+            return cumulative;
+        }
+
+        public long increment() {
+            return UPDATER.incrementAndGet(this);
+        }
+    }
+
+    private final ConcurrentMap<STATISTIC_GROUP, ConcurrentMap<Class<? extends DataContainer>, MessageCounters>> inputStats = new ConcurrentHashMap<>();
+
     @Override
-    public void spyIn(DataContainer message) {
-        AtomicLong[] counters = getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_IN_SUCCESS);
-        counters[0].incrementAndGet();  
+    public void spyIn(final DataContainer message) {
+        getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_IN_SUCCESS).increment();
+    }
+
+    @Override
+    public void spyOut(final DataContainer message) {
+        getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS).increment();
+    }
+
+    @Override
+    public void spyMessage(final DataContainer message, final STATISTIC_GROUP statGroup) {
+        getCounters(message, statGroup).increment();
     }
 
     /**
@@ -41,40 +70,35 @@ public class MessageSpyCounterImpl implements MessageObservatory<DataContainer>
      * @param statGroup TODO
      * @return
      */
-    private AtomicLong[] getCounters(DataContainer message, STATISTIC_GROUP statGroup) {
+    private MessageCounters getCounters(final DataContainer message, final STATISTIC_GROUP statGroup) {
         Class<? extends DataContainer> msgType = message.getImplementedInterface();
-        Map<Class<? extends DataContainer>, AtomicLong[]> groupData = getOrCreateGroupData(statGroup);
-        AtomicLong[] counters = getOrCreateCountersPair(msgType, groupData);
+        ConcurrentMap<Class<? extends DataContainer>, MessageCounters> groupData = getOrCreateGroupData(statGroup);
+        MessageCounters counters = getOrCreateCountersPair(msgType, groupData);
         return counters;
     }
-    
-    private static AtomicLong[] getOrCreateCountersPair(Class<? extends DataContainer> msgType, Map<Class<? extends DataContainer>, AtomicLong[]> groupData) {
-        AtomicLong[] counters = groupData.get(msgType);
-        synchronized(groupData) {
-            if (counters == null) {
-                counters = new AtomicLong[] {new AtomicLong(), new AtomicLong()};
-                groupData.put(msgType, counters);
-            } 
+
+    private static MessageCounters getOrCreateCountersPair(final Class<? extends DataContainer> msgType, final ConcurrentMap<Class<? extends DataContainer>,MessageCounters> groupData) {
+        final MessageCounters lookup = groupData.get(msgType);
+        if (lookup != null) {
+            return lookup;
         }
-        return counters;
+
+        final MessageCounters newCounters = new MessageCounters();
+        final MessageCounters check = groupData.putIfAbsent(msgType, newCounters);
+        return check == null ? newCounters : check;
+
     }
 
-    private Map<Class<? extends DataContainer>, AtomicLong[]> getOrCreateGroupData(STATISTIC_GROUP statGroup) {
-        Map<Class<? extends DataContainer>, AtomicLong[]> groupData = null;
-        synchronized(inputStats) {
-            groupData = inputStats.get(statGroup);
-            if (groupData == null) {
-                groupData = new HashMap<>();
-                inputStats.put(statGroup, groupData);
-            }
+    private ConcurrentMap<Class<? extends DataContainer>, MessageCounters> getOrCreateGroupData(final STATISTIC_GROUP statGroup) {
+        final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> lookup = inputStats.get(statGroup);
+        if (lookup != null) {
+            return lookup;
         }
-        return groupData;
-    }
 
-    @Override
-    public void spyOut(DataContainer message) {
-        AtomicLong[] counters = getCounters(message, STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
-        counters[0].incrementAndGet();  
+        final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> newmap = new ConcurrentHashMap<>();
+        final ConcurrentMap<Class<? extends DataContainer>, MessageCounters> check = inputStats.putIfAbsent(statGroup, newmap);
+
+        return check == null ? newmap : check;
     }
 
     @Override
@@ -90,27 +114,22 @@ public class MessageSpyCounterImpl implements MessageObservatory<DataContainer>
     @Override
     public List<String> dumpMessageCounts() {
         List<String> dump = new ArrayList<>();
+
         for (STATISTIC_GROUP statGroup : STATISTIC_GROUP.values()) {
-            Map<Class<? extends DataContainer>, AtomicLong[]> groupData = inputStats.get(statGroup);
+            Map<Class<? extends DataContainer>, MessageCounters> groupData = inputStats.get(statGroup);
             if (groupData != null) {
-                for (Entry<Class<? extends DataContainer>, AtomicLong[]> statEntry : groupData.entrySet()) {
-                    long amountPerInterval = statEntry.getValue()[0].getAndSet(0);
-                    long cumulativeAmount = statEntry.getValue()[1].addAndGet(amountPerInterval);
+                for (Entry<Class<? extends DataContainer>, MessageCounters> statEntry : groupData.entrySet()) {
+                    long amountPerInterval = statEntry.getValue().accumulate();
+                    long cumulativeAmount = statEntry.getValue().getCumulative();
                     dump.add(String.format("%s: MSG[%s] -> +%d | %d",
                             statGroup,
-                            statEntry.getKey().getSimpleName(), amountPerInterval, cumulativeAmount));
+                            statEntry.getKey().getSimpleName(),
+                            amountPerInterval, cumulativeAmount));
                 }
-                
             } else {
                 dump.add(String.format("%s: no activity detected", statGroup));
             }
         }
         return dump;
     }
-
-    @Override
-    public void spyMessage(DataContainer message, STATISTIC_GROUP statGroup) {
-        AtomicLong[] counters = getCounters(message, statGroup);
-        counters[0].incrementAndGet();
-    }
 }
index 571579405ec83097610ba3af96a8b3cecc72506b..add20f99e2f2745a6396f070124e1de47c1b2a0e 100644 (file)
@@ -34,29 +34,31 @@ class OF_CRUD_Test_Flows( OF_CRUD_Test_Base ):
         data = ( self.host, self.port, ids[TABLE_ID_TAG_NAME], ids[FLOW_ID_TAG_NAME] )
         self.conf_url = 'http://%s:%d/restconf/config/opendaylight-inventory:nodes' \
               '/node/openflow:1/table/%s/flow/%s' % data
+        self.oper_url = 'http://%s:%d/restconf/operational/opendaylight-inventory:nodes' \
+              '/node/openflow:1/table/%s/flow/%s' % data
         data = ( self.host, self.port, ids[TABLE_ID_TAG_NAME] )
         self.conf_url_post = 'http://%s:%d/restconf/config/opendaylight-inventory:nodes' \
               '/node/openflow:1/table/%s' % data
-        self.oper_url = 'http://%s:%d/restconf/operational/opendaylight-inventory:nodes' \
-              '/node/openflow:1/table/%s' % data
         # ---- operations ---
+        self.oper_url_get = 'http://%s:%d/restconf/operational/opendaylight-inventory:nodes' \
+              '/node/openflow:1/table/%s' % data
         data = ( self.host, self.port )
         self.oper_url_add = 'http://%s:%d/restconf/operations/sal-flow:add-flow' % data
         self.oper_url_upd = 'http://%s:%d/restconf/operations/sal-flow:update-flow' % data
         self.oper_url_del = 'http://%s:%d/restconf/operations/sal-flow:remove-flow' % data
         # Modify input operations data
-        data_from_file_input = ''
+        self.data_from_file_input = ''
         for node in self.xml_input_DOM.documentElement.childNodes:
             nodeKey = None if node.localName == None else ( node.localName ).encode( 'utf-8', 'ignore' )
             if ( nodeKey is None or nodeKey != 'id' ) :
-                data_from_file_input += node.toxml( encoding = 'utf-8' )
+                self.data_from_file_input += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all flow's subtags)
         self.oper_input_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
                                     '<input xmlns="urn:opendaylight:flow:service">\n' \
                                         '%s' \
                                         '<node xmlns:inv="urn:opendaylight:inventory" xmlns:finv="urn:opendaylight:flow:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                    '</input>' % data_from_file_input
+                                    '</input>' % self.data_from_file_input
 
 
     def tearDown( self ) :
@@ -153,8 +155,8 @@ class OF_CRUD_Test_Flows( OF_CRUD_Test_Base ):
         # so we expect 404 response code (same as a check after delete
         self.get_REST_XML_deleted_response( self.conf_url )
         # check request content against restconf's operational datastore
-        # operational Data Store has to present new flow
-        response = self.get_REST_XML_response( self.oper_url )
+        # operational Data Store has to present new flow, but with generated key
+        response = self.get_REST_XML_response( self.oper_url_get )
         self.__validate_contain_flow( response, self.xml_input_DOM )
 
         # -------------- UPDATE -------------------
@@ -170,9 +172,14 @@ class OF_CRUD_Test_Flows( OF_CRUD_Test_Base ):
         # The xml body without data - data come from file (all flow's subtags)
         oper_update_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
                                 '<input xmlns="urn:opendaylight:flow:service">\n' \
-                                    '%s' \
-                                    '<node xmlns:inv="urn:opendaylight:inventory" xmlns:finv="urn:opendaylight:flow:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                '</input>' % data_from_updated_stream
+                                    '<original-flow>\n' \
+                                        '%s' \
+                                    '</original-flow>\n' \
+                                    '<updated-flow>\n' \
+                                        '%s' \
+                                    '</updated-flow>\n' \
+                                    '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
+                                '</input>' % ( self.data_from_file_input, data_from_updated_stream )
 
         self.post_REST_XML_request( self.oper_url_upd, oper_update_stream )
         # TODO : check no empty transaction_id from post add_service
@@ -183,7 +190,7 @@ class OF_CRUD_Test_Flows( OF_CRUD_Test_Base ):
         self.get_REST_XML_deleted_response( self.conf_url )
         # check request content against restconf's operational datastore
         # operational Data Store has to present updated flow
-        response = self.get_REST_XML_response( self.oper_url )
+        response = self.get_REST_XML_response( self.oper_url_get )
         self.__validate_contain_flow( response, xml_updated_DOM )
 
         # -------------- DELETE -------------------
@@ -194,7 +201,7 @@ class OF_CRUD_Test_Flows( OF_CRUD_Test_Base ):
         response = self.get_REST_XML_deleted_response( self.conf_url )
         # Flow operational data has a specific content
         # and the comparable data has to be filtered before comparison
-        response = self.get_REST_XML_response( self.oper_url )
+        response = self.get_REST_XML_response( self.oper_url_get )
         self.__validate_contain_flow( response, self.xml_input_DOM, False )
 
 
index 9b9b7f66a683fdc4c2f8244fe3cef291aef25bdb..139b24bdb6753d612754a7d6aa4108cc76d4bdaa 100644 (file)
@@ -45,29 +45,29 @@ class OF_CRUD_Test_Groups( OF_CRUD_Test_Base ):
         self.oper_url_upd = 'http://%s:%d/restconf/operations/sal-group:update-group' % data
         self.oper_delete_url = 'http://%s:%d/restconf/operations/sal-group:remove-group' % data
         # Modify input data
-        data_from_file_input = ''
+        self.data_from_file_input = ''
         for node in self.xml_input_DOM.documentElement.childNodes :
-            data_from_file_input += node.toxml( encoding = 'utf-8' )
+            self.data_from_file_input += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all meter subtags)
         self.oper_input_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
-                                    '<input xmlns="urn:opendaylight:meter:service">\n' \
+                                    '<input xmlns="urn:opendaylight:group:service">\n' \
                                         '%s' \
                                         '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                    '</input>' % data_from_file_input
+                                    '</input>' % self.data_from_file_input
         # Modify input data for delete
-        data_from_file_input = ''
+        data_from_file_input_del = ''
         for node in self.xml_input_DOM.documentElement.childNodes :
             nodeKey = None if node.localName == None else ( node.localName ).encode( 'utf-8', 'ignore' )
             if ( nodeKey is None or nodeKey != 'buckets' ) :
-                data_from_file_input += node.toxml( encoding = 'utf-8' )
+                data_from_file_input_del += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all group subtags)
         self.oper_delete_input_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
                                         '<input xmlns="urn:opendaylight:group:service">\n' \
                                             '%s' \
                                             '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                        '</input>' % data_from_file_input
+                                        '</input>' % data_from_file_input_del
 
 
     def tearDown( self ) :
@@ -176,15 +176,20 @@ class OF_CRUD_Test_Groups( OF_CRUD_Test_Base ):
         xml_updated_stream = self.__update_group_input();
         xml_updated_DOM = md.parseString( xml_updated_stream )
         data_from_updated_stream = ''
-        for node in self.xml_input_DOM.documentElement.childNodes :
+        for node in xml_updated_DOM.documentElement.childNodes :
             data_from_updated_stream += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all groups's subtags)
         oper_update_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
-                                '<input xmlns="urn:opendaylight:meter:service">\n' \
-                                    '%s' \
+                                '<input xmlns="urn:opendaylight:group:service">\n' \
+                                    '<original-group>\n'\
+                                        '%s' \
+                                    '</original-group>\n'\
+                                    '<updated-group>\n'\
+                                        '%s' \
+                                    '</updated-group>\n'\
                                     '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                '</input>' % data_from_updated_stream
+                                '</input>' % ( self.data_from_file_input, data_from_updated_stream )
 
         self.post_REST_XML_request( self.oper_url_upd, oper_update_stream )
         # TODO : check no empty transaction_id from post add_service
@@ -201,7 +206,7 @@ class OF_CRUD_Test_Groups( OF_CRUD_Test_Base ):
         # -------------- DELETE -------------------
         self.log.info( self._paint_msg_yellow( " DELETE Group by remove-sal-service" ) )
         # Delte data from config DataStore
-        response = self.post_REST_XML_request( self.oper_delete_url, self.__get_oper_delete_input_stream() )
+        response = self.post_REST_XML_request( self.oper_delete_url, self.oper_delete_input_stream )
         # Data never been added, so we expect the 404 response code
         response = self.get_REST_XML_deleted_response( self.conf_url )
         # Group operational data has a specific content
index bfe6abd523f4d975dc737fbb53b013bd005a959d..d64fc135ea616ac3151560b6dc77076d9af76c2c 100644 (file)
@@ -45,16 +45,16 @@ class OF_CRUD_Test_Meters( OF_CRUD_Test_Base ):
         self.oper_url_upd = 'http://%s:%d/restconf/operations/sal-meter:update-meter' % data
         self.oper_url_del = 'http://%s:%d/restconf/operations/sal-meter:remove-meter' % data
         # Modify input data
-        data_from_file_input = ''
+        self.data_from_file_input = ''
         for node in self.xml_input_DOM.documentElement.childNodes :
-            data_from_file_input += node.toxml( encoding = 'utf-8' )
+            self.data_from_file_input += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all meter subtags)
         self.oper_input_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
                                     '<input xmlns="urn:opendaylight:meter:service">\n' \
                                         '%s' \
                                         '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                    '</input>' % data_from_file_input
+                                    '</input>' % self.data_from_file_input
 
 
     def tearDown( self ) :
@@ -162,15 +162,20 @@ class OF_CRUD_Test_Meters( OF_CRUD_Test_Base ):
         xml_updated_stream = self.__update_meter_input();
         xml_updated_DOM = md.parseString( xml_updated_stream )
         data_from_updated_stream = ''
-        for node in self.xml_input_DOM.documentElement.childNodes :
+        for node in xml_updated_DOM.documentElement.childNodes :
             data_from_updated_stream += node.toxml( encoding = 'utf-8' )
 
         # The xml body without data - data come from file (all meters's subtags)
         oper_update_stream = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' \
                                 '<input xmlns="urn:opendaylight:meter:service">\n' \
-                                    '%s' \
+                                    '<original-meter>\n' \
+                                        '%s' \
+                                    '</original-meter>\n' \
+                                    '<updated-meter>\n'\
+                                        '%s'\
+                                    '</updated-meter>\n'\
                                     '<node xmlns:inv="urn:opendaylight:inventory">/inv:nodes/inv:node[inv:id="openflow:1"]</node>\n' \
-                                '</input>' % data_from_updated_stream
+                                '</input>' % ( self.data_from_file_input, data_from_updated_stream )
 
         self.post_REST_XML_request( self.oper_url_upd, oper_update_stream )
         # TODO : check no empty transaction_id from post add_service
index 9af58283b31c6b2e53187b92f208e33378fa6bf9..86528d66f0fb4f1493034187806a1f4500daf4fa 100644 (file)
@@ -93,8 +93,8 @@ if __name__ == "__main__":
                          '(default = 0 second) Increase this value is important for a weaker controller machine' )
     parser.add_argument( '--operresp', type = int, default = 3, help = 'delay to the Operational Data Store ' \
                          '(default = 3 second) Increase this value is important for a weaker controller machine' )
-    parser.add_argument( '--coloring', type = int, default = 1, help = 'coloring output '
-                        'definition (coloring enabled = 1 | coloring disabled = 0 )  (default = 1)' )
+    parser.add_argument( '--coloring', type = int, default = 0, help = 'coloring output '
+                        'definition (coloring enabled = 1 | coloring disabled = 0 )  (default = 0)' )
 
     in_args = parser.parse_args()
 
index 368abf07be3fb2d2655ab10c00d7564f03238792..7b878d952db707d02ba9f44cdb31d66f34a46c57 100644 (file)
@@ -26,7 +26,6 @@ class ColorEnum ( object ):
     '''
     BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range( 8 )
 
-
 class OF_CRUD_Test_Base( unittest.TestCase ):
 
 
@@ -155,7 +154,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( self._paint_msg_red( err_msg ) )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -169,7 +168,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
         @raise AssertionError: if response code is not 200
         '''
         self.__log_request( get_url )
-        time.sleep( self.CONTROLLER_OPERATION_DELAY )
+        self.__time_wait_oper()
         response = requests.get( get_url,
                                 auth = self._get_auth(),
                                 headers = self._get_xml_result_header() )
@@ -179,7 +178,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( self._paint_msg_red( err_msg ) )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -202,7 +201,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( self._paint_msg_red( err_msg ) )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -225,7 +224,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( self._paint_msg_red( err_msg ) )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -249,7 +248,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( err_msg )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -275,7 +274,7 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
             self.log.error( self._paint_msg_red( err_msg ) )
             raise AssertionError( err_msg )
 
-        time.sleep( self.CONTROLLER_DELAY )
+        self.__time_wait_conf()
         return response
 
 
@@ -295,6 +294,16 @@ class OF_CRUD_Test_Base( unittest.TestCase ):
         self.log.debug( ' RECEIVED data : \n\n%s\n' % self._paint_msg_green( response.content ) )
 
 
+    def __time_wait_oper( self ):
+        self.log.info( '......... Waiting for operational DataStore %s sec. ......... ' % self.CONTROLLER_OPERATION_DELAY )
+        time.sleep( self.CONTROLLER_OPERATION_DELAY )
+
+
+    def __time_wait_conf( self ):
+        self.log.info( '......... Waiting for controller %s sec. ......... ' % self.CONTROLLER_DELAY )
+        time.sleep( self.CONTROLLER_DELAY )
+
+
     def _paint_msg_green( self, msg ):
         return self.__paint_msg( msg, 2 )