Merge "Cleanup dependencyManagement overrides"
authorTony Tkacik <ttkacik@cisco.com>
Fri, 28 Feb 2014 14:03:52 +0000 (14:03 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 28 Feb 2014 14:03:52 +0000 (14:03 +0000)
13 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-toaster-sample.xml [new file with mode: 0644]
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/forwardingrulesmanager/api/src/test/java/org/opendaylight/controller/forwardingrulesmanager/frmTest.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Path.java

index d42f1fd..c0e857c 100644 (file)
         <artifactId>maven-surefire-plugin</artifactId>
         <version>${surefire.version}</version>
         <configuration>
+          <argLine>${testvm.argLine}</argLine>
           <systemProperties>
             <property>
               <name>logback.configurationFile</name>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-toaster-sample.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/02-toaster-sample.xml
new file mode 100644 (file)
index 0000000..c481485
--- /dev/null
@@ -0,0 +1,73 @@
+<snapshot>
+    <configuration>
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl">
+                        prefix:toaster-provider-impl
+                    </type>
+                    <name>toaster-provider-impl</name>
+
+                    <rpc-registry>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <name>binding-rpc-broker</name>
+                    </rpc-registry>
+
+                    <notification-service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+                            binding:binding-notification-service
+                        </type>
+                        <name>binding-notification-broker</name>
+                    </notification-service>
+                </module>
+
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl">
+                        prefix:toaster-consumer-impl
+                    </type>
+                    <name>toaster-consumer-impl</name>
+
+                    <rpc-registry>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                        <name>binding-rpc-broker</name>
+                    </rpc-registry>
+
+                    <notification-service>
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
+                            binding:binding-notification-service
+                        </type>
+                        <name>binding-notification-broker</name>
+                    </notification-service>
+                </module>
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:toaster="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider">toaster:toaster-provider</type>
+                    <instance>
+                        <name>toaster-provider</name>
+                        <provider>/modules/module[type='toaster-provider-impl'][name='toaster-provider-impl']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:toaster="urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer">toaster:toaster-consumer</type>
+                    <instance>
+                        <name>toaster-consumer</name>
+                        <provider>/modules/module[type='toaster-consumer-impl'][name='toaster-consumer-impl']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+
+    </configuration>
+
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer?module=toaster-consumer&amp;revision=2014-01-31</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-consumer:impl?module=toaster-consumer-impl&amp;revision=2014-01-31</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider?module=toaster-provider&amp;revision=2014-01-31</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl?module=toaster-provider-impl&amp;revision=2014-01-31</capability>
+    </required-capabilities>
+
+</snapshot>
+
index c56eb60..3ad08ca 100644 (file)
@@ -8,6 +8,19 @@
 
 package org.opendaylight.controller.forwardingrulesmanager;
 
+import java.io.Serializable;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
 import org.opendaylight.controller.configuration.ConfigurationObject;
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
@@ -30,38 +43,19 @@ import org.opendaylight.controller.sal.action.SetTpSrc;
 import org.opendaylight.controller.sal.action.SetVlanId;
 import org.opendaylight.controller.sal.action.SetVlanPcp;
 import org.opendaylight.controller.sal.action.SwPath;
-import org.opendaylight.controller.sal.core.ContainerFlow;
-import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.IPProtocols;
 import org.opendaylight.controller.sal.utils.NetUtils;
-import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
-import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
-import org.opendaylight.controller.switchmanager.ISwitchManager;
-import org.opendaylight.controller.switchmanager.Switch;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 /**
  * Configuration Java Object which represents a flow configuration information
  * for Forwarding Rules Manager.
@@ -608,15 +602,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
         return true;
     }
 
-    public boolean isPortValid(Switch sw, String port) {
-        if (sw == null) {
-            log.debug("switch info is not available. Skip checking if port is part of a switch or not.");
-            return true;
-        }
-        NodeConnector nc = NodeConnectorCreator.createNodeConnector(port, sw.getNode());
-        return sw.getNodeConnectors().contains(nc);
-    }
-
     public boolean isVlanIdValid(String vlanId) {
         int vlan = Integer.decode(vlanId);
         return ((vlan >= 0) && (vlan < 4096));
@@ -647,45 +632,11 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
         return (proto != null);
     }
 
-    private Status conflictWithContainerFlow(IContainer container) {
-        // Return true if it's default container
-        if (container.getName().equals(GlobalConstants.DEFAULT.toString())) {
-            return new Status(StatusCode.SUCCESS);
-        }
-
-        // No container flow = no conflict
-        List<ContainerFlow> cFlowList = container.getContainerFlows();
-        if (((cFlowList == null)) || cFlowList.isEmpty()) {
-            return new Status(StatusCode.SUCCESS);
-        }
-
-        // Check against each container's flow
-        Flow flow = this.getFlow();
-
-        // Configuration is rejected if it conflicts with _all_ the container
-        // flows
-        for (ContainerFlow cFlow : cFlowList) {
-            if (cFlow.allowsFlow(flow)) {
-                log.trace("Config is congruent with at least one container flow");
-                return new Status(StatusCode.SUCCESS);
-            }
-        }
-        String msg = "Flow Config conflicts with all existing container flows";
-        log.trace(msg);
-
-        return new Status(StatusCode.BADREQUEST, msg);
-    }
-
-    public Status validate(IContainer container) {
+    public Status validate() {
         EtherIPType etype = EtherIPType.ANY;
         EtherIPType ipsrctype = EtherIPType.ANY;
         EtherIPType ipdsttype = EtherIPType.ANY;
 
-        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container.getName();
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
-                this);
-
-        Switch sw = null;
         try {
             // Flow name cannot be internal flow signature
             if (!isValidResourceName(name) || isInternalFlow()) {
@@ -696,20 +647,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                 return new Status(StatusCode.BADREQUEST, "Node is null");
             }
 
-            if (switchManager != null) {
-                for (Switch device : switchManager.getNetworkDevices()) {
-                    if (device.getNode().equals(node)) {
-                        sw = device;
-                        break;
-                    }
-                }
-                if (sw == null) {
-                    return new Status(StatusCode.BADREQUEST, String.format("Node %s not found", node));
-                }
-            } else {
-                log.debug("switchmanager is not set yet");
-            }
-
             if (priority != null) {
                 if (Integer.decode(priority) < 0 || (Integer.decode(priority) > 65535)) {
                     return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535",
@@ -722,14 +659,8 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                 Long.decode(cookie);
             }
 
-            if (ingressPort != null) {
-                if (!isPortValid(sw, ingressPort)) {
-                    String msg = String.format("Ingress port %s is not valid for the Switch", ingressPort);
-                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                        msg += " in Container " + containerName;
-                    }
-                    return new Status(StatusCode.BADREQUEST, msg);
-                }
+            if (ingressPort != null && ingressPort.isEmpty()) {
+                return new Status(StatusCode.BADREQUEST, "Invalid ingress port");
             }
 
             if ((vlanId != null) && !isVlanIdValid(vlanId)) {
@@ -832,48 +763,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                 return new Status(StatusCode.BADREQUEST, "Actions value is null or empty");
             }
             for (String actiongrp : actions) {
-                // check output ports
-                sstr = Pattern.compile("OUTPUT=(.*)").matcher(actiongrp);
-                if (sstr.matches()) {
-                    for (String t : sstr.group(1).split(",")) {
-                        if (t != null) {
-                            if (!isPortValid(sw, t)) {
-                                String msg = String.format("Output port %s is not valid for this switch", t);
-                                if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                                    msg += " in Container " + containerName;
-                                }
-                                return new Status(StatusCode.BADREQUEST, msg);
-                            }
-                        }
-                    }
-                    continue;
-                }
-                // check enqueue
-                sstr = Pattern.compile("ENQUEUE=(.*)").matcher(actiongrp);
-                if (sstr.matches()) {
-                    for (String t : sstr.group(1).split(",")) {
-                        if (t != null) {
-                            String port = t.split(":")[0];
-                            if (!isPortValid(sw, port)) {
-                                String msg = String.format("Output port %d is not valid for this switch", port);
-                                if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                                    msg += " in Container " + containerName;
-                                }
-                                return new Status(StatusCode.BADREQUEST, msg);
-                            }
-                        }
-                    }
-                    continue;
-                }
-                // Check src IP
-                sstr = Pattern.compile(ActionType.FLOOD.toString()).matcher(actiongrp);
-                if (sstr.matches()) {
-                    if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                        return new Status(StatusCode.BADREQUEST, String.format(
-                                "flood is not allowed in container %s", containerName));
-                    }
-                    continue;
-                }
                 // Check src IP
                 sstr = Pattern.compile(ActionType.SET_NW_SRC.toString() + "=(.*)").matcher(actiongrp);
                 if (sstr.matches()) {
@@ -965,11 +854,6 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                     continue;
                 }
             }
-            // Check against the container flow
-            Status status;
-            if (!containerName.equals(GlobalConstants.DEFAULT.toString()) && !(status = conflictWithContainerFlow(container)).isSuccess()) {
-                return status;
-            }
         } catch (NumberFormatException e) {
             return new Status(StatusCode.BADREQUEST, String.format("Invalid number format %s", e.getMessage()));
         }
index 48e1f07..685ccdb 100644 (file)
@@ -257,7 +257,7 @@ public class frmTest {
         FlowConfig flowConfig = new FlowConfig();
         Assert.assertFalse(flowConfig.isInternalFlow());
         flowConfig.setName("__Internal__");
-        Status status = flowConfig.validate(null);
+        Status status = flowConfig.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("name"));
         Assert.assertTrue(flowConfig.isInternalFlow());
@@ -509,228 +509,228 @@ public class frmTest {
     @Test
     public void testValid() throws UnknownHostException {
         FlowConfig fc2 = createSampleFlowConfig();
-        Assert.assertTrue(fc2.validate(null).isSuccess());
+        Assert.assertTrue(fc2.validate().isSuccess());
 
         FlowConfig fc = new FlowConfig();
-        Status status = fc.validate(null);
+        Status status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Invalid name"));
 
         fc.setName("Config");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Node is null"));
 
         fc.setNode(Node.fromString(Node.NodeIDType.OPENFLOW, "1"));
-        Assert.assertFalse(fc.validate(null).isSuccess());
+        Assert.assertFalse(fc.validate().isSuccess());
         List<String> actions = new ArrayList<String>();
         fc.setActions(actions);
-        Assert.assertFalse(fc.validate(null).isSuccess());
+        Assert.assertFalse(fc.validate().isSuccess());
         actions.add("OUTPUT=2");
         fc.setActions(actions);
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setPriority("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 65535"));
 
         fc.setPriority("100000");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 65535"));
 
         fc.setPriority("2000");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setCookie("100");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setIngressPort("100");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setVlanId(("-1"));
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 4095"));
 
         fc.setVlanId("5000");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 4095"));
 
         fc.setVlanId("100");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setVlanPriority("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 7"));
 
         fc.setVlanPriority("9");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("is not in the range 0 - 7"));
 
         fc.setVlanPriority("5");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setEtherType("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Ethernet type"));
 
         fc.setEtherType("0xfffff");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Ethernet type"));
 
         fc.setEtherType("0x800");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setTosBits("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("IP ToS bits"));
 
         fc.setTosBits("65");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("IP ToS bits"));
 
         fc.setTosBits("60");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcPort("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Transport source port"));
 
         fc.setSrcPort("0xfffff");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Transport source port"));
 
         fc.setSrcPort("0");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcPort("0x00ff");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcPort("0xffff");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstPort("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Transport destination port"));
 
         fc.setDstPort("0xfffff");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Transport destination port"));
 
         fc.setDstPort("0");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstPort("0x00ff");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstPort("0xffff");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcMac("abc");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Ethernet source address"));
 
         fc.setSrcMac("00:A0:C9:14:C8:29");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstMac("abc");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Ethernet destination address"));
 
         fc.setDstMac("00:A0:C9:22:AB:11");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcIp("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("IP source address"));
 
         fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Src IP"));
 
         fc.setEtherType("0x86dd");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setSrcIp("1.1.1.1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Src IP"));
 
         fc.setEtherType("0x800");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstIp("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("IP destination address"));
 
         fc.setDstIp("2001:420:281:1004:407a:57f4:4d15:c355");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Dst IP"));
 
         fc.setEtherType("0x86dd");
         fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setDstIp("2.2.2.2");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Type mismatch between Ethernet & Dst IP"));
 
         fc.setEtherType("0x800");
         fc.setSrcIp("1.1.1.1");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setEtherType(null);
         fc.setSrcIp("2001:420:281:1004:407a:57f4:4d15:c355");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("IP Src Dest Type mismatch"));
 
         fc.setSrcIp("1.1.1.1");
         fc.setIdleTimeout("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Idle Timeout value"));
 
         fc.setIdleTimeout("0xfffff");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Idle Timeout value"));
 
         fc.setIdleTimeout("10");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
         fc.setHardTimeout("-1");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Hard Timeout value"));
 
         fc.setHardTimeout("0xfffff");
-        status = fc.validate(null);
+        status = fc.validate();
         Assert.assertFalse(status.isSuccess());
         Assert.assertTrue(status.getDescription().contains("Hard Timeout value"));
 
         fc.setHardTimeout("10");
-        Assert.assertTrue(fc.validate(null).isSuccess());
+        Assert.assertTrue(fc.validate().isSuccess());
 
     }
 
index b94103f..614c39e 100644 (file)
@@ -50,6 +50,9 @@ import org.opendaylight.controller.forwardingrulesmanager.PortGroupProvider;
 import org.opendaylight.controller.forwardingrulesmanager.implementation.data.FlowEntryDistributionOrder;
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.ActionType;
+import org.opendaylight.controller.sal.action.Enqueue;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
 import org.opendaylight.controller.sal.action.Output;
 import org.opendaylight.controller.sal.connection.ConnectionLocality;
 import org.opendaylight.controller.sal.core.Config;
@@ -243,6 +246,57 @@ public class ForwardingRulesManager implements
         return null;
     }
 
+    /**
+     * Checks if the FlowEntry targets are valid for this container
+     *
+     * @param flowEntry
+     *            The flow entry to test
+     * @return a Status object representing the result of the validation
+     */
+    private Status validateEntry(FlowEntry flowEntry) {
+        // Node presence check
+        Node node = flowEntry.getNode();
+        if (!switchManager.getNodes().contains(node)) {
+            return new Status(StatusCode.BADREQUEST, String.format("Node %s is not present in this container", node));
+        }
+
+        // Ports and actions validation check
+        Flow flow = flowEntry.getFlow();
+        Match match = flow.getMatch();
+        if (match.isPresent(MatchType.IN_PORT)) {
+            NodeConnector inputPort = (NodeConnector)match.getField(MatchType.IN_PORT).getValue();
+            if (!switchManager.getNodeConnectors(node).contains(inputPort)) {
+                String msg = String.format("Ingress port %s is not present on this container", inputPort);
+                return new Status(StatusCode.BADREQUEST, msg);
+            }
+        }
+        for (Action action : flow.getActions()) {
+            if (action instanceof Flood && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) {
+                return new Status(StatusCode.BADREQUEST, String.format("Flood is only allowed in default container"));
+            }
+            if (action instanceof FloodAll && !GlobalConstants.DEFAULT.toString().equals(getContainerName())) {
+                return new Status(StatusCode.BADREQUEST, String.format("FloodAll is only allowed in default container"));
+            }
+            if (action instanceof Output) {
+                Output out = (Output)action;
+                NodeConnector outputPort = out.getPort();
+                if (!switchManager.getNodeConnectors(node).contains(outputPort)) {
+                    String msg = String.format("Output port %s is not present on this container", outputPort);
+                    return new Status(StatusCode.BADREQUEST, msg);
+                }
+            }
+            if (action instanceof Enqueue) {
+                Enqueue out = (Enqueue)action;
+                NodeConnector outputPort = out.getPort();
+                if (!switchManager.getNodeConnectors(node).contains(outputPort)) {
+                    String msg = String.format("Enqueue port %s is not present on this container", outputPort);
+                    return new Status(StatusCode.BADREQUEST, msg);
+                }
+            }
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
     /**
      * Adds a flow entry onto the network node It runs various validity checks
      * and derive the final container flows merged entries that will be
@@ -264,6 +318,15 @@ public class ForwardingRulesManager implements
             return new Status(StatusCode.NOTACCEPTABLE, INVALID_FLOW_ENTRY);
         }
 
+        // Operational check: input, output and queue ports presence check and
+        // action validation for this container
+        Status status = validateEntry(flowEntry);
+        if (!status.isSuccess()) {
+            String msg = String.format("%s: %s", INVALID_FLOW_ENTRY, status.getDescription());
+            log.warn("{}: {}", msg, flowEntry);
+            return new Status(StatusCode.NOTACCEPTABLE, msg);
+        }
+
         /*
          * Redundant Check: Check if the request is a redundant one from the
          * same application the flowEntry is equal to an existing one. Given we
@@ -422,6 +485,15 @@ public class ForwardingRulesManager implements
             return new Status(StatusCode.SUCCESS, msg);
         }
 
+        // Operational check: input, output and queue ports presence check and
+        // action validation for this container
+        Status status = validateEntry(newFlowEntry);
+        if (!status.isSuccess()) {
+            String msg = String.format("Modify: %s: %s", INVALID_FLOW_ENTRY, status.getDescription());
+            log.warn("{}: {}", msg, newFlowEntry);
+            return new Status(StatusCode.NOTACCEPTABLE, msg);
+        }
+
         /*
          * Conflict Check: Verify the new entry would not conflict with an
          * existing one. This is a loose check on the previous original flow
@@ -1121,7 +1193,10 @@ public class ForwardingRulesManager implements
             List<FlowEntryInstall> list = new ArrayList<FlowEntryInstall>(groupFlows.get(groupName));
             toBeRemoved = list.size();
             for (FlowEntryInstall entry : list) {
-                Status status = this.removeEntry(entry.getOriginal(), false);
+                // since this is the entry that was stored in groupFlows
+                // it is already validated and merged
+                // so can call removeEntryInternal directly
+                Status status = this.removeEntryInternal(entry, false);
                 if (status.isSuccess()) {
                     toBeRemoved -= 1;
                 } else {
@@ -1516,7 +1591,7 @@ public class ForwardingRulesManager implements
     @Override
     public Status addStaticFlow(FlowConfig config) {
         // Configuration object validation
-        Status status = config.validate(container);
+        Status status = config.validate();
         if (!status.isSuccess()) {
             log.warn("Invalid Configuration for flow {}. The failure is {}", config, status.getDescription());
             String error = "Invalid Configuration (" + status.getDescription() + ")";
@@ -1680,6 +1755,7 @@ public class ForwardingRulesManager implements
                     config.setStatus(StatusCode.SUCCESS.toString());
                     break;
                 default:
+                    break;
                 }
             }
         }
@@ -1775,7 +1851,7 @@ public class ForwardingRulesManager implements
         }
 
         // Validity Check
-        Status status = newFlowConfig.validate(container);
+        Status status = newFlowConfig.validate();
         if (!status.isSuccess()) {
             String msg = "Invalid Configuration (" + status.getDescription() + ")";
             newFlowConfig.setStatus(msg);
@@ -1855,7 +1931,7 @@ public class ForwardingRulesManager implements
             }
         }
         if (target != null) {
-            Status status = target.validate(container);
+            Status status = target.validate();
             if (!status.isSuccess()) {
                 log.warn(status.getDescription());
                 return status;
@@ -2757,6 +2833,7 @@ public class ForwardingRulesManager implements
             this.reinstallAllFlowEntries();
             break;
         default:
+            break;
         }
 
         // Update our configuration DB
index e48ebbc..e6e935c 100644 (file)
@@ -202,6 +202,16 @@ public class BindingIndependentConnector implements //
             DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
         DataModificationTransaction target = biDataService.beginTransaction();
         LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier());
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeConfigurationData(biEntry);
+            LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry);
+        }
+        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeOperationalData(biEntry);
+            LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry);
+        }
         for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
                 .entrySet()) {
             Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
@@ -216,16 +226,7 @@ public class BindingIndependentConnector implements //
             target.putOperationalData(biEntry.getKey(), biEntry.getValue());
             LOG.debug("Update of Binding Operational Data {} is translated to {}",entry,biEntry);
         }
-        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
-            target.removeConfigurationData(biEntry);
-            LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry);
-        }
-        for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
-            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
-            target.removeOperationalData(biEntry);
-            LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry);
-        }
+
         return target;
     }
 
@@ -233,6 +234,24 @@ public class BindingIndependentConnector implements //
             DataModification<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> source) {
         org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction target = baDataService
                 .beginTransaction();
+        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeConfigurationData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
+            }
+        }
+        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
+            try {
+
+                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
+                target.removeOperationalData(baEntry);
+            } catch (DeserializationException e) {
+                LOG.error("Ommiting from BA transaction: {}.", entry, e);
+            }
+        }
         for (Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> entry : source
                 .getUpdatedConfigurationData().entrySet()) {
             try {
@@ -254,24 +273,6 @@ public class BindingIndependentConnector implements //
                 LOG.error("Ommiting from BA transaction: {}.", entry.getKey(), e);
             }
         }
-        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedConfigurationData()) {
-            try {
-
-                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-                target.removeConfigurationData(baEntry);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry, e);
-            }
-        }
-        for (org.opendaylight.yangtools.yang.data.api.InstanceIdentifier entry : source.getRemovedOperationalData()) {
-            try {
-
-                InstanceIdentifier<?> baEntry = mappingService.fromDataDom(entry);
-                target.removeOperationalData(baEntry);
-            } catch (DeserializationException e) {
-                LOG.error("Ommiting from BA transaction: {}.", entry, e);
-            }
-        }
         return target;
     }
 
index 1159d56..6b5f5ac 100644 (file)
@@ -50,7 +50,7 @@ class BrokerConfigActivator implements AutoCloseable {
         broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders.fromSchemaService(schemaService)));
 
         dataService = new DataBrokerImpl();
-        dataService.setExecutor(broker.getExecutor());
+        //dataService.setExecutor(broker.getExecutor());
 
         dataReg = context.registerService(DataBrokerService, dataService, emptyProperties);
         dataProviderReg = context.registerService(DataProviderService, dataService, emptyProperties);
index f380c27..d831556 100644 (file)
@@ -9,19 +9,14 @@ package org.opendaylight.controller.sal.dom.broker.impl;
 
 import static com.google.common.base.Preconditions.checkState;
 
-import java.io.Console;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.concurrent.Future;
 
-import javax.activation.UnsupportedDataTypeException;
-
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
@@ -34,11 +29,9 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
 import org.opendaylight.yangtools.yang.data.api.Node;
 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@@ -47,7 +40,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableSet;
@@ -180,18 +172,25 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
     private NormalizedDataModification prepareMergedTransaction(
             DataModification<InstanceIdentifier, CompositeNode> original) {
         NormalizedDataModification normalized = new NormalizedDataModification(original);
-        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedConfigurationData().entrySet()) {
-            normalized.putDeepConfigurationData(entry.getKey(), entry.getValue());
-        }
-        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedOperationalData().entrySet()) {
-            normalized.putDeepOperationalData(entry.getKey(), entry.getValue());
-        }
+        LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(),
+                original.getRemovedConfigurationData(), original.getRemovedConfigurationData());
+        LOG.trace("Transaction: {} Created Configuration {}, Created Operational {}", original.getIdentifier(),
+                original.getCreatedConfigurationData().entrySet(), original.getCreatedOperationalData().entrySet());
+        LOG.trace("Transaction: {} Updated Configuration {}, Updated Operational {}", original.getIdentifier(),
+                original.getUpdatedConfigurationData().entrySet(), original.getUpdatedOperationalData().entrySet());
+
         for (InstanceIdentifier entry : original.getRemovedConfigurationData()) {
             normalized.deepRemoveConfigurationData(entry);
         }
         for (InstanceIdentifier entry : original.getRemovedOperationalData()) {
             normalized.deepRemoveOperationalData(entry);
         }
+        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedConfigurationData().entrySet()) {
+            normalized.putDeepConfigurationData(entry.getKey(), entry.getValue());
+        }
+        for (Entry<InstanceIdentifier, CompositeNode> entry : original.getUpdatedOperationalData().entrySet()) {
+            normalized.putDeepOperationalData(entry.getKey(), entry.getValue());
+        }
         return normalized;
     }
 
@@ -359,7 +358,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
         public void putDeepConfigurationData(InstanceIdentifier entryKey, CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, CONFIGURATIONAL_DATA_STORE_MARKER);
         }
-        
+
         public void putDeepOperationalData(InstanceIdentifier entryKey, CompositeNode entryData) {
             this.putCompositeNodeData(entryKey, entryData, OPERATIONAL_DATA_STORE_MARKER);
         }
@@ -401,18 +400,20 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
                     this.putOperationalData(entryKey, entryData);
                     break;
 
-                default :
+                default:
                     LOG.error(dataStoreIdentifier + " is NOT valid DataStore switch marker");
                     throw new RuntimeException(dataStoreIdentifier + " is NOT valid DataStore switch marker");
                 }
             }
         }
 
-        private void putCompositeNodeData(InstanceIdentifier entryKey, CompositeNode entryData, String dataStoreIdentifier) {
+        private void putCompositeNodeData(InstanceIdentifier entryKey, CompositeNode entryData,
+                String dataStoreIdentifier) {
             this.putData(entryKey, entryData, dataStoreIdentifier);
-            
+
             for (Node<?> child : entryData.getChildren()) {
-                InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType()).toInstance();
+                InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType())
+                        .toInstance();
                 if (child instanceof CompositeNode) {
                     DataSchemaNode subSchema = schemaNodeFor(subEntryId);
                     CompositeNode compNode = (CompositeNode) child;
@@ -420,12 +421,13 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
 
                     if (subSchema instanceof ListSchemaNode) {
                         ListSchemaNode listSubSchema = (ListSchemaNode) subSchema;
-                        Map<QName, Object> mapOfSubValues = this.getValuesFromListSchema(listSubSchema, (CompositeNode) child);
+                        Map<QName, Object> mapOfSubValues = this.getValuesFromListSchema(listSubSchema,
+                                (CompositeNode) child);
                         if (mapOfSubValues != null) {
-                            instanceId = InstanceIdentifier.builder(entryKey).nodeWithKey(listSubSchema.getQName(), mapOfSubValues).toInstance();
+                            instanceId = InstanceIdentifier.builder(entryKey)
+                                    .nodeWithKey(listSubSchema.getQName(), mapOfSubValues).toInstance();
                         }
-                    } 
-                    else if (subSchema instanceof ContainerSchemaNode) {
+                    } else if (subSchema instanceof ContainerSchemaNode) {
                         ContainerSchemaNode containerSchema = (ContainerSchemaNode) subSchema;
                         instanceId = InstanceIdentifier.builder(entryKey).node(subSchema.getQName()).toInstance();
                     }
@@ -436,13 +438,13 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator<DataS
             }
         }
 
-        private Map<QName, Object> getValuesFromListSchema (ListSchemaNode listSchema, CompositeNode entryData) {
+        private Map<QName, Object> getValuesFromListSchema(ListSchemaNode listSchema, CompositeNode entryData) {
             List<QName> keyDef = listSchema.getKeyDefinition();
-            if (keyDef != null && ! keyDef.isEmpty()) {
+            if (keyDef != null && !keyDef.isEmpty()) {
                 Map<QName, Object> map = new HashMap<QName, Object>();
                 for (QName key : keyDef) {
                     List<Node<?>> data = entryData.get(key);
-                    if (data != null && ! data.isEmpty()) {
+                    if (data != null && !data.isEmpty()) {
                         for (Node<?> nodeData : data) {
                             if (nodeData instanceof SimpleNode<?>) {
                                 map.put(key, data.get(0).getValue());
index f6c39bf..0683c45 100644 (file)
@@ -94,14 +94,14 @@ public interface RestconfService {
     @Consumes({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML,
                Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML,
                MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier, CompositeNode payload);
     
     @POST
     @Path("/operations/{identifier:.+}")
     @Produces({Draft02.MediaTypes.OPERATION+JSON, Draft02.MediaTypes.OPERATION+XML,
                Draft02.MediaTypes.DATA+JSON, Draft02.MediaTypes.DATA+XML,
                MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
-    public StructuredData invokeRpc(@PathParam("identifier") String identifier, @DefaultValue("") String noPayload);
+    public StructuredData invokeRpc(@Encoded @PathParam("identifier") String identifier, @DefaultValue("") String noPayload);
     
     @GET
     @Path("/config/{identifier:.+}")
index 482dcf8..9b5c507 100644 (file)
@@ -356,7 +356,6 @@ class ControllerContext implements SchemaServiceListener {
 
     private def toUriString(Object object) {
         if(object === null) return "";
-//        return object.toString.replace("/",URI_SLASH_PLACEHOLDER)
         return URLEncoder.encode(object.toString,URI_ENCODING_CHAR_SET)        
     }
     
@@ -620,6 +619,13 @@ class ControllerContext implements SchemaServiceListener {
             decodedPathArgs.add(URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET))
         }
         return decodedPathArgs
+    }
+
+    def urlPathArgDecode(String pathArg) {
+        if (pathArg !== null) {
+            return URLDecoder.decode(pathArg, URI_ENCODING_CHAR_SET)
+        }
+        return null
     }    
 
 }
index cfbce73..e09dc7a 100644 (file)
@@ -230,10 +230,7 @@ class RestconfImpl implements RestconfService {
     }
 
     override invokeRpc(String identifier, CompositeNode payload) {
-        val rpc = identifier.rpcDefinition
-        if (rpc === null) {
-            throw new ResponseException(NOT_FOUND, "RPC does not exist.");
-        }
+        val rpc = resolveIdentifierInInvokeRpc(identifier)
         if (rpc.QName.namespace.toString == SAL_REMOTE_NAMESPACE && rpc.QName.localName == SAL_REMOTE_RPC_SUBSRCIBE) {
             val value = normalizeNode(payload, rpc.input, null)
             val pathNode = value?.getFirstSimpleByName(QName.create(rpc.QName, "path"))
@@ -267,7 +264,22 @@ class RestconfImpl implements RestconfService {
         if (!noPayload.nullOrEmpty) {
             throw new ResponseException(UNSUPPORTED_MEDIA_TYPE, "Content-Type contains unsupported Media Type.");
         }
-        return callRpc(identifier.rpcDefinition, null)
+        val rpc = resolveIdentifierInInvokeRpc(identifier)
+        return callRpc(rpc, null)
+    }
+
+    def resolveIdentifierInInvokeRpc(String identifier) {
+        if (identifier.indexOf("/") === -1) {
+            val identifierDecoded = identifier.urlPathArgDecode
+            val rpc = identifierDecoded.rpcDefinition
+            if (rpc !== null) {
+                return rpc
+            }
+            throw new ResponseException(NOT_FOUND, "RPC does not exist.");
+        }
+        val slashErrorMsg  = String.format("Identifier %n%s%ncan't contain slash character (/). +
+            If slash is part of identifier name then use %2F placeholder.",identifier)
+        throw new ResponseException(NOT_FOUND, slashErrorMsg);
     }
 
     private def StructuredData callRpc(RpcDefinition rpc, CompositeNode payload) {
index 07c0812..4a6a291 100644 (file)
@@ -269,7 +269,7 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createServiceDependency()
                     .setService(IFlowProgrammerNotifier.class)
                     .setCallbacks("setFlowProgrammerNotifier",
-                            "unsetsetFlowProgrammerNotifier")
+                            "unsetFlowProgrammerNotifier")
                     .setRequired(false));
 
             c.add(createServiceDependency()
index ba23941..3a4a192 100644 (file)
@@ -19,6 +19,7 @@ package org.opendaylight.controller.sal.core;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -65,11 +66,9 @@ public class Path implements Serializable {
             for (int i = 0; i < edges.size() - 1; i++) {
                 Edge current = edges.get(i);
                 Edge next = edges.get(i + 1);
-                if (!current.getHeadNodeConnector().getNode()
-                        .equals(
-                                next.getTailNodeConnector()
-                                        .getNode())) {
+                if (!current.getHeadNodeConnector().getNode().equals(next.getTailNodeConnector().getNode())) {
                     sequential = false;
+                    break;
                 }
             }
         } else if (edges.size() == 0) {
@@ -155,10 +154,10 @@ public class Path implements Serializable {
      * getter method for the Path
      *
      *
-     * @return Return the list of edges that constitue the Path
+     * @return Return the list of edges that constitute the Path
      */
     public List<Edge> getEdges() {
-        return this.edges;
+        return (edges == null) ? Collections.<Edge>emptyList() : new ArrayList<Edge>(edges);
     }
 
     @Override
@@ -171,18 +170,23 @@ public class Path implements Serializable {
 
     @Override
     public boolean equals(Object obj) {
-        if (this == obj)
+        if (this == obj) {
             return true;
-        if (obj == null)
+        }
+        if (obj == null) {
             return false;
-        if (getClass() != obj.getClass())
+        }
+        if (getClass() != obj.getClass()) {
             return false;
+        }
         Path other = (Path) obj;
         if (edges == null) {
-            if (other.edges != null)
+            if (other.edges != null) {
                 return false;
-        } else if (!edges.equals(other.edges))
+            }
+        } else if (!edges.equals(other.edges)) {
             return false;
+        }
         return true;
     }
 

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.