Updated ONOS sources to commit ID 3f28c6803193d493b636dd3c43e08a3e6b35acca 27/3127/1
authorAshlee Young <ashlee@wildernessvoice.com>
Sat, 7 Nov 2015 17:43:53 +0000 (09:43 -0800)
committerAshlee Young <ashlee@wildernessvoice.com>
Sat, 7 Nov 2015 17:43:53 +0000 (09:43 -0800)
Change-Id: I08d1eb7ee31b38491b046933c502894d133b2a2d
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
104 files changed:
framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/PolicyHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java [new file with mode: 0644]
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java [moved from framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DeviceConfiguration.java with 87% similarity]
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java [moved from framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DeviceProperties.java with 65% similarity]
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java
framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java
framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json [new file with mode: 0644]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlags.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIGPFlags.java with 66% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IsIsNonPseudonodeTest.java [deleted file]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OspfNonPseudonodeTest.java [deleted file]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPKeepaliveMsgTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BGPKeepaliveMsgTest.java with 90% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BGPOpenMsgTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BGPOpenMsgTest.java with 98% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/protocol/BgpNotificationMsgTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpNotificationMsgTest.java with 97% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java [new file with mode: 0644]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/As4PathTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/As4PathTest.java with 96% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AsPathTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/AsPathTest.java with 96% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AutonomousSystemTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/AutonomousSystemTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/BGPLSIdentifierTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BGPLSIdentifierTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IPReachabilityInformationTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IPReachabilityInformationTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IPv4AddressTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IPv4AddressTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IPv6AddressTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IPv6AddressTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/IsIsPseudonodeTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IsIsPseudonodeTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/LinkLocalRemoteIdentifiersTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/LinkLocalRemoteIdentifiersTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/NextHopTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/NextHopTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/OriginTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OriginTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/OspfPseudonodeTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OspfPseudonodeTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/OspfRouteTypeTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OspfRouteTypeTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpAttrNodeFlagBitTlvTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpAttrNodeFlagBitTlvTest.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpAttrRouterIdV6Test.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpAttrRouterIdV6Test.java with 94% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrIgpMetricTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrIgpMetricTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrMplsProtocolMaskTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrMplsProtocolMaskTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpLinkAttrProtectionTypeTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrProtectionTypeTest.java with 95% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlagsTest.java [new file with mode: 0644]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrMetricTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpPrefixAttrMetricTest.java with 93% similarity]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOspfFwdAddrTest.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpPrefixAttrOspfFwdAddrTest.java with 95% similarity]
framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceEvent.java [new file with mode: 0644]
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceListener.java [moved from framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/AreaIdTest.java with 50% similarity]
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStoreDelegate.java [moved from framework/src/onos/incubator/net/src/main/java/org/onosproject/incubator/net/intf/package-info.java with 75% similarity]
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java
framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java
framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java
framework/src/onos/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/CpqdOFDPA2Pipeline.java
framework/src/onos/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA2Pipeline.java
framework/src/onos/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/Controller.java
framework/src/onos/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OFChannelHandler.java
framework/src/onos/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
framework/src/onos/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/RoleManager.java
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java [new file with mode: 0644]
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java [new file with mode: 0644]
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java [new file with mode: 0644]
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java [new file with mode: 0644]
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java [new file with mode: 0644]
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbClientService.java
framework/src/onos/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/OvsdbNodeId.java
framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
framework/src/onos/utils/junit/src/main/java/org/onlab/junit/TestTools.java
framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks [new file with mode: 0644]

index 28d1e8b..5da5c2b 100644 (file)
@@ -65,6 +65,8 @@ public class PIMInterface {
 
     /**
      * Create a PIMInterface.
+     *
+     * @param intf the network interface configuration
      */
     public PIMInterface(Interface intf) {
 
index 36563f0..96c85ba 100644 (file)
@@ -31,6 +31,8 @@ import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.HostId;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -140,9 +142,16 @@ public class ArpHandler {
      * @param inPort in-port
      */
     public void sendArpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
-
-        byte[] senderMacAddress = config.getDeviceMac(deviceId).toBytes();
-        byte[] senderIpAddress = config.getRouterIp(deviceId).toOctets();
+        byte[] senderMacAddress;
+        byte[] senderIpAddress;
+
+        try {
+            senderMacAddress = config.getDeviceMac(deviceId).toBytes();
+            senderIpAddress = config.getRouterIp(deviceId).toOctets();
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting sendArpRequest.");
+            return;
+        }
 
         ARP arpRequest = new ARP();
         arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
index c4a91c7..a737339 100644 (file)
@@ -23,6 +23,8 @@ import org.onlab.packet.IpPrefix;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -449,7 +451,20 @@ public class DefaultRoutingHandler {
 
         // If both target switch and dest switch are edge routers, then set IP
         // rule for both subnet and router IP.
-        if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
+        boolean targetIsEdge;
+        boolean destIsEdge;
+        Ip4Address destRouterIp;
+
+        try {
+            targetIsEdge = config.isEdgeDevice(targetSw);
+            destIsEdge = config.isEdgeDevice(destSw);
+            destRouterIp = config.getRouterIp(destSw);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateEcmpRoutingRulePartial.");
+            return false;
+        }
+
+        if (targetIsEdge && destIsEdge) {
             Set<Ip4Prefix> subnets = config.getSubnets(destSw);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
                     targetSw, destSw, subnets);
@@ -461,7 +476,7 @@ public class DefaultRoutingHandler {
                 return false;
             }
 
-            Ip4Address routerIp = config.getRouterIp(destSw);
+            Ip4Address routerIp = destRouterIp;
             IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
                     targetSw, destSw, routerIpPrefix);
@@ -471,8 +486,8 @@ public class DefaultRoutingHandler {
             }
 
         // If the target switch is an edge router, then set IP rules for the router IP.
-        } else if (config.isEdgeDevice(targetSw)) {
-            Ip4Address routerIp = config.getRouterIp(destSw);
+        } else if (targetIsEdge) {
+            Ip4Address routerIp = destRouterIp;
             IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
             log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
                     targetSw, destSw, routerIpPrefix);
index b3916b0..c4267eb 100644 (file)
@@ -28,6 +28,8 @@ import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,7 +73,13 @@ public class IcmpHandler {
         Ip4Address destinationAddress =
                 Ip4Address.valueOf(ipv4.getDestinationAddress());
         Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId);
-        Ip4Address routerIp = config.getRouterIp(deviceId);
+        Ip4Address routerIp;
+        try {
+            routerIp = config.getRouterIp(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting processPacketIn.");
+            return;
+        }
         IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
         Ip4Address routerIpAddress = routerIpPrefix.getIp4Prefix().address();
 
index 14ce679..b1682e7 100644 (file)
@@ -26,6 +26,8 @@ import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -127,13 +129,19 @@ public class IpHandler {
 
         for (IPv4 ipPacket : ipPacketQueue.get(destIpAddress)) {
             Ip4Address destAddress = Ip4Address.valueOf(ipPacket.getDestinationAddress());
-            if (ipPacket != null && config.inSameSubnet(deviceId, destAddress)) {
+            if (config.inSameSubnet(deviceId, destAddress)) {
                 ipPacket.setTtl((byte) (ipPacket.getTtl() - 1));
                 ipPacket.setChecksum((short) 0);
                 for (Host dest: srManager.hostService.getHostsByIp(destIpAddress)) {
                     Ethernet eth = new Ethernet();
                     eth.setDestinationMACAddress(dest.mac());
-                    eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                    try {
+                        eth.setSourceMACAddress(config.getDeviceMac(deviceId));
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage()
+                                + " Skipping forwardPackets for this destination.");
+                        continue;
+                    }
                     eth.setEtherType(Ethernet.TYPE_IPV4);
                     eth.setPayload(ipPacket);
 
index 83cb7e8..0a4c26d 100644 (file)
@@ -27,6 +27,7 @@ import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.slf4j.Logger;
 
index d46028e..f827403 100644 (file)
@@ -22,6 +22,8 @@ import org.onlab.packet.IpPrefix;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
@@ -103,6 +105,14 @@ public class RoutingRulePopulator {
      */
     public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
                                       MacAddress hostMac, PortNumber outPort) {
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpRuleForHost.");
+            return;
+        }
+
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
 
@@ -111,7 +121,7 @@ public class RoutingRulePopulator {
 
         tbuilder.deferred()
                 .setEthDst(hostMac)
-                .setEthSrc(config.getDeviceMac(deviceId))
+                .setEthSrc(deviceMac)
                 .setOutput(outPort);
 
         TrafficTreatment treatment = tbuilder.build();
@@ -167,6 +177,13 @@ public class RoutingRulePopulator {
     public boolean populateIpRuleForRouter(DeviceId deviceId,
                                            IpPrefix ipPrefix, DeviceId destSw,
                                            Set<DeviceId> nextHops) {
+        int segmentId;
+        try {
+            segmentId = config.getSegmentId(destSw);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateIpRuleForRouter.");
+            return false;
+        }
 
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
@@ -183,7 +200,7 @@ public class RoutingRulePopulator {
             ns = new NeighborSet(nextHops);
         } else {
             tbuilder.deferred().copyTtlOut();
-            ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
+            ns = new NeighborSet(nextHops, segmentId);
         }
 
         TrafficTreatment treatment = tbuilder.build();
@@ -227,19 +244,26 @@ public class RoutingRulePopulator {
      */
     public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId,
                                     Set<DeviceId> nextHops) {
+        int segmentId;
+        try {
+            segmentId = config.getSegmentId(destSwId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateMplsRule.");
+            return false;
+        }
 
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
         List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<>();
 
         // TODO Handle the case of Bos == false
-        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId)));
+        sbuilder.matchMplsLabel(MplsLabel.mplsLabel(segmentId));
         sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
 
         // If the next hop is the destination router, do PHP
         if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
             log.debug("populateMplsRule: Installing MPLS forwarding objective for "
                     + "label {} in switch {} with PHP",
-                    config.getSegmentId(destSwId),
+                    segmentId,
                     deviceId);
 
             ForwardingObjective.Builder fwdObjBosBuilder =
@@ -264,7 +288,7 @@ public class RoutingRulePopulator {
         } else {
             log.debug("Installing MPLS forwarding objective for "
                     + "label {} in switch {} without PHP",
-                    config.getSegmentId(destSwId),
+                    segmentId,
                     deviceId);
 
             ForwardingObjective.Builder fwdObjBosBuilder =
@@ -310,9 +334,21 @@ public class RoutingRulePopulator {
                                                                    Set<DeviceId> nextHops,
                                                                    boolean phpRequired,
                                                                    boolean isBos) {
-
         ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
                 .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
+        DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
+
+        boolean isEdge;
+        MacAddress srcMac;
+        MacAddress dstMac;
+        try {
+            isEdge = config.isEdgeDevice(deviceId);
+            srcMac = config.getDeviceMac(deviceId);
+            dstMac = config.getDeviceMac(nextHop);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting getMplsForwardingObjective");
+            return null;
+        }
 
         TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
 
@@ -329,16 +365,15 @@ public class RoutingRulePopulator {
             tbuilder.deferred().decMplsTtl();
         }
 
-        if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
+        if (!isECMPSupportedInTransitRouter() && !isEdge) {
             PortNumber port = selectOnePort(deviceId, nextHops);
-            DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
             if (port == null) {
                 log.warn("No link from {} to {}", deviceId, nextHops);
                 return null;
             }
             tbuilder.deferred()
-                    .setEthSrc(config.getDeviceMac(deviceId))
-                    .setEthDst(config.getDeviceMac(nextHop))
+                    .setEthSrc(srcMac)
+                    .setEthDst(dstMac)
                     .setOutput(port);
             fwdBuilder.withTreatment(tbuilder.build());
         } else {
@@ -372,15 +407,27 @@ public class RoutingRulePopulator {
     public void populateRouterMacVlanFilters(DeviceId deviceId) {
         log.debug("Installing per-port filtering objective for untagged "
                 + "packets in device {}", deviceId);
+
+        MacAddress deviceMac;
+        try {
+            deviceMac = config.getDeviceMac(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateRouterMacVlanFilters.");
+            return;
+        }
+
         for (Port port : srManager.deviceService.getPorts(deviceId)) {
             if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
                 Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number());
                 VlanId assignedVlan = (portSubnet == null)
                         ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)
                         : srManager.getSubnetAssignedVlanId(deviceId, portSubnet);
+
+
+
                 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
                 fob.withKey(Criteria.matchInPort(port.number()))
-                .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
+                .addCondition(Criteria.matchEthDst(deviceMac))
                 .addCondition(Criteria.matchVlanId(VlanId.NONE));
                 // vlan assignment is valid only if this instance is master
                 if (srManager.mastershipService.isLocalMaster(deviceId)) {
@@ -405,6 +452,14 @@ public class RoutingRulePopulator {
      * @param deviceId the switch dpid for the router
      */
     public void populateRouterIpPunts(DeviceId deviceId) {
+        Ip4Address routerIp;
+        try {
+            routerIp = config.getRouterIp(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateRouterIpPunts.");
+            return;
+        }
+
         if (!srManager.mastershipService.isLocalMaster(deviceId)) {
             log.debug("Not installing port-IP punts - not the master for dev:{} ",
                       deviceId);
@@ -412,7 +467,7 @@ public class RoutingRulePopulator {
         }
         ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
         Set<Ip4Address> allIps = new HashSet<Ip4Address>(config.getPortIPs(deviceId));
-        allIps.add(config.getRouterIp(deviceId));
+        allIps.add(routerIp);
         for (Ip4Address ipaddr : allIps) {
             TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
             TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
index b82752d..787f934 100644 (file)
@@ -38,6 +38,8 @@ import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
@@ -553,7 +555,10 @@ public class SegmentRoutingManager implements SegmentRoutingService {
 
     private void processLinkAdded(Link link) {
         log.debug("A new link {} was added", link.toString());
-
+        if (!deviceConfiguration.isConfigured(link.src().deviceId())) {
+            log.warn("Source device of this link is not configured.");
+            return;
+        }
         //Irrespective whether the local is a MASTER or not for this device,
         //create group handler instance and push default TTP flow rules.
         //Because in a multi-instance setup, instances can initiate
@@ -596,7 +601,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
 
     private void processDeviceAdded(Device device) {
         log.debug("A new device with ID {} was added", device.id());
-        if (deviceConfiguration == null) {
+        if (deviceConfiguration == null || !deviceConfiguration.isConfigured(device.id())) {
             log.warn("Device configuration uploading. Device {} will be "
                     + "processed after config completes.", device.id());
             return;
@@ -608,14 +613,20 @@ public class SegmentRoutingManager implements SegmentRoutingService {
         // to the switch). To handle this, a default-group-handler instance is necessary
         // per switch.
         if (groupHandlerMap.get(device.id()) == null) {
-            DefaultGroupHandler groupHandler = DefaultGroupHandler.
-                    createGroupHandler(device.id(),
-                                       appId,
-                                       deviceConfiguration,
-                                       linkService,
-                                       flowObjectiveService,
-                                       nsNextObjStore,
-                                       subnetNextObjStore);
+            DefaultGroupHandler groupHandler;
+            try {
+                groupHandler = DefaultGroupHandler.
+                        createGroupHandler(device.id(),
+                                           appId,
+                                           deviceConfiguration,
+                                           linkService,
+                                           flowObjectiveService,
+                                           nsNextObjStore,
+                                           subnetNextObjStore);
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Aborting processDeviceAdded.");
+                return;
+            }
             groupHandlerMap.put(device.id(), groupHandler);
             // Also, in some cases, drivers may need extra
             // information to process rules (eg. Router IP/MAC); and so, we send
@@ -667,12 +678,20 @@ public class SegmentRoutingManager implements SegmentRoutingService {
                 // to the switch). To handle this, a default-group-handler instance is necessary
                 // per switch.
                 if (groupHandlerMap.get(device.id()) == null) {
-                    DefaultGroupHandler groupHandler = DefaultGroupHandler
-                            .createGroupHandler(device.id(), appId,
-                                                deviceConfiguration, linkService,
-                                                flowObjectiveService,
-                                                nsNextObjStore,
-                                                subnetNextObjStore);
+                    DefaultGroupHandler groupHandler;
+                    try {
+                        groupHandler = DefaultGroupHandler.
+                                createGroupHandler(device.id(),
+                                                   appId,
+                                                   deviceConfiguration,
+                                                   linkService,
+                                                   flowObjectiveService,
+                                                   nsNextObjStore,
+                                                   subnetNextObjStore);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + " Aborting configureNetwork.");
+                        return;
+                    }
                     groupHandlerMap.put(device.id(), groupHandler);
 
                     // Also, in some cases, drivers may need extra
index 820bb40..7d025c7 100644 (file)
@@ -18,6 +18,7 @@ package org.onosproject.segmentrouting;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
 import org.onosproject.store.service.EventuallyConsistentMap;
diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfigNotFoundException.java
new file mode 100644 (file)
index 0000000..ae156e6
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.config;
+
+/**
+ * Signals that an error occurred during reading device configuration.
+ */
+public class DeviceConfigNotFoundException extends Exception {
+
+    /**
+     * Creates a new ConfigNotFoundException with the given message.
+     *
+     * @param message exception message
+     */
+    public DeviceConfigNotFoundException(String message) {
+        super(message);
+    }
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.segmentrouting;
+package org.onosproject.segmentrouting.config;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
@@ -26,9 +26,7 @@ import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.host.InterfaceIpAddress;
-import org.onosproject.segmentrouting.config.SegmentRoutingConfig;
 import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid;
-import org.onosproject.segmentrouting.grouphandler.DeviceProperties;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.slf4j.Logger;
@@ -126,23 +124,20 @@ public class DeviceConfiguration implements DeviceProperties {
         });
     }
 
-    /**
-     * Returns the Node segment id of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return segment id
-     */
     @Override
-    public int getSegmentId(DeviceId deviceId) {
+    public boolean isConfigured(DeviceId deviceId) {
+        return deviceConfigMap.get(deviceId) != null;
+    }
+
+    @Override
+    public int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getSegmentId for device{} is {}", deviceId, srinfo.nodeSid);
             return srinfo.nodeSid;
         } else {
-            log.warn("getSegmentId for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getSegmentId fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
@@ -180,71 +175,42 @@ public class DeviceConfiguration implements DeviceProperties {
         return -1;
     }
 
-    /**
-     * Returns the router mac of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return router mac address
-     */
     @Override
-    public MacAddress getDeviceMac(DeviceId deviceId) {
+    public MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getDeviceMac for device{} is {}", deviceId, srinfo.mac);
             return srinfo.mac;
         } else {
-            log.warn("getDeviceMac for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getDeviceMac fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Returns the router ip address of a segment router.
-     *
-     * @param deviceId device identifier
-     * @return router ip address
-     */
-    public Ip4Address getRouterIp(DeviceId deviceId) {
+    @Override
+    public Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("getDeviceIp for device{} is {}", deviceId, srinfo.ip);
             return srinfo.ip;
         } else {
-            log.warn("getRouterIp for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "getRouterIp fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Indicates if the segment router is a edge router or
-     * a core/backbone router.
-     *
-     * @param deviceId device identifier
-     * @return boolean
-     */
     @Override
-    public boolean isEdgeDevice(DeviceId deviceId) {
+    public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
         if (srinfo != null) {
             log.trace("isEdgeDevice for device{} is {}", deviceId, srinfo.isEdge);
             return srinfo.isEdge;
         } else {
-            log.warn("isEdgeDevice for device {} "
-                    + "throwing IllegalStateException "
-                    + "because device does not exist in config", deviceId);
-            throw new IllegalStateException();
+            String message = "isEdgeDevice fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
         }
     }
 
-    /**
-     * Returns the node segment ids of all configured segment routers.
-     *
-     * @return list of node segment ids
-     */
     @Override
     public List<Integer> getAllDeviceSegmentIds() {
         return allSegmentIds;
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.segmentrouting.grouphandler;
+package org.onosproject.segmentrouting.config;
 
 import java.util.List;
 import java.util.Map;
 
+import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.DeviceId;
@@ -29,29 +30,49 @@ import org.onosproject.net.PortNumber;
  * Mac address...etc from group handler applications.
  */
 public interface DeviceProperties {
+    /**
+     * Checks if the device is configured.
+     *
+     * @param deviceId device identifier
+     * @return true if the device is configured
+     */
+    boolean isConfigured(DeviceId deviceId);
+
     /**
      * Returns the segment id of a device to be used in group creation.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return segment id of a device
      */
-    int getSegmentId(DeviceId deviceId);
+    int getSegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Returns the Mac address of a device to be used in group creation.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return mac address of a device
      */
-    MacAddress getDeviceMac(DeviceId deviceId);
+    MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
+     * Returns the router ip address of a segment router.
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return router ip address
+     */
+    Ip4Address getRouterIp(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Indicates whether a device is edge device or transit/core device.
      *
      * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return boolean
      */
-    boolean isEdgeDevice(DeviceId deviceId);
+    boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
      * Returns all segment IDs to be considered in building auto
index a5c1090..33496bd 100644 (file)
@@ -24,6 +24,7 @@ import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 
 /**
index 69a0d86..55b556e 100644 (file)
@@ -48,6 +48,8 @@ import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.DefaultGroupKey;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.slf4j.Logger;
 
@@ -63,9 +65,9 @@ public class DefaultGroupHandler {
     protected final ApplicationId appId;
     protected final DeviceProperties deviceConfig;
     protected final List<Integer> allSegmentIds;
-    protected final int nodeSegmentId;
-    protected final boolean isEdgeRouter;
-    protected final MacAddress nodeMacAddr;
+    protected int nodeSegmentId = -1;
+    protected boolean isEdgeRouter = false;
+    protected MacAddress nodeMacAddr = null;
     protected LinkService linkService;
     protected FlowObjectiveService flowObjectiveService;
 
@@ -99,10 +101,15 @@ public class DefaultGroupHandler {
         this.appId = checkNotNull(appId);
         this.deviceConfig = checkNotNull(config);
         this.linkService = checkNotNull(linkService);
-        allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
-        nodeSegmentId = config.getSegmentId(deviceId);
-        isEdgeRouter = config.isEdgeDevice(deviceId);
-        nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+        this.allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
+        try {
+            this.nodeSegmentId = config.getSegmentId(deviceId);
+            this.isEdgeRouter = config.isEdgeDevice(deviceId);
+            this.nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage()
+                    + " Skipping value assignment in DefaultGroupHandler");
+        }
         this.flowObjectiveService = flowObjService;
         this.nsNextObjStore = nsNextObjStore;
         this.subnetNextObjStore = subnetNextObjStore;
@@ -122,6 +129,7 @@ public class DefaultGroupHandler {
      * @param flowObjService flow objective service object
      * @param nsNextObjStore NeighborSet next objective store map
      * @param subnetNextObjStore subnet next objective store map
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
      * @return default group handler type
      */
     public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
@@ -133,7 +141,9 @@ public class DefaultGroupHandler {
                                                                  NeighborSetNextObjectiveStoreKey,
                                                                  Integer> nsNextObjStore,
                                                          EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
-                                                                 Integer> subnetNextObjStore) {
+                                                                 Integer> subnetNextObjStore)
+                                                         throws DeviceConfigNotFoundException {
+        // handle possible exception in the caller
         if (config.isEdgeDevice(deviceId)) {
             return new DefaultEdgeGroupHandler(deviceId, appId, config,
                                                linkService,
@@ -176,6 +186,14 @@ public class DefaultGroupHandler {
             return;
         }
 
+        MacAddress dstMac;
+        try {
+            dstMac = deviceConfig.getDeviceMac(newLink.dst().deviceId());
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting linkUp.");
+            return;
+        }
+
         log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
                   newLink.src().port(), newLink.dst().deviceId());
         addNeighborAtPort(newLink.dst().deviceId(),
@@ -202,8 +220,7 @@ public class DefaultGroupHandler {
             TrafficTreatment.Builder tBuilder =
                     DefaultTrafficTreatment.builder();
             tBuilder.setOutput(newLink.src().port())
-                    .setEthDst(deviceConfig.getDeviceMac(
-                          newLink.dst().deviceId()))
+                    .setEthDst(dstMac)
                     .setEthSrc(nodeMacAddr);
             if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                 tBuilder.pushMpls()
@@ -242,6 +259,15 @@ public class DefaultGroupHandler {
             log.warn("portDown: unknown port");
             return;
         }
+
+        MacAddress dstMac;
+        try {
+            dstMac = deviceConfig.getDeviceMac(portDeviceMap.get(port));
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting portDown.");
+            return;
+        }
+
         log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
                   portDeviceMap.get(port));
         /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
@@ -263,8 +289,8 @@ public class DefaultGroupHandler {
             TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                     .builder();
             tBuilder.setOutput(port)
-                    .setEthDst(deviceConfig.getDeviceMac(portDeviceMap
-                                       .get(port))).setEthSrc(nodeMacAddr);
+                    .setEthDst(dstMac)
+                    .setEthSrc(nodeMacAddr);
             if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
                                                     .getEdgeLabel()));
@@ -432,7 +458,15 @@ public class DefaultGroupHandler {
     }
 
     private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
-        return (deviceConfig.getSegmentId(deviceId) == sId);
+        int segmentId;
+        try {
+            segmentId = deviceConfig.getSegmentId(deviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting isSegmentIdSameAsNodeSegmentId.");
+            return false;
+        }
+
+        return segmentId == sId;
     }
 
     protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) {
@@ -487,11 +521,19 @@ public class DefaultGroupHandler {
                     return;
                 }
 
+                MacAddress deviceMac;
+                try {
+                    deviceMac = deviceConfig.getDeviceMac(d);
+                } catch (DeviceConfigNotFoundException e) {
+                    log.warn(e.getMessage() + " Aborting createGroupsFromNeighborsets.");
+                    return;
+                }
+
                 for (PortNumber sp : devicePortMap.get(d)) {
                     TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                             .builder();
                     tBuilder.setOutput(sp)
-                            .setEthDst(deviceConfig.getDeviceMac(d))
+                            .setEthDst(deviceMac)
                             .setEthSrc(nodeMacAddr);
                     if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
                         tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
@@ -535,6 +577,7 @@ public class DefaultGroupHandler {
 
             ports.forEach(port -> {
                 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+                tBuilder.popVlan();
                 tBuilder.setOutput(port);
                 nextObjBuilder.addTreatment(tBuilder.build());
             });
index b009e86..8e1b6a8 100644 (file)
@@ -23,6 +23,8 @@ import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.link.LinkService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.store.service.EventuallyConsistentMap;
 
 /**
@@ -171,7 +173,15 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
             if (deviceSubSet.size() > 1) {
                 boolean avoidEdgeRouterPairing = true;
                 for (DeviceId device : deviceSubSet) {
-                    if (!deviceConfig.isEdgeDevice(device)) {
+                    boolean isEdge;
+                    try {
+                        isEdge = deviceConfig.isEdgeDevice(device);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device.");
+                        continue;
+                    }
+
+                    if (!isEdge) {
                         avoidEdgeRouterPairing = false;
                         break;
                     }
index e47a662..5514207 100644 (file)
@@ -24,8 +24,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 
+import org.onlab.packet.MacAddress;
 import org.onlab.packet.MplsLabel;
 import org.onosproject.core.ApplicationId;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
+import org.onosproject.segmentrouting.config.DeviceProperties;
 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
 import org.onosproject.store.service.EventuallyConsistentMap;
 import org.onosproject.net.DeviceId;
@@ -105,11 +108,19 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
                                     PolicyGroupIdentifier(id,
                                                           Collections.singletonList(param),
                                                           Collections.singletonList(bucketId));
+                            MacAddress neighborEthDst;
+                            try {
+                                neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                            } catch (DeviceConfigNotFoundException e) {
+                                log.warn(e.getMessage()
+                                        + " Skipping createPolicyGroupChain for this label.");
+                                continue;
+                            }
+
                             TrafficTreatment.Builder tBuilder =
                                     DefaultTrafficTreatment.builder();
                             tBuilder.setOutput(sp)
-                                    .setEthDst(deviceConfig.
-                                               getDeviceMac(neighbor))
+                                    .setEthDst(neighborEthDst)
                                     .setEthSrc(nodeMacAddr)
                                     .pushMpls()
                                     .setMpls(MplsLabel.mplsLabel(label));
@@ -168,14 +179,23 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
 
             if (fullyResolved) {
                 List<GroupBucket> outBuckets = new ArrayList<>();
-                for (GroupBucketIdentifier bucketId:bucketIds) {
+                for (GroupBucketIdentifier bucketId : bucketIds) {
                     DeviceId neighbor = portDeviceMap.
                             get(bucketId.outPort());
+
+                    MacAddress neighborEthDst;
+                    try {
+                        neighborEthDst = deviceConfig.getDeviceMac(neighbor);
+                    } catch (DeviceConfigNotFoundException e) {
+                        log.warn(e.getMessage()
+                                + " Skipping createPolicyGroupChain for this bucketId.");
+                        continue;
+                    }
+
                     TrafficTreatment.Builder tBuilder =
                             DefaultTrafficTreatment.builder();
                     tBuilder.setOutput(bucketId.outPort())
-                            .setEthDst(deviceConfig.
-                                       getDeviceMac(neighbor))
+                            .setEthDst(neighborEthDst)
                             .setEthSrc(nodeMacAddr);
                     if (bucketId.label() != NeighborSet.NO_EDGE_LABEL) {
                         tBuilder.pushMpls()
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortChainCodecTest.java
new file mode 100644 (file)
index 0000000..02681db
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnweb.web;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.PortChain;
+import org.onosproject.vtnrsc.PortChainId;
+import org.onosproject.vtnrsc.TenantId;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Flow rule codec unit tests.
+ */
+public class PortChainCodecTest {
+
+    SfcCodecContext context;
+    JsonCodec<PortChain> portChainCodec;
+    /**
+     * Sets up for each test.  Creates a context and fetches the flow rule
+     * codec.
+     */
+    @Before
+    public void setUp() {
+        context = new SfcCodecContext();
+        portChainCodec = context.codec(PortChain.class);
+        assertThat(portChainCodec, notNullValue());
+    }
+
+    /**
+     * Reads in a rule from the given resource and decodes it.
+     *
+     * @param resourceName resource to use to read the JSON for the rule
+     * @return decoded flow rule
+     * @throws IOException if processing the resource fails
+     */
+    private PortChain getPortChain(String resourceName) throws IOException {
+        InputStream jsonStream = PortChainCodecTest.class
+                .getResourceAsStream(resourceName);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode json = mapper.readTree(jsonStream);
+        assertThat(json, notNullValue());
+        PortChain portChain = portChainCodec.decode((ObjectNode) json, context);
+        assertThat(portChain, notNullValue());
+        return portChain;
+    }
+
+    /**
+     * Checks that a simple rule decodes properly.
+     *
+     * @throws IOException if the resource cannot be processed
+     */
+    @Test
+    public void codecPortChainTest() throws IOException {
+
+        PortChain portChain = getPortChain("portChain.json");
+
+        assertThat(portChain, notNullValue());
+
+        PortChainId portChainId = PortChainId.of("1278dcd4-459f-62ed-754b-87fc5e4a6751");
+        TenantId tenantId = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+
+        assertThat(portChain.portChainId().toString(), is(portChainId.toString()));
+        assertThat(portChain.name(), is("PC2"));
+        assertThat(portChain.tenantId().toString(), is(tenantId.toString()));
+        assertThat(portChain.description(), is("Two flows and two port-pair-groups"));
+
+        assertThat(portChain.flowClassifiers(), notNullValue());
+        assertThat(portChain.portPairGroups(), notNullValue());
+    }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/PortPairGroupCodecTest.java
new file mode 100644 (file)
index 0000000..de2ee00
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnweb.web;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.PortPairGroup;
+import org.onosproject.vtnrsc.PortPairGroupId;
+import org.onosproject.vtnrsc.TenantId;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Flow rule codec unit tests.
+ */
+public class PortPairGroupCodecTest {
+
+    SfcCodecContext context;
+    JsonCodec<PortPairGroup> portPairGroupCodec;
+    /**
+     * Sets up for each test.  Creates a context and fetches the flow rule
+     * codec.
+     */
+    @Before
+    public void setUp() {
+        context = new SfcCodecContext();
+        portPairGroupCodec = context.codec(PortPairGroup.class);
+        assertThat(portPairGroupCodec, notNullValue());
+    }
+
+    /**
+     * Reads in a rule from the given resource and decodes it.
+     *
+     * @param resourceName resource to use to read the JSON for the rule
+     * @return decoded flow rule
+     * @throws IOException if processing the resource fails
+     */
+    private PortPairGroup getPortPairGroup(String resourceName) throws IOException {
+        InputStream jsonStream = PortPairGroupCodecTest.class
+                .getResourceAsStream(resourceName);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode json = mapper.readTree(jsonStream);
+        assertThat(json, notNullValue());
+        PortPairGroup portPairGroup = portPairGroupCodec.decode((ObjectNode) json, context);
+        assertThat(portPairGroup, notNullValue());
+        return portPairGroup;
+    }
+
+    /**
+     * Checks that a simple rule decodes properly.
+     *
+     * @throws IOException if the resource cannot be processed
+     */
+    @Test
+    public void codecPortPairGroupTest() throws IOException {
+
+        PortPairGroup portPairGroup = getPortPairGroup("portPairGroup.json");
+
+        assertThat(portPairGroup, notNullValue());
+
+        PortPairGroupId portPairGroupId = PortPairGroupId.of("4512d643-24fc-4fae-af4b-321c5e2eb3d1");
+        TenantId tenantId = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5");
+
+        assertThat(portPairGroup.portPairGroupId().toString(), is(portPairGroupId.toString()));
+        assertThat(portPairGroup.name(), is("PG1"));
+        assertThat(portPairGroup.tenantId().toString(), is(tenantId.toString()));
+        assertThat(portPairGroup.description(), is("Two port-pairs"));
+        assertThat(portPairGroup.portPairs(), notNullValue());
+    }
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portChain.json
new file mode 100644 (file)
index 0000000..07a1bc2
--- /dev/null
@@ -0,0 +1,14 @@
+{
+    "id": "1278dcd4-459f-62ed-754b-87fc5e4a6751",
+    "name": "PC2",
+    "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+    "description": "Two flows and two port-pair-groups",
+    "flow_classifiers": [
+        "456a4a34-2e9c-14ae-37fb-765feae2eb05",
+        "4a334cd4-fe9c-4fae-af4b-321c5e2eb051"
+    ],
+    "port_pair_groups": [
+        "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+        "4a634d49-76dc-4fae-af4b-321c5e23d651"
+    ]
+}
diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/web/portPairGroup.json
new file mode 100644 (file)
index 0000000..e19a66f
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "id": "4512d643-24fc-4fae-af4b-321c5e2eb3d1",
+    "name": "PG1",
+    "tenant_id": "d382007aa9904763a801f68ecf065cf5",
+    "description": "Two port-pairs",
+    "port_pairs": [
+        "875dfeda-43ed-23fe-454b-764feab2c342",
+        "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"
+    ]
+}
@@ -30,24 +30,24 @@ import com.google.common.base.MoreObjects;
 /**
  * Implements BGP prefix IGP Flag attribute.
  */
-public class BgpPrefixAttrIGPFlags implements BGPValueType {
+public final class BgpPrefixAttrIgpFlags implements BGPValueType {
 
     protected static final Logger log = LoggerFactory
-            .getLogger(BgpPrefixAttrIGPFlags.class);
+            .getLogger(BgpPrefixAttrIgpFlags.class);
 
     public static final int ATTR_PREFIX_FLAGBIT = 1152;
     public static final int ATTR_PREFIX_FLAG_LEN = 1;
 
-    public static final int FIRST_BIT = 0x80;
-    public static final int SECOND_BIT = 0x40;
-    public static final int THIRD_BIT = 0x20;
-    public static final int FOURTH_BIT = 0x01;
+    public static final byte FIRST_BIT = (byte) 0x80;
+    public static final byte SECOND_BIT = 0x40;
+    public static final byte THIRD_BIT = 0x20;
+    public static final byte FOURTH_BIT = 0x01;
 
     /* Prefix IGP flag bit TLV */
-    private boolean bisisUpDownBit = false;
-    private boolean bOspfNoUnicastBit = false;
-    private boolean bOspfLclAddrBit = false;
-    private boolean bOspfNSSABit = false;
+    private final boolean bisisUpDownBit;
+    private final boolean bOspfNoUnicastBit;
+    private final boolean bOspfLclAddrBit;
+    private final boolean bOspfNSSABit;
 
     /**
      * Constructor to initialize the value.
@@ -57,7 +57,8 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      * @param bOspfLclAddrBit OSPF local address Bit
      * @param bOspfNSSABit OSPF propagate NSSA Bit
      */
-    BgpPrefixAttrIGPFlags(boolean bisisUpDownBit, boolean bOspfNoUnicastBit,
+    BgpPrefixAttrIgpFlags(boolean bisisUpDownBit,
+                          boolean bOspfNoUnicastBit,
                           boolean bOspfLclAddrBit, boolean bOspfNSSABit) {
         this.bisisUpDownBit = bisisUpDownBit;
         this.bOspfNoUnicastBit = bOspfNoUnicastBit;
@@ -65,6 +66,23 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
         this.bOspfNSSABit = bOspfNSSABit;
     }
 
+    /**
+     * Returns object of this class with specified values.
+     *
+     * @param bisisUpDownBit IS-IS Up/Down Bit
+     * @param bOspfNoUnicastBit OSPF no unicast Bit
+     * @param bOspfLclAddrBit OSPF local address Bit
+     * @param bOspfNSSABit OSPF propagate NSSA Bit
+     * @return object of BgpPrefixAttrIGPFlags
+     */
+    public static BgpPrefixAttrIgpFlags of(final boolean bisisUpDownBit,
+                                           final boolean bOspfNoUnicastBit,
+                                           final boolean bOspfLclAddrBit,
+                                           final boolean bOspfNSSABit) {
+        return new BgpPrefixAttrIgpFlags(bisisUpDownBit, bOspfNoUnicastBit,
+                                         bOspfLclAddrBit, bOspfNSSABit);
+    }
+
     /**
      * Reads the IGP Flags.
      *
@@ -72,7 +90,7 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      * @return object of BgpPrefixAttrIGPFlags
      * @throws BGPParseException while parsing BgpPrefixAttrIGPFlags
      */
-    public static BgpPrefixAttrIGPFlags read(ChannelBuffer cb)
+    public static BgpPrefixAttrIgpFlags read(ChannelBuffer cb)
             throws BGPParseException {
         boolean bisisUpDownBit = false;
         boolean bOspfNoUnicastBit = false;
@@ -90,13 +108,13 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
 
         byte nodeFlagBits = cb.readByte();
 
-        bisisUpDownBit = ((nodeFlagBits & (byte) FIRST_BIT) == FIRST_BIT);
-        bOspfNoUnicastBit = ((nodeFlagBits & (byte) SECOND_BIT) == SECOND_BIT);
-        bOspfLclAddrBit = ((nodeFlagBits & (byte) THIRD_BIT) == THIRD_BIT);
-        bOspfNSSABit = ((nodeFlagBits & (byte) FOURTH_BIT) == FOURTH_BIT);
+        bisisUpDownBit = ((nodeFlagBits & FIRST_BIT) == FIRST_BIT);
+        bOspfNoUnicastBit = ((nodeFlagBits & SECOND_BIT) == SECOND_BIT);
+        bOspfLclAddrBit = ((nodeFlagBits & THIRD_BIT) == THIRD_BIT);
+        bOspfNSSABit = ((nodeFlagBits & FOURTH_BIT) == FOURTH_BIT);
 
-        return new BgpPrefixAttrIGPFlags(bisisUpDownBit, bOspfNoUnicastBit,
-                                         bOspfLclAddrBit, bOspfNSSABit);
+        return BgpPrefixAttrIgpFlags.of(bisisUpDownBit, bOspfNoUnicastBit,
+                                        bOspfLclAddrBit, bOspfNSSABit);
     }
 
     /**
@@ -104,7 +122,7 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      *
      * @return IS-IS Up/Down Bit set or not
      */
-    boolean getisisUpDownBit() {
+    public boolean isisUpDownBit() {
         return bisisUpDownBit;
     }
 
@@ -113,7 +131,7 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      *
      * @return OSPF no unicast Bit set or not
      */
-    boolean getOspfNoUnicastBit() {
+    public boolean ospfNoUnicastBit() {
         return bOspfNoUnicastBit;
     }
 
@@ -122,7 +140,7 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      *
      * @return OSPF local address Bit set or not
      */
-    boolean getOspfLclAddrBit() {
+    public boolean ospfLclAddrBit() {
         return bOspfLclAddrBit;
     }
 
@@ -131,7 +149,7 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
      *
      * @return OSPF propagate NSSA Bit set or not
      */
-    boolean getOspfNSSABit() {
+    public boolean ospfNSSABit() {
         return bOspfNSSABit;
     }
 
@@ -158,13 +176,13 @@ public class BgpPrefixAttrIGPFlags implements BGPValueType {
             return true;
         }
 
-        if (obj instanceof BgpPrefixAttrIGPFlags) {
-            BgpPrefixAttrIGPFlags other = (BgpPrefixAttrIGPFlags) obj;
+        if (obj instanceof BgpPrefixAttrIgpFlags) {
+            BgpPrefixAttrIgpFlags other = (BgpPrefixAttrIgpFlags) obj;
             return Objects.equals(bisisUpDownBit, other.bisisUpDownBit)
                     && Objects.equals(bOspfNoUnicastBit,
                                       other.bOspfNoUnicastBit)
-                    && Objects.equals(bOspfLclAddrBit, other.bOspfLclAddrBit)
-                    && Objects.equals(bOspfNSSABit, other.bOspfNSSABit);
+                                      && Objects.equals(bOspfLclAddrBit, other.bOspfLclAddrBit)
+                                      && Objects.equals(bOspfNSSABit, other.bOspfNSSABit);
         }
         return false;
     }
diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IsIsNonPseudonodeTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/IsIsNonPseudonodeTest.java
deleted file mode 100644 (file)
index 8112b51..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.bgp;
-
-import org.junit.Test;
-import org.onosproject.bgpio.types.IsIsNonPseudonode;
-
-import com.google.common.testing.EqualsTester;
-
-/**
- * Test for IsIsNonPseudonode Tlv.
- */
-public class IsIsNonPseudonodeTest {
-    private final byte[] value1 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
-    private final byte[] value2 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x59};
-    private final IsIsNonPseudonode tlv1 = IsIsNonPseudonode.of(value1);
-    private final IsIsNonPseudonode sameAsTlv1 = IsIsNonPseudonode.of(value1);
-    private final IsIsNonPseudonode tlv2 = IsIsNonPseudonode.of(value2);
-
-    @Test
-    public void basics() {
-        new EqualsTester()
-        .addEqualityGroup(tlv1, sameAsTlv1)
-        .addEqualityGroup(tlv2)
-        .testEquals();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OspfNonPseudonodeTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/OspfNonPseudonodeTest.java
deleted file mode 100644 (file)
index 1900291..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.bgp;
-
-import org.junit.Test;
-import org.onosproject.bgpio.types.OSPFNonPseudonode;
-
-import com.google.common.testing.EqualsTester;
-
-/**
- * Test for OSPFNonPseudonode Tlv.
- */
-public class OspfNonPseudonodeTest {
-    private final int value1 = 0x12121212;
-    private final int value2 = 0x12121211;
-    private final OSPFNonPseudonode tlv1 = OSPFNonPseudonode.of(value1);
-    private final OSPFNonPseudonode sameAsTlv1 = OSPFNonPseudonode.of(value1);
-    private final OSPFNonPseudonode tlv2 = OSPFNonPseudonode.of(value2);
-
-    @Test
-    public void basics() {
-        new EqualsTester()
-        .addEqualityGroup(tlv1, sameAsTlv1)
-        .addEqualityGroup(tlv2)
-        .testEquals();
-    }
-}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.core.Is.is;
+package org.onosproject.bgpio.protocol;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPKeepaliveMsg;
-import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPMessageReader;
 import org.onosproject.bgpio.types.BGPHeader;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+
 /**
  * Test case for BGP KEEPALIVE Message.
  */
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.core.Is.is;
+package org.onosproject.bgpio.protocol;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPMessageReader;
-import org.onosproject.bgpio.protocol.BGPOpenMsg;
 import org.onosproject.bgpio.types.BGPHeader;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+
 /**
  * Test cases for BGP Open Message.
  */
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.core.Is.is;
+package org.onosproject.bgpio.protocol;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.junit.Test;
 import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPMessageReader;
-import org.onosproject.bgpio.protocol.BGPNotificationMsg;
 import org.onosproject.bgpio.types.BGPHeader;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.core.Is.is;
+
 /**
  * Test for Notification message.
  */
@@ -225,4 +221,4 @@ public class BgpNotificationMsgTest {
         buf.readBytes(testNotificationMsg, 0, iReadLen);
         assertThat(testNotificationMsg, is(notificationMsg));
     }
-}
\ No newline at end of file
+}
diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/AreaIdTest.java
new file mode 100644 (file)
index 0000000..6a9e2ec
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.types;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Test for AreaID Tlv.
+ */
+public class AreaIdTest {
+    private final int value1 = 10;
+    private final int value2 = 20;
+    private final AreaIDTlv tlv1 = AreaIDTlv.of(value1);
+    private final AreaIDTlv sameAsTlv1 = AreaIDTlv.of(value1);
+    private final AreaIDTlv tlv2 = AreaIDTlv.of(value2);
+
+    @Test
+    public void testEquality() {
+        new EqualsTester()
+        .addEqualityGroup(tlv1, sameAsTlv1)
+        .addEqualityGroup(tlv2)
+        .testEquals();
+    }
+
+    /**
+     * Test for OSPFNonPseudonode Tlv.
+     */
+    public static class OspfNonPseudonodeTest {
+        private final int value1 = 0x12121212;
+        private final int value2 = 0x12121211;
+        private final OSPFNonPseudonode tlv1 = OSPFNonPseudonode.of(value1);
+        private final OSPFNonPseudonode sameAsTlv1 = OSPFNonPseudonode.of(value1);
+        private final OSPFNonPseudonode tlv2 = OSPFNonPseudonode.of(value2);
+
+        @Test
+        public void basics() {
+            new EqualsTester()
+            .addEqualityGroup(tlv1, sameAsTlv1)
+            .addEqualityGroup(tlv2)
+            .testEquals();
+        }
+    }
+
+    /**
+     * Test for IsIsNonPseudonode Tlv.
+     */
+    public static class IsIsNonPseudonodeTest {
+        private final byte[] value1 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x58};
+        private final byte[] value2 = new byte[] {0x19, 0x00, (byte) 0x95, 0x01, (byte) 0x90, 0x59};
+        private final IsIsNonPseudonode tlv1 = IsIsNonPseudonode.of(value1);
+        private final IsIsNonPseudonode sameAsTlv1 = IsIsNonPseudonode.of(value1);
+        private final IsIsNonPseudonode tlv2 = IsIsNonPseudonode.of(value2);
+
+        @Test
+        public void basics() {
+            new EqualsTester()
+            .addEqualityGroup(tlv1, sameAsTlv1)
+            .addEqualityGroup(tlv2)
+            .testEquals();
+        }
+    }
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.As4Path;
 
 import com.google.common.testing.EqualsTester;
 
@@ -53,4 +52,4 @@ public class As4PathTest {
         .addEqualityGroup(attr4)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.AsPath;
 
 import com.google.common.testing.EqualsTester;
 
@@ -53,4 +52,4 @@ public class AsPathTest {
         .addEqualityGroup(attr4)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
-
-import com.google.common.testing.EqualsTester;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.AutonomousSystemTlv;
+
+import com.google.common.testing.EqualsTester;
 
 /**
  * Test for AutonomousSystem Tlv.
@@ -37,4 +36,4 @@ public class AutonomousSystemTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.BGPLSIdentifierTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -37,4 +36,4 @@ public class BGPLSIdentifierTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.IPReachabilityInformationTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -38,4 +37,4 @@ public class IPReachabilityInformationTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
 import org.onlab.packet.Ip4Address;
-import org.onosproject.bgpio.types.IPv4AddressTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -38,4 +37,4 @@ public class IPv4AddressTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
 import org.onlab.packet.Ip6Address;
-import org.onosproject.bgpio.types.IPv6AddressTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -38,4 +37,4 @@ public class IPv6AddressTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.IsIsPseudonode;
 
 import com.google.common.testing.EqualsTester;
 
@@ -37,4 +36,4 @@ public class IsIsPseudonodeTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.LinkLocalRemoteIdentifiersTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -37,4 +36,4 @@ public class LinkLocalRemoteIdentifiersTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
 import org.onlab.packet.Ip4Address;
-import org.onosproject.bgpio.types.NextHop;
 
 import com.google.common.testing.EqualsTester;
 
@@ -38,4 +37,4 @@ public class NextHopTest {
         .addEqualityGroup(attr2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.Origin;
 
 import com.google.common.testing.EqualsTester;
 
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
 import org.onlab.packet.Ip4Address;
-import org.onosproject.bgpio.types.OSPFPseudonode;
 
 import com.google.common.testing.EqualsTester;
 
@@ -40,4 +39,4 @@ public class OspfPseudonodeTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.OSPFRouteTypeTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -37,4 +36,4 @@ public class OspfRouteTypeTest {
         .addEqualityGroup(tlv2)
         .testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
 
 import com.google.common.testing.EqualsTester;
 
@@ -48,4 +47,4 @@ public class BgpAttrNodeFlagBitTlvTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
 import org.onlab.packet.Ip6Address;
-import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV6;
 
 import com.google.common.testing.EqualsTester;
 
@@ -47,4 +46,4 @@ public class BgpAttrRouterIdV6Test {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
 
 import com.google.common.testing.EqualsTester;
 
@@ -41,4 +40,4 @@ public class BgpLinkAttrIgpMetricTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.attr.BgpLinkAttrMplsProtocolMask;
 
 import com.google.common.testing.EqualsTester;
 
@@ -40,4 +39,4 @@ public class BgpLinkAttrMplsProtocolMaskTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType;
 
 import com.google.common.testing.EqualsTester;
 
@@ -54,4 +53,4 @@ public class BgpLinkAttrProtectionTypeTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlagsTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrIgpFlagsTest.java
new file mode 100644 (file)
index 0000000..535518f
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.types.attr;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Test for BGP prefix IGP Flag attribute.
+ */
+public class BgpPrefixAttrIgpFlagsTest {
+
+    private final boolean bisisUpDownBit = true;
+    private final boolean bOspfNoUnicastBit = true;
+    private final boolean bOspfLclAddrBit = true;
+    private final boolean bOspfNSSABit = true;
+
+    private final boolean bisisUpDownBit1 = false;
+    private final boolean bOspfNoUnicastBit1 = false;
+    private final boolean bOspfLclAddrBit1 = false;
+    private final boolean bOspfNSSABit1 = false;
+
+    private final BgpPrefixAttrIgpFlags data = BgpPrefixAttrIgpFlags
+            .of(bisisUpDownBit, bOspfNoUnicastBit, bOspfLclAddrBit,
+                bOspfNSSABit);
+    private final BgpPrefixAttrIgpFlags sameAsData = BgpPrefixAttrIgpFlags
+            .of(bisisUpDownBit, bOspfNoUnicastBit, bOspfLclAddrBit,
+                bOspfNSSABit);
+    private final BgpPrefixAttrIgpFlags diffData = BgpPrefixAttrIgpFlags
+            .of(bisisUpDownBit1, bOspfNoUnicastBit1, bOspfLclAddrBit1,
+                bOspfNSSABit1);
+
+    @Test
+    public void basics() {
+
+        new EqualsTester().addEqualityGroup(data, sameAsData)
+        .addEqualityGroup(diffData).testEquals();
+    }
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
-import org.onosproject.bgpio.types.attr.BgpPrefixAttrMetric;
 
 import com.google.common.testing.EqualsTester;
 
@@ -37,4 +36,4 @@ public class BgpPrefixAttrMetricTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.bgpio.types.attr;
 
 import org.junit.Test;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip6Address;
-import org.onosproject.bgpio.types.attr.BgpPrefixAttrOspfFwdAddr;
 
 import com.google.common.testing.EqualsTester;
 
@@ -49,4 +48,4 @@ public class BgpPrefixAttrOspfFwdAddrTest {
         new EqualsTester().addEqualityGroup(data, sameAsData)
         .addEqualityGroup(diffData).testEquals();
     }
-}
\ No newline at end of file
+}
index b10621d..8e30fa4 100644 (file)
@@ -121,11 +121,11 @@ public class GroupsListCommand extends AbstractShellCommand {
     private void printGroups(DeviceId deviceId, List<Group> groups) {
         print("deviceId=%s", deviceId);
         for (Group group : groups) {
-            print(FORMAT, group.id().id(), group.state(), group.type(),
+            print(FORMAT, Integer.toHexString(group.id().id()), group.state(), group.type(),
                   group.bytes(), group.packets(), group.appId().name());
             int i = 0;
             for (GroupBucket bucket:group.buckets().buckets()) {
-                print(BUCKET_FORMAT, group.id().id(), ++i,
+                print(BUCKET_FORMAT, Integer.toHexString(group.id().id()), ++i,
                       bucket.bytes(), bucket.packets(),
                       bucket.treatment().allInstructions());
             }
index 4e5d39a..126e722 100644 (file)
@@ -630,7 +630,8 @@ public final class Instructions {
         @Override
         public String toString() {
             return toStringHelper(type().toString())
-                    .add("group ID", groupId.id()).toString();
+                    .addValue("group ID=0x" + Integer.toHexString(groupId.id()))
+                    .toString();
         }
 
         @Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceEvent.java
new file mode 100644 (file)
index 0000000..98abf30
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.newresource;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.event.AbstractEvent;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Describes an event related to a resource.
+ */
+@Beta
+public final class ResourceEvent extends AbstractEvent<ResourceEvent.Type, ResourcePath> {
+
+    /**
+     * Type of resource events.
+     */
+    @Beta
+    public enum Type {
+        /**
+         * Signifies that a new resource has been detected.
+         */
+        RESOURCE_ADDED,
+
+        /**
+         * Signifies that a resource has been removed.
+         */
+        RESOURCE_REMOVED
+    }
+
+    /**
+     * Create a resource event.
+     *
+     * @param type type of resource event
+     * @param subject subject of resource event
+     */
+    public ResourceEvent(Type type, ResourcePath subject) {
+        super(checkNotNull(type), checkNotNull(subject));
+    }
+}
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgp;
+package org.onosproject.net.newresource;
 
-import com.google.common.testing.EqualsTester;
-
-import org.junit.Test;
-import org.onosproject.bgpio.types.AreaIDTlv;
+import com.google.common.annotations.Beta;
+import org.onosproject.event.EventListener;
 
 /**
- * Test for AreaID Tlv.
+ * Entity capable of receiving resource related events.
  */
-public class AreaIdTest {
-    private final int value1 = 10;
-    private final int value2 = 20;
-    private final AreaIDTlv tlv1 = AreaIDTlv.of(value1);
-    private final AreaIDTlv sameAsTlv1 = AreaIDTlv.of(value1);
-    private final AreaIDTlv tlv2 = AreaIDTlv.of(value2);
-
-    @Test
-    public void testEquality() {
-        new EqualsTester()
-        .addEqualityGroup(tlv1, sameAsTlv1)
-        .addEqualityGroup(tlv2)
-        .testEquals();
-    }
-}
\ No newline at end of file
+@Beta
+public interface ResourceListener extends EventListener<ResourceEvent> {
+}
index ad684c8..966de50 100644 (file)
@@ -17,6 +17,7 @@ package org.onosproject.net.newresource;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
+import org.onosproject.event.ListenerService;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -29,7 +30,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
  * Service for allocating/releasing resource(s) and retrieving allocation(s) and availability.
  */
 @Beta
-public interface ResourceService {
+public interface ResourceService extends ListenerService<ResourceEvent, ResourceListener> {
     /**
      * Allocates the specified resource to the specified user.
      *
index 2cab9d4..7c67430 100644 (file)
@@ -16,6 +16,7 @@
 package org.onosproject.net.newresource;
 
 import com.google.common.annotations.Beta;
+import org.onosproject.store.Store;
 
 import java.util.Collection;
 import java.util.List;
@@ -25,7 +26,7 @@ import java.util.Optional;
  * Service for storing resource and consumer information.
  */
 @Beta
-public interface ResourceStore {
+public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegate> {
 
     /**
      * Registers the resources in transactional way.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.onosproject.net.newresource;
+
+import org.onosproject.store.StoreDelegate;
 
 /**
- * Service for interacting with interfaces.
+ * Resource store delegate abstraction.
  */
-package org.onosproject.incubator.net.intf;
+public interface ResourceStoreDelegate extends StoreDelegate<ResourceEvent> {
+}
index 0bfb379..d3bd2d7 100644 (file)
@@ -23,7 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Representation of bandwidth resource in bps.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public final class BandwidthResource implements LinkResource {
 
     private final Bandwidth bandwidth;
index 05cf28f..5f36d5f 100644 (file)
@@ -23,7 +23,10 @@ import java.util.Objects;
 
 /**
  * Representation of allocated bandwidth resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class BandwidthResourceAllocation implements ResourceAllocation {
     private final BandwidthResource bandwidth;
 
index 722b870..ff26e81 100644 (file)
@@ -23,7 +23,10 @@ import org.onosproject.net.resource.ResourceType;
 
 /**
  * Representation of a request for bandwidth resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class BandwidthResourceRequest implements ResourceRequest {
     private final BandwidthResource bandwidth;
 
index 379bf71..2fa4fa6 100644 (file)
@@ -36,7 +36,10 @@ import java.util.Set;
 
 /**
  * Implementation of {@link LinkResourceAllocations}.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
     private final LinkResourceRequest request;
     // TODO: probably should be using LinkKey instead
index f8e143a..b57465f 100644 (file)
@@ -39,7 +39,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Implementation of {@link LinkResourceRequest}.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public final class DefaultLinkResourceRequest implements LinkResourceRequest {
 
     private final IntentId intentId;
index 3733e46..0658249 100644 (file)
@@ -23,7 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Representation of lambda resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public final class LambdaResource implements LinkResource {
 
     private final IndexedLambda lambda;
index 161cf45..930a6b2 100644 (file)
@@ -23,7 +23,10 @@ import java.util.Objects;
 
 /**
  * Representation of allocated lambda resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class LambdaResourceAllocation implements ResourceAllocation {
     private final LambdaResource lambda;
 
index d264d5e..24d3d78 100644 (file)
@@ -24,7 +24,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Representation of a request for lambda resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class LambdaResourceRequest implements ResourceRequest {
 
     private final LambdaResource lambda;
index 7828867..d0211e2 100644 (file)
@@ -25,7 +25,10 @@ import org.onosproject.net.resource.ResourceRequest;
 
 /**
  * Representation of allocated link resources.
+ *
+ * @deprecated
  */
+@Deprecated
 public interface LinkResourceAllocations extends ResourceAllocation {
 
     /**
index 3edb386..a370292 100644 (file)
@@ -23,7 +23,10 @@ import com.google.common.collect.ImmutableList;
 
 /**
  * Describes an event related to a Link Resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public final class LinkResourceEvent
        extends AbstractEvent<LinkResourceEvent.Type, Collection<LinkResourceAllocations>> {
 
index 599dd4f..bbb02e2 100644 (file)
@@ -19,6 +19,9 @@ import org.onosproject.event.EventListener;
 
 /**
  * Entity for receiving link resource events.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public interface LinkResourceListener extends EventListener<LinkResourceEvent> {
 }
index 37622e7..9774e8e 100644 (file)
@@ -27,7 +27,10 @@ import org.onosproject.net.resource.ResourceRequest;
 
 /**
  * Representation of a request for link resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public interface LinkResourceRequest extends ResourceRequest {
 
     /**
index e6674db..e8a295c 100644 (file)
@@ -23,7 +23,10 @@ import org.onosproject.net.resource.ResourceAllocation;
 
 /**
  * Manages link resources.
+ *
+ * @deprecated in Emu Release.
  */
+@Deprecated
 public interface LinkResourceStore {
     /**
      * Returns free resources for given link.
index 6c051d6..dbfb3b0 100644 (file)
@@ -19,6 +19,9 @@ import org.onosproject.store.StoreDelegate;
 
 /**
  * Link resource store delegate abstraction.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public interface LinkResourceStoreDelegate extends StoreDelegate<LinkResourceEvent> {
 }
index dc00522..4645042 100644 (file)
@@ -19,7 +19,10 @@ import java.util.Set;
 
 /**
  * Abstraction of a resources of a link.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public interface LinkResources {
 
     /**
@@ -31,7 +34,10 @@ public interface LinkResources {
 
     /**
      * Builder of {@link LinkResources}.
+     *
+     * @deprecated in Emu Release
      */
+    @Deprecated
     interface Builder {
 
         /**
index 89c8776..5138d02 100644 (file)
@@ -20,7 +20,10 @@ import java.util.Objects;
 
 /**
  * Representation of MPLS label resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public final class MplsLabel implements LinkResource {
 
     private final org.onlab.packet.MplsLabel mplsLabel;
index cc9edc2..7441bee 100644 (file)
@@ -24,7 +24,10 @@ import java.util.Objects;
 
 /**
  * Representation of allocated MPLS label resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class MplsLabelResourceAllocation implements ResourceAllocation {
     private final MplsLabel mplsLabel;
 
index 01a048b..5b9c4a0 100644 (file)
@@ -24,7 +24,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * Representation of a request for lambda resource.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 public class MplsLabelResourceRequest implements ResourceRequest {
 
     private final MplsLabel mplsLabel;
index b10e4ba..f374d77 100644 (file)
 /**
  * Services for reserving links and their capacity as network resources,
  * e.g.&nbsp;bandwidth, lambdas.
+ * <p>
+ * Note: Classes under the package will be remove.
+ * Developers should not use the classes.
+ * This package is marked as deprecated in Emu Release.
+ * </p>
  */
+@Deprecated
 package org.onosproject.net.resource.link;
index e676fc8..a05dfda 100644 (file)
@@ -16,5 +16,9 @@
 
 /**
  * Abstractions for reserving network resources.
+ * <p>
+ * Note: Classes under the package will be removed.
+ * Developers should not use the classes.
+ * </p>
  */
 package org.onosproject.net.resource;
index 58b446c..22df937 100644 (file)
@@ -52,7 +52,10 @@ import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Manages link resources using trivial in-memory structures implementation.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 @Component(immediate = true)
 @Service
 public class SimpleLinkResourceStore implements LinkResourceStore {
index 5ebc812..ebf681a 100644 (file)
@@ -48,9 +48,9 @@ import org.onosproject.net.intent.PartitionEvent;
 import org.onosproject.net.intent.PartitionEventListener;
 import org.onosproject.net.intent.PartitionService;
 import org.onosproject.net.link.LinkEvent;
-import org.onosproject.net.resource.link.LinkResourceEvent;
-import org.onosproject.net.resource.link.LinkResourceListener;
-import org.onosproject.net.resource.link.LinkResourceService;
+import org.onosproject.net.newresource.ResourceEvent;
+import org.onosproject.net.newresource.ResourceListener;
+import org.onosproject.net.newresource.ResourceService;
 import org.onosproject.net.topology.TopologyEvent;
 import org.onosproject.net.topology.TopologyListener;
 import org.onosproject.net.topology.TopologyService;
@@ -60,6 +60,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -101,7 +102,7 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
     protected TopologyService topologyService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected LinkResourceService resourceManager;
+    protected ResourceService resourceService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
@@ -122,8 +123,7 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
             .newScheduledThreadPool(1);
 
     private TopologyListener listener = new InternalTopologyListener();
-    private LinkResourceListener linkResourceListener =
-            new InternalLinkResourceListener();
+    private ResourceListener resourceListener = new InternalResourceListener();
     private DeviceListener deviceListener = new InternalDeviceListener();
     private HostListener hostListener = new InternalHostListener();
     private PartitionEventListener partitionListener = new InternalPartitionListener();
@@ -134,7 +134,7 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
     @Activate
     public void activate() {
         topologyService.addListener(listener);
-        resourceManager.addListener(linkResourceListener);
+        resourceService.addListener(resourceListener);
         deviceService.addListener(deviceListener);
         hostService.addListener(hostListener);
         partitionService.addListener(partitionListener);
@@ -144,7 +144,7 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
     @Deactivate
     public void deactivate() {
         topologyService.removeListener(listener);
-        resourceManager.removeListener(linkResourceListener);
+        resourceService.removeListener(resourceListener);
         deviceService.removeListener(deviceListener);
         hostService.removeListener(hostListener);
         partitionService.removeListener(partitionListener);
@@ -299,35 +299,22 @@ public class ObjectiveTracker implements ObjectiveTrackerService {
         }
     }
 
-    /**
-     * Internal re-actor to resource available events.
-     */
-    private class InternalLinkResourceListener implements LinkResourceListener {
+    private class InternalResourceListener implements ResourceListener {
         @Override
-        public void event(LinkResourceEvent event) {
-            executorService.execute(new ResourceAvailableHandler(event));
-        }
-    }
-
-    /*
-     * Re-dispatcher of resource available events.
-     */
-    private class ResourceAvailableHandler implements Runnable {
-
-        private final LinkResourceEvent event;
-
-        ResourceAvailableHandler(LinkResourceEvent event) {
-            this.event = event;
-        }
+        public void event(ResourceEvent event) {
+            Optional<Class<?>> linkEvent = event.subject().components().stream()
+                    .map(Object::getClass)
+                    .filter(x -> x == LinkKey.class)
+                    .findFirst();
+            if (linkEvent.isPresent()) {
+                executorService.execute(() -> {
+                    if (delegate == null) {
+                        return;
+                    }
 
-        @Override
-        public void run() {
-            // If there is no delegate, why bother? Just bail.
-            if (delegate == null) {
-                return;
+                    delegate.triggerCompile(Collections.emptySet(), true);
+                });
             }
-
-            delegate.triggerCompile(Collections.emptySet(), true);
         }
     }
 
index 1f55b15..db3f655 100644 (file)
@@ -18,16 +18,22 @@ package org.onosproject.net.newresource.impl;
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
+import org.onosproject.event.AbstractListenerManager;
 import org.onosproject.net.newresource.ResourceAdminService;
 import org.onosproject.net.newresource.ResourceAllocation;
 import org.onosproject.net.newresource.ResourceConsumer;
+import org.onosproject.net.newresource.ResourceEvent;
+import org.onosproject.net.newresource.ResourceListener;
 import org.onosproject.net.newresource.ResourceService;
 import org.onosproject.net.newresource.ResourcePath;
 import org.onosproject.net.newresource.ResourceStore;
+import org.onosproject.net.newresource.ResourceStoreDelegate;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -44,11 +50,26 @@ import static com.google.common.base.Preconditions.checkNotNull;
 @Component(immediate = true)
 @Service
 @Beta
-public final class ResourceManager implements ResourceService, ResourceAdminService {
+public final class ResourceManager extends AbstractListenerManager<ResourceEvent, ResourceListener>
+        implements ResourceService, ResourceAdminService {
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected ResourceStore store;
 
+    private final ResourceStoreDelegate delegate = new InternalStoreDelegate();
+
+    @Activate
+    public void activate() {
+        store.setDelegate(delegate);
+        eventDispatcher.addSink(ResourceEvent.class, listenerRegistry);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        store.unsetDelegate(delegate);
+        eventDispatcher.addSink(ResourceEvent.class, listenerRegistry);
+    }
+
     @Override
     public List<ResourceAllocation> allocate(ResourceConsumer consumer,
                                              List<ResourcePath> resources) {
@@ -161,4 +182,11 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
         List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
         return store.unregister(resources);
     }
+
+    private class InternalStoreDelegate implements ResourceStoreDelegate {
+        @Override
+        public void notify(ResourceEvent event) {
+            post(event);
+        }
+    }
 }
index 58fa129..8d7452b 100644 (file)
@@ -16,7 +16,6 @@
 package org.onosproject.net.intent.impl;
 
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -38,8 +37,9 @@ import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MockIdGenerator;
 import org.onosproject.net.link.LinkEvent;
-import org.onosproject.net.resource.link.LinkResourceEvent;
-import org.onosproject.net.resource.link.LinkResourceListener;
+import org.onosproject.net.newresource.ResourceEvent;
+import org.onosproject.net.newresource.ResourceListener;
+import org.onosproject.net.newresource.ResourcePath;
 import org.onosproject.net.topology.Topology;
 import org.onosproject.net.topology.TopologyEvent;
 import org.onosproject.net.topology.TopologyListener;
@@ -52,6 +52,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
+import static org.onosproject.net.LinkKey.linkKey;
+import static org.onosproject.net.newresource.ResourceEvent.Type.*;
 import static org.onosproject.net.NetTestTools.APP_ID;
 import static org.onosproject.net.NetTestTools.device;
 import static org.onosproject.net.NetTestTools.link;
@@ -67,7 +69,7 @@ public class ObjectiveTrackerTest {
     private List<Event> reasons;
     private TopologyListener listener;
     private DeviceListener deviceListener;
-    private LinkResourceListener linkResourceListener;
+    private ResourceListener resourceListener;
     private IdGenerator mockGenerator;
 
     /**
@@ -84,7 +86,7 @@ public class ObjectiveTrackerTest {
         reasons = new LinkedList<>();
         listener = TestUtils.getField(tracker, "listener");
         deviceListener = TestUtils.getField(tracker, "deviceListener");
-        linkResourceListener = TestUtils.getField(tracker, "linkResourceListener");
+        resourceListener = TestUtils.getField(tracker, "resourceListener");
         mockGenerator = new MockIdGenerator();
         Intent.bindIdGenerator(mockGenerator);
     }
@@ -228,10 +230,9 @@ public class ObjectiveTrackerTest {
      */
     @Test
     public void testResourceEvent() throws Exception {
-        LinkResourceEvent event = new LinkResourceEvent(
-                LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
-                new HashSet<>());
-        linkResourceListener.event(event);
+        ResourceEvent event = new ResourceEvent(RESOURCE_ADDED,
+                new ResourcePath(linkKey(link("a", 1, "b", 1))));
+        resourceListener.event(event);
 
         assertThat(
                 delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
index 06b2c81..8ec09bd 100644 (file)
@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList;
 import org.onlab.packet.MplsLabel;
 import org.onosproject.net.newresource.ResourceAllocation;
 import org.onosproject.net.newresource.ResourceConsumer;
+import org.onosproject.net.newresource.ResourceListener;
 import org.onosproject.net.newresource.ResourcePath;
 import org.onosproject.net.newresource.ResourceService;
 
@@ -97,4 +98,10 @@ class MockResourceService implements ResourceService {
     public boolean isAvailable(ResourcePath resource) {
         return true;
     }
+
+    @Override
+    public void addListener(ResourceListener listener) {}
+
+    @Override
+    public void removeListener(ResourceListener listener) {}
 }
index 9f6c413..e4a09ce 100644 (file)
@@ -55,6 +55,10 @@ public class StaticClusterMetadataStore
     implements ClusterMetadataStore {
 
     private final Logger log = getLogger(getClass());
+
+    private static final String ONOS_IP = "ONOS_IP";
+    private static final String ONOS_INTERFACE = "ONOS_INTERFACE";
+    private static final String DEFAULT_ONOS_INTERFACE = "eth0";
     private static final String CLUSTER_METADATA_FILE = "../config/cluster.json";
     private static final int DEFAULT_ONOS_PORT = 9876;
     private final File metadataFile = new File(CLUSTER_METADATA_FILE);
@@ -194,6 +198,22 @@ public class StaticClusterMetadataStore
 
 
     private static String getSiteLocalAddress() {
+
+        /*
+         * If the IP ONOS should use is set via the environment variable we will assume it is valid and should be used.
+         * Setting the IP address takes presidence over setting the interface via the environment.
+         */
+        String useOnosIp = System.getenv(ONOS_IP);
+        if (useOnosIp != null) {
+            return useOnosIp;
+        }
+
+        // Read environment variables for IP interface information or set to default
+        String useOnosInterface = System.getenv(ONOS_INTERFACE);
+        if (useOnosInterface == null) {
+            useOnosInterface = DEFAULT_ONOS_INTERFACE;
+        }
+
         Function<NetworkInterface, IpAddress> ipLookup = nif -> {
             for (InetAddress address : Collections.list(nif.getInetAddresses())) {
                 if (address.isSiteLocalAddress()) {
@@ -203,7 +223,7 @@ public class StaticClusterMetadataStore
             return null;
         };
         try {
-            IpAddress ip = ipLookup.apply(NetworkInterface.getByName("eth0"));
+            IpAddress ip = ipLookup.apply(NetworkInterface.getByName(useOnosInterface));
             if (ip != null) {
                 return ip.toString();
             }
@@ -218,4 +238,4 @@ public class StaticClusterMetadataStore
         }
         return IpAddress.valueOf(InetAddress.getLoopbackAddress()).toString();
     }
-}
\ No newline at end of file
+}
index c9aaba5..82dfe32 100644 (file)
 package org.onosproject.store.newresource.impl;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onosproject.net.newresource.ResourceConsumer;
+import org.onosproject.net.newresource.ResourceEvent;
 import org.onosproject.net.newresource.ResourcePath;
 import org.onosproject.net.newresource.ResourceStore;
+import org.onosproject.net.newresource.ResourceStoreDelegate;
+import org.onosproject.store.AbstractStore;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.Serializer;
@@ -47,6 +51,7 @@ import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.newresource.ResourceEvent.Type.*;
 
 /**
  * Implementation of ResourceStore using TransactionalMap.
@@ -54,7 +59,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
 @Component(immediate = true)
 @Service
 @Beta
-public class ConsistentResourceStore implements ResourceStore {
+public class ConsistentResourceStore extends AbstractStore<ResourceEvent, ResourceStoreDelegate>
+        implements ResourceStore {
     private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class);
 
     private static final String CONSUMER_MAP = "onos-resource-consumers";
@@ -78,6 +84,8 @@ public class ConsistentResourceStore implements ResourceStore {
                 .withName(CHILD_MAP)
                 .withSerializer(SERIALIZER)
                 .build();
+
+        childMap.put(ResourcePath.ROOT, ImmutableList.of());
     }
 
     @Override
@@ -116,7 +124,15 @@ public class ConsistentResourceStore implements ResourceStore {
             }
         }
 
-        return tx.commit();
+        boolean success = tx.commit();
+        if (success) {
+            List<ResourceEvent> events = resources.stream()
+                    .filter(x -> x.parent().isPresent())
+                    .map(x -> new ResourceEvent(RESOURCE_ADDED, x))
+                    .collect(Collectors.toList());
+            notifyDelegate(events);
+        }
+        return success;
     }
 
     @Override
@@ -147,7 +163,15 @@ public class ConsistentResourceStore implements ResourceStore {
             }
         }
 
-        return tx.commit();
+        boolean success = tx.commit();
+        if (success) {
+            List<ResourceEvent> events = resources.stream()
+                    .filter(x -> x.parent().isPresent())
+                    .map(x -> new ResourceEvent(RESOURCE_REMOVED, x))
+                    .collect(Collectors.toList());
+            notifyDelegate(events);
+        }
+        return success;
     }
 
     @Override
index a38550e..351c7a5 100644 (file)
@@ -72,7 +72,10 @@ import static org.onosproject.net.AnnotationKeys.BANDWIDTH;
 
 /**
  * Store that manages link resources using Copycat-backed TransactionalMaps.
+ *
+ * @deprecated in Emu Release
  */
+@Deprecated
 @Component(immediate = true, enabled = true)
 @Service
 public class ConsistentLinkResourceStore extends
index 16aa1b0..a20b247 100644 (file)
@@ -49,6 +49,8 @@ public class NiciraSetTunnelDst extends AbstractExtensionInstruction {
     /**
      * Creates a new set tunnel destination instruction with a particular IPv4
      * address.
+     *
+     * @param tunnelDst tunnel destination IPv4 address
      */
     NiciraSetTunnelDst(Ip4Address tunnelDst) {
         checkNotNull(tunnelDst);
index 8f976da..0cb30d2 100644 (file)
@@ -18,7 +18,10 @@ package org.onosproject.driver.pipeline;
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
@@ -54,11 +57,16 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline {
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
         selector.matchVlanId(vidCriterion.vlanId());
+        treatment.transition(TMAC_TABLE);
+
+        VlanId storeVlan = null;
         if (vidCriterion.vlanId() == VlanId.NONE) {
             // untagged packets are assigned vlans
             treatment.pushVlan().setVlanId(assignedVlan);
+            storeVlan = assignedVlan;
+        } else {
+            storeVlan = vidCriterion.vlanId();
         }
-        treatment.transition(TMAC_TABLE);
 
         // ofdpa cannot match on ALL portnumber, so we need to use separate
         // rules for each port.
@@ -72,7 +80,20 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline {
         } else {
             portnums.add(portCriterion.port());
         }
+
         for (PortNumber pnum : portnums) {
+            // update storage
+            port2Vlan.put(pnum, storeVlan);
+            Set<PortNumber> vlanPorts = vlan2Port.get(storeVlan);
+            if (vlanPorts == null) {
+                vlanPorts = Collections.newSetFromMap(
+                                    new ConcurrentHashMap<PortNumber, Boolean>());
+                vlanPorts.add(pnum);
+                vlan2Port.put(storeVlan, vlanPorts);
+            } else {
+                vlanPorts.add(pnum);
+            }
+            // create rest of flowrule
             selector.matchInPort(pnum);
             FlowRule rule = DefaultFlowRule.builder()
                     .forDevice(deviceId)
index e63a404..cf3c7e8 100644 (file)
@@ -23,11 +23,13 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 import org.onlab.osgi.ServiceDirectory;
@@ -147,6 +149,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
     private static final int L3UNICASTMASK = 0x20000000;
     //private static final int MPLSINTERFACEMASK = 0x90000000;
     private static final int L3ECMPMASK = 0x70000000;
+    private static final int L2FLOODMASK = 0x40000000;
 
     private final Logger log = getLogger(getClass());
     private ServiceDirectory serviceDirectory;
@@ -176,6 +179,13 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
     private Set<IPCriterion> sentIpFilters = Collections.newSetFromMap(
                                                new ConcurrentHashMap<IPCriterion, Boolean>());
 
+    // local stores for port-vlan mapping
+    Map<PortNumber, VlanId> port2Vlan = new ConcurrentHashMap<PortNumber, VlanId>();
+    Map<VlanId, Set<PortNumber>> vlan2Port = new ConcurrentHashMap<VlanId,
+                                                        Set<PortNumber>>();
+
+
+
     @Override
     public void init(DeviceId deviceId, PipelinerContext context) {
         this.serviceDirectory = context.directory();
@@ -275,26 +285,23 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
 
     @Override
     public void next(NextObjective nextObjective) {
-        switch (nextObjective.type()) {
-        case SIMPLE:
-            Collection<TrafficTreatment> treatments = nextObjective.next();
-            if (treatments.size() != 1) {
-                log.error("Next Objectives of type Simple should only have a "
-                        + "single Traffic Treatment. Next Objective Id:{}", nextObjective.id());
-               fail(nextObjective, ObjectiveError.BADPARAMS);
-               return;
+        log.debug("Processing NextObjective id{} op{}", nextObjective.id(),
+                  nextObjective.op());
+        if (nextObjective.op() == Objective.Operation.REMOVE) {
+            if (nextObjective.next().isEmpty()) {
+                removeGroup(nextObjective);
+            } else {
+                removeBucketFromGroup(nextObjective);
             }
-            processSimpleNextObjective(nextObjective);
-            break;
-        case HASHED:
-        case BROADCAST:
-        case FAILOVER:
-            fail(nextObjective, ObjectiveError.UNSUPPORTED);
-            log.warn("Unsupported next objective type {}", nextObjective.type());
-            break;
-        default:
-            fail(nextObjective, ObjectiveError.UNKNOWN);
-            log.warn("Unknown next objective type {}", nextObjective.type());
+        } else if (nextObjective.op() == Objective.Operation.ADD) {
+            NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id());
+            if (nextGroup != null) {
+                addBucketToGroup(nextObjective);
+            } else {
+                addGroup(nextObjective);
+            }
+        } else {
+            log.warn("Unsupported operation {}", nextObjective.op());
         }
     }
 
@@ -302,6 +309,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
     //  Flow handling
     //////////////////////////////////////
 
+
     /**
      * As per OFDPA 2.0 TTP, filtering of VLAN ids, MAC addresses (for routing)
      * and IP addresses configured on switch ports happen in different tables.
@@ -455,14 +463,19 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
         selector.matchVlanId(vidCriterion.vlanId());
+        treatment.transition(TMAC_TABLE);
+
+        VlanId storeVlan = null;
         if (vidCriterion.vlanId() == VlanId.NONE) {
             // untagged packets are assigned vlans
             treatment.pushVlan().setVlanId(assignedVlan);
             // XXX ofdpa will require an additional vlan match on the assigned vlan
             // and it may not require the push. This is not in compliance with OF
             // standard. Waiting on what the exact flows are going to look like.
+            storeVlan = assignedVlan;
+        } else {
+            storeVlan = vidCriterion.vlanId();
         }
-        treatment.transition(TMAC_TABLE);
 
         // ofdpa cannot match on ALL portnumber, so we need to use separate
         // rules for each port.
@@ -476,7 +489,20 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
         } else {
             portnums.add(portCriterion.port());
         }
+
         for (PortNumber pnum : portnums) {
+            // update storage
+            port2Vlan.put(pnum, storeVlan);
+            Set<PortNumber> vlanPorts = vlan2Port.get(storeVlan);
+            if (vlanPorts == null) {
+                vlanPorts = Collections.newSetFromMap(
+                                    new ConcurrentHashMap<PortNumber, Boolean>());
+                vlanPorts.add(pnum);
+                vlan2Port.put(storeVlan, vlanPorts);
+            } else {
+                vlanPorts.add(pnum);
+            }
+            // create rest of flowrule
             selector.matchInPort(pnum);
             FlowRule rule = DefaultFlowRule.builder()
                     .forDevice(deviceId)
@@ -708,10 +734,39 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
     //  Group handling
     //////////////////////////////////////
 
+    private void addGroup(NextObjective nextObjective) {
+        switch (nextObjective.type()) {
+        case SIMPLE:
+            Collection<TrafficTreatment> treatments = nextObjective.next();
+            if (treatments.size() != 1) {
+                log.error("Next Objectives of type Simple should only have a "
+                        + "single Traffic Treatment. Next Objective Id:{}",
+                        nextObjective.id());
+               fail(nextObjective, ObjectiveError.BADPARAMS);
+               return;
+            }
+            processSimpleNextObjective(nextObjective);
+            break;
+        case BROADCAST:
+            processBroadcastNextObjective(nextObjective);
+            break;
+        case HASHED:
+            processHashedNextObjective(nextObjective);
+            break;
+        case FAILOVER:
+            fail(nextObjective, ObjectiveError.UNSUPPORTED);
+            log.warn("Unsupported next objective type {}", nextObjective.type());
+            break;
+        default:
+            fail(nextObjective, ObjectiveError.UNKNOWN);
+            log.warn("Unknown next objective type {}", nextObjective.type());
+        }
+    }
+
     /**
      * As per the OFDPA 2.0 TTP, packets are sent out of ports by using
      * a chain of groups, namely an L3 Unicast Group that points to an L2 Interface
-     * Group which in turns points to an output port. The Next Objective passed
+     * Group which in-turn points to an output port. The Next Objective passed
      * in by the application has to be broken up into a group chain
      * to satisfy this TTP.
      *
@@ -770,7 +825,9 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
         Integer l3groupId = L3UNICASTMASK | (int) portNum;
         l3utt.group(new DefaultGroupId(l2groupId));
         GroupChainElem gce = new GroupChainElem(l3groupkey, l3groupId,
-                                                l3utt.build(), nextObj.appId());
+                                                GroupDescription.Type.INDIRECT,
+                                                Collections.singletonList(l3utt.build()),
+                                                nextObj.appId(), 1);
 
         // create object for local and distributed storage
         List<GroupKey> gkeys = new ArrayList<GroupKey>();
@@ -796,6 +853,145 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
         groupService.addGroup(groupDescription);
     }
 
+    /**
+     * As per the OFDPA 2.0 TTP, packets are sent out of ports by using
+     * a chain of groups. The Next Objective passed in by the application
+     * has to be broken up into a group chain comprising of an
+     * L2 Flood group whose buckets point to L2 Interface groups.
+     *
+     * @param nextObj  the nextObjective of type BROADCAST
+     */
+    private void processBroadcastNextObjective(NextObjective nextObj) {
+        // break up broadcast next objective to multiple groups
+        Collection<TrafficTreatment> buckets = nextObj.next();
+
+        // each treatment is converted to an L2 interface group
+        int indicator = 0;
+        VlanId vlanid = null;
+        List<GroupInfo> groupInfoCollection = new ArrayList<>();
+        for (TrafficTreatment treatment : buckets) {
+            TrafficTreatment.Builder newTreatment = DefaultTrafficTreatment.builder();
+            PortNumber portNum = null;
+            // ensure that the only allowed treatments are pop-vlan and output
+            for (Instruction ins : treatment.allInstructions()) {
+                if (ins.type() == Instruction.Type.L2MODIFICATION) {
+                    L2ModificationInstruction l2ins = (L2ModificationInstruction) ins;
+                    switch (l2ins.subtype()) {
+                    case VLAN_POP:
+                        newTreatment.add(l2ins);
+                        break;
+                    default:
+                        log.debug("action {} not permitted for broadcast nextObj",
+                                  l2ins.subtype());
+                        break;
+                    }
+                } else if (ins.type() == Instruction.Type.OUTPUT) {
+                    portNum = ((OutputInstruction) ins).port();
+                    newTreatment.add(ins);
+                } else {
+                    log.debug("TrafficTreatment of type {} not permitted in "
+                            + " broadcast nextObjective", ins.type());
+                }
+            }
+
+            // also ensure that all ports are in the same vlan
+            VlanId thisvlanid = port2Vlan.get(portNum);
+            if (vlanid == null) {
+                vlanid = thisvlanid;
+            } else {
+                if (!vlanid.equals(thisvlanid)) {
+                    log.error("Driver requires all ports in a broadcast nextObj "
+                            + "to be in the same vlan. Different vlans found "
+                            + "{} and {}. Aborting group creation", vlanid, thisvlanid);
+                    return;
+                }
+            }
+
+            // assemble info for all l2 interface groups
+            indicator += GROUP1MASK;
+            int l2gk = nextObj.id() | indicator;
+            final GroupKey l2groupkey = new DefaultGroupKey(appKryo.serialize(l2gk));
+            Integer l2groupId = L2INTERFACEMASK | (vlanid.toShort() << 16) |
+                                    (int) portNum.toLong();
+            GroupBucket newbucket =
+                    DefaultGroupBucket.createIndirectGroupBucket(newTreatment.build());
+
+            // store the info needed to create this group
+            groupInfoCollection.add(new GroupInfo(l2groupId, l2groupkey, newbucket));
+        }
+
+        // assemble info for l2 flood group
+        int l2floodgk = nextObj.id() | GROUP0MASK;
+        final GroupKey l2floodgroupkey = new DefaultGroupKey(appKryo.serialize(l2floodgk));
+        Integer l2floodgroupId = L2FLOODMASK | (vlanid.toShort() << 16) | nextObj.id();
+        // collection of treatment with groupids of l2 interface groups
+        List<TrafficTreatment> floodtt = new ArrayList<>();
+        for (GroupInfo gi : groupInfoCollection) {
+            TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
+            ttb.group(new DefaultGroupId(gi.groupId));
+            floodtt.add(ttb.build());
+        }
+        GroupChainElem gce = new GroupChainElem(l2floodgroupkey, l2floodgroupId,
+                                                GroupDescription.Type.ALL,
+                                                floodtt,
+                                                nextObj.appId(),
+                                                groupInfoCollection.size());
+
+        // create objects for local and distributed storage
+        List<GroupKey> gkeys = new ArrayList<GroupKey>();
+        gkeys.add(l2floodgroupkey); // group0 in chain
+        OfdpaGroupChain ofdpaGrp = new OfdpaGroupChain(gkeys, nextObj);
+
+        // store l2floodgroupkey with the ofdpaGroupChain for the nextObjective
+        // that depends on it
+        pendingNextObjectives.put(l2floodgroupkey, ofdpaGrp);
+
+        for (GroupInfo gi : groupInfoCollection) {
+            // store all l2groupkeys with the groupChainElem for the l2floodgroup
+            // that depends on it
+            pendingGroups.put(gi.groupKey, gce);
+
+            // create and send groups for all l2 interface groups
+            GroupDescription groupDescription =
+                    new DefaultGroupDescription(
+                            deviceId,
+                            GroupDescription.Type.INDIRECT,
+                            new GroupBuckets(Collections.singletonList(gi.groupBucket)),
+                            gi.groupKey,
+                            gi.groupId,
+                            nextObj.appId());
+            groupService.addGroup(groupDescription);
+        }
+    }
+
+    private class GroupInfo {
+        private Integer groupId;
+        private GroupKey groupKey;
+        private GroupBucket groupBucket;
+
+        GroupInfo(Integer groupId, GroupKey groupKey, GroupBucket groupBucket) {
+            this.groupBucket = groupBucket;
+            this.groupId = groupId;
+            this.groupKey = groupKey;
+        }
+    }
+
+    private void processHashedNextObjective(NextObjective nextObj) {
+        // TODO Auto-generated method stub
+    }
+
+    private void addBucketToGroup(NextObjective nextObjective) {
+        // TODO Auto-generated method stub
+    }
+
+    private void removeBucketFromGroup(NextObjective nextObjective) {
+        // TODO Auto-generated method stub
+    }
+
+    private void removeGroup(NextObjective nextObjective) {
+        // TODO Auto-generated method stub
+    }
+
     /**
      * Processes next element of a group chain. Assumption is that if this
      * group points to another group, the latter has already been created
@@ -803,21 +999,56 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
      * that if there is another group waiting for this group then the appropriate
      * stores already have the information to act upon the notification for the
      * creating of this group.
+     * <p>
+     * The processing of the GroupChainElement depends on the number of groups
+     * this element is waiting on. For all group types other than SIMPLE, a
+     * GroupChainElement could be waiting on multiple groups.
      *
      * @param gce the group chain element to be processed next
      */
     private void processGroupChain(GroupChainElem gce) {
-        GroupBucket bucket = DefaultGroupBucket
-                .createIndirectGroupBucket(gce.getBucketActions());
-        GroupDescription groupDesc = new DefaultGroupDescription(deviceId,
-                             GroupDescription.Type.INDIRECT,
-                             new GroupBuckets(Collections.singletonList(bucket)),
-                             gce.getGkey(),
-                             gce.getGivenGroupId(),
-                             gce.getAppId());
-        groupService.addGroup(groupDesc);
-    }
+        int waitOnGroups = gce.decrementAndGetGroupsWaitedOn();
+        if (waitOnGroups != 0) {
+            log.debug("GCE: {} waiting on {} groups. Not processing yet",
+                      gce, waitOnGroups);
+            return;
+        }
+        List<GroupBucket> buckets = new ArrayList<>();
+        switch (gce.groupType) {
+        case INDIRECT:
+            GroupBucket ibucket = DefaultGroupBucket
+                .createIndirectGroupBucket(gce.bucketActions.iterator().next());
+            buckets.add(ibucket);
+            break;
+        case ALL:
+            for (TrafficTreatment tt : gce.bucketActions) {
+                GroupBucket abucket = DefaultGroupBucket
+                        .createAllGroupBucket(tt);
+                buckets.add(abucket);
+            }
+            break;
+        case SELECT:
+            for (TrafficTreatment tt : gce.bucketActions) {
+                GroupBucket sbucket = DefaultGroupBucket
+                        .createSelectGroupBucket(tt);
+                buckets.add(sbucket);
+            }
+            break;
+        case FAILOVER:
+        default:
+            log.error("Unknown or unimplemented GroupChainElem {}", gce);
+        }
 
+        if (buckets.size() > 0) {
+            GroupDescription groupDesc = new DefaultGroupDescription(
+                                                 deviceId, gce.groupType,
+                                                 new GroupBuckets(buckets),
+                                                 gce.gkey,
+                                                 gce.givenGroupId,
+                                                 gce.appId);
+            groupService.addGroup(groupDesc);
+        }
+    }
 
     private class GroupChecker implements Runnable {
         @Override
@@ -837,7 +1068,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
                     log.info("Group service processed group key {}. Processing next "
                             + "group in group chain with group key {}",
                             appKryo.deserialize(key.key()),
-                            appKryo.deserialize(gce.getGkey().key()));
+                            appKryo.deserialize(gce.gkey.key()));
                     processGroupChain(gce);
                 } else {
                     OfdpaGroupChain obj = pendingNextObjectives.getIfPresent(key);
@@ -866,7 +1097,7 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
                     log.info("group ADDED with group key {} .. "
                             + "Processing next group in group chain with group key {}",
                             appKryo.deserialize(key.key()),
-                            appKryo.deserialize(gce.getGkey().key()));
+                            appKryo.deserialize(gce.gkey.key()));
                     processGroupChain(gce);
                 } else {
                     OfdpaGroupChain obj = pendingNextObjectives.getIfPresent(key);
@@ -890,6 +1121,11 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
      * look like group0 --> group 1 --> outPort. Information about the groups
      * themselves can be fetched from the Group Service using the group keys from
      * objects instantiating this class.
+     *
+     * XXX Revisit this - since the forwarding objective only ever needs the
+     * groupkey of the top-level group in the group chain, why store a series
+     * of groupkeys. Also the group-chain list only works for 1-to-1 chaining,
+     * not for 1-to-many chaining.
      */
     private class OfdpaGroupChain implements NextGroup {
         private final NextObjective nextObj;
@@ -925,33 +1161,40 @@ public class OFDPA2Pipeline extends AbstractHandlerBehaviour implements Pipeline
      * preceding groups in the group chain to be created.
      */
     private class GroupChainElem {
-        private TrafficTreatment bucketActions;
+        private Collection<TrafficTreatment> bucketActions;
         private Integer givenGroupId;
+        private GroupDescription.Type groupType;
         private GroupKey gkey;
         private ApplicationId appId;
+        private AtomicInteger waitOnGroups;
 
-        public GroupChainElem(GroupKey gkey, Integer givenGroupId,
-                              TrafficTreatment tr, ApplicationId appId) {
+        GroupChainElem(GroupKey gkey, Integer givenGroupId,
+                       GroupDescription.Type groupType,
+                       Collection<TrafficTreatment> tr, ApplicationId appId,
+                       int waitOnGroups) {
             this.bucketActions = tr;
             this.givenGroupId = givenGroupId;
+            this.groupType = groupType;
             this.gkey = gkey;
             this.appId = appId;
+            this.waitOnGroups = new AtomicInteger(waitOnGroups);
         }
 
-        public TrafficTreatment getBucketActions() {
-            return bucketActions;
-        }
-
-        public Integer getGivenGroupId() {
-            return givenGroupId;
+        /**
+         * This methods atomically decrements the counter for the number of
+         * groups this GroupChainElement is waiting on, for notifications from
+         * the Group Service. When this method returns a value of 0, this
+         * GroupChainElement is ready to be processed.
+         *
+         * @return integer indication of the number of notifications being waited on
+         */
+        int decrementAndGetGroupsWaitedOn() {
+            return waitOnGroups.decrementAndGet();
         }
 
-        public GroupKey getGkey() {
-            return gkey;
-        }
-
-        public ApplicationId getAppId() {
-            return appId;
+        @Override
+        public String toString() {
+            return Integer.toHexString(givenGroupId);
         }
 
     }
index 69c0616..d9848be 100644 (file)
@@ -94,7 +94,7 @@ public class Controller {
     protected String tsLocation;
     protected char[] ksPwd;
     protected char[] tsPwd;
-    private SSLEngine serverSSLEngine;
+    protected SSLEngine serverSSLEngine;
 
     // Perf. related configuration
     protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
index 1a088ff..ff92b77 100644 (file)
@@ -445,7 +445,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
 
 
                 log.debug("Switch {} bound to class {}, description {}",
-                        new Object[] {h.sw, h.sw.getClass(), drep });
+                        h.sw, h.sw.getClass(), drep);
                 //Put switch in EQUAL mode until we hear back from the global registry
                 //log.debug("Setting new switch {} to EQUAL and sending Role request",
                 //        h.sw.getStringId());
@@ -730,10 +730,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
          */
         protected void logError(OFChannelHandler h, OFErrorMsg error) {
             log.error("{} from switch {} in state {}",
-                    new Object[] {
                     error,
                     h.getSwitchInfoString(),
-                    this.toString()});
+                    this.toString());
         }
 
         /**
index d042994..fdcd2f0 100644 (file)
@@ -498,10 +498,10 @@ public class OpenFlowControllerImpl implements OpenFlowController {
                     activeEqualSwitches.get(dpid) != null) {
                 log.error("Trying to activate switch but it is already "
                         + "activated: dpid {}. Found in activeMaster: {} "
-                        + "Found in activeEqual: {}. Aborting ..", new Object[]{
-                                dpid,
-                                (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
-                                        (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+                        + "Found in activeEqual: {}. Aborting ..",
+                          dpid,
+                          (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
+                          (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y');
                 return false;
             }
             return true;
index e7e5ffe..bd4875c 100644 (file)
@@ -213,8 +213,9 @@ class RoleManager implements RoleHandler {
             log.debug("Received unexpected RoleReply {} from "
                     + "Switch: {}. "
                     + "This controller has no current role for this sw. "
-                    + "Ignoring ...", new Object[] {rri,
-                            sw == null ? "(null)" : sw.getStringId(), });
+                    + "Ignoring ...",
+                      rri,
+                      sw == null ? "(null)" : sw.getStringId());
             return RoleRecvStatus.OTHER_EXPECTATION;
         }
 
@@ -232,7 +233,7 @@ class RoleManager implements RoleHandler {
         if (expectedRole == receivedRole) {
             log.debug("Received role reply message from {} that matched "
                     + "expected role-reply {} with expectations {}",
-                    new Object[] {sw.getStringId(), receivedRole, expectation});
+                    sw.getStringId(), receivedRole, expectation);
 
             // Done with this RoleReply; Invalidate
             pendingReplies.invalidate(xid);
@@ -283,10 +284,10 @@ class RoleManager implements RoleHandler {
             log.error("Received a error msg {} from sw {} for "
                     + "pending role request {}. Switch driver indicates "
                     + "role-messaging is supported. Possible issues in "
-                    + "switch driver configuration?", new Object[] {
-                            ((OFBadRequestErrorMsg) error).toString(),
-                            sw.getStringId(), errorRole
-                    });
+                    + "switch driver configuration?",
+                    ((OFBadRequestErrorMsg) error).toString(),
+                    sw.getStringId(),
+                    errorRole);
             return RoleRecvStatus.UNSUPPORTED;
         }
 
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverAdapter.java
new file mode 100644 (file)
index 0000000..57becf9
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
+
+/**
+ * Created by ray on 11/4/15.
+ */
+public class DriverAdapter implements Driver {
+    @Override
+    public String name() {
+        return null;
+    }
+
+    @Override
+    public Driver parent() {
+        return null;
+    }
+
+    @Override
+    public String manufacturer() {
+        return null;
+    }
+
+    @Override
+    public String hwVersion() {
+        return null;
+    }
+
+    @Override
+    public String swVersion() {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Behaviour>> behaviours() {
+        return null;
+    }
+
+    @Override
+    public Class<? extends Behaviour> implementation(Class<? extends Behaviour> behaviour) {
+        return null;
+    }
+
+    @Override
+    public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
+        return true;
+    }
+
+    @Override
+    public <T extends Behaviour> T createBehaviour(DriverData data, Class<T> behaviourClass) {
+        return null;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {
+        if (behaviourClass == OpenFlowSwitchDriver.class) {
+            return (T) new OpenflowSwitchDriverAdapter();
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, String> properties() {
+        return null;
+    }
+
+    @Override
+    public Driver merge(Driver other) {
+        return null;
+    }
+
+    @Override
+    public Set<String> keys() {
+        return null;
+    }
+
+    @Override
+    public String value(String key) {
+        return null;
+    }
+}
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/DriverServiceAdapter.java
new file mode 100644 (file)
index 0000000..25596ad
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow;
+
+import java.util.Set;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+
+/**
+ * Created by ray on 11/4/15.
+ */
+public class DriverServiceAdapter implements DriverService {
+    @Override
+    public Set<Driver> getDrivers() {
+        return null;
+    }
+
+    @Override
+    public Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour) {
+        return null;
+    }
+
+    @Override
+    public Driver getDriver(String mfr, String hw, String sw) {
+        return null;
+    }
+
+    @Override
+    public Driver getDriver(DeviceId deviceId) {
+        return null;
+    }
+
+    @Override
+    public DriverHandler createHandler(DeviceId deviceId, String... credentials) {
+        return null;
+    }
+
+    @Override
+    public Driver getDriver(String driverName) {
+        return null;
+    }
+}
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OFDescStatsReplyAdapter.java
new file mode 100644 (file)
index 0000000..1e86641
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow;
+
+import java.util.Set;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
+import org.projectfloodlight.openflow.protocol.OFStatsType;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+import com.google.common.hash.PrimitiveSink;
+
+/**
+ * Created by ray on 11/4/15.
+ */
+public class OFDescStatsReplyAdapter implements OFDescStatsReply {
+    @Override
+    public OFVersion getVersion() {
+        return null;
+    }
+
+    @Override
+    public OFType getType() {
+        return null;
+    }
+
+    @Override
+    public long getXid() {
+        return 0;
+    }
+
+    @Override
+    public OFStatsType getStatsType() {
+        return null;
+    }
+
+    @Override
+    public Set<OFStatsReplyFlags> getFlags() {
+        return null;
+    }
+
+    @Override
+    public String getMfrDesc() {
+        return null;
+    }
+
+    @Override
+    public String getHwDesc() {
+        return null;
+    }
+
+    @Override
+    public String getSwDesc() {
+        return null;
+    }
+
+    @Override
+    public String getSerialNum() {
+        return null;
+    }
+
+    @Override
+    public String getDpDesc() {
+        return null;
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer channelBuffer) {
+
+    }
+
+    @Override
+    public Builder createBuilder() {
+        return null;
+    }
+
+    @Override
+    public void putTo(PrimitiveSink sink) {
+
+    }
+}
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
new file mode 100644 (file)
index 0000000..25ea641
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow;
+
+import java.util.List;
+
+import org.jboss.netty.channel.Channel;
+import org.onosproject.net.Device;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.RoleState;
+import org.onosproject.openflow.controller.driver.OpenFlowAgent;
+import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
+import org.onosproject.openflow.controller.driver.RoleHandler;
+import org.onosproject.openflow.controller.driver.SwitchStateException;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFFactories;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFVersion;
+
+/**
+ * Testing adapter for the OpenFlow switch driver class.
+ */
+public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver {
+    @Override
+    public void setAgent(OpenFlowAgent agent) {
+
+    }
+
+    @Override
+    public void setRoleHandler(RoleHandler roleHandler) {
+
+    }
+
+    @Override
+    public void reassertRole() {
+
+    }
+
+    @Override
+    public boolean handleRoleError(OFErrorMsg error) {
+        return false;
+    }
+
+    @Override
+    public void handleNiciraRole(OFMessage m) throws SwitchStateException {
+
+    }
+
+    @Override
+    public void handleRole(OFMessage m) throws SwitchStateException {
+
+    }
+
+    @Override
+    public boolean connectSwitch() {
+        return false;
+    }
+
+    @Override
+    public boolean activateMasterSwitch() {
+        return false;
+    }
+
+    @Override
+    public boolean activateEqualSwitch() {
+        return false;
+    }
+
+    @Override
+    public void transitionToEqualSwitch() {
+
+    }
+
+    @Override
+    public void transitionToMasterSwitch() {
+
+    }
+
+    @Override
+    public void removeConnectedSwitch() {
+
+    }
+
+    @Override
+    public void setPortDescReply(OFPortDescStatsReply portDescReply) {
+
+    }
+
+    @Override
+    public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
+
+    }
+
+    @Override
+    public void setFeaturesReply(OFFeaturesReply featuresReply) {
+
+    }
+
+    @Override
+    public void setSwitchDescription(OFDescStatsReply desc) {
+
+    }
+
+    @Override
+    public int getNextTransactionId() {
+        return 0;
+    }
+
+    @Override
+    public void setOFVersion(OFVersion ofV) {
+
+    }
+
+    @Override
+    public void setTableFull(boolean full) {
+
+    }
+
+    @Override
+    public void setChannel(Channel channel) {
+
+    }
+
+    @Override
+    public void setConnected(boolean connected) {
+
+    }
+
+    @Override
+    public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
+
+    }
+
+    @Override
+    public Boolean supportNxRole() {
+        return true;
+    }
+
+    @Override
+    public void startDriverHandshake() {
+
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        return false;
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+
+    }
+
+    @Override
+    public void sendRoleRequest(OFMessage message) {
+
+    }
+
+    @Override
+    public void sendHandshakeMessage(OFMessage message) {
+
+    }
+
+    @Override
+    public DriverHandler handler() {
+        return null;
+    }
+
+    @Override
+    public void setHandler(DriverHandler handler) {
+
+    }
+
+    @Override
+    public DriverData data() {
+        return null;
+    }
+
+    @Override
+    public void setData(DriverData data) {
+
+    }
+
+    @Override
+    public void sendMsg(OFMessage msg) {
+
+    }
+
+    @Override
+    public void sendMsg(List<OFMessage> msgs) {
+
+    }
+
+    @Override
+    public void handleMessage(OFMessage fromSwitch) {
+
+    }
+
+    @Override
+    public void setRole(RoleState role) {
+
+    }
+
+    @Override
+    public RoleState getRole() {
+        return null;
+    }
+
+    @Override
+    public List<OFPortDesc> getPorts() {
+        return null;
+    }
+
+    @Override
+    public OFFactory factory() {
+        // return what-ever triggers requestPending = true
+        return OFFactories.getFactory(OFVersion.OF_10);
+    }
+
+    @Override
+    public String getStringId() {
+        return "100";
+    }
+
+    @Override
+    public long getId() {
+        return 0;
+    }
+
+    @Override
+    public String manufacturerDescription() {
+        return null;
+    }
+
+    @Override
+    public String datapathDescription() {
+        return null;
+    }
+
+    @Override
+    public String hardwareDescription() {
+        return null;
+    }
+
+    @Override
+    public String softwareDescription() {
+        return null;
+    }
+
+    @Override
+    public String serialNumber() {
+        return null;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return false;
+    }
+
+    @Override
+    public void disconnectSwitch() {
+
+    }
+
+    @Override
+    public void returnRoleReply(RoleState requested, RoleState response) {
+
+    }
+
+    @Override
+    public Device.Type deviceType() {
+        return Device.Type.SWITCH;
+    }
+
+    @Override
+    public String channelId() {
+        return null;
+    }
+}
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/ControllerTest.java
new file mode 100644 (file)
index 0000000..3ff3bde
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow.controller.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.stream.IntStream;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.openflow.DriverAdapter;
+import org.onosproject.openflow.DriverServiceAdapter;
+import org.onosproject.openflow.OFDescStatsReplyAdapter;
+import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Files;
+
+import static com.google.common.io.ByteStreams.toByteArray;
+import static com.google.common.io.Files.write;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.lessThan;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+
+/**
+ * Unit tests for the OpenFlow controller class.
+ */
+public class ControllerTest {
+
+    Controller controller;
+    protected static final Logger log = LoggerFactory.getLogger(ControllerTest.class);
+
+    static final File TEST_DIR = Files.createTempDir();
+
+    /*
+     * Writes the necessary file for the tests in the temporary directory
+     */
+    static File stageTestResource(String name) throws IOException {
+        File file = new File(TEST_DIR, name);
+        byte[] bytes = toByteArray(ControllerTest.class.getResourceAsStream(name));
+        write(bytes, file);
+        return file;
+    }
+
+    class MockDriverService extends DriverServiceAdapter {
+        static final int NO_SUCH_DRIVER_ID = 1;
+        static final int ITEM_NOT_FOUND_DRIVER_ID = 2;
+        static final int DRIVER_EXISTS_ID = 3;
+
+        static final String BASE_DRIVER_NAME = "of:000000000000000";
+
+        static final String NO_SUCH_DRIVER = BASE_DRIVER_NAME
+                + NO_SUCH_DRIVER_ID;
+        static final String ITEM_NOT_FOUND_DRIVER = BASE_DRIVER_NAME
+                + ITEM_NOT_FOUND_DRIVER_ID;
+        static final String DRIVER_EXISTS = BASE_DRIVER_NAME
+                + DRIVER_EXISTS_ID;
+
+        @Override
+        public Driver getDriver(DeviceId deviceId) {
+            switch (deviceId.toString()) {
+                case NO_SUCH_DRIVER:
+                    return null;
+                case ITEM_NOT_FOUND_DRIVER:
+                    throw new ItemNotFoundException();
+                case DRIVER_EXISTS:
+                    return new DriverAdapter();
+                default:
+                    throw new AssertionError();
+            }
+        }
+    }
+
+    /**
+     * Creates and initializes a new controller.
+     */
+    @Before
+    public void setUp() {
+        controller = new Controller();
+        Dictionary<String, String> properties = new Hashtable<>();
+        properties.put("openflowPorts",
+                       Integer.toString(TestTools.findAvailablePort(0)));
+        controller.setConfigParams(properties);
+    }
+
+    /**
+     * Tests fetching a driver that does not exist.
+     */
+    @Test
+    public void switchInstanceNotFoundTest() {
+        controller.start(null, new MockDriverService());
+        OpenFlowSwitchDriver driver =
+                controller.getOFSwitchInstance(MockDriverService.NO_SUCH_DRIVER_ID,
+                                               null,
+                                               null);
+        assertThat(driver, nullValue());
+        controller.stop();
+    }
+
+    /**
+     * Tests fetching a driver that throws an ItemNotFoundException.
+     */
+    @Test
+    public void switchItemNotFoundTest() {
+        controller.start(null, new MockDriverService());
+        OFDescStatsReply stats =
+                new OFDescStatsReplyAdapter();
+        OpenFlowSwitchDriver driver =
+                controller.getOFSwitchInstance(MockDriverService.ITEM_NOT_FOUND_DRIVER_ID,
+                                               stats,
+                                               null);
+        assertThat(driver, nullValue());
+        controller.stop();
+    }
+
+    /**
+     * Tests fetching a driver that throws an ItemNotFoundException.
+     */
+    @Test
+    public void driverExistsTest() {
+        controller.start(null, new MockDriverService());
+        OFDescStatsReply stats =
+                new OFDescStatsReplyAdapter();
+        OpenFlowSwitchDriver driver =
+                controller.getOFSwitchInstance(MockDriverService.DRIVER_EXISTS_ID,
+                                               stats,
+                                               null);
+        assertThat(driver, notNullValue());
+        controller.stop();
+    }
+
+    /**
+     * Tests configuring the controller.
+     */
+    @Test
+    public void testConfiguration() {
+        Dictionary<String, String> properties = new Hashtable<>();
+        properties.put("openflowPorts", "1,2,3,4,5");
+        properties.put("workerThreads", "5");
+
+        controller.setConfigParams(properties);
+        IntStream.rangeClosed(1, 5)
+                .forEach(i -> assertThat(controller.openFlowPorts, hasItem(i)));
+        assertThat(controller.workerThreads, is(5));
+    }
+
+    /**
+     * Tests the SSL/TLS methods in the controller.
+     */
+    @Test
+    public void testSsl() throws IOException {
+        File keystore = stageTestResource("ControllerTestKeystore.jks");
+        String keystoreName = keystore.getAbsolutePath();
+
+        System.setProperty("enableOFTLS", Boolean.toString(Boolean.TRUE));
+        System.setProperty("javax.net.ssl.keyStore", keystoreName);
+        System.setProperty("javax.net.ssl.trustStore", keystoreName);
+        System.setProperty("javax.net.ssl.keyStorePassword", "password");
+        System.setProperty("javax.net.ssl.trustStorePassword", "password");
+        Dictionary<String, String> properties = new Hashtable<>();
+        properties.put("openflowPorts",
+                       Integer.toString(TestTools.findAvailablePort(0)));
+        properties.put("workerThreads", "0");
+
+        controller.setConfigParams(properties);
+        controller.start(null, new MockDriverService());
+
+        assertThat(controller.serverSSLEngine, notNullValue());
+
+        controller.stop();
+        boolean removed = keystore.delete();
+        if (!removed) {
+            log.warn("Could not remove temporary file");
+        }
+    }
+
+    /**
+     * Tests controll utility health methods.
+     */
+    @Test
+    public void testHealth() {
+        Map<String, Long> memory = controller.getMemory();
+        assertThat(memory.size(), is(2));
+        assertThat(memory.get("total"), is(not(0)));
+        assertThat(memory.get("free"), is(not(0)));
+
+        long startTime = controller.getSystemStartTime();
+        assertThat(startTime, lessThan(System.currentTimeMillis()));
+
+        long upTime = controller.getSystemUptime();
+        assertThat(upTime, lessThan(30L * 1000));
+    }
+}
index 0a71a40..4b59438 100644 (file)
  */
 package org.onosproject.openflow.controller.impl;
 
-import org.jboss.netty.channel.Channel;
+import java.io.IOException;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.onosproject.net.Device;
-import org.onosproject.net.driver.DriverData;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
 import org.onosproject.openflow.controller.RoleState;
-import org.onosproject.openflow.controller.driver.OpenFlowAgent;
 import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
-import org.onosproject.openflow.controller.driver.RoleHandler;
 import org.onosproject.openflow.controller.driver.RoleRecvStatus;
 import org.onosproject.openflow.controller.driver.RoleReplyInfo;
 import org.onosproject.openflow.controller.driver.SwitchStateException;
 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFErrorMsg;
-import org.projectfloodlight.openflow.protocol.OFFactories;
-import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
-import org.projectfloodlight.openflow.protocol.OFVersion;
 import org.projectfloodlight.openflow.types.U64;
 
-import java.io.IOException;
-import java.util.List;
-
 import static org.junit.Assert.assertEquals;
 import static org.onosproject.openflow.controller.RoleState.MASTER;
 import static org.onosproject.openflow.controller.RoleState.SLAVE;
@@ -103,24 +89,11 @@ public class RoleManagerTest {
         }
     }
 
-    private class TestSwitchDriver implements OpenFlowSwitchDriver {
+    private class TestSwitchDriver extends OpenflowSwitchDriverAdapter {
 
         RoleState failed = null;
         RoleState current = null;
 
-        @Override
-        public void sendMsg(OFMessage msg) {
-        }
-
-        @Override
-        public void sendMsg(List<OFMessage> msgs) {
-        }
-
-
-        @Override
-        public void handleMessage(OFMessage fromSwitch) {
-        }
-
         @Override
         public void setRole(RoleState role) {
             current = role;
@@ -131,143 +104,6 @@ public class RoleManagerTest {
             return current;
         }
 
-        @Override
-        public List<OFPortDesc> getPorts() {
-            return null;
-        }
-
-        @Override
-        public OFFactory factory() {
-            // return what-ever triggers requestPending = true
-            return OFFactories.getFactory(OFVersion.OF_10);
-        }
-
-        @Override
-        public String getStringId() {
-            return "100";
-        }
-
-        @Override
-        public long getId() {
-            return 0;
-        }
-
-        @Override
-        public String manufacturerDescription() {
-            return null;
-        }
-
-        @Override
-        public String datapathDescription() {
-            return null;
-        }
-
-        @Override
-        public String hardwareDescription() {
-            return null;
-        }
-
-        @Override
-        public String softwareDescription() {
-            return null;
-        }
-
-        @Override
-        public String serialNumber() {
-            return null;
-        }
-
-        @Override
-        public void disconnectSwitch() {
-        }
-
-        @Override
-        public Device.Type deviceType() {
-            return Device.Type.SWITCH;
-        }
-
-        @Override
-        public void setAgent(OpenFlowAgent agent) {
-        }
-
-        @Override
-        public void setRoleHandler(RoleHandler roleHandler) {
-        }
-
-        @Override
-        public void reassertRole() {
-        }
-
-        @Override
-        public boolean handleRoleError(OFErrorMsg error) {
-            return false;
-        }
-
-        @Override
-        public void handleNiciraRole(OFMessage m) throws SwitchStateException {
-        }
-
-        @Override
-        public void handleRole(OFMessage m) throws SwitchStateException {
-        }
-
-        @Override
-        public void startDriverHandshake() {
-        }
-
-        @Override
-        public boolean isDriverHandshakeComplete() {
-            return false;
-        }
-
-        @Override
-        public void processDriverHandshakeMessage(OFMessage m) {
-        }
-
-        @Override
-        public void sendRoleRequest(OFMessage message) {
-
-        }
-
-        @Override
-        public void sendHandshakeMessage(OFMessage message) {
-        }
-
-        @Override
-        public boolean connectSwitch() {
-            return false;
-        }
-
-        @Override
-        public boolean activateMasterSwitch() {
-            return false;
-        }
-
-        @Override
-        public boolean activateEqualSwitch() {
-            return false;
-        }
-
-        @Override
-        public void transitionToEqualSwitch() {
-        }
-
-        @Override
-        public void transitionToMasterSwitch() {
-        }
-
-        @Override
-        public void removeConnectedSwitch() {
-        }
-
-        @Override
-        public void setPortDescReply(OFPortDescStatsReply portDescReply) {
-        }
-
-        @Override
-        public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
-        }
-
         @Override
         public void setFeaturesReply(OFFeaturesReply featuresReply) {
         }
@@ -281,37 +117,6 @@ public class RoleManagerTest {
             return (int) XID;
         }
 
-        @Override
-        public Boolean supportNxRole() {
-            return true;
-        }
-
-        @Override
-        public void setOFVersion(OFVersion ofV) {
-        }
-
-        @Override
-        public void setTableFull(boolean full) {
-        }
-
-        @Override
-        public void setChannel(Channel channel) {
-        }
-
-        @Override
-        public void setConnected(boolean connected) {
-        }
-
-        @Override
-        public void init(Dpid dpid, OFDescStatsReply desc, OFVersion ofv) {
-
-        }
-
-        @Override
-        public boolean isConnected() {
-            return false;
-        }
-
         @Override
         public void returnRoleReply(RoleState requested, RoleState response) {
             failed = requested;
@@ -321,25 +126,5 @@ public class RoleManagerTest {
         public String channelId() {
             return "1.2.3.4:1";
         }
-
-        @Override
-        public DriverHandler handler() {
-            return null;
-        }
-
-        @Override
-        public void setHandler(DriverHandler handler) {
-
-        }
-
-        @Override
-        public DriverData data() {
-            return null;
-        }
-
-        @Override
-        public void setData(DriverData data) {
-
-        }
     }
 }
index edd25ac..65ff024 100644 (file)
@@ -204,7 +204,7 @@ public interface OvsdbClientService extends OvsdbRPC {
     String getControllerUuid(String controllerName, String controllerTarget);
 
     /**
-     * Gets the Ovs uuid.
+     * Gets the OVS uuid.
      *
      * @param dbName database name
      * @return ovs uuid, empty if no uuid is find
@@ -212,7 +212,7 @@ public interface OvsdbClientService extends OvsdbRPC {
     String getOvsUuid(String dbName);
 
     /**
-     * Gets the ovsdb database schema.
+     * Gets the OVSDB database schema.
      *
      * @param dbName database name
      * @return database schema
@@ -220,7 +220,7 @@ public interface OvsdbClientService extends OvsdbRPC {
     ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName);
 
     /**
-     * Gets the ovsdb table updates.
+     * Gets the OVSDB table updates.
      *
      * @param dbName database name
      * @param id     random uuid
@@ -229,7 +229,7 @@ public interface OvsdbClientService extends OvsdbRPC {
     ListenableFuture<TableUpdates> monitorTables(String dbName, String id);
 
     /**
-     * Gets the ovsdb config operation result.
+     * Gets the OVSDB config operation result.
      *
      * @param dbName     database name
      * @param operations the list of operations
@@ -239,7 +239,7 @@ public interface OvsdbClientService extends OvsdbRPC {
                                                            List<Operation> operations);
 
     /**
-     * Gets the ovsdb database schema from local.
+     * Gets the OVSDB database schema from local.
      *
      * @param dbName database name
      * @return database schema
@@ -247,17 +247,17 @@ public interface OvsdbClientService extends OvsdbRPC {
     DatabaseSchema getDatabaseSchema(String dbName);
 
     /**
-     * Gets the ovsdb row from local ovsdb store.
+     * Gets the OVSDB row from local OVSDB store.
      *
      * @param dbName    database name
      * @param tableName table name
      * @param uuid      row uuid
-     * @return row ovsdb row
+     * @return row OVSDB row
      */
     Row getRow(String dbName, String tableName, String uuid);
 
     /**
-     * Removes the ovsdb row from local ovsdb store.
+     * Removes the OVSDB row from local OVSDB store.
      *
      * @param dbName    database name
      * @param tableName table name
@@ -266,25 +266,25 @@ public interface OvsdbClientService extends OvsdbRPC {
     void removeRow(String dbName, String tableName, String uuid);
 
     /**
-     * Updates the local ovsdb store.
+     * Updates the local OVSDB store.
      *
      * @param dbName    database name
      * @param tableName table name
      * @param uuid      row uuid
-     * @param row       ovsdb row
+     * @param row       OVSDB row
      */
     void updateOvsdbStore(String dbName, String tableName, String uuid, Row row);
 
     /**
-     * Gets ovsdb local ports.
+     * Gets OVSDB local ports.
      *
      * @param ifaceids the ifaceid that needed
-     * @return ovsdb ports
+     * @return OVSDB ports
      */
     Set<OvsdbPort> getLocalPorts(Iterable<String> ifaceids);
 
     /**
-     * Disconnects the ovsdb server.
+     * Disconnects the OVSDB server.
      */
     void disconnect();
 }
index d7a5f61..60146c8 100644 (file)
@@ -22,7 +22,7 @@ import java.util.Objects;
 import org.onlab.packet.IpAddress;
 
 /**
- * The class representing a OpenStack Compute or Network nodeId.
+ * The class representing a nodeId of node which using ovsdb connection.
  * This class is immutable.
  */
 public final class OvsdbNodeId {
index 7eca492..010d7e7 100644 (file)
@@ -105,6 +105,7 @@ public abstract class FlowModBuilder {
      * @param flowRule the flow rule to transform into a flow mod
      * @param factory the OpenFlow factory to use to build the flow mod
      * @param xid the transaction ID
+     * @param driverService the device driver service
      * @return the new flow mod builder
      */
     public static FlowModBuilder builder(FlowRule flowRule,
@@ -127,6 +128,7 @@ public abstract class FlowModBuilder {
      *
      * @param flowRule the flow rule to transform into a flow mod
      * @param factory the OpenFlow factory to use to build the flow mod
+     * @param driverService the device driver service
      * @param xid the transaction ID
      */
     protected FlowModBuilder(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
index 6c4ee4d..bdea09d 100644 (file)
@@ -69,6 +69,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
      * @param flowRule the flow rule to transform into a flow mod
      * @param factory the OpenFlow factory to use to build the flow mod
      * @param xid the transaction ID
+     * @param driverService the device driver service
      */
     protected FlowModBuilderVer10(FlowRule flowRule,
                                   OFFactory factory, Optional<Long> xid,
index a99aa81..e2fc30d 100644 (file)
@@ -103,6 +103,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
      * @param flowRule the flow rule to transform into a flow mod
      * @param factory the OpenFlow factory to use to build the flow mod
      * @param xid the transaction ID
+     * @param driverService the device driver service
      */
     protected FlowModBuilderVer13(FlowRule flowRule, OFFactory factory, Optional<Long> xid,
                                   Optional<DriverService> driverService) {
index e2fcefc..40e8686 100644 (file)
@@ -20,6 +20,7 @@ import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.IOException;
+import java.net.ServerSocket;
 import java.util.List;
 import java.util.Random;
 
@@ -207,4 +208,20 @@ public final class TestTools {
         }
     }
 
+    /*
+     * Finds an available port that a test can bind to.
+     */
+    public static int findAvailablePort(int defaultPort) {
+        try {
+            ServerSocket socket = new ServerSocket(0);
+            socket.setReuseAddress(true);
+            int port = socket.getLocalPort();
+            socket.close();
+            return port;
+        } catch (IOException ex) {
+            return defaultPort;
+        }
+    }
+
+
 }
diff --git a/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks b/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks
new file mode 100644 (file)
index 0000000..ba75051
Binary files /dev/null and b/framework/src/onos/utils/junit/src/main/resources/org/onosproject/openflow/controller/impl/ControllerTestKeystore.jks differ