aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core')
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java7
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java7
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java12
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java7
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java17
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java17
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java15
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java129
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java9
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java143
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java31
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java22
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java21
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java7
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java33
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java9
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpHaCriterion.java83
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java34
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java37
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L1ModificationInstruction.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java21
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java40
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java6
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java6
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java20
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java8
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceEvent.java54
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceListener.java26
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java168
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStoreDelegate.java24
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java6
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java3
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java6
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java4
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java5
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java2
-rw-r--r--framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java26
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationEventTest.java2
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationServiceAdapter.java4
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/app/DefaultApplicationDescriptionTest.java4
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/core/CoreServiceAdapter.java7
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java11
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/PortNumberTest.java37
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/device/DefaultDeviceDescriptionTest.java2
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java4
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java1
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java5
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsIntentTest.java1
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsPathIntentTest.java3
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/PathIntentTest.java2
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java6
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java32
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java3
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/ui/table/cell/DefaultCellComparatorTest.java8
-rw-r--r--framework/src/onos/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java44
-rw-r--r--framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/ApplicationCodec.java8
-rw-r--r--framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java12
-rw-r--r--framework/src/onos/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java13
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java2
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleApplicationStore.java6
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java6
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java12
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java3
-rw-r--r--framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SystemClockTimestamp.java2
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java34
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java21
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java4
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java4
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java20
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java55
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java8
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java8
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java14
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java4
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java2
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java37
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java2
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java10
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java92
-rw-r--r--framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java18
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/app/impl/ApplicationManagerTest.java21
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java17
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java19
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java9
-rw-r--r--framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java553
-rw-r--r--framework/src/onos/core/store/dist/pom.xml7
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/app/GossipApplicationStore.java138
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java55
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java18
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java20
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/AsyncCachingConsistentMap.java12
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseManager.java7
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java10
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java12
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java11
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java63
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/flow/impl/NewDistributedFlowRuleStore.java29
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java94
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/impl/LogicalTimestamp.java2
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/intent/impl/PartitionId.java2
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java187
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java14
-rw-r--r--framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/device/impl/GossipDeviceStoreTest.java4
-rw-r--r--framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java7
-rw-r--r--framework/src/onos/core/store/persistence/pom.xml2
-rw-r--r--framework/src/onos/core/store/pom.xml2
-rw-r--r--framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java4
-rw-r--r--framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/UriSerializer.java (renamed from framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/URISerializer.java)8
-rw-r--r--framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java4
153 files changed, 2302 insertions, 791 deletions
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java
index 2561280b..e8ff9ec4 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationDescription.java
@@ -86,4 +86,11 @@ public interface ApplicationDescription {
* @return application features
*/
List<String> features();
+
+ /**
+ * Returns list of required application names.
+ *
+ * @return list of application names
+ */
+ List<String> requiredApps();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java
index 73dcc86c..1e543b85 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationService.java
@@ -67,4 +67,11 @@ public interface ApplicationService
*/
Set<Permission> getPermissions(ApplicationId appId);
+ /**
+ * Registers application pre-deactivation processing hook.
+ *
+ * @param appId application identifier
+ * @param hook pre-deactivation hook
+ */
+ void registerDeactivateHook(ApplicationId appId, Runnable hook);
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java
index b3cdc43e..0a1f0727 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/ApplicationStore.java
@@ -76,7 +76,7 @@ public interface ApplicationStore extends Store<ApplicationEvent, ApplicationSto
void remove(ApplicationId appId);
/**
- * Mark the application as actived.
+ * Mark the application as active.
*
* @param appId application identifier
*/
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java
index 710d0f9c..569183a7 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/app/DefaultApplicationDescription.java
@@ -41,6 +41,7 @@ public class DefaultApplicationDescription implements ApplicationDescription {
private final Set<Permission> permissions;
private final Optional<URI> featuresRepo;
private final List<String> features;
+ private final List<String> requiredApps;
/**
* Creates a new application descriptor using the supplied data.
@@ -53,11 +54,13 @@ public class DefaultApplicationDescription implements ApplicationDescription {
* @param permissions requested permissions
* @param featuresRepo optional features repo URI
* @param features application features
+ * @param requiredApps list of required application names
*/
public DefaultApplicationDescription(String name, Version version,
String description, String origin,
ApplicationRole role, Set<Permission> permissions,
- URI featuresRepo, List<String> features) {
+ URI featuresRepo, List<String> features,
+ List<String> requiredApps) {
this.name = checkNotNull(name, "Name cannot be null");
this.version = checkNotNull(version, "Version cannot be null");
this.description = checkNotNull(description, "Description cannot be null");
@@ -66,6 +69,7 @@ public class DefaultApplicationDescription implements ApplicationDescription {
this.permissions = checkNotNull(permissions, "Permissions cannot be null");
this.featuresRepo = Optional.ofNullable(featuresRepo);
this.features = checkNotNull(features, "Features cannot be null");
+ this.requiredApps = checkNotNull(requiredApps, "Required apps cannot be null");
checkArgument(!features.isEmpty(), "There must be at least one feature");
}
@@ -110,6 +114,11 @@ public class DefaultApplicationDescription implements ApplicationDescription {
}
@Override
+ public List<String> requiredApps() {
+ return requiredApps;
+ }
+
+ @Override
public String toString() {
return toStringHelper(this)
.add("name", name)
@@ -120,6 +129,7 @@ public class DefaultApplicationDescription implements ApplicationDescription {
.add("permissions", permissions)
.add("featuresRepo", featuresRepo)
.add("features", features)
+ .add("requiredApps", requiredApps)
.toString();
}
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java
index 36cd22b5..f1b602e8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cfg/ConfigProperty.java
@@ -245,7 +245,7 @@ public final class ConfigProperty {
@Override
public int hashCode() {
- return Objects.hash(name);
+ return name.hashCode();
}
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java
index 5f3e0e19..3787daa5 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/DefaultControllerNode.java
@@ -20,6 +20,7 @@ import org.onlab.packet.IpAddress;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Default implementation of a controller instance descriptor.
@@ -57,7 +58,7 @@ public class DefaultControllerNode implements ControllerNode {
* @param tcpPort TCP port
*/
public DefaultControllerNode(NodeId id, IpAddress ip, int tcpPort) {
- this.id = id;
+ this.id = checkNotNull(id);
this.ip = ip;
this.tcpPort = tcpPort;
}
@@ -79,7 +80,7 @@ public class DefaultControllerNode implements ControllerNode {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java
index 6cfb42c7..e5ab9dc8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/cluster/NodeId.java
@@ -35,7 +35,7 @@ public class NodeId implements Comparable<NodeId> {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java
index fca53843..ea2eab9b 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Application.java
@@ -84,4 +84,11 @@ public interface Application {
* @return application features
*/
List<String> features();
+
+ /**
+ * Returns list of required application names.
+ *
+ * @return list of application names
+ */
+ List<String> requiredApps();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java
index 303ad395..0825a6d1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/CoreService.java
@@ -50,6 +50,7 @@ public interface CoreService {
/**
* Returns an existing application id from a given id.
+ *
* @param id the short value of the id
* @return an application id
*/
@@ -57,6 +58,7 @@ public interface CoreService {
/**
* Returns an existing application id from a given id.
+ *
* @param name the name portion of the ID to look up
* @return an application id
*/
@@ -67,10 +69,21 @@ public interface CoreService {
* to follow the reverse DNS convention, e.g.
* {@code org.flying.circus.app}
*
- * @param identifier string identifier
+ * @param name string identifier
+ * @return the application id
+ */
+ ApplicationId registerApplication(String name);
+
+ /**
+ * Registers a new application by its name, which is expected
+ * to follow the reverse DNS convention, e.g.
+ * {@code org.flying.circus.app}, along with its pre-deactivation hook.
+ *
+ * @param name string identifier
+ * @param preDeactivate pre-deactivation hook
* @return the application id
*/
- ApplicationId registerApplication(String identifier);
+ ApplicationId registerApplication(String name, Runnable preDeactivate);
/**
* Returns an id generator for a given topic.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java
index d8062ddf..c3515638 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplication.java
@@ -40,6 +40,7 @@ public class DefaultApplication implements Application {
private final Set<Permission> permissions;
private final Optional<URI> featuresRepo;
private final List<String> features;
+ private final List<String> requiredApps;
/**
* Creates a new application descriptor using the supplied data.
@@ -52,11 +53,13 @@ public class DefaultApplication implements Application {
* @param permissions requested permissions
* @param featuresRepo optional features repo URI
* @param features application features
+ * @param requiredApps list of required application names
*/
public DefaultApplication(ApplicationId appId, Version version,
String description, String origin,
ApplicationRole role, Set<Permission> permissions,
- Optional<URI> featuresRepo, List<String> features) {
+ Optional<URI> featuresRepo, List<String> features,
+ List<String> requiredApps) {
this.appId = checkNotNull(appId, "ID cannot be null");
this.version = checkNotNull(version, "Version cannot be null");
this.description = checkNotNull(description, "Description cannot be null");
@@ -65,6 +68,7 @@ public class DefaultApplication implements Application {
this.permissions = checkNotNull(permissions, "Permissions cannot be null");
this.featuresRepo = checkNotNull(featuresRepo, "Features repo cannot be null");
this.features = checkNotNull(features, "Features cannot be null");
+ this.requiredApps = checkNotNull(requiredApps, "Required apps cannot be null");
checkArgument(!features.isEmpty(), "There must be at least one feature");
}
@@ -109,9 +113,14 @@ public class DefaultApplication implements Application {
}
@Override
+ public List<String> requiredApps() {
+ return requiredApps;
+ }
+
+ @Override
public int hashCode() {
return Objects.hash(appId, version, description, origin, role, permissions,
- featuresRepo, features);
+ featuresRepo, features, requiredApps);
}
@Override
@@ -130,7 +139,8 @@ public class DefaultApplication implements Application {
Objects.equals(this.role, other.role) &&
Objects.equals(this.permissions, other.permissions) &&
Objects.equals(this.featuresRepo, other.featuresRepo) &&
- Objects.equals(this.features, other.features);
+ Objects.equals(this.features, other.features) &&
+ Objects.equals(this.requiredApps, other.requiredApps);
}
@Override
@@ -144,6 +154,7 @@ public class DefaultApplication implements Application {
.add("permissions", permissions)
.add("featuresRepo", featuresRepo)
.add("features", features)
+ .add("requiredApps", requiredApps)
.toString();
}
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java
index c7b5b2da..aedfb0d3 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultApplicationId.java
@@ -58,7 +58,7 @@ public class DefaultApplicationId implements ApplicationId {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return Short.hashCode(id);
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
index 9fa8d2b6..243e5216 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
@@ -42,7 +42,7 @@ public class DefaultGroupId implements GroupId {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id;
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java
index a5377016..06e9e206 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/core/Version.java
@@ -127,7 +127,7 @@ public final class Version {
@Override
public int hashCode() {
- return Objects.hash(format);
+ return format.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
index d81b83cc..34042dad 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/AbstractDescription.java
@@ -16,6 +16,7 @@
package org.onosproject.net;
import static com.google.common.base.Preconditions.checkArgument;
+import com.google.common.base.Objects;
/**
* Base implementation of an annotated model description.
@@ -46,4 +47,18 @@ public abstract class AbstractDescription implements Annotated {
return annotations;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(annotations);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof AbstractDescription) {
+ AbstractDescription that = (AbstractDescription) object;
+ return Objects.equal(this.annotations, that.annotations);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
index 2877701e..557fa5c1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultHost.java
@@ -98,7 +98,8 @@ public class DefaultHost extends AbstractElement implements Host {
return Objects.equals(this.id, other.id) &&
Objects.equals(this.mac, other.mac) &&
Objects.equals(this.vlan, other.vlan) &&
- Objects.equals(this.location, other.location);
+ Objects.equals(this.location, other.location) &&
+ Objects.equals(this.ipAddresses(), other.ipAddresses());
}
return false;
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java
index a4789cac..2da2463a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DefaultPath.java
@@ -88,7 +88,7 @@ public class DefaultPath extends DefaultLink implements Path {
@Override
public int hashCode() {
- return Objects.hash(links);
+ return links.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java
index 5331342e..e2c1214f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/DeviceId.java
@@ -75,7 +75,7 @@ public final class DeviceId extends ElementId {
@Override
public int hashCode() {
- return Objects.hash(str);
+ return str.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java
index 03e6dba9..8c9b1349 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/PortNumber.java
@@ -15,6 +15,16 @@
*/
package org.onosproject.net;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.primitives.UnsignedLongs;
/**
@@ -26,8 +36,7 @@ public final class PortNumber {
// TODO: revisit the max and the logical port value assignments
- private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
-
+ static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
static final long IN_PORT_NUMBER = -8L;
static final long TABLE_NUMBER = -7L;
@@ -37,6 +46,39 @@ public final class PortNumber {
static final long LOCAL_NUMBER = -2L;
static final long CONTROLLER_NUMBER = -3L;
+ /**
+ * Logical PortNumbers.
+ */
+ public static enum Logical {
+ IN_PORT(IN_PORT_NUMBER),
+ TABLE(TABLE_NUMBER),
+ NORMAL(NORMAL_NUMBER),
+ FLOOD(FLOOD_NUMBER),
+ ALL(ALL_NUMBER),
+ LOCAL(LOCAL_NUMBER),
+ CONTROLLER(CONTROLLER_NUMBER);
+
+ private final long number;
+ private final PortNumber instance;
+
+ public long number() {
+ return number;
+ }
+
+ /**
+ * PortNumber instance for the logical port.
+ * @return {@link PortNumber}
+ */
+ public PortNumber instance() {
+ return instance;
+ }
+
+ Logical(long number) {
+ this.number = number;
+ this.instance = new PortNumber(number);
+ }
+ }
+
public static final PortNumber IN_PORT = new PortNumber(IN_PORT_NUMBER);
public static final PortNumber TABLE = new PortNumber(TABLE_NUMBER);
public static final PortNumber NORMAL = new PortNumber(NORMAL_NUMBER);
@@ -45,6 +87,15 @@ public final class PortNumber {
public static final PortNumber LOCAL = new PortNumber(LOCAL_NUMBER);
public static final PortNumber CONTROLLER = new PortNumber(CONTROLLER_NUMBER);
+ // lazily populated Logical port number to PortNumber
+ static final Supplier<Map<Long, Logical>> LOGICAL = Suppliers.memoize(() -> {
+ Builder<Long, Logical> builder = ImmutableMap.<Long, Logical>builder();
+ for (Logical lp : Logical.values()) {
+ builder.put(lp.number(), lp);
+ }
+ return builder.build();
+ });
+
private final long number;
private final String name;
private final boolean hasName;
@@ -136,30 +187,68 @@ public final class PortNumber {
}
private String decodeLogicalPort() {
- if (number == CONTROLLER_NUMBER) {
- return "CONTROLLER";
- } else if (number == LOCAL_NUMBER) {
- return "LOCAL";
- } else if (number == ALL_NUMBER) {
- return "ALL";
- } else if (number == FLOOD_NUMBER) {
- return "FLOOD";
- } else if (number == NORMAL_NUMBER) {
- return "NORMAL";
- } else if (number == TABLE_NUMBER) {
- return "TABLE";
- } else if (number == IN_PORT_NUMBER) {
- return "IN_PORT";
+ Logical logical = LOGICAL.get().get(number);
+ if (logical != null) {
+ // enum name
+ return logical.toString();
+ }
+ return String.format("UNKNOWN(%s)", UnsignedLongs.toString(number));
+ }
+
+
+ /**
+ * Regular expression to match String representation of named PortNumber.
+ *
+ * Format: "[name](num:unsigned decimal string)"
+ */
+ private static final Pattern NAMED = Pattern.compile("^\\[(?<name>.*)\\]\\((?<num>\\d+)\\)$");
+
+ private static boolean isAsciiDecimal(char c) {
+ return '0' <= c && c <= '9';
+ }
+
+ /**
+ * Returns PortNumber instance from String representation.
+ *
+ * @param s String representation equivalent to {@link PortNumber#toString()}
+ * @return {@link PortNumber} instance
+ * @throws IllegalArgumentException if given String was malformed
+ */
+ public static PortNumber fromString(String s) {
+ checkNotNull(s);
+ checkArgument(!s.isEmpty(), "cannot be empty");
+
+ if (isAsciiDecimal(s.charAt(0))) {
+ // unsigned decimal string
+ return portNumber(s);
+ } else if (s.startsWith("[")) {
+ // named PortNumber
+ Matcher matcher = NAMED.matcher(s);
+ checkArgument(matcher.matches(), "Invalid named PortNumber %s", s);
+
+ String name = matcher.group("name");
+ String num = matcher.group("num");
+ return portNumber(UnsignedLongs.parseUnsignedLong(num), name);
+ }
+
+ // Logical
+ if (s.startsWith("UNKNOWN(") && s.endsWith(")")) {
+ return portNumber(s.substring("UNKNOWN(".length(), s.length() - 1));
+ } else {
+ return Logical.valueOf(s).instance;
}
- return "UNKNOWN";
}
@Override
public String toString() {
- if (!isLogical()) {
- return name;
- } else {
+ if (isLogical()) {
return decodeLogicalPort();
+ } else if (hasName()) {
+ // named port
+ return String.format("[%s](%d)", name, number);
+ } else {
+ // unsigned decimal string
+ return name;
}
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
index e3d6993c..cf7bed6d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeConfig.java
@@ -36,6 +36,15 @@ public interface BridgeConfig extends HandlerBehaviour {
void addBridge(BridgeName bridgeName);
/**
+ * Adds a bridge with given bridge name, dpid and exPortName.
+ *
+ * @param bridgeName bridge name
+ * @param dpid dpid
+ * @param exPortName external port name
+ */
+ void addBridge(BridgeName bridgeName, String dpid, String exPortName);
+
+ /**
* Adds a bridge with given bridge name and dpid, and sets the controller
* of the bridge with given controllers.
*
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java
index 3f782954..a15217c6 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/behaviour/BridgeName.java
@@ -52,7 +52,7 @@ public final class BridgeName {
@Override
public int hashCode() {
- return Objects.hash(name);
+ return name.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
index 5cdc0c12..3757d327 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/Config.java
@@ -20,10 +20,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
import java.util.Collection;
import java.util.List;
+import java.util.Set;
import java.util.function.Function;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -51,6 +56,21 @@ public abstract class Config<S> {
protected ConfigApplyDelegate delegate;
/**
+ * Indicator of whether a configuration JSON field is required.
+ */
+ public enum FieldPresence {
+ /**
+ * Signifies that config field is an optional one.
+ */
+ OPTIONAL,
+
+ /**
+ * Signifies that config field is mandatory.
+ */
+ MANDATORY
+ }
+
+ /**
* Initializes the configuration behaviour with necessary context.
*
* @param subject configuration subject
@@ -71,6 +91,29 @@ public abstract class Config<S> {
}
/**
+ * Indicates whether or not the backing JSON node contains valid data.
+ * <p>
+ * Default implementation returns true.
+ * Subclasses are expected to override this with their own validation.
+ * </p>
+ *
+ * @return true if the data is valid; false otherwise
+ */
+ public boolean isValid() {
+ // TODO: figure out what assertions could be made in the base class
+ // NOTE: The thought is to have none, but instead to provide a set
+ // of predicates to allow configs to test validity of present fields,
+ // e.g.:
+ // isString(path)
+ // isBoolean(path)
+ // isNumber(path, [min, max])
+ // isDecimal(path, [min, max])
+ // isMacAddress(path)
+ // isIpAddress(path)
+ return true;
+ }
+
+ /**
* Returns the specific subject to which this configuration pertains.
*
* @return configuration subject
@@ -309,4 +352,104 @@ public abstract class Config<S> {
return this;
}
+ /**
+ * Indicates whether only the specified fields are present in the backing JSON.
+ *
+ * @param allowedFields allowed field names
+ * @return true if all allowedFields are present; false otherwise
+ */
+ protected boolean hasOnlyFields(String... allowedFields) {
+ Set<String> fields = ImmutableSet.copyOf(allowedFields);
+ return !Iterators.any(object.fieldNames(), f -> !fields.contains(f));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid MAC address.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid MAC
+ */
+ protected boolean isMacAddress(String field, FieldPresence presence) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ MacAddress.valueOf(node.asText()) != null);
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid IP address.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid IP
+ */
+ protected boolean isIpAddress(String field, FieldPresence presence) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ IpAddress.valueOf(node.asText()) != null);
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid string value.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param pattern optional regex pattern
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid MAC
+ */
+ protected boolean isString(String field, FieldPresence presence, String... pattern) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, node.isTextual() &&
+ (pattern.length > 0 && node.asText().matches(pattern[0]) || pattern.length < 1));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid number.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param minMax optional min/max values
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid
+ */
+ protected boolean isNumber(String field, FieldPresence presence, long... minMax) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, (node.isLong() || node.isInt()) &&
+ (minMax.length > 0 && minMax[0] <= node.asLong() || minMax.length < 1) &&
+ (minMax.length > 1 && minMax[1] > node.asLong() || minMax.length < 2));
+ }
+
+ /**
+ * Indicates whether the specified field holds a valid decimal number.
+ *
+ * @param field JSON field name
+ * @param presence specifies if field is optional or mandatory
+ * @param minMax optional min/max values
+ * @return true if valid; false otherwise
+ * @throws IllegalArgumentException if field is present, but not valid
+ */
+ protected boolean isDecimal(String field, FieldPresence presence, double... minMax) {
+ JsonNode node = object.path(field);
+ return isValid(node, presence, (node.isDouble() || node.isFloat()) &&
+ (minMax.length > 0 && minMax[0] <= node.asDouble() || minMax.length < 1) &&
+ (minMax.length > 1 && minMax[1] > node.asDouble() || minMax.length < 2));
+ }
+
+ /**
+ * Indicates whether the node is present and of correct value or not
+ * mandatory and absent.
+ *
+ * @param node JSON node
+ * @param presence specifies if field is optional or mandatory
+ * @param correctValue true if the value is correct
+ * @return true if the field is as expected
+ */
+ private boolean isValid(JsonNode node, FieldPresence presence, boolean correctValue) {
+ boolean isMandatory = presence == FieldPresence.MANDATORY;
+ return isMandatory && correctValue || !isMandatory && !node.isNull() || correctValue;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
index 8eb69a45..f1b22c41 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigService.java
@@ -119,7 +119,7 @@ public interface NetworkConfigService
/**
* Applies configuration for the specified subject and configuration
- * class using the raw JSON object. If configuration already exists, it
+ * class using the raw JSON node. If configuration already exists, it
* will be updated.
*
* @param subject configuration subject
@@ -128,6 +128,8 @@ public interface NetworkConfigService
* @param <S> type of subject
* @param <C> type of configuration
* @return configuration or null if one is not available
+ * @throws IllegalArgumentException if the supplied JSON node contains
+ * invalid data
*/
<S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
JsonNode json);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
index 9dd66e8d..9be4b120 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/config/NetworkConfigStore.java
@@ -113,6 +113,8 @@ public interface NetworkConfigStore extends Store<NetworkConfigEvent, NetworkCon
* @param <S> type of subject
* @param <C> type of configuration
* @return configuration object
+ * @throws IllegalArgumentException if the supplied JSON node contains
+ * invalid data
*/
<S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass,
JsonNode json);
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
index 3a8c8c1f..9074792c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultDeviceDescription.java
@@ -24,6 +24,7 @@ import java.net.URI;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.Device.Type;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable device description entity.
@@ -71,7 +72,7 @@ public class DefaultDeviceDescription extends AbstractDescription
*/
public DefaultDeviceDescription(DeviceDescription base,
SparseAnnotations... annotations) {
- this(base.deviceURI(), base.type(), base.manufacturer(),
+ this(base.deviceUri(), base.type(), base.manufacturer(),
base.hwVersion(), base.swVersion(), base.serialNumber(),
base.chassisId(), annotations);
}
@@ -83,13 +84,13 @@ public class DefaultDeviceDescription extends AbstractDescription
* @param annotations Annotations to use.
*/
public DefaultDeviceDescription(DeviceDescription base, Type type, SparseAnnotations... annotations) {
- this(base.deviceURI(), type, base.manufacturer(),
+ this(base.deviceUri(), type, base.manufacturer(),
base.hwVersion(), base.swVersion(), base.serialNumber(),
base.chassisId(), annotations);
}
@Override
- public URI deviceURI() {
+ public URI deviceUri() {
return uri;
}
@@ -132,6 +133,30 @@ public class DefaultDeviceDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), uri, type, manufacturer,
+ hwVersion, swVersion, serialNumber, chassisId);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof DefaultDeviceDescription) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultDeviceDescription that = (DefaultDeviceDescription) object;
+ return Objects.equal(this.uri, that.uri)
+ && Objects.equal(this.type, that.type)
+ && Objects.equal(this.manufacturer, that.manufacturer)
+ && Objects.equal(this.hwVersion, that.hwVersion)
+ && Objects.equal(this.swVersion, that.swVersion)
+ && Objects.equal(this.serialNumber, that.serialNumber)
+ && Objects.equal(this.chassisId, that.chassisId);
+ }
+ return false;
+ }
+
// default constructor for serialization
private DefaultDeviceDescription() {
this.uri = null;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
index 572d201c..d62e932c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
@@ -21,6 +21,7 @@ import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import static org.onosproject.net.Port.Type;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable port description.
@@ -117,4 +118,25 @@ public class DefaultPortDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), number, isEnabled, type,
+ portSpeed);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultPortDescription that = (DefaultPortDescription) object;
+ return Objects.equal(this.number, that.number)
+ && Objects.equal(this.isEnabled, that.isEnabled)
+ && Objects.equal(this.type, that.type)
+ && Objects.equal(this.portSpeed, that.portSpeed);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
index 64b84b5a..f206b080 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/device/DeviceDescription.java
@@ -33,7 +33,7 @@ public interface DeviceDescription extends Description {
*
* @return provider specific URI for the device
*/
- URI deviceURI();
+ URI deviceUri();
/**
* Returns the type of the infrastructure device.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index 453a7648..a842d600 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -23,6 +23,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -353,6 +354,26 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@Override
+ public Builder matchArpTpa(Ip4Address addr) {
+ return add(Criteria.matchArpTpa(addr));
+ }
+
+ @Override
+ public Builder matchArpSpa(Ip4Address addr) {
+ return add(Criteria.matchArpSpa(addr));
+ }
+
+ @Override
+ public Builder matchArpTha(MacAddress addr) {
+ return add(Criteria.matchArpTha(addr));
+ }
+
+ @Override
+ public Builder matchArpSha(MacAddress addr) {
+ return add(Criteria.matchArpSha(addr));
+ }
+
+ @Override
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 6beeecc9..4615a82b 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -388,7 +388,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
@Override
public Builder setQueue(long queueId) {
- return add(Instructions.setQueue(queueId));
+ return add(Instructions.setQueue(queueId, null));
+ }
+
+ @Override
+ public Builder setQueue(long queueId, PortNumber port) {
+ return add(Instructions.setQueue(queueId, port));
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index 1286ffc1..9fe88d5a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -17,6 +17,7 @@ package org.onosproject.net.flow;
import java.util.Set;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
@@ -386,6 +387,38 @@ public interface TrafficSelector {
Builder matchIPv6ExthdrFlags(short exthdrFlags);
/**
+ * Matches a arp IPv4 destination address.
+ *
+ * @param addr a arp IPv4 destination address
+ * @return a selection builder
+ */
+ Builder matchArpTpa(Ip4Address addr);
+
+ /**
+ * Matches a arp IPv4 source address.
+ *
+ * @param addr a arp IPv4 source address
+ * @return a selection builder
+ */
+ Builder matchArpSpa(Ip4Address addr);
+
+ /**
+ * Matches a arp_eth_dst address.
+ *
+ * @param addr a arp_eth_dst address
+ * @return a selection builder
+ */
+ Builder matchArpTha(MacAddress addr);
+
+ /**
+ * Matches a arp_eth_src address.
+ *
+ * @param addr a arp_eth_src address
+ * @return a selection builder
+ */
+ Builder matchArpSha(MacAddress addr);
+
+ /**
* Builds an immutable traffic selector.
*
* @return traffic selector
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index b14ab99c..f1a676ab 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -271,6 +271,15 @@ public interface TrafficTreatment {
Builder setQueue(long queueId);
/**
+ * Sets the Queue ID for a specific port.
+ *
+ * @param queueId a queue ID
+ * @param port a port number
+ * @return a treatment builder
+ */
+ Builder setQueue(long queueId, PortNumber port);
+
+ /**
* Sets a meter to be used by this flow.
*
* @param meterId a meter id
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpHaCriterion.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpHaCriterion.java
new file mode 100644
index 00000000..71269dd1
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/ArpHaCriterion.java
@@ -0,0 +1,83 @@
+/*
+ * 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.flow.criteria;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.packet.MacAddress;
+
+/**
+ * Implementation of arp_eth_src address or arp_eth_dst address criterion.
+ */
+public final class ArpHaCriterion implements Criterion {
+ private final MacAddress mac;
+ private final Type type;
+
+ /**
+ * Constructor.
+ *
+ * @param mac the MAC Address to match.
+ * @param type the match type. Should be one of the following:
+ * Type.ARP_SHA, Type.ARP_THA
+ */
+ ArpHaCriterion(MacAddress mac, Type type) {
+ checkNotNull(mac, "mac cannot be null");
+ checkNotNull(type, "type cannot be null");
+ this.mac = mac;
+ this.type = type;
+ }
+
+ @Override
+ public Type type() {
+ return this.type;
+ }
+
+ /**
+ * Gets the MAC Address to match.
+ *
+ * @return the MAC Address to match
+ */
+ public MacAddress mac() {
+ return this.mac;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("mac", mac).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type().ordinal(), mac);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ArpHaCriterion) {
+ ArpHaCriterion that = (ArpHaCriterion) obj;
+ return Objects.equals(mac, that.mac) &&
+ Objects.equals(type, that.type);
+ }
+ return false;
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index 778d50a5..554b8e74 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -510,15 +510,45 @@ public final class Criteria {
}
/**
- * Creates a match on IPv4 source field using the specified value.
+ * Creates a match on IPv4 destination field using the specified value.
*
- * @param ip ipv4 source value
+ * @param ip ipv4 destination value
* @return match criterion
*/
public static Criterion matchArpTpa(Ip4Address ip) {
return new ArpPaCriterion(ip, Type.ARP_TPA);
}
+ /**
+ * Creates a match on IPv4 source field using the specified value.
+ *
+ * @param ip ipv4 source value
+ * @return match criterion
+ */
+ public static Criterion matchArpSpa(Ip4Address ip) {
+ return new ArpPaCriterion(ip, Type.ARP_SPA);
+ }
+
+ /**
+ * Creates a match on MAC destination field using the specified value.
+ *
+ * @param mac MAC destination value
+ * @return match criterion
+ */
+ public static Criterion matchArpTha(MacAddress mac) {
+ return new ArpHaCriterion(mac, Type.ARP_THA);
+ }
+
+ /**
+ * Creates a match on MAC source field using the specified value.
+ *
+ * @param mac MAC source value
+ * @return match criterion
+ */
+ public static Criterion matchArpSha(MacAddress mac) {
+ return new ArpHaCriterion(mac, Type.ARP_SHA);
+ }
+
public static Criterion dummy() {
return new DummyCriterion();
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
index 747a85b5..3e1cb75c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionType.java
@@ -32,7 +32,8 @@ public final class ExtensionType {
*/
public enum ExtensionTypes {
// TODO fix type numbers to include experimenter id
- NICIRA_SET_TUNNEL_DST(31);
+ NICIRA_SET_TUNNEL_DST(31),
+ NICIRA_RESUBMIT(32);
private ExtensionType type;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index aad407c8..126e722e 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.net.flow.instructions;
+import com.google.common.base.MoreObjects;
import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
@@ -99,11 +100,12 @@ public final class Instructions {
* Creates a set-queue instruction.
*
* @param queueId Queue Id
+ * @param port Port number
* @return set-queue instruction
*/
- public static SetQueueInstruction setQueue(final long queueId) {
+ public static SetQueueInstruction setQueue(final long queueId, final PortNumber port) {
checkNotNull(queueId, "queue ID cannot be null");
- return new SetQueueInstruction(queueId);
+ return new SetQueueInstruction(queueId, port);
}
public static MeterInstruction meterTraffic(final MeterId meterId) {
@@ -514,7 +516,7 @@ public final class Instructions {
@Override
public int hashCode() {
- return Objects.hash(type().ordinal());
+ return type().ordinal();
}
@Override
@@ -548,7 +550,7 @@ public final class Instructions {
@Override
public int hashCode() {
- return Objects.hash(type().ordinal());
+ return type().ordinal();
}
@Override
@@ -628,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
@@ -655,15 +658,26 @@ public final class Instructions {
*/
public static final class SetQueueInstruction implements Instruction {
private final long queueId;
+ private final PortNumber port;
private SetQueueInstruction(long queueId) {
this.queueId = queueId;
+ this.port = null;
+ }
+
+ private SetQueueInstruction(long queueId, PortNumber port) {
+ this.queueId = queueId;
+ this.port = port;
}
public long queueId() {
return queueId;
}
+ public PortNumber port() {
+ return port;
+ }
+
@Override
public Type type() {
return Type.QUEUE;
@@ -671,13 +685,18 @@ public final class Instructions {
@Override
public String toString() {
- return toStringHelper(type().toString())
- .add("queueId", queueId).toString();
+ MoreObjects.ToStringHelper toStringHelper = toStringHelper(type().toString());
+ toStringHelper.add("queueId", queueId);
+
+ if (port() != null) {
+ toStringHelper.add("port", port);
+ }
+ return toStringHelper.toString();
}
@Override
public int hashCode() {
- return Objects.hash(type().ordinal(), queueId);
+ return Objects.hash(type().ordinal(), queueId, port);
}
@Override
@@ -687,7 +706,7 @@ public final class Instructions {
}
if (obj instanceof SetQueueInstruction) {
SetQueueInstruction that = (SetQueueInstruction) obj;
- return Objects.equals(queueId, that.queueId);
+ return Objects.equals(queueId, that.queueId) && Objects.equals(port, that.port);
}
return false;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java
index a6e5903c..4af3d168 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L0ModificationInstruction.java
@@ -114,7 +114,7 @@ public abstract class L0ModificationInstruction implements Instruction {
@Override
public int hashCode() {
- return Objects.hash(lambda);
+ return lambda.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L1ModificationInstruction.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L1ModificationInstruction.java
index c6847d1c..b72dd7bc 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L1ModificationInstruction.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/flow/instructions/L1ModificationInstruction.java
@@ -62,7 +62,7 @@ public abstract class L1ModificationInstruction implements Instruction {
@Override
public int hashCode() {
- return Objects.hash(oduSignalId);
+ return oduSignalId.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java
index 546a4513..97f8aedf 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/group/DefaultGroup.java
@@ -186,7 +186,7 @@ public class DefaultGroup extends DefaultGroupDescription
*/
@Override
public int hashCode() {
- return super.hashCode() + Objects.hash(id);
+ return Objects.hash(super.hashCode(), id);
}
/*
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
index 1f05197a..307a6078 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/DefaultHostDescription.java
@@ -28,6 +28,7 @@ import org.onlab.packet.VlanId;
import com.google.common.collect.ImmutableSet;
import static com.google.common.base.MoreObjects.toStringHelper;
+import com.google.common.base.Objects;
/**
* Default implementation of an immutable host description.
@@ -119,4 +120,24 @@ public class DefaultHostDescription extends AbstractDescription
.toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), mac, vlan, location, ip);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultHostDescription that = (DefaultHostDescription) object;
+ return Objects.equal(this.mac, that.mac)
+ && Objects.equal(this.vlan, that.vlan)
+ && Objects.equal(this.location, that.location)
+ && Objects.equal(this.ip, that.ip);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
index 98329df0..92824cf8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
@@ -15,9 +15,12 @@
*/
package org.onosproject.net.host;
+import org.joda.time.LocalDateTime;
import org.onosproject.event.AbstractEvent;
import org.onosproject.net.Host;
+import static com.google.common.base.MoreObjects.toStringHelper;
+
/**
* Describes end-station host event.
*/
@@ -48,6 +51,8 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
HOST_MOVED
}
+ private Host prevSubject;
+
/**
* Creates an event of a given type and for the specified host and the
* current time.
@@ -70,4 +75,39 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
super(type, host, time);
}
+ /**
+ * Creates an event with previous subject.
+ *
+ * The previous subject is ignored if the type is not moved or updated
+ *
+ * @param type host event type
+ * @param host event host subject
+ * @param prevSubject previous host subject
+ */
+ public HostEvent(Type type, Host host, Host prevSubject) {
+ super(type, host);
+ if (type == Type.HOST_MOVED || type == Type.HOST_UPDATED) {
+ this.prevSubject = prevSubject;
+ }
+ }
+
+ /**
+ * Gets the previous subject in this host event.
+ *
+ * @return the previous subject, or null if previous subject is not
+ * specified.
+ */
+ public Host prevSubject() {
+ return this.prevSubject;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("time", new LocalDateTime(time()))
+ .add("type", type())
+ .add("subject", subject())
+ .add("prevSubject", prevSubject())
+ .toString();
+ }
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
index caa5fbb9..4548c44d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
@@ -42,6 +42,7 @@ public final class MplsPathIntent extends PathIntent {
* ports and using the specified explicit path.
*
* @param appId application identifier
+ * @param key intent key
* @param selector traffic selector
* @param treatment treatment
* @param path traversed links
@@ -51,11 +52,11 @@ public final class MplsPathIntent extends PathIntent {
* @param priority priority to use for flows generated by this intent
* @throws NullPointerException {@code path} is null
*/
- private MplsPathIntent(ApplicationId appId, TrafficSelector selector,
+ private MplsPathIntent(ApplicationId appId, Key key, TrafficSelector selector,
TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel,
Optional<MplsLabel> egressLabel, List<Constraint> constraints,
int priority) {
- super(appId, selector, treatment, path, constraints,
+ super(appId, key, selector, treatment, path, constraints,
priority);
this.ingressLabel = checkNotNull(ingressLabel);
@@ -149,6 +150,7 @@ public final class MplsPathIntent extends PathIntent {
return new MplsPathIntent(
appId,
+ key,
selector,
treatment,
path,
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
index 0c831fd5..9bf137a1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
@@ -42,6 +42,7 @@ public class PathIntent extends ConnectivityIntent {
* ports and using the specified explicit path.
*
* @param appId application identifier
+ * @param key intent key
* @param selector traffic selector
* @param treatment treatment
* @param path traversed links
@@ -50,12 +51,13 @@ public class PathIntent extends ConnectivityIntent {
* @throws NullPointerException {@code path} is null
*/
protected PathIntent(ApplicationId appId,
+ Key key,
TrafficSelector selector,
TrafficTreatment treatment,
Path path,
List<Constraint> constraints,
int priority) {
- super(appId, null, resources(path.links()), selector, treatment, constraints,
+ super(appId, key, resources(path.links()), selector, treatment, constraints,
priority);
PathIntent.validate(path.links());
this.path = path;
@@ -138,6 +140,7 @@ public class PathIntent extends ConnectivityIntent {
return new PathIntent(
appId,
+ key,
selector,
treatment,
path,
@@ -184,6 +187,7 @@ public class PathIntent extends ConnectivityIntent {
public String toString() {
return MoreObjects.toStringHelper(getClass())
.add("id", id())
+ .add("key", key())
.add("appId", appId())
.add("priority", priority())
.add("resources", resources())
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
index 20ccb55d..444feee4 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/BandwidthConstraint.java
@@ -87,7 +87,7 @@ public final class BandwidthConstraint extends BooleanConstraint {
@Override
public int hashCode() {
- return Objects.hash(bandwidth);
+ return bandwidth.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
index 9dd813b2..7811a004 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LambdaConstraint.java
@@ -69,7 +69,7 @@ public class LambdaConstraint extends BooleanConstraint {
@Override
public int hashCode() {
- return Objects.hash(lambda);
+ return Objects.hashCode(lambda);
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java
index 54eb4ea5..aecef879 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/LatencyConstraint.java
@@ -67,7 +67,7 @@ public class LatencyConstraint implements Constraint {
@Override
public int hashCode() {
- return Objects.hash(latency);
+ return latency.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java
index cb1e6b2b..ca4f3fd3 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/ObstacleConstraint.java
@@ -66,7 +66,7 @@ public class ObstacleConstraint extends BooleanConstraint {
@Override
public int hashCode() {
- return Objects.hash(obstacles);
+ return obstacles.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java
index 1acf6dfe..4839feec 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/intent/constraint/WaypointConstraint.java
@@ -91,7 +91,7 @@ public class WaypointConstraint implements Constraint {
@Override
public int hashCode() {
- return Objects.hash(waypoints);
+ return waypoints.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
index 891eb65d..cba17640 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/link/DefaultLinkDescription.java
@@ -20,6 +20,7 @@ import org.onosproject.net.AbstractDescription;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.SparseAnnotations;
+import com.google.common.base.Objects;
/**
* Default implementation of immutable link description entity.
@@ -70,4 +71,23 @@ public class DefaultLinkDescription extends AbstractDescription
.add("type", type()).toString();
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), src, dst, type);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object != null && getClass() == object.getClass()) {
+ if (!super.equals(object)) {
+ return false;
+ }
+ DefaultLinkDescription that = (DefaultLinkDescription) object;
+ return Objects.equal(this.src, that.src)
+ && Objects.equal(this.dst, that.dst)
+ && Objects.equal(this.type, that.type);
+ }
+ return false;
+ }
+
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
index e94ee452..cdcd4072 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
@@ -26,7 +26,7 @@ import java.util.List;
@Beta
public interface ResourceAdminService {
/**
- * Register resources as the children of the parent resource path.
+ * Registers resources as the children of the parent resource path.
*
* @param parent parent resource path under which the resource are registered
* @param children resources to be registered as the children of the parent
@@ -39,7 +39,7 @@ public interface ResourceAdminService {
}
/**
- * Register resources as the children of the parent resource path.
+ * Registers resources as the children of the parent resource path.
*
* @param parent parent resource path under which the resource are registered
* @param children resources to be registered as the children of the parent
@@ -50,7 +50,7 @@ public interface ResourceAdminService {
<T> boolean registerResources(ResourcePath parent, List<T> children);
/**
- * Unregister resources as the children of the parent resource path.
+ * Unregisters resources as the children of the parent resource path.
*
* @param parent parent resource path under which the resource are unregistered
* @param children resources to be unregistered as the children of the parent
@@ -63,7 +63,7 @@ public interface ResourceAdminService {
}
/**
- * Unregister resources as the children of the parent resource path.
+ * Unregisters resources as the children of the parent resource path.
*
* @param parent parent resource path under which the resource are unregistered
* @param children resources to be unregistered as the children of the parent
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
index 00000000..98abf301
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceEvent.java
@@ -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));
+ }
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceListener.java
new file mode 100644
index 00000000..3f871900
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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.EventListener;
+
+/**
+ * Entity capable of receiving resource related events.
+ */
+@Beta
+public interface ResourceListener extends EventListener<ResourceEvent> {
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
index 3aa29f6b..d87682a9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourcePath.java
@@ -19,12 +19,14 @@ import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
-import java.util.Arrays;
+import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
/**
* An object that is used to locate a resource in a network.
@@ -32,32 +34,45 @@ import static com.google.common.base.Preconditions.checkNotNull;
* of elementary resources that are not globally identifiable. A ResourcePath can be a globally
* unique resource identifier.
*
+ * Two types of resource are considered. One is discrete type and the other is continuous type.
+ * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
+ * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
+ * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
+ * A double value is associated with a continuous type value.
+ *
* Users of this class must keep the semantics of resources regarding the hierarchical structure.
* For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
* is not valid because a link is not a sub-component of a VLAN ID.
*/
@Beta
-public final class ResourcePath {
+public abstract class ResourcePath {
- private final List<Object> resources;
+ private final Discrete parent;
+ private final Object last;
- public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of());
+ public static final Discrete ROOT = new Discrete();
- public static ResourcePath child(ResourcePath parent, Object child) {
- ImmutableList<Object> components = ImmutableList.builder()
- .addAll(parent.components())
- .add(child)
- .build();
- return new ResourcePath(components);
+ /**
+ * Creates an resource path which represents a discrete-type resource from the specified components.
+ *
+ * @param components components of the path. The order represents hierarchical structure of the resource.
+ */
+ public static ResourcePath discrete(Object... components) {
+ if (components.length == 0) {
+ return ROOT;
+ } else {
+ return new Discrete(ImmutableList.copyOf(components));
+ }
}
/**
- * Creates an resource path from the specified components.
+ * Creates an resource path which represents a continuous-type resource from the specified components.
*
+ * @param value amount of the resource
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(Object... components) {
- this(Arrays.asList(components));
+ public static ResourcePath continuous(double value, Object... components) {
+ return new Continuous(ImmutableList.copyOf(components), value);
}
/**
@@ -65,15 +80,37 @@ public final class ResourcePath {
*
* @param components components of the path. The order represents hierarchical structure of the resource.
*/
- public ResourcePath(List<Object> components) {
+ ResourcePath(List<Object> components) {
checkNotNull(components);
+ checkArgument(!components.isEmpty());
+
+ LinkedList<Object> children = new LinkedList<>(components);
+ this.last = children.pollLast();
+ if (children.isEmpty()) {
+ this.parent = ROOT;
+ } else {
+ this.parent = new Discrete(children);
+ }
+ }
- this.resources = ImmutableList.copyOf(components);
+ /**
+ * Creates an resource path from the specified parent and child.
+ *
+ * @param parent the parent of this resource
+ * @param last a child of the parent
+ */
+ ResourcePath(Discrete parent, Object last) {
+ checkNotNull(parent);
+ checkNotNull(last);
+
+ this.parent = parent;
+ this.last = last;
}
// for serialization
private ResourcePath() {
- this.resources = null;
+ this.parent = null;
+ this.last = null;
}
/**
@@ -82,7 +119,15 @@ public final class ResourcePath {
* @return the components of this resource path
*/
public List<Object> components() {
- return resources;
+ LinkedList<Object> components = new LinkedList<>();
+
+ ResourcePath current = this;
+ while (current.parent().isPresent()) {
+ components.addFirst(current.last);
+ current = current.parent;
+ }
+
+ return components;
}
/**
@@ -92,21 +137,20 @@ public final class ResourcePath {
* @return the parent resource path of this instance.
* If there is no parent, empty instance will be returned.
*/
- public Optional<ResourcePath> parent() {
- if (!isRoot()) {
- return Optional.of(new ResourcePath(resources.subList(0, resources.size() - 1)));
- }
+ public Optional<Discrete> parent() {
+ return Optional.ofNullable(parent);
+ }
+
+ public ResourcePath child(Object child) {
+ checkState(this instanceof Discrete);
- return Optional.empty();
+ return new Discrete((Discrete) this, child);
}
- /**
- * Returns true if the path represents root.
- *
- * @return true if the path represents root, false otherwise.
- */
- public boolean isRoot() {
- return resources.size() == 0;
+ public ResourcePath child(Object child, double value) {
+ checkState(this instanceof Discrete);
+
+ return new Continuous((Discrete) this, child, value);
}
/**
@@ -115,14 +159,13 @@ public final class ResourcePath {
* @return the last component of this instance.
* The return value is equal to the last object of {@code components()}.
*/
- public Object lastComponent() {
- int last = resources.size() - 1;
- return resources.get(last);
+ public Object last() {
+ return last;
}
@Override
public int hashCode() {
- return resources.hashCode();
+ return Objects.hash(this.parent, this.last);
}
@Override
@@ -134,13 +177,68 @@ public final class ResourcePath {
return false;
}
final ResourcePath that = (ResourcePath) obj;
- return Objects.equals(this.resources, that.resources);
+ return Objects.equals(this.parent, that.parent)
+ && Objects.equals(this.last, that.last);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
- .add("resources", resources)
+ .add("parent", parent)
+ .add("last", last)
.toString();
}
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ * </p>
+ */
+ public static final class Discrete extends ResourcePath {
+ private Discrete() {
+ super();
+ }
+
+ private Discrete(List<Object> components) {
+ super(components);
+ }
+
+ private Discrete(Discrete parent, Object last) {
+ super(parent, last);
+ }
+ }
+
+ /**
+ * Represents a resource path which specifies a resource which can be measured
+ * as continuous value. Bandwidth of a link is an example of the resource.
+ * <p>
+ * Note: This class is exposed to the public, but intended to be used in the resource API
+ * implementation only. It is not for resource API user.
+ */
+ public static final class Continuous extends ResourcePath {
+ // Note: value is not taken into account for equality
+ private final double value;
+
+ private Continuous(List<Object> components, double value) {
+ super(components);
+ this.value = value;
+ }
+
+ public Continuous(Discrete parent, Object last, double value) {
+ super(parent, last);
+ this.value = value;
+ }
+
+ /**
+ * Returns the value of the resource amount.
+ *
+ * @return the value of the resource amount
+ */
+ public double value() {
+ return value;
+ }
+ }
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java
index ad684c8c..966de500 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceService.java
@@ -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.
*
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java
index 2cab9d4b..7c67430e 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStore.java
@@ -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.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStoreDelegate.java
new file mode 100644
index 00000000..a0b9bb25
--- /dev/null
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceStoreDelegate.java
@@ -0,0 +1,24 @@
+/*
+ * 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 org.onosproject.store.StoreDelegate;
+
+/**
+ * Resource store delegate abstraction.
+ */
+public interface ResourceStoreDelegate extends StoreDelegate<ResourceEvent> {
+}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java
index 0bfb3795..d3bd2d7b 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResource.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java
index 74f6e102..5f36d5f8 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceAllocation.java
@@ -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;
@@ -53,7 +56,7 @@ public class BandwidthResourceAllocation implements ResourceAllocation {
@Override
public int hashCode() {
- return Objects.hash(bandwidth);
+ return bandwidth.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java
index e07309cb..ff26e81e 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/BandwidthResourceRequest.java
@@ -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;
@@ -53,7 +56,7 @@ public class BandwidthResourceRequest implements ResourceRequest {
@Override
public int hashCode() {
- return Objects.hash(bandwidth);
+ return bandwidth.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java
index 379bf71e..2fa4fa6b 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceAllocations.java
@@ -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
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
index f8e143a4..b57465f2 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/DefaultLinkResourceRequest.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java
index 3733e467..06582497 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResource.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java
index 545f025f..930a6b27 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceAllocation.java
@@ -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;
@@ -53,7 +56,7 @@ public class LambdaResourceAllocation implements ResourceAllocation {
@Override
public int hashCode() {
- return Objects.hash(lambda);
+ return Objects.hashCode(lambda);
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
index d264d5e5..24d3d78d 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LambdaResourceRequest.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java
index ec06611e..b06f16bf 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResource.java
@@ -17,6 +17,9 @@ package org.onosproject.net.resource.link;
/**
* Abstraction of link resource.
+ *
+ * @deprecated in Emu Release
*/
+@Deprecated
public interface LinkResource {
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java
index 7828867c..d0211e26 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceAllocations.java
@@ -25,7 +25,10 @@ import org.onosproject.net.resource.ResourceRequest;
/**
* Representation of allocated link resources.
+ *
+ * @deprecated
*/
+@Deprecated
public interface LinkResourceAllocations extends ResourceAllocation {
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java
index 3edb386a..a3702923 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceEvent.java
@@ -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>> {
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java
index 599dd4fb..bbb02e2f 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceListener.java
@@ -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> {
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
index 37622e79..9774e8e7 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceRequest.java
@@ -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 {
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java
index e6674dbd..e8a295c2 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStore.java
@@ -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.
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java
index 6c051d6a..dbfb3b04 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResourceStoreDelegate.java
@@ -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> {
}
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java
index dc005227..46450427 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/LinkResources.java
@@ -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 {
/**
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java
index 89c87760..5138d02c 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabel.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java
index 10911539..7441bee9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceAllocation.java
@@ -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;
@@ -54,7 +57,7 @@ public class MplsLabelResourceAllocation implements ResourceAllocation {
@Override
public int hashCode() {
- return Objects.hash(mplsLabel);
+ return Objects.hashCode(mplsLabel);
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java
index 01a048b7..5b9c4a0a 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/MplsLabelResourceRequest.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java
index b10e4ba4..f374d778 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/link/package-info.java
@@ -17,5 +17,11 @@
/**
* 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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java
index e676fc87..a05dfda1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/resource/package-info.java
@@ -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;
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java
index 676f0068..1e6780fa 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/ClusterId.java
@@ -53,7 +53,7 @@ public final class ClusterId {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id;
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java
index dacb5fd8..99d700e1 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyEdge.java
@@ -20,6 +20,7 @@ import org.onosproject.net.Link;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Implementation of the topology edge backed by a link.
@@ -40,7 +41,7 @@ public class DefaultTopologyEdge implements TopologyEdge {
public DefaultTopologyEdge(TopologyVertex src, TopologyVertex dst, Link link) {
this.src = src;
this.dst = dst;
- this.link = link;
+ this.link = checkNotNull(link);
}
@Override
@@ -60,7 +61,7 @@ public class DefaultTopologyEdge implements TopologyEdge {
@Override
public int hashCode() {
- return Objects.hash(link);
+ return link.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java
index 07a09cbd..4782bc95 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/net/topology/DefaultTopologyVertex.java
@@ -42,7 +42,7 @@ public class DefaultTopologyVertex implements TopologyVertex {
@Override
public int hashCode() {
- return Objects.hash(deviceId);
+ return deviceId.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java
index 0cc7b453..4be7ede7 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/store/service/WallClockTimestamp.java
@@ -52,7 +52,7 @@ public class WallClockTimestamp implements Timestamp {
}
@Override
public int hashCode() {
- return Objects.hash(unixTimestamp);
+ return Long.hashCode(unixTimestamp);
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java
index 2b8b7fa2..c8671159 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/UiView.java
@@ -138,7 +138,7 @@ public class UiView {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id.hashCode();
}
@Override
diff --git a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
index a165be33..c75eccf9 100644
--- a/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
+++ b/framework/src/onos/core/api/src/main/java/org/onosproject/ui/topo/PropertyPanel.java
@@ -18,7 +18,7 @@ package org.onosproject.ui.topo;
import com.google.common.collect.Sets;
-import java.text.DecimalFormat;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -28,7 +28,7 @@ import java.util.Set;
*/
public class PropertyPanel {
- private static final DecimalFormat DF0 = new DecimalFormat("#,###");
+ private static final NumberFormat NF = NumberFormat.getInstance();
private String title;
private String typeId;
@@ -49,6 +49,24 @@ public class PropertyPanel {
}
/**
+ * Returns a number formatter to use for formatting integer and long
+ * property values.
+ * <p>
+ * This default implementation uses a formatter for the default
+ * locale. For example:
+ * <pre>
+ * Locale.ENGLISH : 1000 -&gt; "1,000"
+ * Locale.FRENCH : 1000 -&gt; "1 000"
+ * Locale.GERMAN : 1000 -&gt; "1.000"
+ * </pre>
+ *
+ * @return the number formatter
+ */
+ protected NumberFormat formatter() {
+ return NF;
+ }
+
+ /**
* Adds an ID field to the panel data, to be included in
* the returned JSON data to the client.
*
@@ -80,7 +98,7 @@ public class PropertyPanel {
* @return self, for chaining
*/
public PropertyPanel addProp(String key, int value) {
- properties.add(new Prop(key, DF0.format(value)));
+ properties.add(new Prop(key, formatter().format(value)));
return this;
}
@@ -92,7 +110,7 @@ public class PropertyPanel {
* @return self, for chaining
*/
public PropertyPanel addProp(String key, long value) {
- properties.add(new Prop(key, DF0.format(value)));
+ properties.add(new Prop(key, formatter().format(value)));
return this;
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationEventTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationEventTest.java
index d31cc268..34c593c4 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationEventTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationEventTest.java
@@ -33,7 +33,7 @@ public class ApplicationEventTest extends AbstractEventTest {
private Application createApp() {
return new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE,
- PERMS, Optional.of(FURL), FEATURES);
+ PERMS, Optional.of(FURL), FEATURES, APPS);
}
@Test
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationServiceAdapter.java b/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationServiceAdapter.java
index 479cc59a..96324a91 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationServiceAdapter.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/app/ApplicationServiceAdapter.java
@@ -51,6 +51,10 @@ public class ApplicationServiceAdapter implements ApplicationService {
}
@Override
+ public void registerDeactivateHook(ApplicationId appId, Runnable hook) {
+ }
+
+ @Override
public void addListener(ApplicationListener listener) {
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/app/DefaultApplicationDescriptionTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/app/DefaultApplicationDescriptionTest.java
index d40d3fea..0e93c1fe 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/app/DefaultApplicationDescriptionTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/app/DefaultApplicationDescriptionTest.java
@@ -46,12 +46,13 @@ public class DefaultApplicationDescriptionTest {
new Permission(AppPermission.class.getName(), "FLOWRULE_READ"));
public static final URI FURL = URI.create("mvn:org.foo-features/1.2a/xml/features");
public static final List<String> FEATURES = ImmutableList.of("foo", "bar");
+ public static final List<String> APPS = ImmutableList.of("fifi");
@Test
public void basics() {
ApplicationDescription app =
new DefaultApplicationDescription(APP_NAME, VER, DESC, ORIGIN,
- ROLE, PERMS, FURL, FEATURES);
+ ROLE, PERMS, FURL, FEATURES, APPS);
assertEquals("incorrect id", APP_NAME, app.name());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect description", DESC, app.description());
@@ -60,6 +61,7 @@ public class DefaultApplicationDescriptionTest {
assertEquals("incorrect permissions", PERMS, app.permissions());
assertEquals("incorrect features repo", FURL, app.featuresRepo().get());
assertEquals("incorrect features", FEATURES, app.features());
+ assertEquals("incorrect apps", APPS, app.requiredApps());
assertTrue("incorrect toString", app.toString().contains(APP_NAME));
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/core/CoreServiceAdapter.java b/framework/src/onos/core/api/src/test/java/org/onosproject/core/CoreServiceAdapter.java
index 0f6abd68..6d45e8c5 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/core/CoreServiceAdapter.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/core/CoreServiceAdapter.java
@@ -43,7 +43,12 @@ public class CoreServiceAdapter implements CoreService {
}
@Override
- public ApplicationId registerApplication(String identifier) {
+ public ApplicationId registerApplication(String name) {
+ return null;
+ }
+
+ @Override
+ public ApplicationId registerApplication(String name, Runnable preDeactivate) {
return null;
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
index cbedb79c..77b3812b 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/core/DefaultApplicationTest.java
@@ -34,7 +34,7 @@ public class DefaultApplicationTest {
@Test
public void basics() {
Application app = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE,
- PERMS, Optional.of(FURL), FEATURES);
+ PERMS, Optional.of(FURL), FEATURES, APPS);
assertEquals("incorrect id", APP_ID, app.id());
assertEquals("incorrect version", VER, app.version());
assertEquals("incorrect description", DESC, app.description());
@@ -43,19 +43,20 @@ public class DefaultApplicationTest {
assertEquals("incorrect permissions", PERMS, app.permissions());
assertEquals("incorrect features repo", FURL, app.featuresRepo().get());
assertEquals("incorrect features", FEATURES, app.features());
+ assertEquals("incorrect apps", APPS, app.requiredApps());
assertTrue("incorrect toString", app.toString().contains(APP_NAME));
}
@Test
public void testEquality() {
Application a1 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE,
- PERMS, Optional.of(FURL), FEATURES);
+ PERMS, Optional.of(FURL), FEATURES, APPS);
Application a2 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE,
- PERMS, Optional.of(FURL), FEATURES);
+ PERMS, Optional.of(FURL), FEATURES, APPS);
Application a3 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE,
- PERMS, Optional.empty(), FEATURES);
+ PERMS, Optional.empty(), FEATURES, APPS);
Application a4 = new DefaultApplication(APP_ID, VER, DESC, ORIGIN + "asd", ROLE,
- PERMS, Optional.of(FURL), FEATURES);
+ PERMS, Optional.of(FURL), FEATURES, APPS);
new EqualsTester().addEqualityGroup(a1, a2)
.addEqualityGroup(a3).addEqualityGroup(a4).testEquals();
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/PortNumberTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/PortNumberTest.java
index 6f7b2c2d..de153dc2 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/PortNumberTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/PortNumberTest.java
@@ -15,12 +15,17 @@
*/
package org.onosproject.net;
+import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
+import org.onosproject.net.PortNumber.Logical;
+import static java.util.stream.Collectors.toList;
import static org.junit.Assert.assertEquals;
import static org.onosproject.net.PortNumber.portNumber;
+import java.util.List;
+
/**
* Test of the port number.
*/
@@ -39,5 +44,37 @@ public class PortNumberTest {
assertEquals("incorrect long value", 12345, portNumber(12345).toLong());
}
+ @Test
+ public void decimalPortNumberIsReconstructableFromString() {
+ List<PortNumber> ps = ImmutableList.<PortNumber>builder()
+ .add(portNumber(0))
+ .add(portNumber(1))
+ .add(portNumber(6653))
+ .add(portNumber(PortNumber.MAX_NUMBER))
+ .build();
+ ps.forEach(p -> assertEquals(p, PortNumber.fromString(p.toString())));
+ }
+
+ @Test
+ public void logicalPortNumberIsReconstructableFromString() {
+ List<PortNumber> ps = ImmutableList.copyOf(Logical.values())
+ .stream().map(Logical::instance).collect(toList());
+
+ ps.forEach(p -> assertEquals(p, PortNumber.fromString(p.toString())));
+
+ PortNumber unknown = portNumber(-42);
+ assertEquals(unknown, PortNumber.fromString(unknown.toString()));
+ }
+
+ @Test
+ public void namedPortNumberIsReconstructableFromString() {
+ List<PortNumber> ps = ImmutableList.<PortNumber>builder()
+ .add(portNumber(0, "Zero"))
+ .add(portNumber(1, "[ONE]"))
+ .add(portNumber(6653, "OpenFlow (1.3+)"))
+ .add(portNumber(PortNumber.MAX_NUMBER, "(大)"))
+ .build();
+ ps.forEach(p -> assertEquals(p, PortNumber.fromString(p.toString())));
+ }
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/device/DefaultDeviceDescriptionTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/device/DefaultDeviceDescriptionTest.java
index 3dcdc22d..c00a6de0 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/device/DefaultDeviceDescriptionTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/device/DefaultDeviceDescriptionTest.java
@@ -41,7 +41,7 @@ public class DefaultDeviceDescriptionTest {
public void basics() {
DeviceDescription device =
new DefaultDeviceDescription(DURI, SWITCH, MFR, HW, SW, SN, CID);
- assertEquals("incorrect uri", DURI, device.deviceURI());
+ assertEquals("incorrect uri", DURI, device.deviceUri());
assertEquals("incorrect type", SWITCH, device.type());
assertEquals("incorrect manufacturer", MFR, device.manufacturer());
assertEquals("incorrect hw", HW, device.hwVersion());
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
index f54e7411..15abc2bf 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
@@ -57,7 +57,7 @@ public class XmlDriverLoaderTest {
}
@Test(expected = IOException.class)
- public void badXML() throws IOException {
+ public void badXml() throws IOException {
XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader());
loader.loadDrivers(getClass().getResourceAsStream("drivers.bad.xml"), null);
}
@@ -77,4 +77,4 @@ public class XmlDriverLoaderTest {
driver.createBehaviour(new DefaultDriverData(driver, DEVICE_ID), TestBehaviour.class);
}
-} \ No newline at end of file
+}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
index e03ed850..c510b60a 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
@@ -33,6 +33,7 @@ import org.onosproject.net.flow.TrafficTreatment;
public abstract class ConnectivityIntentTest extends IntentTest {
public static final ApplicationId APPID = new TestApplicationId("foo");
+ public static final Key KEY = Key.of(1L, APPID);
public static final IntentId IID = new IntentId(123);
public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index d42e22fa..14201472 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -192,14 +192,17 @@ public class IntentTestsMocks {
new MplsLabelResourceAllocation(MplsLabel.valueOf(10)));
}
+ @Override
public IntentId intentId() {
return null;
}
+ @Override
public Collection<Link> links() {
return null;
}
+ @Override
public Set<ResourceRequest> resources() {
return null;
}
@@ -408,7 +411,7 @@ public class IntentTestsMocks {
@Override
public int hashCode() {
- return Objects.hash(priority);
+ return priority;
}
@Override
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsIntentTest.java
index 196d6ad4..7fbdf232 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsIntentTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsIntentTest.java
@@ -112,6 +112,5 @@ public class MplsIntentTest extends AbstractIntentTest {
assertThat(intent1.selector(), equalTo(intent2.selector()));
assertThat(intent1.treatment(), equalTo(intent2.treatment()));
assertThat(intent1.priority(), is(PRIORITY));
-
}
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsPathIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsPathIntentTest.java
index 551f19eb..64528cb9 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsPathIntentTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/MplsPathIntentTest.java
@@ -47,6 +47,7 @@ public class MplsPathIntentTest extends AbstractIntentTest {
Optional<MplsLabel> label2;
TrafficSelector selector;
TrafficTreatment treatment;
+ static final Key KEY1 = Key.of(5L, APP_ID);
@Before
public void mplsPathIntentTestSetUp() {
@@ -58,6 +59,7 @@ public class MplsPathIntentTest extends AbstractIntentTest {
label2 = Optional.of(MplsLabel.mplsLabel(2));
intent1 = MplsPathIntent.builder()
.appId(APP_ID)
+ .key(KEY1)
.ingressLabel(label1)
.egressLabel(label2)
.path(defaultPath)
@@ -105,6 +107,7 @@ public class MplsPathIntentTest extends AbstractIntentTest {
assertThat(intent1.treatment(), equalTo(intent2.treatment()));
assertThat(intent1.priority(), is(PRIORITY));
assertThat(intent1.path(), is(defaultPath));
+ assertThat(intent1.key(), equalTo(KEY1));
}
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/PathIntentTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/PathIntentTest.java
index dfbc1846..9e675347 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/PathIntentTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/intent/PathIntentTest.java
@@ -62,12 +62,14 @@ public class PathIntentTest extends ConnectivityIntentTest {
assertEquals("incorrect match", MATCH, intent.selector());
assertEquals("incorrect action", NOP, intent.treatment());
assertEquals("incorrect path", PATH1, intent.path());
+ assertEquals("incorrect key", KEY, intent.key());
}
@Override
protected PathIntent createOne() {
return PathIntent.builder()
.appId(APPID)
+ .key(KEY)
.selector(MATCH)
.treatment(NOP)
.path(PATH1)
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
index a84927a0..5f448221 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourceAllocationTest.java
@@ -38,9 +38,9 @@ public class ResourceAllocationTest {
@Test
public void testEquals() {
- ResourceAllocation alloc1 = new ResourceAllocation(new ResourcePath(LK1, VLAN1), IID1);
- ResourceAllocation sameAsAlloc1 = new ResourceAllocation(new ResourcePath(LK1, VLAN1), IID1);
- ResourceAllocation alloc2 = new ResourceAllocation(new ResourcePath(LK2, VLAN1), IID1);
+ ResourceAllocation alloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
+ ResourceAllocation sameAsAlloc1 = new ResourceAllocation(ResourcePath.discrete(LK1, VLAN1), IID1);
+ ResourceAllocation alloc2 = new ResourceAllocation(ResourcePath.discrete(LK2, VLAN1), IID1);
new EqualsTester()
.addEqualityGroup(alloc1, sameAsAlloc1)
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
index 4a8886a4..35dcf1ec 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/net/newresource/ResourcePathTest.java
@@ -18,6 +18,7 @@ package org.onosproject.net.newresource;
import com.google.common.testing.EqualsTester;
import org.junit.Test;
import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.LinkKey;
@@ -25,6 +26,7 @@ import org.onosproject.net.PortNumber;
import java.util.Optional;
+import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@@ -36,37 +38,49 @@ public class ResourcePathTest {
private static final ConnectPoint CP1_1 = new ConnectPoint(D1, P1);
private static final ConnectPoint CP2_1 = new ConnectPoint(D2, P1);
private static final VlanId VLAN1 = VlanId.vlanId((short) 100);
+ private static final Bandwidth BW1 = Bandwidth.gbps(2);
+ private static final Bandwidth BW2 = Bandwidth.gbps(1);
@Test
public void testEquals() {
- ResourcePath resource1 = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath sameAsResource1 = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath resource2 = new ResourcePath(LinkKey.linkKey(CP2_1, CP1_1), VLAN1);
+ ResourcePath resource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath sameAsResource1 = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath resource2 = ResourcePath.discrete(LinkKey.linkKey(CP2_1, CP1_1), VLAN1);
+ ResourcePath resource3 = ResourcePath.continuous(BW1.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
+ ResourcePath sameAsResource3 = ResourcePath.continuous(BW2.bps(), LinkKey.linkKey(CP1_1, CP2_1), BW1);
new EqualsTester()
.addEqualityGroup(resource1, sameAsResource1)
.addEqualityGroup(resource2)
+ .addEqualityGroup(resource3, sameAsResource3) // this is intentional
.testEquals();
}
@Test
public void testCreateWithZeroComponent() {
- ResourcePath path = new ResourcePath();
+ ResourcePath path = ResourcePath.discrete();
assertThat(path, is(ResourcePath.ROOT));
}
@Test
+ public void testComponents() {
+ ResourcePath port = ResourcePath.discrete(D1, P1);
+
+ assertThat(port.components(), contains(D1, P1));
+ }
+
+ @Test
public void testThereIsParent() {
- ResourcePath path = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
- ResourcePath parent = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1), VLAN1);
+ ResourcePath parent = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
assertThat(path.parent(), is(Optional.of(parent)));
}
@Test
public void testNoParent() {
- ResourcePath path = new ResourcePath(LinkKey.linkKey(CP1_1, CP2_1));
+ ResourcePath path = ResourcePath.discrete(LinkKey.linkKey(CP1_1, CP2_1));
assertThat(path.parent(), is(Optional.of(ResourcePath.ROOT)));
}
@@ -74,9 +88,9 @@ public class ResourcePathTest {
@Test
public void testBase() {
LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
- ResourcePath path = new ResourcePath(linkKey);
+ ResourcePath path = ResourcePath.discrete(linkKey);
- LinkKey child = (LinkKey) path.lastComponent();
+ LinkKey child = (LinkKey) path.last();
assertThat(child, is(linkKey));
}
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java b/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
index 4f612de2..02462e85 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/store/service/TestEventuallyConsistentMap.java
@@ -30,7 +30,8 @@ import org.onlab.util.KryoNamespace;
import org.onosproject.cluster.NodeId;
import org.onosproject.store.Timestamp;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.*;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
/**
* Testing version of an Eventually Consistent Map.
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/ui/table/cell/DefaultCellComparatorTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/ui/table/cell/DefaultCellComparatorTest.java
index d77c1b2b..b870d483 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/ui/table/cell/DefaultCellComparatorTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/ui/table/cell/DefaultCellComparatorTest.java
@@ -115,19 +115,19 @@ public class DefaultCellComparatorTest {
}
@Test
- public void swEpisodeII() {
+ public void swEpisodeIi() {
assertTrue("r2d2 c3po",
cmp.compare(SmallStarWars.R2D2, SmallStarWars.C3PO) > 0);
}
@Test
- public void swEpisodeIII() {
+ public void swEpisodeIii() {
assertTrue("luke c3po",
cmp.compare(SmallStarWars.LUKE, SmallStarWars.C3PO) > 0);
}
@Test
- public void swEpisodeIV() {
+ public void swEpisodeIv() {
assertTrue("c3po luke",
cmp.compare(SmallStarWars.C3PO, SmallStarWars.LUKE) < 0);
}
@@ -139,7 +139,7 @@ public class DefaultCellComparatorTest {
}
@Test
- public void swEpisodeVI() {
+ public void swEpisodeVi() {
assertTrue("r2d2 luke",
cmp.compare(SmallStarWars.R2D2, SmallStarWars.LUKE) < 0);
}
diff --git a/framework/src/onos/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java b/framework/src/onos/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
index 7e6cc227..b6d32bed 100644
--- a/framework/src/onos/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
+++ b/framework/src/onos/core/api/src/test/java/org/onosproject/ui/topo/PropertyPanelTest.java
@@ -20,17 +20,38 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.onosproject.ui.topo.PropertyPanel.Prop;
+import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.Locale;
import java.util.Map;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
/**
* Unit tests for {@link PropertyPanel}.
*/
public class PropertyPanelTest {
+ // Modified property panel subclass to use ENGLISH locale formatter so
+ // we know formatted numbers will use comma for the thousand separator.
+ private static final class EnglishPropertyPanel extends PropertyPanel {
+ private static final NumberFormat ENGLISH_FORMATTER =
+ NumberFormat.getInstance(Locale.ENGLISH);
+
+ public EnglishPropertyPanel(String title, String typeId) {
+ super(title, typeId);
+ }
+
+ @Override
+ protected NumberFormat formatter() {
+ return ENGLISH_FORMATTER;
+ }
+ }
+
private static final String TITLE_ORIG = "Original Title";
private static final String TYPE_ORIG = "Original type ID";
private static final String TITLE_NEW = "New Title";
@@ -42,6 +63,7 @@ public class PropertyPanelTest {
private static final String KEY_C = "C";
private static final String SEP = "-";
private static final String KEY_Z = "Z";
+
private static final String VALUE_A = "Hay";
private static final String VALUE_B = "Bee";
private static final String VALUE_C = "Sea";
@@ -76,7 +98,7 @@ public class PropertyPanelTest {
@Test
public void basic() {
- pp = new PropertyPanel(TITLE_ORIG, TYPE_ORIG);
+ pp = new EnglishPropertyPanel(TITLE_ORIG, TYPE_ORIG);
assertEquals("wrong title", TITLE_ORIG, pp.title());
assertEquals("wrong type", TYPE_ORIG, pp.typeId());
assertNull("id?", pp.id());
@@ -134,8 +156,8 @@ public class PropertyPanelTest {
public void props() {
basic();
pp.addProp(KEY_A, VALUE_A)
- .addProp(KEY_B, VALUE_B)
- .addProp(KEY_C, VALUE_C);
+ .addProp(KEY_B, VALUE_B)
+ .addProp(KEY_C, VALUE_C);
assertEquals("bad props", 3, pp.properties().size());
validateProps(KEY_A, KEY_B, KEY_C);
}
@@ -144,7 +166,7 @@ public class PropertyPanelTest {
public void separator() {
props();
pp.addSeparator()
- .addProp(KEY_Z, VALUE_Z);
+ .addProp(KEY_Z, VALUE_Z);
assertEquals("bad props", 5, pp.properties().size());
validateProps(KEY_A, KEY_B, KEY_C, SEP, KEY_Z);
@@ -170,8 +192,8 @@ public class PropertyPanelTest {
public void intValues() {
basic();
pp.addProp(KEY_A, 200)
- .addProp(KEY_B, 2000)
- .addProp(KEY_C, 1234567);
+ .addProp(KEY_B, 2000)
+ .addProp(KEY_C, 1234567);
validateProp(KEY_A, "200");
validateProp(KEY_B, "2,000");
@@ -182,9 +204,9 @@ public class PropertyPanelTest {
public void longValues() {
basic();
pp.addProp(KEY_A, 200L)
- .addProp(KEY_B, 2000L)
- .addProp(KEY_C, 1234567L)
- .addProp(KEY_Z, Long.MAX_VALUE);
+ .addProp(KEY_B, 2000L)
+ .addProp(KEY_C, 1234567L)
+ .addProp(KEY_Z, Long.MAX_VALUE);
validateProp(KEY_A, "200");
validateProp(KEY_B, "2,000");
@@ -196,7 +218,7 @@ public class PropertyPanelTest {
public void objectValue() {
basic();
pp.addProp(KEY_A, new FooClass("a"))
- .addProp(KEY_B, new FooClass("bxyyzy"), "[xz]");
+ .addProp(KEY_B, new FooClass("bxyyzy"), "[xz]");
validateProp(KEY_A, ">a<");
validateProp(KEY_B, ">byyy<");
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/ApplicationCodec.java b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/ApplicationCodec.java
index b2cab094..a09c0bdb 100644
--- a/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/ApplicationCodec.java
+++ b/framework/src/onos/core/common/src/main/java/org/onosproject/codec/impl/ApplicationCodec.java
@@ -32,18 +32,18 @@ public final class ApplicationCodec extends JsonCodec<Application> {
public ObjectNode encode(Application app, CodecContext context) {
checkNotNull(app, "Application cannot be null");
ApplicationService service = context.getService(ApplicationService.class);
- ObjectNode result = context.mapper().createObjectNode()
+ return context.mapper().createObjectNode()
.put("name", app.id().name())
.put("id", app.id().id())
.put("version", app.version().toString())
.put("description", app.description())
.put("origin", app.origin())
- .put("permissions", app.permissions().toString())
+ .put("permissions", app.permissions().toString()) // FIXME: change to an array
.put("featuresRepo", app.featuresRepo().isPresent() ?
app.featuresRepo().get().toString() : "")
- .put("features", app.features().toString())
+ .put("features", app.features().toString()) // FIXME: change to an array
+ .put("requiredApps", app.requiredApps().toString()) // FIXME: change to an array
.put("state", service.getState(app.id()).toString());
- return result;
}
}
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
index 3c5c540d..84cde424 100644
--- a/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
+++ b/framework/src/onos/core/common/src/main/java/org/onosproject/common/DefaultTopology.java
@@ -26,10 +26,10 @@ import org.onlab.graph.DijkstraGraphSearch;
import org.onlab.graph.DisjointPathPair;
import org.onlab.graph.GraphPathSearch;
import org.onlab.graph.GraphPathSearch.Result;
-import org.onlab.graph.SRLGGraphSearch;
+import org.onlab.graph.SrlgGraphSearch;
import org.onlab.graph.SuurballeGraphSearch;
import org.onlab.graph.TarjanGraphSearch;
-import org.onlab.graph.TarjanGraphSearch.SCCResult;
+import org.onlab.graph.TarjanGraphSearch.SccResult;
import org.onosproject.net.AbstractModel;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultDisjointPath;
@@ -83,7 +83,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
private final TopologyGraph graph;
private final LinkWeight weight;
- private final Supplier<SCCResult<TopologyVertex, TopologyEdge>> clusterResults;
+ private final Supplier<SccResult<TopologyVertex, TopologyEdge>> clusterResults;
private final Supplier<ImmutableMap<ClusterId, TopologyCluster>> clusters;
private final Supplier<ImmutableSet<ConnectPoint>> infrastructurePoints;
private final Supplier<ImmutableSetMultimap<ClusterId, ConnectPoint>> broadcastSets;
@@ -385,7 +385,7 @@ public class DefaultTopology extends AbstractModel implements Topology {
return ImmutableSet.of();
}
- SRLGGraphSearch<TopologyVertex, TopologyEdge> srlg = new SRLGGraphSearch<>(riskProfile);
+ SrlgGraphSearch<TopologyVertex, TopologyEdge> srlg = new SrlgGraphSearch<>(riskProfile);
GraphPathSearch.Result<TopologyVertex, TopologyEdge> result =
srlg.search(graph, srcV, dstV, weight, ALL_PATHS);
ImmutableSet.Builder<DisjointPath> builder = ImmutableSet.builder();
@@ -455,14 +455,14 @@ public class DefaultTopology extends AbstractModel implements Topology {
// Searches for SCC clusters in the network topology graph using Tarjan
// algorithm.
- private SCCResult<TopologyVertex, TopologyEdge> searchForClusters() {
+ private SccResult<TopologyVertex, TopologyEdge> searchForClusters() {
return TARJAN.search(graph, new NoIndirectLinksWeight());
}
// Builds the topology clusters and returns the id-cluster bindings.
private ImmutableMap<ClusterId, TopologyCluster> buildTopologyClusters() {
ImmutableMap.Builder<ClusterId, TopologyCluster> clusterBuilder = ImmutableMap.builder();
- SCCResult<TopologyVertex, TopologyEdge> results = clusterResults.get();
+ SccResult<TopologyVertex, TopologyEdge> results = clusterResults.get();
// Extract both vertexes and edges from the results; the lists form
// pairs along the same index.
diff --git a/framework/src/onos/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java b/framework/src/onos/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
index 54f0fb89..37cdbdfc 100644
--- a/framework/src/onos/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
+++ b/framework/src/onos/core/common/src/main/java/org/onosproject/common/app/ApplicationArchive.java
@@ -17,6 +17,7 @@ package org.onosproject.common.app;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import org.apache.commons.configuration.ConfigurationException;
@@ -33,7 +34,6 @@ import org.onosproject.core.Version;
import org.onosproject.security.AppPermission;
import org.onosproject.security.Permission;
import org.onosproject.store.AbstractStore;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,7 +46,6 @@ import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.NoSuchFileException;
-import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
@@ -79,6 +78,7 @@ public class ApplicationArchive
private static final String VERSION = "[@version]";
private static final String FEATURES_REPO = "[@featuresRepo]";
private static final String FEATURES = "[@features]";
+ private static final String APPS = "[@apps]";
private static final String DESCRIPTION = "description";
private static final String ROLE = "security.role";
@@ -291,8 +291,13 @@ public class ApplicationArchive
URI featuresRepo = featRepo != null ? URI.create(featRepo) : null;
List<String> features = ImmutableList.copyOf(cfg.getString(FEATURES).split(","));
+ String apps = cfg.getString(APPS, "");
+ List<String> requiredApps = apps.isEmpty() ?
+ ImmutableList.of() : ImmutableList.copyOf(apps.split(","));
+
return new DefaultApplicationDescription(name, version, desc, origin, role,
- perms, featuresRepo, features);
+ perms, featuresRepo, features,
+ requiredApps);
}
// Expands the specified ZIP stream into app-specific directory.
@@ -390,7 +395,7 @@ public class ApplicationArchive
// Returns the set of Permissions specified in the app.xml file
private ImmutableSet<Permission> getPermissions(XMLConfiguration cfg) {
- List<Permission> permissionList = new ArrayList();
+ List<Permission> permissionList = Lists.newArrayList();
for (Object o : cfg.getList(APP_PERMISSIONS)) {
String name = (String) o;
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java
index 7cbce4d1..2f933966 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/codec/impl/IntentCodecTest.java
@@ -217,7 +217,7 @@ public class IntentCodecTest extends AbstractIntentTest {
* @throws IOException if processing the resource fails
*/
private Intent getIntent(String resourceName, JsonCodec intentCodec) throws IOException {
- InputStream jsonStream = FlowRuleCodecTest.class
+ InputStream jsonStream = IntentCodecTest.class
.getResourceAsStream(resourceName);
JsonNode json = context.mapper().readTree(jsonStream);
assertThat(json, notNullValue());
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleApplicationStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleApplicationStore.java
index ea9a773e..d9f5285c 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleApplicationStore.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleApplicationStore.java
@@ -75,7 +75,8 @@ public class SimpleApplicationStore extends ApplicationArchive implements Applic
new DefaultApplication(appId, appDesc.version(),
appDesc.description(), appDesc.origin(),
appDesc.role(), appDesc.permissions(),
- appDesc.featuresRepo(), appDesc.features());
+ appDesc.featuresRepo(), appDesc.features(),
+ appDesc.requiredApps());
apps.put(appId, app);
states.put(appId, isActive(name) ? INSTALLED : ACTIVE);
// load app permissions
@@ -117,7 +118,8 @@ public class SimpleApplicationStore extends ApplicationArchive implements Applic
DefaultApplication app =
new DefaultApplication(appId, appDesc.version(), appDesc.description(),
appDesc.origin(), appDesc.role(), appDesc.permissions(),
- appDesc.featuresRepo(), appDesc.features());
+ appDesc.featuresRepo(), appDesc.features(),
+ appDesc.requiredApps());
apps.put(appId, app);
states.put(appId, INSTALLED);
delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
index 72fc1b05..11a12040 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleDeviceStore.java
@@ -532,7 +532,7 @@ public class SimpleDeviceStore
checkArgument(!providerDescs.isEmpty(), "No Device descriptions supplied");
- ProviderId primary = pickPrimaryPID(providerDescs);
+ ProviderId primary = pickPrimaryPid(providerDescs);
DeviceDescriptions desc = providerDescs.get(primary);
@@ -575,7 +575,7 @@ public class SimpleDeviceStore
private Port composePort(Device device, PortNumber number,
Map<ProviderId, DeviceDescriptions> descsMap) {
- ProviderId primary = pickPrimaryPID(descsMap);
+ ProviderId primary = pickPrimaryPid(descsMap);
DeviceDescriptions primDescs = descsMap.get(primary);
// if no primary, assume not enabled
// TODO: revisit this default port enabled/disabled behavior
@@ -613,7 +613,7 @@ public class SimpleDeviceStore
/**
* @return primary ProviderID, or randomly chosen one if none exists
*/
- private ProviderId pickPrimaryPID(Map<ProviderId, DeviceDescriptions> descsMap) {
+ private ProviderId pickPrimaryPid(Map<ProviderId, DeviceDescriptions> descsMap) {
ProviderId fallBackPrimary = null;
for (Entry<ProviderId, DeviceDescriptions> e : descsMap.entrySet()) {
if (!e.getKey().isAncillary()) {
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
index 72ec98ca..a56daab1 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
@@ -88,10 +88,14 @@ public class SimpleHostStore
boolean replaceIps) {
//TODO We need a way to detect conflicting changes and abort update.
StoredHost host = hosts.get(hostId);
+ HostEvent hostEvent;
if (host == null) {
- return createHost(providerId, hostId, hostDescription);
+ hostEvent = createHost(providerId, hostId, hostDescription);
+ } else {
+ hostEvent = updateHost(providerId, host, hostDescription, replaceIps);
}
- return updateHost(providerId, host, hostDescription, replaceIps);
+ notifyDelegate(hostEvent);
+ return hostEvent;
}
// creates a new host and sends HOST_ADDED
@@ -153,7 +157,9 @@ public class SimpleHostStore
Host host = hosts.remove(hostId);
if (host != null) {
locations.remove((host.location()), host);
- return new HostEvent(HOST_REMOVED, host);
+ HostEvent hostEvent = new HostEvent(HOST_REMOVED, host);
+ notifyDelegate(hostEvent);
+ return hostEvent;
}
return null;
}
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
index 58b446cf..22df937b 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
@@ -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 {
diff --git a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SystemClockTimestamp.java b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SystemClockTimestamp.java
index 2ee41945..500a09c7 100644
--- a/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SystemClockTimestamp.java
+++ b/framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SystemClockTimestamp.java
@@ -51,7 +51,7 @@ public class SystemClockTimestamp implements Timestamp {
}
@Override
public int hashCode() {
- return Objects.hash(nanoTimestamp);
+ return Long.hashCode(nanoTimestamp);
}
@Override
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
index 161659f9..d09eb1f1 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.app.impl;
+import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -30,20 +31,21 @@ import org.onosproject.app.ApplicationService;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStore;
import org.onosproject.app.ApplicationStoreDelegate;
-import org.onosproject.event.AbstractListenerManager;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.security.Permission;
import org.onosproject.security.SecurityUtil;
import org.slf4j.Logger;
import java.io.InputStream;
+import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.app.ApplicationEvent.Type.*;
-import static org.onosproject.security.AppPermission.Type.*;
import static org.onosproject.security.AppGuard.checkPermission;
+import static org.onosproject.security.AppPermission.Type.APP_READ;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -69,6 +71,9 @@ public class ApplicationManager
private boolean initializing;
+ // Application supplied hooks for pre-activation processing.
+ private final Map<String, Runnable> deactivateHooks = Maps.newConcurrentMap();
+
@Activate
public void activate() {
eventDispatcher.addSink(ApplicationEvent.class, listenerRegistry);
@@ -122,6 +127,14 @@ public class ApplicationManager
}
@Override
+ public void registerDeactivateHook(ApplicationId appId, Runnable hook) {
+ checkPermission(APP_READ);
+ checkNotNull(appId, APP_ID_NULL);
+ checkNotNull(hook, "Hook cannot be null");
+ deactivateHooks.put(appId.name(), hook);
+ }
+
+ @Override
public Application install(InputStream appDescStream) {
checkNotNull(appDescStream, "Application archive stream cannot be null");
Application app = store.create(appDescStream);
@@ -199,6 +212,7 @@ public class ApplicationManager
// The following methods are fully synchronized to guard against remote vs.
// locally induced feature service interactions.
+ // Installs all feature repositories required by the specified app.
private synchronized boolean installAppArtifacts(Application app) throws Exception {
if (app.featuresRepo().isPresent() &&
featuresService.getRepository(app.featuresRepo().get()) == null) {
@@ -208,6 +222,7 @@ public class ApplicationManager
return false;
}
+ // Uninstalls all the feature repositories required by the specified app.
private synchronized boolean uninstallAppArtifacts(Application app) throws Exception {
if (app.featuresRepo().isPresent() &&
featuresService.getRepository(app.featuresRepo().get()) != null) {
@@ -217,6 +232,7 @@ public class ApplicationManager
return false;
}
+ // Installs all features that define the specified app.
private synchronized boolean installAppFeatures(Application app) throws Exception {
boolean changed = false;
for (String name : app.features()) {
@@ -233,8 +249,10 @@ public class ApplicationManager
return changed;
}
+ // Uninstalls all features that define the specified app.
private synchronized boolean uninstallAppFeatures(Application app) throws Exception {
boolean changed = false;
+ invokeHook(deactivateHooks.get(app.id().name()), app.id());
for (String name : app.features()) {
Feature feature = featuresService.getFeature(name);
if (feature != null && featuresService.isInstalled(feature)) {
@@ -247,4 +265,16 @@ public class ApplicationManager
return changed;
}
+ // Invokes the specified function, if not null.
+ private void invokeHook(Runnable hook, ApplicationId appId) {
+ if (hook != null) {
+ try {
+ hook.run();
+ } catch (Exception e) {
+ log.warn("Deactivate hook for application {} encountered an error",
+ appId.name(), e);
+ }
+ }
+ }
+
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
index f4d560a4..ec99c18b 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
@@ -24,6 +24,7 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.SharedExecutors;
+import org.onosproject.app.ApplicationService;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
@@ -48,7 +49,7 @@ import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.security.AppGuard.checkPermission;
-import static org.onosproject.security.AppPermission.Type.*;
+import static org.onosproject.security.AppPermission.Type.APP_READ;
@@ -71,6 +72,9 @@ public class CoreManager implements CoreService {
protected IdBlockStore idBlockStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ApplicationService appService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -111,28 +115,24 @@ public class CoreManager implements CoreService {
@Override
public Version version() {
checkPermission(APP_READ);
-
return version;
}
@Override
public Set<ApplicationId> getAppIds() {
checkPermission(APP_READ);
-
return applicationIdStore.getAppIds();
}
@Override
public ApplicationId getAppId(Short id) {
checkPermission(APP_READ);
-
return applicationIdStore.getAppId(id);
}
@Override
public ApplicationId getAppId(String name) {
checkPermission(APP_READ);
-
return applicationIdStore.getAppId(name);
}
@@ -144,6 +144,13 @@ public class CoreManager implements CoreService {
}
@Override
+ public ApplicationId registerApplication(String name, Runnable preDeactivate) {
+ ApplicationId id = registerApplication(name);
+ appService.registerDeactivateHook(id, preDeactivate);
+ return id;
+ }
+
+ @Override
public IdGenerator getIdGenerator(String topic) {
IdBlockAllocator allocator = new StoreBasedIdBlockAllocator(topic, idBlockStore);
return new BlockAllocatorBasedIdGenerator(allocator);
@@ -185,10 +192,10 @@ public class CoreManager implements CoreService {
*/
private static Integer getIntegerProperty(Dictionary<?, ?> properties,
String propertyName) {
- Integer value = null;
+ Integer value;
try {
String s = (String) properties.get(propertyName);
- value = isNullOrEmpty(s) ? value : Integer.parseInt(s.trim());
+ value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
} catch (NumberFormatException | ClassCastException e) {
value = null;
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
index fa90eb65..a498b3f4 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/BasicDeviceOperator.java
@@ -51,7 +51,7 @@ public final class BasicDeviceOperator implements ConfigOperator {
* @return DeviceDescription based on both sources
*/
public static DeviceDescription combine(BasicDeviceConfig bdc, DeviceDescription descr) {
- if (bdc == null) {
+ if (bdc == null || descr == null) {
return descr;
}
@@ -61,7 +61,7 @@ public final class BasicDeviceOperator implements ConfigOperator {
}
SparseAnnotations sa = combine(bdc, descr.annotations());
- return new DefaultDeviceDescription(descr.deviceURI(), type, descr.manufacturer(),
+ return new DefaultDeviceDescription(descr.deviceUri(), type, descr.manufacturer(),
descr.hwVersion(), descr.swVersion(),
descr.serialNumber(), descr.chassisId(), sa);
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
index 9215d3a0..03281bef 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/DeviceManager.java
@@ -740,7 +740,7 @@ public class DeviceManager
Device dev = getDevice(did);
DeviceDescription desc = (dev == null) ? null : BasicDeviceOperator.descriptionOf(dev);
desc = BasicDeviceOperator.combine(cfg, desc);
- if (getProvider(did) != null) {
+ if (desc != null && getProvider(did) != null) {
de = store.createOrUpdateDevice(getProvider(did).id(), did, desc);
}
}
@@ -754,7 +754,7 @@ public class DeviceManager
OpticalPortConfig opc = networkConfigService.getConfig(cpt, OpticalPortConfig.class);
PortDescription desc = OpticalPortOperator.descriptionOf(dpt);
desc = OpticalPortOperator.combine(opc, desc);
- if (getProvider(did) != null) {
+ if (desc != null && getProvider(did) != null) {
de = store.updatePortStatus(getProvider(did).id(), did, desc);
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
index 1473f33f..f48b8366 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
@@ -192,10 +192,7 @@ public class HostManager
@Override
public void removeHost(HostId hostId) {
checkNotNull(hostId, HOST_ID_NULL);
- HostEvent event = store.removeHost(hostId);
- if (event != null) {
- post(event);
- }
+ store.removeHost(hostId);
}
// Personalized host provider service issued to the supplied provider.
@@ -211,11 +208,8 @@ public class HostManager
checkNotNull(hostId, HOST_ID_NULL);
checkValidity();
hostDescription = validateHost(hostDescription, hostId);
- HostEvent event = store.createOrUpdateHost(provider().id(), hostId,
+ store.createOrUpdateHost(provider().id(), hostId,
hostDescription, replaceIps);
- if (event != null) {
- post(event);
- }
}
// returns a HostDescription made from the union of the BasicHostConfig
@@ -231,20 +225,14 @@ public class HostManager
public void hostVanished(HostId hostId) {
checkNotNull(hostId, HOST_ID_NULL);
checkValidity();
- HostEvent event = store.removeHost(hostId);
- if (event != null) {
- post(event);
- }
+ store.removeHost(hostId);
}
@Override
public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
checkNotNull(hostId, HOST_ID_NULL);
checkValidity();
- HostEvent event = store.removeIp(hostId, ipAddress);
- if (event != null) {
- post(event);
- }
+ store.removeIp(hostId, ipAddress);
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
index 5ebc812e..ebf681a2 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/ObjectiveTracker.java
@@ -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);
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
index acc5a5d5..718c7bbf 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
@@ -121,7 +121,7 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
}
List<ResourcePath> resources = labels.entrySet().stream()
- .map(x -> new ResourcePath(linkKey(x.getKey().src(), x.getKey().src()), x.getValue()))
+ .map(x -> ResourcePath.discrete(linkKey(x.getKey().src(), x.getKey().src()), x.getValue()))
.collect(Collectors.toList());
List<org.onosproject.net.newresource.ResourceAllocation> allocations =
resourceService.allocate(intent.id(), resources);
@@ -145,9 +145,9 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
}
private Optional<MplsLabel> findMplsLabel(LinkKey link) {
- return resourceService.getAvailableResources(new ResourcePath(link)).stream()
- .filter(x -> x.lastComponent() instanceof MplsLabel)
- .map(x -> (MplsLabel) x.lastComponent())
+ return resourceService.getAvailableResources(ResourcePath.discrete(link)).stream()
+ .filter(x -> x.last() instanceof MplsLabel)
+ .map(x -> (MplsLabel) x.last())
.findFirst();
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
index fce8498c..ee04aab5 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
@@ -160,8 +160,8 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
log.debug("Compiling optical circuit intent between {} and {}", src, dst);
// Reserve OduClt ports
- ResourcePath srcPortPath = new ResourcePath(src.deviceId(), src.port());
- ResourcePath dstPortPath = new ResourcePath(dst.deviceId(), dst.port());
+ ResourcePath srcPortPath = ResourcePath.discrete(src.deviceId(), src.port());
+ ResourcePath dstPortPath = ResourcePath.discrete(dst.deviceId(), dst.port());
List<ResourceAllocation> allocation = resourceService.allocate(intent.id(), srcPortPath, dstPortPath);
if (allocation.isEmpty()) {
throw new IntentCompilationException("Unable to reserve ports for intent " + intent);
@@ -312,7 +312,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
if (ochCP != null) {
OchPort ochPort = (OchPort) deviceService.getPort(ochCP.deviceId(), ochCP.port());
Optional<IntentId> intentId =
- resourceService.getResourceAllocation(new ResourcePath(ochCP.deviceId(), ochCP.port()))
+ resourceService.getResourceAllocation(ResourcePath.discrete(ochCP.deviceId(), ochCP.port()))
.map(ResourceAllocation::consumer)
.filter(x -> x instanceof IntentId)
.map(x -> (IntentId) x);
@@ -331,7 +331,7 @@ public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircu
}
Optional<IntentId> intentId =
- resourceService.getResourceAllocation(new ResourcePath(oduPort.deviceId(), port.number()))
+ resourceService.getResourceAllocation(ResourcePath.discrete(oduPort.deviceId(), port.number()))
.map(ResourceAllocation::consumer)
.filter(x -> x instanceof IntentId)
.map(x -> (IntentId) x);
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index d6725b7c..a4ed551a 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -107,8 +107,8 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
log.debug("Compiling optical connectivity intent between {} and {}", src, dst);
// Reserve OCh ports
- ResourcePath srcPortPath = new ResourcePath(src.deviceId(), src.port());
- ResourcePath dstPortPath = new ResourcePath(dst.deviceId(), dst.port());
+ ResourcePath srcPortPath = ResourcePath.discrete(src.deviceId(), src.port());
+ ResourcePath dstPortPath = ResourcePath.discrete(dst.deviceId(), dst.port());
List<org.onosproject.net.newresource.ResourceAllocation> allocation =
resourceService.allocate(intent.id(), srcPortPath, dstPortPath);
if (allocation.isEmpty()) {
@@ -182,8 +182,8 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
IndexedLambda minLambda = findFirstLambda(lambdas);
List<ResourcePath> lambdaResources = path.links().stream()
- .map(x -> new ResourcePath(linkKey(x.src(), x.dst())))
- .map(x -> ResourcePath.child(x, minLambda))
+ .map(x -> ResourcePath.discrete(linkKey(x.src(), x.dst())))
+ .map(x -> x.child(minLambda))
.collect(Collectors.toList());
List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), lambdaResources);
@@ -196,10 +196,10 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
private Set<IndexedLambda> findCommonLambdasOverLinks(List<Link> links) {
return links.stream()
- .map(x -> new ResourcePath(linkKey(x.src(), x.dst())))
+ .map(x -> ResourcePath.discrete(linkKey(x.src(), x.dst())))
.map(resourceService::getAvailableResources)
- .map(x -> Iterables.filter(x, r -> r.lastComponent() instanceof IndexedLambda))
- .map(x -> Iterables.transform(x, r -> (IndexedLambda) r.lastComponent()))
+ .map(x -> Iterables.filter(x, r -> r.last() instanceof IndexedLambda))
+ .map(x -> Iterables.transform(x, r -> (IndexedLambda) r.last()))
.map(x -> (Set<IndexedLambda>) ImmutableSet.copyOf(x))
.reduce(Sets::intersection)
.orElse(Collections.emptySet());
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
index e6d92253..066dd33e 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceDeviceListener.java
@@ -75,12 +75,12 @@ final class ResourceDeviceListener implements DeviceListener {
}
private void registerPortResource(Device device, Port port) {
- ResourcePath parent = new ResourcePath(device.id());
+ ResourcePath parent = ResourcePath.discrete(device.id());
executor.submit(() -> adminService.registerResources(parent, port.number()));
}
private void unregisterPortResource(Device device, Port port) {
- ResourcePath parent = new ResourcePath(device.id());
+ ResourcePath parent = ResourcePath.discrete(device.id());
executor.submit(() -> adminService.unregisterResources(parent, port.number()));
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java
index f04c78b9..68fd6612 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceLinkListener.java
@@ -87,7 +87,7 @@ final class ResourceLinkListener implements LinkListener {
LinkKey linkKey = LinkKey.linkKey(link);
adminService.registerResources(ResourcePath.ROOT, linkKey);
- ResourcePath linkPath = new ResourcePath(linkKey);
+ ResourcePath linkPath = ResourcePath.discrete(linkKey);
// register VLAN IDs against the link
if (isEnabled(link, this::isVlanEnabled)) {
adminService.registerResources(linkPath, ENTIRE_VLAN_IDS);
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
index 10fe75ea..1c6930bb 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
@@ -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,20 +50,32 @@ 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.removeSink(ResourceEvent.class);
+ }
+
@Override
public List<ResourceAllocation> allocate(ResourceConsumer consumer,
List<ResourcePath> resources) {
checkNotNull(consumer);
checkNotNull(resources);
- // TODO: implement support of resource hierarchy
- // allocation for a particular resource implies allocations for all of the sub-resources need to be done
-
boolean success = store.allocate(resources, consumer);
if (!success) {
return ImmutableList.of();
@@ -151,7 +169,7 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
checkNotNull(children);
checkArgument(!children.isEmpty());
- List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
+ List<ResourcePath> resources = Lists.transform(children, parent::child);
return store.register(resources);
}
@@ -161,7 +179,14 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
checkNotNull(children);
checkArgument(!children.isEmpty());
- List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
+ List<ResourcePath> resources = Lists.transform(children, parent::child);
return store.unregister(resources);
}
+
+ private class InternalStoreDelegate implements ResourceStoreDelegate {
+ @Override
+ public void notify(ResourceEvent event) {
+ post(event);
+ }
+ }
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
index 4067d017..143f8c2b 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceRegistrar.java
@@ -36,7 +36,7 @@ import static org.onlab.util.Tools.groupedThreads;
/**
* A class registering resources when they are detected.
*/
-@Component(immediate = true, enabled = false)
+@Component(immediate = true)
@Beta
public final class ResourceRegistrar {
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
index 8e87a07d..793030f2 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
@@ -312,9 +312,13 @@ public class PacketManager
public void processPacket(PacketContext context) {
// TODO filter packets sent to processors based on registrations
for (ProcessorEntry entry : processors) {
- long start = System.nanoTime();
- entry.processor().process(context);
- entry.addNanos(System.nanoTime() - start);
+ try {
+ long start = System.nanoTime();
+ entry.processor().process(context);
+ entry.addNanos(System.nanoTime() - start);
+ } catch (Exception e) {
+ log.warn("Packet processor {} threw an exception", entry.processor(), e);
+ }
}
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
index 25a2640d..5ecf2806 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
@@ -53,6 +53,7 @@ import org.slf4j.Logger;
import java.nio.ByteBuffer;
import java.util.Set;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -199,11 +200,49 @@ public class ProxyArpManager implements ProxyArpService {
return;
}
+ // If the packets has a vlanId look if there are some other
+ // interfaces in the configuration on the same vlan and broadcast
+ // the packet out just of through those interfaces.
+ VlanId vlanId = context.vlan();
+
+ Set<Interface> filteredVlanInterfaces =
+ filterVlanInterfacesNoIp(interfaceService.getInterfacesByVlan(vlanId));
+
+ if (vlanId != null
+ && !vlanId.equals(VlanId.NONE)
+ && confContainsVlans(vlanId, context.inPort())) {
+ vlanFlood(context.packet(), filteredVlanInterfaces, context.inPort);
+ return;
+ }
+
// The request couldn't be resolved.
// Flood the request on all ports except the incoming port.
flood(context.packet(), context.inPort());
}
+ private Set<Interface> filterVlanInterfacesNoIp(Set<Interface> vlanInterfaces) {
+ return vlanInterfaces
+ .stream()
+ .filter(intf -> intf.ipAddresses().isEmpty())
+ .collect(Collectors.toSet());
+ }
+
+ /**
+ * States if the interface configuration contains more than one interface configured
+ * on a specific vlan, including the interface passed as argument.
+ *
+ * @param vlanId the vlanid to look for in the interface configuration
+ * @param connectPoint the connect point to exclude from the search
+ * @return true if interfaces are found. False otherwise
+ */
+ private boolean confContainsVlans(VlanId vlanId, ConnectPoint connectPoint) {
+ Set<Interface> vlanInterfaces = interfaceService.getInterfacesByVlan(vlanId);
+ return interfaceService.getInterfacesByVlan(vlanId)
+ .stream()
+ .anyMatch(intf -> intf.connectPoint().equals(connectPoint) && intf.ipAddresses().isEmpty())
+ && vlanInterfaces.size() > 1;
+ }
+
/**
* Builds and sends a reply message given a request context and the resolved
* MAC address to answer with.
@@ -259,14 +298,29 @@ public class ProxyArpManager implements ProxyArpService {
/**
* Returns whether the given port has any IP addresses configured or not.
*
- * @param port the port to check
+ * @param connectPoint the port to check
* @return true if the port has at least one IP address configured,
- * otherwise false
+ * false otherwise
+ */
+ private boolean hasIpAddress(ConnectPoint connectPoint) {
+ return interfaceService.getInterfacesByPort(connectPoint)
+ .stream()
+ .flatMap(intf -> intf.ipAddresses().stream())
+ .findAny()
+ .isPresent();
+ }
+
+ /**
+ * Returns whether the given port has any VLAN configured or not.
+ *
+ * @param connectPoint the port to check
+ * @return true if the port has at least one VLAN configured,
+ * false otherwise
*/
- private boolean hasIpAddress(ConnectPoint port) {
- return interfaceService.getInterfacesByPort(port)
+ private boolean hasVlan(ConnectPoint connectPoint) {
+ return interfaceService.getInterfacesByPort(connectPoint)
.stream()
- .map(intf -> intf.ipAddresses())
+ .filter(intf -> !intf.vlan().equals(VlanId.NONE))
.findAny()
.isPresent();
}
@@ -322,6 +376,30 @@ public class ProxyArpManager implements ProxyArpService {
}
/**
+ * Flood the arp request at all edges on a specifc VLAN.
+ *
+ * @param request the arp request
+ * @param dsts the destination interfaces
+ * @param inPort the connect point the arp request was received on
+ */
+ private void vlanFlood(Ethernet request, Set<Interface> dsts, ConnectPoint inPort) {
+ TrafficTreatment.Builder builder = null;
+ ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+ for (Interface intf : dsts) {
+ ConnectPoint cPoint = intf.connectPoint();
+ if (cPoint.equals(inPort)) {
+ continue;
+ }
+
+ builder = DefaultTrafficTreatment.builder();
+ builder.setOutput(cPoint.port());
+ packetService.emit(new DefaultOutboundPacket(cPoint.deviceId(),
+ builder.build(), buf));
+ }
+ }
+
+ /**
* Flood the arp request at all edges in the network.
*
* @param request the arp request
@@ -332,7 +410,9 @@ public class ProxyArpManager implements ProxyArpService {
ByteBuffer buf = ByteBuffer.wrap(request.serialize());
for (ConnectPoint connectPoint : edgeService.getEdgePoints()) {
- if (hasIpAddress(connectPoint) || connectPoint.equals(inPort)) {
+ if (hasIpAddress(connectPoint)
+ || hasVlan(connectPoint)
+ || connectPoint.equals(inPort)) {
continue;
}
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
index 6515ef31..f18c56dc 100644
--- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
+++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
@@ -255,7 +255,7 @@ public class FlowStatisticManager implements FlowStatisticService {
Instruction.Type instType) {
checkPermission(STATISTIC_READ);
- List<TypedFlowEntryWithLoad> retTFEL = new ArrayList<>();
+ List<TypedFlowEntryWithLoad> retTfel = new ArrayList<>();
Set<FlowEntry> currentStats;
Set<FlowEntry> previousStats;
@@ -264,11 +264,11 @@ public class FlowStatisticManager implements FlowStatisticService {
synchronized (flowStatisticStore) {
currentStats = flowStatisticStore.getCurrentFlowStatistic(cp);
if (currentStats == null) {
- return retTFEL;
+ return retTfel;
}
previousStats = flowStatisticStore.getPreviousFlowStatistic(cp);
if (previousStats == null) {
- return retTFEL;
+ return retTfel;
}
// copy to local flow entry set
typedStatistics = new TypedStatistics(currentStats, previousStats);
@@ -291,7 +291,7 @@ public class FlowStatisticManager implements FlowStatisticService {
List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
if (fel.size() > 0) {
- retTFEL.addAll(fel);
+ retTfel.addAll(fel);
}
}
@@ -302,7 +302,7 @@ public class FlowStatisticManager implements FlowStatisticService {
List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
if (fel.size() > 0) {
- retTFEL.addAll(fel);
+ retTfel.addAll(fel);
}
}
@@ -313,7 +313,7 @@ public class FlowStatisticManager implements FlowStatisticService {
List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
isAllInstType, instType, TypedFlowEntryWithLoad.midPollInterval());
if (fel.size() > 0) {
- retTFEL.addAll(fel);
+ retTfel.addAll(fel);
}
}
@@ -324,7 +324,7 @@ public class FlowStatisticManager implements FlowStatisticService {
List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
isAllInstType, instType, TypedFlowEntryWithLoad.longPollInterval());
if (fel.size() > 0) {
- retTFEL.addAll(fel);
+ retTfel.addAll(fel);
}
}
@@ -335,11 +335,11 @@ public class FlowStatisticManager implements FlowStatisticService {
List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
isAllInstType, instType, TypedFlowEntryWithLoad.avgPollInterval());
if (fel.size() > 0) {
- retTFEL.addAll(fel);
+ retTfel.addAll(fel);
}
}
- return retTFEL;
+ return retTfel;
}
private List<TypedFlowEntryWithLoad> typedFlowEntryLoadByInstInternal(ConnectPoint cp,
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/app/impl/ApplicationManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/app/impl/ApplicationManagerTest.java
index 1ce31ac3..a99fd216 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/app/impl/ApplicationManagerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/app/impl/ApplicationManagerTest.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.app.impl;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
@@ -24,11 +25,11 @@ import org.onosproject.app.ApplicationListener;
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStoreAdapter;
import org.onosproject.common.app.ApplicationArchive;
+import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.DefaultApplication;
import org.onosproject.core.DefaultApplicationId;
-import org.onosproject.common.event.impl.TestEventDispatcher;
import java.io.InputStream;
import java.net.URI;
@@ -36,7 +37,7 @@ import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
import static org.onosproject.app.ApplicationEvent.Type.*;
import static org.onosproject.app.ApplicationState.ACTIVE;
import static org.onosproject.app.ApplicationState.INSTALLED;
@@ -53,6 +54,8 @@ public class ApplicationManagerTest {
private ApplicationManager mgr = new ApplicationManager();
private ApplicationListener listener = new TestListener();
+ private boolean deactivated = false;
+
@Before
public void setUp() {
injectEventDispatcher(mgr, new TestEventDispatcher());
@@ -88,6 +91,11 @@ public class ApplicationManagerTest {
assertEquals("incorrect app count", 1, mgr.getApplications().size());
assertEquals("incorrect app", app, mgr.getApplication(APP_ID));
assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
+ mgr.registerDeactivateHook(app.id(), this::deactivateHook);
+ }
+
+ private void deactivateHook() {
+ deactivated = true;
}
@Test
@@ -102,6 +110,7 @@ public class ApplicationManagerTest {
install();
mgr.activate(APP_ID);
assertEquals("incorrect app state", ACTIVE, mgr.getState(APP_ID));
+ assertFalse("preDeactivate hook wrongly called", deactivated);
}
@Test
@@ -109,6 +118,7 @@ public class ApplicationManagerTest {
activate();
mgr.deactivate(APP_ID);
assertEquals("incorrect app state", INSTALLED, mgr.getState(APP_ID));
+ assertTrue("preDeactivate hook not called", deactivated);
}
@@ -129,7 +139,7 @@ public class ApplicationManagerTest {
@Override
public Application create(InputStream appDescStream) {
app = new DefaultApplication(APP_ID, VER, DESC, ORIGIN, ROLE, PERMS,
- Optional.of(FURL), FEATURES);
+ Optional.of(FURL), FEATURES, ImmutableList.of());
state = INSTALLED;
delegate.notify(new ApplicationEvent(APP_INSTALLED, app));
return app;
@@ -168,6 +178,11 @@ public class ApplicationManagerTest {
state = INSTALLED;
delegate.notify(new ApplicationEvent(APP_DEACTIVATED, app));
}
+
+ @Override
+ public ApplicationId getId(String name) {
+ return new DefaultApplicationId(0, name);
+ }
}
private class TestFeaturesService extends FeaturesServiceAdapter {
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java
index 92c6c931..c5a6cabd 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java
@@ -20,6 +20,7 @@ import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.junit.TestTools;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
@@ -129,13 +130,15 @@ public class HostManagerTest {
}
private void validateEvents(Enum... types) {
- int i = 0;
- assertEquals("wrong events received", types.length, listener.events.size());
- for (Event event : listener.events) {
- assertEquals("incorrect event type", types[i], event.type());
- i++;
- }
- listener.events.clear();
+ TestTools.assertAfter(100, () -> {
+ int i = 0;
+ assertEquals("wrong events received", types.length, listener.events.size());
+ for (Event event : listener.events) {
+ assertEquals("incorrect event type", types[i], event.type());
+ i++;
+ }
+ listener.events.clear();
+ });
}
@Test
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
index 58fa1292..eb7f2ccd 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/ObjectiveTrackerTest.java
@@ -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,
+ ResourcePath.discrete(linkKey(link("a", 1, "b", 1))));
+ resourceListener.event(event);
assertThat(
delegate.latch.await(WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS),
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
index 06b2c81e..f5d3d0f3 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
@@ -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;
@@ -89,7 +90,7 @@ class MockResourceService implements ResourceService {
@Override
public Collection<ResourcePath> getAvailableResources(ResourcePath parent) {
- ResourcePath resource = ResourcePath.child(parent, MplsLabel.mplsLabel(10));
+ ResourcePath resource = parent.child(MplsLabel.mplsLabel(10));
return ImmutableList.of(resource);
}
@@ -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) {}
}
diff --git a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
index 3e806a73..70fdb406 100644
--- a/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
+++ b/framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.net.proxyarp.impl;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +47,7 @@ import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.edgeservice.impl.EdgeManager;
+import org.onosproject.net.edge.EdgePortService;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flow.instructions.Instruction;
@@ -67,6 +66,7 @@ import org.onosproject.net.proxyarp.ProxyArpStoreDelegate;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -88,47 +88,65 @@ import static org.junit.Assert.assertTrue;
*/
public class ProxyArpManagerTest {
- private static final int NUM_DEVICES = 6;
+ private static final int NUM_DEVICES = 10;
private static final int NUM_PORTS_PER_DEVICE = 3;
- private static final int NUM_ADDRESS_PORTS = NUM_DEVICES / 2;
- private static final int NUM_FLOOD_PORTS = 3;
+ private static final int LAST_CONF_DEVICE_INTF_VLAN_IP = 3;
+ private static final int LAST_CONF_DEVICE_INTF_VLAN = 6;
private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
- private static final Ip6Address IP3 = Ip6Address.valueOf("1000::1");
- private static final Ip6Address IP4 = Ip6Address.valueOf("1000::2");
+ private static final Ip6Address IP3 = Ip6Address.valueOf("1000:ffff::1");
+ private static final Ip6Address IP4 = Ip6Address.valueOf("1000:ffff::2");
private static final ProviderId PID = new ProviderId("of", "foo");
private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
private static final VlanId VLAN2 = VlanId.vlanId((short) 2);
- private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01");
- private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
- private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03");
- private static final MacAddress MAC4 = MacAddress.valueOf("00:00:44:00:00:04");
+ private static final VlanId VLAN10 = VlanId.vlanId((short) 10);
+
+ private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
+ private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
+ private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
+ private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
+ private static final MacAddress MAC10 = MacAddress.valueOf("00:00:00:00:00:0A");
+
private static final MacAddress SOLICITED_MAC3 = MacAddress.valueOf("33:33:FF:00:00:01");
+
private static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
private static final HostId HID2 = HostId.hostId(MAC2, VLAN1);
private static final HostId HID3 = HostId.hostId(MAC3, VLAN1);
private static final HostId HID4 = HostId.hostId(MAC4, VLAN1);
+ private static final HostId HID10 = HostId.hostId(MAC10, VLAN10);
+
private static final HostId SOLICITED_HID3 = HostId.hostId(SOLICITED_MAC3, VLAN1);
private static final DeviceId DID1 = getDeviceId(1);
private static final DeviceId DID2 = getDeviceId(2);
+
private static final PortNumber P1 = PortNumber.portNumber(1);
+
private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L);
- private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
- //Return values used for various functions of the TestPacketService inner class.
- private boolean isEdgePointReturn;
- private List<ConnectPoint> getEdgePointsNoArg;
+ private final byte[] zeroMacAddress = MacAddress.ZERO.toBytes();
+
+ // The first three devices in the topology have interfaces configured
+ // with VLANs and IPs
+ private final List<ConnectPoint> configIpCPoints = new ArrayList<>();
+ // Other three devices in the topology (from 4 to 6) have interfaces
+ // configured only with VLANs
+ private final List<ConnectPoint> configVlanCPoints = new ArrayList<>();
+
+ // Remaining devices in the network (id > 6) don't have any interface
+ // configured.
+ private final List<ConnectPoint> noConfigCPoints = new ArrayList<>();
private ProxyArpManager proxyArp;
private TestPacketService packetService;
private DeviceService deviceService;
+ private EdgePortService edgePortService;
private LinkService linkService;
private HostService hostService;
private InterfaceService interfaceService;
@@ -140,20 +158,27 @@ public class ProxyArpManagerTest {
proxyArp.packetService = packetService;
proxyArp.store = new TestProxyArpStoreAdapter();
- proxyArp.edgeService = new TestEdgePortService();
-
- // Create a host service mock here. Must be replayed by tests once the
- // expectations have been set up
+ // Create a host service mock here.
hostService = createMock(HostService.class);
proxyArp.hostService = hostService;
+ // Create an edge port service.
+ edgePortService = createMock(EdgePortService.class);
+ proxyArp.edgeService = edgePortService;
+
+ // Create interface service
interfaceService = createMock(InterfaceService.class);
proxyArp.interfaceService = interfaceService;
+ // Create the topology
createTopology();
proxyArp.deviceService = deviceService;
proxyArp.linkService = linkService;
+ setupNoConfigCPoints();
+ setupconfigIpCPoints();
+ setupconfigVlanCPoints();
+
proxyArp.activate();
}
@@ -176,7 +201,8 @@ public class ProxyArpManagerTest {
createDevices(NUM_DEVICES, NUM_PORTS_PER_DEVICE);
createLinks(NUM_DEVICES);
- addAddressBindings();
+ addIntfConfig();
+ popluateEdgePortService();
}
/**
@@ -237,13 +263,22 @@ public class ProxyArpManagerTest {
replay(linkService);
}
- private void addAddressBindings() {
+ /**
+ * On the first three devices two config interfaces are binded on port 1.
+ * The first one with VLAN1, the second one with VLAN equals to none.
+ * Both interfaces have an IP.
+ * On devices 4, 5 and 6 it's binded a config interface on port 1.
+ * The interface is configured with VLAN 1 and no IP.
+ */
+ private void addIntfConfig() {
Set<Interface> interfaces = Sets.newHashSet();
- for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) {
+ Set<Interface> vlanOneSet = new HashSet<>();
+
+ for (int i = 1; i <= LAST_CONF_DEVICE_INTF_VLAN_IP; i++) {
ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
- // Interface address for IPv4
+ // Interface addresses for IPv4
Ip4Prefix prefix1 = Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24");
Ip4Address addr1 = Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1");
Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24");
@@ -251,39 +286,131 @@ public class ProxyArpManagerTest {
InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1);
InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2);
- // Interface address for IPv6
+ // Interface addresses for IPv6
Ip6Prefix prefix3 = Ip6Prefix.valueOf((2 * i - 1) + "000::0/64");
Ip6Address addr3 = Ip6Address.valueOf((2 * i - 1) + "000::1");
Ip6Prefix prefix4 = Ip6Prefix.valueOf((2 * i) + "000::0/64");
- Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::1");
+ Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::2");
InterfaceIpAddress ia3 = new InterfaceIpAddress(addr3, prefix3);
InterfaceIpAddress ia4 = new InterfaceIpAddress(addr4, prefix4);
+ // Setting up interfaces
Interface intf1 = new Interface(cp, Sets.newHashSet(ia1, ia3),
MacAddress.valueOf(2 * i - 1),
VlanId.vlanId((short) 1));
Interface intf2 = new Interface(cp, Sets.newHashSet(ia2, ia4),
MacAddress.valueOf(2 * i),
VlanId.NONE);
+
interfaces.add(intf1);
interfaces.add(intf2);
+ vlanOneSet.add(intf1);
+
expect(interfaceService.getInterfacesByPort(cp))
.andReturn(Sets.newHashSet(intf1, intf2)).anyTimes();
}
+ for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) {
+ ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
+ Interface intf1 = new Interface(cp, null,
+ MacAddress.NONE,
+ VlanId.vlanId((short) 1));
+
+ interfaces.add(intf1);
+ vlanOneSet.add(intf1);
+ expect(interfaceService.getInterfacesByPort(cp))
+ .andReturn(Sets.newHashSet(intf1)).anyTimes();
+ }
+ expect(interfaceService.getInterfacesByVlan(VLAN1))
+ .andReturn(vlanOneSet).anyTimes();
+ expect(interfaceService.getInterfacesByVlan(VLAN10))
+ .andReturn(Collections.emptySet()).anyTimes();
expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
- for (int i = 1; i <= NUM_FLOOD_PORTS; i++) {
- ConnectPoint cp = new ConnectPoint(getDeviceId(i + NUM_ADDRESS_PORTS),
+ for (int i = LAST_CONF_DEVICE_INTF_VLAN + 1; i <= NUM_DEVICES; i++) {
+ ConnectPoint cp = new ConnectPoint(getDeviceId(i),
P1);
-
expect(interfaceService.getInterfacesByPort(cp))
.andReturn(Collections.emptySet()).anyTimes();
}
}
/**
+ * Populates edge ports in the EdgePortService to return all port 1
+ * as edge ports.
+ */
+ private void popluateEdgePortService() {
+ Set<ConnectPoint> edgeConnectPoints = new HashSet<>();
+
+ for (int i = 1; i <= NUM_DEVICES; i++) {
+ for (int j = 1; j <= NUM_PORTS_PER_DEVICE; j++) {
+ ConnectPoint edgeConnectPoint = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(1));
+ ConnectPoint noEdgeConnectPointOne = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(2));
+ ConnectPoint noEdgeConnectPointTwo = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(3));
+
+ edgeConnectPoints.add(edgeConnectPoint);
+
+ expect(edgePortService.isEdgePoint(edgeConnectPoint))
+ .andReturn(true).anyTimes();
+ expect(edgePortService.isEdgePoint(noEdgeConnectPointOne))
+ .andReturn(false).anyTimes();
+ expect(edgePortService.isEdgePoint(noEdgeConnectPointTwo))
+ .andReturn(false).anyTimes();
+ }
+ }
+ expect(edgePortService.getEdgePoints())
+ .andReturn(edgeConnectPoints).anyTimes();
+
+ replay(edgePortService);
+ }
+
+ /**
+ * Creates a list of connect points used to verify floodling on ports
+ * with no interfaces configured (all ports without interface config).
+ */
+ private void setupNoConfigCPoints() {
+ for (int i = NUM_DEVICES / 2 + 2; i <= NUM_DEVICES; i++) {
+ ConnectPoint connectPoint = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(1));
+ noConfigCPoints.add(connectPoint);
+ }
+ }
+
+ /**
+ * Creates a list of connect points used to verify floodling on ports
+ * with interfaces configured (both VLAN and IP).
+ */
+ private void setupconfigIpCPoints() {
+ for (int i = 1; i <= 3; i++) {
+ ConnectPoint connectPoint = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(1));
+ configIpCPoints.add(connectPoint);
+ }
+ }
+
+ /**
+ * Creates a list of connect points used to verify floodling on ports
+ * with interfaces configured (both VLAN and IP).
+ */
+ private void setupconfigVlanCPoints() {
+ for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) {
+ ConnectPoint connectPoint = new ConnectPoint(
+ getDeviceId(i),
+ PortNumber.portNumber(1));
+ configVlanCPoints.add(connectPoint);
+ }
+ }
+
+ /**
* Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the
* case where the IP address is not known.
* Verifies the method returns false.
@@ -318,33 +445,34 @@ public class ProxyArpManagerTest {
/**
* Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
* destination host is known.
- * Verifies the correct ARP reply is sent out the correct port.
+ * Two host using the same VLAN are registered on the host service on devices 5 and 6.
+ * Host on port 6 asks for the MAC of the device on port 5.
+ * Since the destination mac address is known, the request is not flooded to anywhere
+ * and ONOS directly builds an ARP reply, sended back to the requester on device 6.
+ * It's verified that a proper ARP reply is received on port 1 of device 6.
*/
@Test
public void testReplyKnown() {
- //Set the return value of isEdgePoint from the edgemanager.
- isEdgePointReturn = true;
-
- Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(4),
+ Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES),
Collections.singleton(IP1));
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
+ Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(NUM_DEVICES - 1),
Collections.singleton(IP2));
- expect(hostService.getHostsByIp(IP1))
+ expect(hostService.getHostsByIp(IP2))
.andReturn(Collections.singleton(replyer));
- expect(hostService.getHost(HID2)).andReturn(requestor);
+ expect(hostService.getHost(HID1)).andReturn(requestor);
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
- proxyArp.reply(arpRequest, getLocation(5));
+ proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
assertEquals(1, packetService.packets.size());
- Ethernet arpReply = buildArp(ARP.OP_REPLY, MAC1, MAC2, IP1, IP2);
- verifyPacketOut(arpReply, getLocation(5), packetService.packets.get(0));
+ Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1);
+ verifyPacketOut(arpReply, getLocation(NUM_DEVICES), packetService.packets.get(0));
}
/**
@@ -354,9 +482,6 @@ public class ProxyArpManagerTest {
*/
@Test
public void testReplyKnownIpv6() {
- //Set the return value of isEdgePoint from the edgemanager.
- isEdgePointReturn = true;
-
Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(4),
Collections.singleton(IP3));
@@ -370,49 +495,46 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC4, SOLICITED_MAC3,
- IP4, IP3);
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC4, SOLICITED_MAC3,
+ IP4, IP3);
proxyArp.reply(ndpRequest, getLocation(5));
assertEquals(1, packetService.packets.size());
- Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT,
- MAC3, MAC4, IP3, IP4);
+ Ethernet ndpReply = buildNdp(ICMP6.NEIGHBOR_ADVERTISEMENT,
+ MAC3, MAC4, IP3, IP4);
verifyPacketOut(ndpReply, getLocation(5), packetService.packets.get(0));
}
/**
* Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
* destination host is not known.
+ * Only a requestor is present (on device 6, port 1). The device has a VLAN configured
+ * which is not configured anywhere in the system.
+ * Since the destination is not known, and since the ARP request can't be sent out of
+ * interfaces configured, the ARP request is flooded out of ports 4 and 5.
* Verifies the ARP request is flooded out the correct edge ports.
*/
@Test
public void testReplyUnknown() {
- isEdgePointReturn = true;
-
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
- Collections.singleton(IP2));
+ Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES),
+ Collections.singleton(IP1));
- expect(hostService.getHostsByIp(IP1))
+ expect(hostService.getHostsByIp(IP2))
.andReturn(Collections.emptySet());
- expect(interfaceService.getInterfacesByIp(IP2))
+ expect(interfaceService.getInterfacesByIp(IP1))
.andReturn(Collections.emptySet());
- expect(hostService.getHost(HID2)).andReturn(requestor);
+ expect(hostService.getHost(HID10)).andReturn(requestor);
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
-
- //Setup the set of edge ports to be used in the reply method
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2);
- proxyArp.reply(arpRequest, getLocation(6));
+ proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
- verifyFlood(arpRequest);
+ verifyFlood(arpRequest, noConfigCPoints);
}
/**
@@ -422,9 +544,7 @@ public class ProxyArpManagerTest {
*/
@Test
public void testReplyUnknownIpv6() {
- isEdgePointReturn = true;
-
- Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5),
+ Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES),
Collections.singleton(IP4));
expect(hostService.getHostsByIp(IP3))
@@ -436,53 +556,111 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC4, SOLICITED_MAC3,
- IP4, IP3);
-
- //Setup the set of edge ports to be used in the reply method
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC4, SOLICITED_MAC3,
+ IP4, IP3);
- proxyArp.reply(ndpRequest, getLocation(6));
+ proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES));
- verifyFlood(ndpRequest);
+ verifyFlood(ndpRequest, noConfigCPoints);
}
/**
* Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
* destination host is known for that IP address, but is not on the same
* VLAN as the source host.
+ * An host is connected on device 6, port 1 where no interfaces are defined. It sends
+ * ARP requests from VLAN10, not configured anywhere in the network. Another host with
+ * the IP address requested lives on device 5, port 1 in the network. Anyway, since the
+ * host uses another VLAN it's not found and the ARP packet is flooded out of port
+ * 4 and 5.
+ *
* Verifies the ARP request is flooded out the correct edge ports.
*/
@Test
public void testReplyDifferentVlan() {
-
- Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN2, getLocation(4),
+ Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES),
Collections.singleton(IP1));
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
+ Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN2, getLocation(NUM_DEVICES - 1),
Collections.singleton(IP2));
- expect(hostService.getHostsByIp(IP1))
+ expect(hostService.getHostsByIp(IP2))
.andReturn(Collections.singleton(replyer));
- expect(interfaceService.getInterfacesByIp(IP2))
+ expect(interfaceService.getInterfacesByIp(IP1))
.andReturn(Collections.emptySet());
- expect(hostService.getHost(HID2)).andReturn(requestor);
+ expect(hostService.getHost(HID10)).andReturn(requestor);
+
+ replay(hostService);
+ replay(interfaceService);
+
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2);
+
+ proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
+
+ verifyFlood(arpRequest, noConfigCPoints);
+ }
+
+ /**
+ * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
+ * a vlan packet comes in from a port without interfaces configured. The destination
+ * host is unknown for that IP address and there are some interfaces configured on
+ * the same vlan.
+ * It's expected to see the ARP request going out through ports with no interfaces
+ * configured, devices 4 and 5, port 1.
+ *
+ * Verifies the ARP request is flooded out the correct edge ports.
+ */
+ @Test
+ public void testConfiguredVlan() {
+ Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES),
+ Collections.singleton(IP1));
+
+ expect(hostService.getHostsByIp(IP2))
+ .andReturn(Collections.emptySet());
+ expect(interfaceService.getInterfacesByIp(IP1))
+ .andReturn(Collections.emptySet());
+ expect(hostService.getHost(HID1)).andReturn(requestor);
+
+ replay(hostService);
+ replay(interfaceService);
+
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
+
+ proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
+
+ verifyFlood(arpRequest, noConfigCPoints);
+ }
+
+ /**
+ * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
+ * a vlan packet comes in from a port without interfaces configured. The destination
+ * host is not known for that IP address and there are some interfaces configured on
+ * the same vlan.
+ * It's expected to see the ARP request going out through ports with no interfaces
+ * configured, devices 4 and 5, port 1.
+ *
+ * Verifies the ARP request is flooded out the correct edge ports.
+ */
+ @Test
+ public void testConfiguredVlanOnInterfaces() {
+ Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(6),
+ Collections.singleton(IP1));
+
+ expect(hostService.getHostsByIp(IP2))
+ .andReturn(Collections.emptySet());
+ expect(interfaceService.getInterfacesByIp(IP1))
+ .andReturn(Collections.emptySet());
+ expect(hostService.getHost(HID1)).andReturn(requestor);
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
- //Setup for flood test
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
proxyArp.reply(arpRequest, getLocation(6));
- verifyFlood(arpRequest);
+ verifyFlood(arpRequest, configVlanCPoints);
}
/**
@@ -493,13 +671,12 @@ public class ProxyArpManagerTest {
*/
@Test
public void testReplyDifferentVlanIpv6() {
-
- Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(4),
- Collections.singleton(IP3));
-
- Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5),
+ Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES),
Collections.singleton(IP4));
+ Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(NUM_DEVICES - 1),
+ Collections.singleton(IP3));
+
expect(hostService.getHostsByIp(IP3))
.andReturn(Collections.singleton(replyer));
expect(interfaceService.getInterfacesByIp(IP4))
@@ -509,17 +686,13 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC4, SOLICITED_MAC3,
- IP4, IP3);
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC4, SOLICITED_MAC3,
+ IP4, IP3);
- //Setup for flood test
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
- proxyArp.reply(ndpRequest, getLocation(6));
+ proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES));
- verifyFlood(ndpRequest);
+ verifyFlood(ndpRequest, noConfigCPoints);
}
/**
@@ -533,29 +706,29 @@ public class ProxyArpManagerTest {
MacAddress firstMac = MacAddress.valueOf(1L);
MacAddress secondMac = MacAddress.valueOf(2L);
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+ Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1,
Collections.singleton(theirIp));
- expect(hostService.getHost(HID2)).andReturn(requestor);
+ expect(hostService.getHost(HID1)).andReturn(requestor);
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourFirstIp);
- isEdgePointReturn = true;
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourFirstIp);
+
proxyArp.reply(arpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- Ethernet arpReply = buildArp(ARP.OP_REPLY, firstMac, MAC2, ourFirstIp, theirIp);
+ Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, firstMac, MAC1, ourFirstIp, theirIp);
verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
// Test a request for the second address on that port
packetService.packets.clear();
- arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourSecondIp);
+ arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourSecondIp);
proxyArp.reply(arpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- arpReply = buildArp(ARP.OP_REPLY, secondMac, MAC2, ourSecondIp, theirIp);
+ arpReply = buildArp(ARP.OP_REPLY, VLAN1, secondMac, MAC1, ourSecondIp, theirIp);
verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
}
@@ -566,7 +739,7 @@ public class ProxyArpManagerTest {
public void testReplyToRequestForUsIpv6() {
Ip6Address theirIp = Ip6Address.valueOf("1000::ffff");
Ip6Address ourFirstIp = Ip6Address.valueOf("1000::1");
- Ip6Address ourSecondIp = Ip6Address.valueOf("2000::1");
+ Ip6Address ourSecondIp = Ip6Address.valueOf("2000::2");
MacAddress firstMac = MacAddress.valueOf(1L);
MacAddress secondMac = MacAddress.valueOf(2L);
@@ -579,37 +752,37 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC2,
- MacAddress.valueOf("33:33:ff:00:00:01"),
- theirIp,
- ourFirstIp);
- isEdgePointReturn = true;
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC2,
+ MacAddress.valueOf("33:33:ff:00:00:01"),
+ theirIp,
+ ourFirstIp);
+
proxyArp.reply(ndpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- Ethernet ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT,
- firstMac,
- MAC2,
- ourFirstIp,
- theirIp);
+ Ethernet ndpReply = buildNdp(ICMP6.NEIGHBOR_ADVERTISEMENT,
+ firstMac,
+ MAC2,
+ ourFirstIp,
+ theirIp);
verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0));
// Test a request for the second address on that port
packetService.packets.clear();
- ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC2,
- MacAddress.valueOf("33:33:ff:00:00:01"),
- theirIp,
- ourSecondIp);
+ ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC2,
+ MacAddress.valueOf("33:33:ff:00:00:01"),
+ theirIp,
+ ourSecondIp);
proxyArp.reply(ndpRequest, LOC1);
assertEquals(1, packetService.packets.size());
- ndpReply = buildNDP(ICMP6.NEIGHBOR_ADVERTISEMENT,
- secondMac,
- MAC2,
- ourSecondIp,
- theirIp);
+ ndpReply = buildNdp(ICMP6.NEIGHBOR_ADVERTISEMENT,
+ secondMac,
+ MAC2,
+ ourSecondIp,
+ theirIp);
verifyPacketOut(ndpReply, LOC1, packetService.packets.get(0));
}
@@ -624,14 +797,14 @@ public class ProxyArpManagerTest {
Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254");
// Request for a valid external IP address but coming in the wrong port
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp,
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp,
Ip4Address.valueOf("10.0.3.1"));
proxyArp.reply(arpRequest, LOC1);
assertEquals(0, packetService.packets.size());
// Request for a valid internal IP address but coming in an external port
packetService.packets.clear();
- arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp, IP1);
+ arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, IP1);
proxyArp.reply(arpRequest, LOC1);
assertEquals(0, packetService.packets.size());
}
@@ -646,21 +819,21 @@ public class ProxyArpManagerTest {
Ip6Address theirIp = Ip6Address.valueOf("1000::ffff");
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC1,
- MacAddress.valueOf("33:33:ff:00:00:01"),
- theirIp,
- Ip6Address.valueOf("3000::1"));
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC1,
+ MacAddress.valueOf("33:33:ff:00:00:01"),
+ theirIp,
+ Ip6Address.valueOf("3000::1"));
proxyArp.reply(ndpRequest, LOC1);
assertEquals(0, packetService.packets.size());
// Request for a valid internal IP address but coming in an external port
packetService.packets.clear();
- ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC1,
- MacAddress.valueOf("33:33:ff:00:00:01"),
- theirIp,
- IP3);
+ ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC1,
+ MacAddress.valueOf("33:33:ff:00:00:01"),
+ theirIp,
+ IP3);
proxyArp.reply(ndpRequest, LOC1);
assertEquals(0, packetService.packets.size());
}
@@ -685,9 +858,8 @@ public class ProxyArpManagerTest {
// This is a request from something inside our network (like a BGP
// daemon) to an external host.
- Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp);
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, ourMac, null, ourIp, theirIp);
//Ensure the packet is allowed through (it is not to an internal port)
- isEdgePointReturn = true;
proxyArp.reply(arpRequest, getLocation(5));
assertEquals(1, packetService.packets.size());
@@ -722,14 +894,11 @@ public class ProxyArpManagerTest {
// This is a request from something inside our network (like a BGP
// daemon) to an external host.
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- ourMac,
- MacAddress.valueOf("33:33:ff:00:00:01"),
- ourIp,
- theirIp);
-
- //Ensure the packet is allowed through (it is not to an internal port)
- isEdgePointReturn = true;
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ ourMac,
+ MacAddress.valueOf("33:33:ff:00:00:01"),
+ ourIp,
+ theirIp);
proxyArp.reply(ndpRequest, getLocation(5));
assertEquals(1, packetService.packets.size());
@@ -758,7 +927,7 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1);
+ Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1);
proxyArp.forward(arpRequest, LOC2);
@@ -785,9 +954,9 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC4, SOLICITED_MAC3,
- IP4, IP3);
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC4, SOLICITED_MAC3,
+ IP4, IP3);
proxyArp.forward(ndpRequest, LOC2);
@@ -804,22 +973,15 @@ public class ProxyArpManagerTest {
*/
@Test
public void testForwardFlood() {
- expect(hostService.getHost(HID1)).andReturn(null);
+ expect(hostService.getHost(HID2)).andReturn(null);
replay(hostService);
replay(interfaceService);
- Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1);
-
- //populate the list of edges when so that when forward hits flood in the manager it contains the values
- //that should continue on
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+ Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC1, MAC2, IP1, IP2);
- proxyArp.forward(arpRequest, getLocation(6));
+ proxyArp.forward(arpRequest, getLocation(NUM_DEVICES));
- verifyFlood(arpRequest);
+ verifyFlood(arpRequest, noConfigCPoints);
}
/**
@@ -833,20 +995,13 @@ public class ProxyArpManagerTest {
replay(hostService);
replay(interfaceService);
- Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
- MAC4, SOLICITED_MAC3,
- IP4, IP3);
+ Ethernet ndpRequest = buildNdp(ICMP6.NEIGHBOR_SOLICITATION,
+ MAC4, SOLICITED_MAC3,
+ IP4, IP3);
- //populate the list of edges when so that when forward hits flood in the manager it contains the values
- //that should continue on
- getEdgePointsNoArg = Lists.newLinkedList();
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
- getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+ proxyArp.forward(ndpRequest, getLocation(NUM_DEVICES));
- proxyArp.forward(ndpRequest, getLocation(6));
-
- verifyFlood(ndpRequest);
+ verifyFlood(ndpRequest, noConfigCPoints);
}
/**
@@ -854,21 +1009,20 @@ public class ProxyArpManagerTest {
* except for the input port.
*
* @param packet the packet that was expected to be flooded
+ * @param connectPoints the connectPoints where the outpacket should be
+ * observed
*/
- private void verifyFlood(Ethernet packet) {
+ private void verifyFlood(Ethernet packet, List<ConnectPoint> connectPoints) {
+
// There should be 1 less than NUM_FLOOD_PORTS; the inPort should be excluded.
- assertEquals(NUM_FLOOD_PORTS - 1, packetService.packets.size());
+ assertEquals(connectPoints.size() - 1, packetService.packets.size());
Collections.sort(packetService.packets,
(o1, o2) -> o1.sendThrough().uri().compareTo(o2.sendThrough().uri()));
-
- for (int i = 0; i < NUM_FLOOD_PORTS - 1; i++) {
- ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1),
- PortNumber.portNumber(1));
-
+ for (int i = 0; i < connectPoints.size() - 1; i++) {
OutboundPacket outboundPacket = packetService.packets.get(i);
- verifyPacketOut(packet, cp, outboundPacket);
+ verifyPacketOut(packet, connectPoints.get(i), outboundPacket);
}
}
@@ -913,8 +1067,8 @@ public class ProxyArpManagerTest {
* @param dstIp destination IP address
* @return the ARP packet
*/
- private Ethernet buildArp(short opcode, MacAddress srcMac, MacAddress dstMac,
- Ip4Address srcIp, Ip4Address dstIp) {
+ private Ethernet buildArp(short opcode, VlanId vlanId, MacAddress srcMac,
+ MacAddress dstMac, Ip4Address srcIp, Ip4Address dstIp) {
Ethernet eth = new Ethernet();
if (dstMac == null) {
@@ -925,7 +1079,7 @@ public class ProxyArpManagerTest {
eth.setSourceMACAddress(srcMac);
eth.setEtherType(Ethernet.TYPE_ARP);
- eth.setVlanID(VLAN1.toShort());
+ eth.setVlanID(vlanId.toShort());
ARP arp = new ARP();
arp.setOpCode(opcode);
@@ -937,7 +1091,7 @@ public class ProxyArpManagerTest {
arp.setSenderHardwareAddress(srcMac.toBytes());
if (dstMac == null) {
- arp.setTargetHardwareAddress(ZERO_MAC_ADDRESS);
+ arp.setTargetHardwareAddress(zeroMacAddress);
} else {
arp.setTargetHardwareAddress(dstMac.toBytes());
}
@@ -959,7 +1113,7 @@ public class ProxyArpManagerTest {
* @param dstIp destination IP address
* @return the NDP packet
*/
- private Ethernet buildNDP(byte type, MacAddress srcMac, MacAddress dstMac,
+ private Ethernet buildNdp(byte type, MacAddress srcMac, MacAddress dstMac,
Ip6Address srcIp, Ip6Address dstIp) {
assertThat(type, anyOf(
is(ICMP6.NEIGHBOR_SOLICITATION),
@@ -1019,19 +1173,6 @@ public class ProxyArpManagerTest {
}
- class TestEdgePortService extends EdgeManager {
-
- @Override
- public boolean isEdgePoint(ConnectPoint connectPoint) {
- return isEdgePointReturn;
- }
-
- @Override
- public Iterable<ConnectPoint> getEdgePoints() {
- return getEdgePointsNoArg;
- }
- }
-
private class TestProxyArpStoreAdapter implements ProxyArpStore {
@Override
public void forward(ConnectPoint outPort, Host subject, ByteBuffer packet) {
diff --git a/framework/src/onos/core/store/dist/pom.xml b/framework/src/onos/core/store/dist/pom.xml
index f2ec2a71..0b8b72bc 100644
--- a/framework/src/onos/core/store/dist/pom.xml
+++ b/framework/src/onos/core/store/dist/pom.xml
@@ -69,6 +69,12 @@
</dependency>
<dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-persistence</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.mapdb</groupId>
<artifactId>mapdb</artifactId>
<version>1.0.8</version>
@@ -110,5 +116,4 @@
<artifactId>onlab-thirdparty</artifactId>
</dependency>
</dependencies>
-
</project>
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/app/GossipApplicationStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/app/GossipApplicationStore.java
index 6764c222..fe4aa0be 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/app/GossipApplicationStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/app/GossipApplicationStore.java
@@ -17,7 +17,9 @@ package org.onosproject.store.app;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet;
-
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -37,6 +39,7 @@ import org.onosproject.common.app.ApplicationArchive;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
+import org.onosproject.core.CoreService;
import org.onosproject.core.DefaultApplication;
import org.onosproject.security.Permission;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
@@ -61,6 +64,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Function;
+import static com.google.common.collect.Multimaps.newSetMultimap;
+import static com.google.common.collect.Multimaps.synchronizedSetMultimap;
import static com.google.common.io.ByteStreams.toByteArray;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.onlab.util.Tools.groupedThreads;
@@ -115,6 +120,14 @@ public class GossipApplicationStore extends ApplicationArchive
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ApplicationIdStore idStore;
+ // Multimap to track which apps are required by others apps
+ // app -> { required-by, ... }
+ // Apps explicitly activated will be required by the CORE app
+ private final Multimap<ApplicationId, ApplicationId> requiredBy =
+ synchronizedSetMultimap(newSetMultimap(Maps.newHashMap(), Sets::newHashSet));
+
+ private ApplicationId coreAppId;
+
@Activate
public void activate() {
KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
@@ -128,16 +141,16 @@ public class GossipApplicationStore extends ApplicationArchive
groupedThreads("onos/store/app", "message-handler"));
clusterCommunicator.<String, byte[]>addSubscriber(APP_BITS_REQUEST,
- bytes -> new String(bytes, Charsets.UTF_8),
- name -> {
- try {
- return toByteArray(getApplicationInputStream(name));
- } catch (IOException e) {
- throw new StorageException(e);
- }
- },
- Function.identity(),
- messageHandlingExecutor);
+ bytes -> new String(bytes, Charsets.UTF_8),
+ name -> {
+ try {
+ return toByteArray(getApplicationInputStream(name));
+ } catch (IOException e) {
+ throw new StorageException(e);
+ }
+ },
+ Function.identity(),
+ messageHandlingExecutor);
// FIXME: Consider consolidating into a single map.
@@ -161,6 +174,7 @@ public class GossipApplicationStore extends ApplicationArchive
.withTimestampProvider((k, v) -> clockService.getTimestamp())
.build();
+ coreAppId = getId(CoreService.CORE_APP_NAME);
log.info("Started");
}
@@ -169,20 +183,34 @@ public class GossipApplicationStore extends ApplicationArchive
* they are marked to be active.
*/
private void loadFromDisk() {
- for (String name : getApplicationNames()) {
- for (int i = 0; i < MAX_LOAD_RETRIES; i++) {
- try {
- Application app = create(getApplicationDescription(name), false);
- if (app != null && isActive(app.id().name())) {
- activate(app.id(), false);
- // load app permissions
- }
- } catch (Exception e) {
- log.warn("Unable to load application {} from disk; retrying", name);
- randomDelay(RETRY_DELAY_MS); // FIXME: This is a deliberate hack; fix in Drake
+ getApplicationNames().forEach(appName -> {
+ Application app = loadFromDisk(appName);
+ if (app != null && isActive(app.id().name())) {
+ activate(app.id(), false);
+ // TODO Load app permissions
+ }
+ });
+ }
+
+ private Application loadFromDisk(String appName) {
+ for (int i = 0; i < MAX_LOAD_RETRIES; i++) {
+ try {
+ // Directly return if app already exists
+ ApplicationId appId = getId(appName);
+ if (appId != null) {
+ return getApplication(appId);
}
+
+ ApplicationDescription appDesc = getApplicationDescription(appName);
+ boolean success = appDesc.requiredApps().stream()
+ .noneMatch(requiredApp -> loadFromDisk(requiredApp) == null);
+ return success ? create(appDesc, false) : null;
+ } catch (Exception e) {
+ log.warn("Unable to load application {} from disk; retrying", appName);
+ randomDelay(RETRY_DELAY_MS); //FIXME: This is a deliberate hack; fix in Falcon
}
}
+ return null;
}
@Deactivate
@@ -200,7 +228,6 @@ public class GossipApplicationStore extends ApplicationArchive
public void setDelegate(ApplicationStoreDelegate delegate) {
super.setDelegate(delegate);
loadFromDisk();
-// executor.schedule(this::pruneUninstalledApps, LOAD_TIMEOUT_MS, MILLISECONDS);
}
@Override
@@ -229,7 +256,15 @@ public class GossipApplicationStore extends ApplicationArchive
@Override
public Application create(InputStream appDescStream) {
ApplicationDescription appDesc = saveApplication(appDescStream);
- return create(appDesc, true);
+ if (hasPrerequisites(appDesc)) {
+ return create(appDesc, true);
+ }
+ throw new ApplicationException("Missing dependencies for app " + appDesc.name());
+ }
+
+ private boolean hasPrerequisites(ApplicationDescription app) {
+ return !app.requiredApps().stream().map(n -> getId(n))
+ .anyMatch(id -> id == null || getApplication(id) == null);
}
private Application create(ApplicationDescription appDesc, boolean updateTime) {
@@ -246,36 +281,80 @@ public class GossipApplicationStore extends ApplicationArchive
public void remove(ApplicationId appId) {
Application app = apps.get(appId);
if (app != null) {
+ uninstallDependentApps(app);
apps.remove(appId);
states.remove(app);
permissions.remove(app);
}
}
+ // Uninstalls all apps that depend on the given app.
+ private void uninstallDependentApps(Application app) {
+ getApplications().stream()
+ .filter(a -> a.requiredApps().contains(app.id().name()))
+ .forEach(a -> remove(a.id()));
+ }
+
@Override
public void activate(ApplicationId appId) {
+ activate(appId, coreAppId);
+ }
+
+ private void activate(ApplicationId appId, ApplicationId forAppId) {
+ requiredBy.put(appId, forAppId);
activate(appId, true);
}
+
private void activate(ApplicationId appId, boolean updateTime) {
Application app = apps.get(appId);
if (app != null) {
if (updateTime) {
updateTime(appId.name());
}
+ activateRequiredApps(app);
states.put(app, ACTIVATED);
}
}
+ // Activates all apps required by this application.
+ private void activateRequiredApps(Application app) {
+ app.requiredApps().stream().map(this::getId).forEach(id -> activate(id, app.id()));
+ }
+
@Override
public void deactivate(ApplicationId appId) {
- Application app = apps.get(appId);
- if (app != null) {
- updateTime(appId.name());
- states.put(app, DEACTIVATED);
+ deactivateDependentApps(getApplication(appId));
+ deactivate(appId, coreAppId);
+ }
+
+ private void deactivate(ApplicationId appId, ApplicationId forAppId) {
+ requiredBy.remove(appId, forAppId);
+ if (requiredBy.get(appId).isEmpty()) {
+ Application app = apps.get(appId);
+ if (app != null) {
+ updateTime(appId.name());
+ states.put(app, DEACTIVATED);
+ deactivateRequiredApps(app);
+ }
}
}
+ // Deactivates all apps that require this application.
+ private void deactivateDependentApps(Application app) {
+ getApplications().stream()
+ .filter(a -> states.get(a) == ACTIVATED)
+ .filter(a -> a.requiredApps().contains(app.id().name()))
+ .forEach(a -> deactivate(a.id()));
+ }
+
+ // Deactivates all apps required by this application.
+ private void deactivateRequiredApps(Application app) {
+ app.requiredApps().stream().map(this::getId).map(this::getApplication)
+ .filter(a -> states.get(a) == ACTIVATED)
+ .forEach(a -> deactivate(a.id(), app.id()));
+ }
+
@Override
public Set<Permission> getPermissions(ApplicationId appId) {
Application app = apps.get(appId);
@@ -424,6 +503,7 @@ public class GossipApplicationStore extends ApplicationArchive
ApplicationId appId = idStore.registerApplication(appDesc.name());
return new DefaultApplication(appId, appDesc.version(), appDesc.description(),
appDesc.origin(), appDesc.role(), appDesc.permissions(),
- appDesc.featuresRepo(), appDesc.features());
+ appDesc.featuresRepo(), appDesc.features(),
+ appDesc.requiredApps());
}
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java
index 9f6c4130..3cd992bb 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/impl/StaticClusterMetadataStore.java
@@ -7,6 +7,7 @@ import static org.slf4j.LoggerFactory.getLogger;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
+import java.net.Inet4Address;
import java.net.NetworkInterface;
import java.util.Arrays;
import java.util.Collection;
@@ -55,6 +56,11 @@ 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 ONOS_ALLOW_IPV6 = "ONOS_ALLOW_IPV6";
+ 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,28 +200,59 @@ 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;
+ }
+
+ // Capture if they want to limit IP address selection to only IPv4 (default).
+ boolean allowIPv6 = (System.getenv(ONOS_ALLOW_IPV6) != null);
+
Function<NetworkInterface, IpAddress> ipLookup = nif -> {
- for (InetAddress address : Collections.list(nif.getInetAddresses())) {
- if (address.isSiteLocalAddress()) {
- return IpAddress.valueOf(address);
+ IpAddress fallback = null;
+
+ // nif can be null if the interface name specified doesn't exist on the node's host
+ if (nif != null) {
+ for (InetAddress address : Collections.list(nif.getInetAddresses())) {
+ if (address.isSiteLocalAddress() && (allowIPv6 || address instanceof Inet4Address)) {
+ return IpAddress.valueOf(address);
+ }
+ if (fallback == null && !address.isLoopbackAddress() && !address.isMulticastAddress()
+ && (allowIPv6 || address instanceof Inet4Address)) {
+ fallback = IpAddress.valueOf(address);
+ }
}
}
- return null;
+ return fallback;
};
try {
- IpAddress ip = ipLookup.apply(NetworkInterface.getByName("eth0"));
+ IpAddress ip = ipLookup.apply(NetworkInterface.getByName(useOnosInterface));
if (ip != null) {
return ip.toString();
}
for (NetworkInterface nif : Collections.list(getNetworkInterfaces())) {
- ip = ipLookup.apply(nif);
- if (ip != null) {
- return ip.toString();
+ if (!nif.getName().equals(useOnosInterface)) {
+ ip = ipLookup.apply(nif);
+ if (ip != null) {
+ return ip.toString();
+ }
}
}
} catch (Exception e) {
throw new IllegalStateException("Unable to get network interfaces", e);
}
+
return IpAddress.valueOf(InetAddress.getLoopbackAddress()).toString();
}
-} \ No newline at end of file
+}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
index 23c81869..d61d7dcf 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/cluster/messaging/impl/NettyMessagingManager.java
@@ -47,7 +47,7 @@ public class NettyMessagingManager extends NettyMessaging {
@Activate
public void activate() throws Exception {
ControllerNode localNode = clusterMetadataService.getLocalNode();
- getTLSParameters();
+ getTlsParameters();
super.start(new Endpoint(localNode.ip(), localNode.tcpPort()));
log.info("Started");
}
@@ -58,29 +58,29 @@ public class NettyMessagingManager extends NettyMessaging {
log.info("Stopped");
}
- private void getTLSParameters() {
+ private void getTlsParameters() {
String tempString = System.getProperty("enableNettyTLS");
- enableNettyTLS = Strings.isNullOrEmpty(tempString) ? TLS_DISABLED : Boolean.parseBoolean(tempString);
- log.info("enableNettyTLS = {}", enableNettyTLS);
- if (enableNettyTLS) {
+ enableNettyTls = Strings.isNullOrEmpty(tempString) ? TLS_DISABLED : Boolean.parseBoolean(tempString);
+ log.info("enableNettyTLS = {}", enableNettyTls);
+ if (enableNettyTls) {
ksLocation = System.getProperty("javax.net.ssl.keyStore");
if (Strings.isNullOrEmpty(ksLocation)) {
- enableNettyTLS = TLS_DISABLED;
+ enableNettyTls = TLS_DISABLED;
return;
}
tsLocation = System.getProperty("javax.net.ssl.trustStore");
if (Strings.isNullOrEmpty(tsLocation)) {
- enableNettyTLS = TLS_DISABLED;
+ enableNettyTls = TLS_DISABLED;
return;
}
ksPwd = System.getProperty("javax.net.ssl.keyStorePassword").toCharArray();
if (MIN_KS_LENGTH > ksPwd.length) {
- enableNettyTLS = TLS_DISABLED;
+ enableNettyTls = TLS_DISABLED;
return;
}
tsPwd = System.getProperty("javax.net.ssl.trustStorePassword").toCharArray();
if (MIN_KS_LENGTH > tsPwd.length) {
- enableNettyTLS = TLS_DISABLED;
+ enableNettyTls = TLS_DISABLED;
return;
}
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
index 3e73d8f4..ca8eea37 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/config/impl/DistributedNetworkConfigStore.java
@@ -60,6 +60,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.onosproject.net.config.NetworkConfigEvent.Type.*;
/**
@@ -71,10 +72,12 @@ public class DistributedNetworkConfigStore
extends AbstractStore<NetworkConfigEvent, NetworkConfigStoreDelegate>
implements NetworkConfigStore {
- private static final int MAX_BACKOFF = 10;
-
private final Logger log = LoggerFactory.getLogger(getClass());
+ private static final int MAX_BACKOFF = 10;
+ private static final String INVALID_CONFIG_JSON =
+ "JSON node does not contain valid configuration";
+
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService;
@@ -187,8 +190,17 @@ public class DistributedNetworkConfigStore
@Override
public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, JsonNode json) {
- return createConfig(subject, configClass,
- configs.putAndGet(key(subject, configClass), json).value());
+ // Create the configuration and validate it.
+ C config = createConfig(subject, configClass, json);
+ checkArgument(config.isValid(), INVALID_CONFIG_JSON);
+
+ // Insert the validated configuration and get it back.
+ Versioned<JsonNode> versioned = configs.putAndGet(key(subject, configClass), json);
+
+ // Re-create the config if for some reason what we attempted to put
+ // was supplanted by someone else already.
+ return versioned.value() == json ? config :
+ createConfig(subject, configClass, versioned.value());
}
@Override
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/AsyncCachingConsistentMap.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/AsyncCachingConsistentMap.java
index 7e575b01..92db5b44 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/AsyncCachingConsistentMap.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/AsyncCachingConsistentMap.java
@@ -26,8 +26,12 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
/**
- * Extension of DefaultAsyncConsistentMap that provides a weaker read consistency
+ * Extension of {@link DefaultAsyncConsistentMap} that provides a weaker read consistency
* guarantee in return for better read performance.
+ * <p>
+ * For read/write operations that are local to a node this map implementation provides
+ * guarantees similar to a ConsistentMap. However for read/write operations executed
+ * across multiple nodes this implementation only provides eventual consistency.
*
* @param <K> key type
* @param <V> value type
@@ -68,4 +72,10 @@ public class AsyncCachingConsistentMap<K, V> extends DefaultAsyncConsistentMap<K
}
return cache.getUnchecked(key);
}
+
+ @Override
+ protected void beforeUpdate(K key) {
+ super.beforeUpdate(key);
+ cache.invalidate(key);
+ }
} \ No newline at end of file
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseManager.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseManager.java
index 3e89635a..90d81ee7 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseManager.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DatabaseManager.java
@@ -55,6 +55,7 @@ import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.IdGenerator;
+import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.ecmap.EventuallyConsistentMapBuilderImpl;
import org.onosproject.store.service.AtomicCounterBuilder;
@@ -128,6 +129,9 @@ public class DatabaseManager implements StorageService, StorageAdminService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ClusterCommunicationService clusterCommunicator;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PersistenceService persistenceService;
+
protected String nodeIdToUri(NodeId nodeId) {
ControllerNode node = clusterService.getNode(nodeId);
return String.format("onos://%s:%d", node.ip(), node.tcpPort());
@@ -312,7 +316,8 @@ public class DatabaseManager implements StorageService, StorageAdminService {
@Override
public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
return new EventuallyConsistentMapBuilderImpl<>(clusterService,
- clusterCommunicator);
+ clusterCommunicator,
+ persistenceService);
}
@Override
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
index 0ea66861..c6d300c9 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
@@ -405,6 +405,14 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
.thenApply(v -> v.updated());
}
+ /**
+ * Pre-update hook for performing required checks/actions before going forward with an update operation.
+ * @param key map key.
+ */
+ protected void beforeUpdate(K key) {
+ checkIfUnmodifiable();
+ }
+
private Map.Entry<K, Versioned<V>> mapRawEntry(Map.Entry<String, Versioned<byte[]>> e) {
return Maps.immutableEntry(dK(e.getKey()), e.getValue().<V>map(serializer::decode));
}
@@ -413,7 +421,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
Match<V> oldValueMatch,
Match<Long> oldVersionMatch,
V value) {
- checkIfUnmodifiable();
+ beforeUpdate(key);
return database.mapUpdate(name,
keyCache.getUnchecked(key),
oldValueMatch.map(serializer::encode),
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
index 687762e0..a9a9098e 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
@@ -986,6 +986,10 @@ public class GossipDeviceStore
// accept removal request if given timestamp is newer than
// the latest Timestamp from Primary provider
DeviceDescriptions primDescs = getPrimaryDescriptions(descs);
+ if (primDescs == null) {
+ return null;
+ }
+
Timestamp lastTimestamp = primDescs.getLatestTimestamp();
if (timestamp.compareTo(lastTimestamp) <= 0) {
// outdated event ignore
@@ -1036,7 +1040,7 @@ public class GossipDeviceStore
checkArgument(!providerDescs.isEmpty(), "No device descriptions supplied");
- ProviderId primary = pickPrimaryPID(providerDescs);
+ ProviderId primary = pickPrimaryPid(providerDescs);
DeviceDescriptions desc = providerDescs.get(primary);
@@ -1099,7 +1103,7 @@ public class GossipDeviceStore
private Port composePort(Device device, PortNumber number,
Map<ProviderId, DeviceDescriptions> descsMap) {
- ProviderId primary = pickPrimaryPID(descsMap);
+ ProviderId primary = pickPrimaryPid(descsMap);
DeviceDescriptions primDescs = descsMap.get(primary);
// if no primary, assume not enabled
boolean isEnabled = false;
@@ -1145,7 +1149,7 @@ public class GossipDeviceStore
/**
* @return primary ProviderID, or randomly chosen one if none exists
*/
- private ProviderId pickPrimaryPID(
+ private ProviderId pickPrimaryPid(
Map<ProviderId, DeviceDescriptions> providerDescs) {
ProviderId fallBackPrimary = null;
for (Entry<ProviderId, DeviceDescriptions> e : providerDescs.entrySet()) {
@@ -1161,7 +1165,7 @@ public class GossipDeviceStore
private DeviceDescriptions getPrimaryDescriptions(
Map<ProviderId, DeviceDescriptions> providerDescs) {
- ProviderId pid = pickPrimaryPID(providerDescs);
+ ProviderId pid = pickPrimaryPid(providerDescs);
return providerDescs.get(pid);
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java
index a553ffff..eb98c829 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapBuilderImpl.java
@@ -18,6 +18,7 @@ package org.onosproject.store.ecmap;
import org.onlab.util.KryoNamespace;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
+import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.Timestamp;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.service.EventuallyConsistentMap;
@@ -52,6 +53,8 @@ public class EventuallyConsistentMapBuilderImpl<K, V>
private TimeUnit antiEntropyTimeUnit = TimeUnit.SECONDS;
private boolean convergeFaster = false;
private boolean persistent = false;
+ private boolean persistentMap = false;
+ private final PersistenceService persistenceService;
/**
* Creates a new eventually consistent map builder.
@@ -60,7 +63,9 @@ public class EventuallyConsistentMapBuilderImpl<K, V>
* @param clusterCommunicator cluster communication service
*/
public EventuallyConsistentMapBuilderImpl(ClusterService clusterService,
- ClusterCommunicationService clusterCommunicator) {
+ ClusterCommunicationService clusterCommunicator,
+ PersistenceService persistenceService) {
+ this.persistenceService = persistenceService;
this.clusterService = checkNotNull(clusterService);
this.clusterCommunicator = checkNotNull(clusterCommunicator);
}
@@ -133,6 +138,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V>
@Override
public EventuallyConsistentMapBuilder<K, V> withPersistence() {
+ checkNotNull(this.persistenceService);
persistent = true;
return this;
}
@@ -156,6 +162,7 @@ public class EventuallyConsistentMapBuilderImpl<K, V>
antiEntropyPeriod,
antiEntropyTimeUnit,
convergeFaster,
- persistent);
+ persistent,
+ persistenceService);
}
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
index f1e0dbd4..b5ea52e0 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/ecmap/EventuallyConsistentMapImpl.java
@@ -28,6 +28,7 @@ import org.onlab.util.SlidingWindowCounter;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.NodeId;
+import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.Timestamp;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.MessageSubject;
@@ -37,6 +38,7 @@ import org.onosproject.store.serializers.KryoSerializer;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapEvent;
import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.WallClockTimestamp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -81,6 +83,7 @@ public class EventuallyConsistentMapImpl<K, V>
private final ClusterCommunicationService clusterCommunicator;
private final KryoSerializer serializer;
private final NodeId localNodeId;
+ private final PersistenceService persistenceService;
private final BiFunction<K, V, Timestamp> timestampProvider;
@@ -116,7 +119,9 @@ public class EventuallyConsistentMapImpl<K, V>
private SlidingWindowCounter counter = new SlidingWindowCounter(WINDOW_SIZE);
private final boolean persistent;
- private final PersistentStore<K, V> persistentStore;
+
+ private static final String PERSISTENT_LOCAL_MAP_NAME = "itemsMap";
+
/**
* Creates a new eventually consistent map shared amongst multiple instances.
@@ -158,9 +163,32 @@ public class EventuallyConsistentMapImpl<K, V>
long antiEntropyPeriod,
TimeUnit antiEntropyTimeUnit,
boolean convergeFaster,
- boolean persistent) {
+ boolean persistent,
+ PersistenceService persistenceService) {
this.mapName = mapName;
- items = Maps.newConcurrentMap();
+ this.serializer = createSerializer(serializerBuilder);
+ this.persistenceService = persistenceService;
+ this.persistent =
+ persistent;
+ if (persistent) {
+ items = this.persistenceService.<K, MapValue<V>>persistentMapBuilder()
+ .withName(PERSISTENT_LOCAL_MAP_NAME)
+ .withSerializer(new Serializer() {
+
+ @Override
+ public <T> byte[] encode(T object) {
+ return EventuallyConsistentMapImpl.this.serializer.encode(object);
+ }
+
+ @Override
+ public <T> T decode(byte[] bytes) {
+ return EventuallyConsistentMapImpl.this.serializer.decode(bytes);
+ }
+ })
+ .build();
+ } else {
+ items = Maps.newConcurrentMap();
+ }
senderPending = Maps.newConcurrentMap();
destroyedMessage = mapName + ERROR_DESTROYED;
@@ -168,8 +196,6 @@ public class EventuallyConsistentMapImpl<K, V>
this.clusterCommunicator = clusterCommunicator;
this.localNodeId = clusterService.getLocalNode().id();
- this.serializer = createSerializer(serializerBuilder);
-
this.timestampProvider = timestampProvider;
if (peerUpdateFunction != null) {
@@ -198,20 +224,6 @@ public class EventuallyConsistentMapImpl<K, V>
newFixedThreadPool(8, groupedThreads("onos/ecm", mapName + "-publish-%d"));
}
- this.persistent = persistent;
-
- if (this.persistent) {
- String dataDirectory = System.getProperty("karaf.data", "./data");
- String filename = dataDirectory + "/" + "mapdb-ecm-" + mapName;
-
- ExecutorService dbExecutor =
- newFixedThreadPool(1, groupedThreads("onos/ecm", mapName + "-dbwriter"));
-
- persistentStore = new MapDbPersistentStore<>(filename, dbExecutor, serializer);
- persistentStore.readInto(items);
- } else {
- this.persistentStore = null;
- }
if (backgroundExecutor != null) {
this.backgroundExecutor = backgroundExecutor;
@@ -373,15 +385,6 @@ public class EventuallyConsistentMapImpl<K, V>
return existing;
}
});
- if (updated.get()) {
- if (persistent) {
- if (tombstone.isPresent()) {
- persistentStore.update(key, tombstone.get());
- } else {
- persistentStore.remove(key);
- }
- }
- }
return previousValue.get();
}
@@ -455,6 +458,7 @@ public class EventuallyConsistentMapImpl<K, V>
/**
* Returns true if newValue was accepted i.e. map is updated.
+ *
* @param key key
* @param newValue proposed new value
* @return true if update happened; false if map already contains a more recent value for the key
@@ -473,9 +477,6 @@ public class EventuallyConsistentMapImpl<K, V>
}
return existing;
});
- if (updated.get() && persistent) {
- persistentStore.update(key, newValue);
- }
return updated.get();
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/flow/impl/NewDistributedFlowRuleStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/flow/impl/NewDistributedFlowRuleStore.java
index 8cd63e7d..1695e5ff 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/flow/impl/NewDistributedFlowRuleStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/flow/impl/NewDistributedFlowRuleStore.java
@@ -59,6 +59,7 @@ import org.onosproject.net.flow.FlowRuleStore;
import org.onosproject.net.flow.FlowRuleStoreDelegate;
import org.onosproject.net.flow.StoredFlowEntry;
import org.onosproject.net.flow.TableStatisticsEntry;
+import org.onosproject.persistence.PersistenceService;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.ClusterMessage;
@@ -74,6 +75,7 @@ import org.onosproject.store.serializers.custom.DistributedStoreSerializers;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapEvent;
import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.WallClockTimestamp;
import org.osgi.service.component.ComponentContext;
@@ -113,6 +115,7 @@ public class NewDistributedFlowRuleStore
private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8;
private static final boolean DEFAULT_BACKUP_ENABLED = true;
+ private static final boolean DEFAULT_PERSISTENCE_ENABLED = false;
private static final int DEFAULT_BACKUP_PERIOD_MILLIS = 2000;
private static final long FLOW_RULE_STORE_TIMEOUT_MILLIS = 5000;
// number of devices whose flow entries will be backed up in one communication round
@@ -129,6 +132,9 @@ public class NewDistributedFlowRuleStore
@Property(name = "backupPeriod", intValue = DEFAULT_BACKUP_PERIOD_MILLIS,
label = "Delay in ms between successive backup runs")
private int backupPeriod = DEFAULT_BACKUP_PERIOD_MILLIS;
+ @Property(name = "persistenceEnabled", boolValue = false,
+ label = "Indicates whether or not changes in the flow table should be persisted to disk.")
+ private boolean persistenceEnabled = DEFAULT_PERSISTENCE_ENABLED;
private InternalFlowTable flowTable = new InternalFlowTable();
@@ -153,6 +159,9 @@ public class NewDistributedFlowRuleStore
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PersistenceService persistenceService;
+
private Map<Long, NodeId> pendingResponses = Maps.newConcurrentMap();
private ExecutorService messageHandlingExecutor;
@@ -716,7 +725,25 @@ public class NewDistributedFlowRuleStore
* @return Map representing Flow Table of given device.
*/
private Map<FlowId, Set<StoredFlowEntry>> getFlowTable(DeviceId deviceId) {
- return flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap());
+ if (persistenceEnabled) {
+ return flowEntries.computeIfAbsent(deviceId, id -> persistenceService
+ .<FlowId, Set<StoredFlowEntry>>persistentMapBuilder()
+ .withName("FlowTable:" + deviceId.toString())
+ .withSerializer(new Serializer() {
+ @Override
+ public <T> byte[] encode(T object) {
+ return SERIALIZER.encode(object);
+ }
+
+ @Override
+ public <T> T decode(byte[] bytes) {
+ return SERIALIZER.decode(bytes);
+ }
+ })
+ .build());
+ } else {
+ return flowEntries.computeIfAbsent(deviceId, id -> Maps.newConcurrentMap());
+ }
}
private Set<StoredFlowEntry> getFlowEntriesInternal(DeviceId deviceId, FlowId flowId) {
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
index f9c96891..20124576 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
@@ -19,8 +19,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.onosproject.net.DefaultAnnotations.merge;
import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
import static org.onosproject.net.host.HostEvent.Type.HOST_MOVED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
@@ -28,9 +28,10 @@ import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -56,7 +57,6 @@ import org.onosproject.net.host.HostDescription;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostStore;
import org.onosproject.net.host.HostStoreDelegate;
-import org.onosproject.net.host.HostEvent.Type;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces;
@@ -67,10 +67,7 @@ import org.onosproject.store.service.LogicalClockService;
import org.onosproject.store.service.StorageService;
import org.slf4j.Logger;
-import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
/**
@@ -90,13 +87,11 @@ public class ECHostStore
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected LogicalClockService clockService;
- // Hosts tracked by their location
- private final SetMultimap<ConnectPoint, Host> locations =
- Multimaps.synchronizedSetMultimap(
- HashMultimap.<ConnectPoint, Host>create());
-
private EventuallyConsistentMap<HostId, DefaultHost> hosts;
+ private final ConcurrentHashMap<HostId, DefaultHost> prevHosts =
+ new ConcurrentHashMap<>();
+
private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
new HostLocationTracker();
@@ -120,11 +115,12 @@ public class ECHostStore
public void deactivate() {
hosts.removeListener(hostLocationTracker);
hosts.destroy();
- locations.clear();
+ prevHosts.clear();
log.info("Stopped");
}
+ // TODO No longer need to return HostEvent
@Override
public HostEvent createOrUpdateHost(ProviderId providerId,
HostId hostId,
@@ -133,18 +129,7 @@ public class ECHostStore
// TODO: We need a way to detect conflicting changes and abort update.
// (BOC) Compute might do this for us.
- final AtomicReference<Type> eventType = new AtomicReference<>();
- final AtomicReference<DefaultHost> oldHost = new AtomicReference<>();
- DefaultHost host = hosts.compute(hostId, (id, existingHost) -> {
- if (existingHost != null) {
- oldHost.set(existingHost);
- checkState(Objects.equals(hostDescription.hwAddress(), existingHost.mac()),
- "Existing and new MAC addresses differ.");
- checkState(Objects.equals(hostDescription.vlan(), existingHost.vlan()),
- "Existing and new VLANs differ.");
- }
-
- // TODO do we ever want the existing location?
+ hosts.compute(hostId, (id, existingHost) -> {
HostLocation location = hostDescription.location();
final Set<IpAddress> addresses;
@@ -163,15 +148,6 @@ public class ECHostStore
annotations = hostDescription.annotations();
}
- if (existingHost == null) {
- eventType.set(HOST_ADDED);
- } else if (!Objects.equals(existingHost.location(), hostDescription.location())) {
- eventType.set(HOST_MOVED);
- } else if (!existingHost.ipAddresses().containsAll(hostDescription.ipAddress()) ||
- !hostDescription.annotations().keys().isEmpty()) {
- eventType.set(HOST_UPDATED);
- } // else, eventType == null; this means we don't send an event
-
return new DefaultHost(providerId,
hostId,
hostDescription.hwAddress(),
@@ -181,24 +157,20 @@ public class ECHostStore
annotations);
});
- if (oldHost.get() != null) {
- DefaultHost old = oldHost.get();
- locations.remove(old.location(), old);
- }
- locations.put(host.location(), host);
-
- return eventType.get() != null ? new HostEvent(eventType.get(), host) : null;
+ return null;
}
+ // TODO No longer need to return HostEvent
@Override
public HostEvent removeHost(HostId hostId) {
- Host host = hosts.remove(hostId);
- return host != null ? new HostEvent(HOST_REMOVED, host) : null;
+ hosts.remove(hostId);
+ return null;
}
+ // TODO No longer need to return HostEvent
@Override
public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
- DefaultHost host = hosts.compute(hostId, (id, existingHost) -> {
+ hosts.compute(hostId, (id, existingHost) -> {
if (existingHost != null) {
checkState(Objects.equals(hostId.mac(), existingHost.mac()),
"Existing and new MAC addresses differ.");
@@ -222,7 +194,7 @@ public class ECHostStore
}
return null;
});
- return host != null ? new HostEvent(HOST_UPDATED, host) : null;
+ return null;
}
@Override
@@ -257,22 +229,19 @@ public class ECHostStore
@Override
public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
- synchronized (locations) {
- return ImmutableSet.copyOf(locations.get(connectPoint));
- }
+ Set<Host> filtered = hosts.entrySet().stream()
+ .filter(entry -> entry.getValue().location().equals(connectPoint))
+ .map(Map.Entry::getValue)
+ .collect(Collectors.toSet());
+ return ImmutableSet.copyOf(filtered);
}
@Override
public Set<Host> getConnectedHosts(DeviceId deviceId) {
- Set<Host> filtered;
- synchronized (locations) {
- filtered = locations
- .entries()
- .stream()
- .filter(entry -> entry.getKey().deviceId().equals(deviceId))
- .map(entry -> entry.getValue())
- .collect(Collectors.toSet());
- }
+ Set<Host> filtered = hosts.entrySet().stream()
+ .filter(entry -> entry.getValue().location().deviceId().equals(deviceId))
+ .map(Map.Entry::getValue)
+ .collect(Collectors.toSet());
return ImmutableSet.copyOf(filtered);
}
@@ -285,13 +254,18 @@ public class ECHostStore
public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
DefaultHost host = checkNotNull(event.value());
if (event.type() == PUT) {
- boolean isNew = locations.put(host.location(), host);
- notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
+ Host prevHost = prevHosts.put(host.id(), host);
+ if (prevHost == null) {
+ notifyDelegate(new HostEvent(HOST_ADDED, host));
+ } else if (!Objects.equals(prevHost.location(), host.location())) {
+ notifyDelegate(new HostEvent(HOST_MOVED, host, prevHost));
+ } else if (!Objects.equals(prevHost, host)) {
+ notifyDelegate(new HostEvent(HOST_UPDATED, host, prevHost));
+ }
} else if (event.type() == REMOVE) {
- if (locations.remove(host.location(), host)) {
+ if (prevHosts.remove(host.id()) != null) {
notifyDelegate(new HostEvent(HOST_REMOVED, host));
}
-
}
}
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/impl/LogicalTimestamp.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/impl/LogicalTimestamp.java
index 9382960f..dfee9980 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/impl/LogicalTimestamp.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/impl/LogicalTimestamp.java
@@ -50,7 +50,7 @@ public class LogicalTimestamp implements Timestamp {
@Override
public int hashCode() {
- return Objects.hash(value);
+ return Long.hashCode(value);
}
@Override
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/intent/impl/PartitionId.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/intent/impl/PartitionId.java
index 885361f0..f6cd198f 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/intent/impl/PartitionId.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/intent/impl/PartitionId.java
@@ -56,7 +56,7 @@ public class PartitionId {
@Override
public int hashCode() {
- return Objects.hash(id);
+ return id;
}
@Override
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
index 687576c3..0335ba5d 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
@@ -16,20 +16,23 @@
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;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TransactionContext;
-import org.onosproject.store.service.TransactionException;
import org.onosproject.store.service.TransactionalMap;
import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;
@@ -48,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.
@@ -55,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";
@@ -79,6 +84,8 @@ public class ConsistentResourceStore implements ResourceStore {
.withName(CHILD_MAP)
.withSerializer(SERIALIZER)
.build();
+
+ childMap.put(ResourcePath.ROOT, ImmutableList.of());
}
@Override
@@ -100,29 +107,32 @@ public class ConsistentResourceStore implements ResourceStore {
TransactionContext tx = service.transactionContextBuilder().build();
tx.begin();
- try {
- TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
- tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
+ TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
+ tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
- Map<ResourcePath, List<ResourcePath>> resourceMap = resources.stream()
- .filter(x -> x.parent().isPresent())
- .collect(Collectors.groupingBy(x -> x.parent().get()));
+ Map<ResourcePath, List<ResourcePath>> resourceMap = resources.stream()
+ .filter(x -> x.parent().isPresent())
+ .collect(Collectors.groupingBy(x -> x.parent().get()));
- for (Map.Entry<ResourcePath, List<ResourcePath>> entry: resourceMap.entrySet()) {
- if (!isRegistered(childTxMap, entry.getKey())) {
- return abortTransaction(tx);
- }
+ for (Map.Entry<ResourcePath, List<ResourcePath>> entry: resourceMap.entrySet()) {
+ if (!isRegistered(childTxMap, entry.getKey())) {
+ return abortTransaction(tx);
+ }
- if (!appendValues(childTxMap, entry.getKey(), entry.getValue())) {
- return abortTransaction(tx);
- }
+ if (!appendValues(childTxMap, entry.getKey(), entry.getValue())) {
+ return abortTransaction(tx);
}
+ }
- return commitTransaction(tx);
- } catch (TransactionException e) {
- log.error("Exception thrown, abort the transaction", e);
- return abortTransaction(tx);
+ 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
@@ -132,33 +142,36 @@ public class ConsistentResourceStore implements ResourceStore {
TransactionContext tx = service.transactionContextBuilder().build();
tx.begin();
- try {
- TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
- tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
- TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
- tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
+ TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
+ tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
+ TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
+ tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
- Map<ResourcePath, List<ResourcePath>> resourceMap = resources.stream()
- .filter(x -> x.parent().isPresent())
- .collect(Collectors.groupingBy(x -> x.parent().get()));
-
- // even if one of the resources is allocated to a consumer,
- // all unregistrations are regarded as failure
- for (Map.Entry<ResourcePath, List<ResourcePath>> entry: resourceMap.entrySet()) {
- if (entry.getValue().stream().anyMatch(x -> consumerTxMap.get(x) != null)) {
- return abortTransaction(tx);
- }
-
- if (!removeValues(childTxMap, entry.getKey(), entry.getValue())) {
- return abortTransaction(tx);
- }
+ Map<ResourcePath, List<ResourcePath>> resourceMap = resources.stream()
+ .filter(x -> x.parent().isPresent())
+ .collect(Collectors.groupingBy(x -> x.parent().get()));
+
+ // even if one of the resources is allocated to a consumer,
+ // all unregistrations are regarded as failure
+ for (Map.Entry<ResourcePath, List<ResourcePath>> entry: resourceMap.entrySet()) {
+ if (entry.getValue().stream().anyMatch(x -> consumerTxMap.get(x) != null)) {
+ return abortTransaction(tx);
}
- return commitTransaction(tx);
- } catch (TransactionException e) {
- log.error("Exception thrown, abort the transaction", e);
- return abortTransaction(tx);
+ if (!removeValues(childTxMap, entry.getKey(), entry.getValue())) {
+ return abortTransaction(tx);
+ }
+ }
+
+ 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
@@ -169,28 +182,23 @@ public class ConsistentResourceStore implements ResourceStore {
TransactionContext tx = service.transactionContextBuilder().build();
tx.begin();
- try {
- TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
- tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
- TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
- tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
-
- for (ResourcePath resource: resources) {
- if (!isRegistered(childTxMap, resource)) {
- return abortTransaction(tx);
- }
-
- ResourceConsumer oldValue = consumerTxMap.put(resource, consumer);
- if (oldValue != null) {
- return abortTransaction(tx);
- }
+ TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
+ tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
+ TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
+ tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
+
+ for (ResourcePath resource: resources) {
+ if (!isRegistered(childTxMap, resource)) {
+ return abortTransaction(tx);
}
- return commitTransaction(tx);
- } catch (TransactionException e) {
- log.error("Exception thrown, abort the transaction", e);
- return abortTransaction(tx);
+ ResourceConsumer oldValue = consumerTxMap.put(resource, consumer);
+ if (oldValue != null) {
+ return abortTransaction(tx);
+ }
}
+
+ return tx.commit();
}
@Override
@@ -202,28 +210,23 @@ public class ConsistentResourceStore implements ResourceStore {
TransactionContext tx = service.transactionContextBuilder().build();
tx.begin();
- try {
- TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
- tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
- Iterator<ResourcePath> resourceIte = resources.iterator();
- Iterator<ResourceConsumer> consumerIte = consumers.iterator();
-
- while (resourceIte.hasNext() && consumerIte.hasNext()) {
- ResourcePath resource = resourceIte.next();
- ResourceConsumer consumer = consumerIte.next();
-
- // if this single release fails (because the resource is allocated to another consumer,
- // the whole release fails
- if (!consumerTxMap.remove(resource, consumer)) {
- return abortTransaction(tx);
- }
- }
+ TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
+ tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
+ Iterator<ResourcePath> resourceIte = resources.iterator();
+ Iterator<ResourceConsumer> consumerIte = consumers.iterator();
+
+ while (resourceIte.hasNext() && consumerIte.hasNext()) {
+ ResourcePath resource = resourceIte.next();
+ ResourceConsumer consumer = consumerIte.next();
- return commitTransaction(tx);
- } catch (TransactionException e) {
- log.error("Exception thrown, abort the transaction", e);
- return abortTransaction(tx);
+ // if this single release fails (because the resource is allocated to another consumer,
+ // the whole release fails
+ if (!consumerTxMap.remove(resource, consumer)) {
+ return abortTransaction(tx);
+ }
}
+
+ return tx.commit();
}
@Override
@@ -261,7 +264,7 @@ public class ConsistentResourceStore implements ResourceStore {
}
return children.value().stream()
- .filter(x -> x.lastComponent().getClass().equals(cls))
+ .filter(x -> x.last().getClass().equals(cls))
.filter(consumerMap::containsKey)
.collect(Collectors.toList());
}
@@ -278,17 +281,6 @@ public class ConsistentResourceStore implements ResourceStore {
}
/**
- * Commit the transaction.
- *
- * @param tx transaction context
- * @return always true
- */
- private boolean commitTransaction(TransactionContext tx) {
- tx.commit();
- return true;
- }
-
- /**
* Appends the values to the existing values associated with the specified key.
* If the map already has all the given values, appending will not happen.
*
@@ -300,9 +292,9 @@ public class ConsistentResourceStore implements ResourceStore {
* @return true if the operation succeeds, false otherwise.
*/
private <K, V> boolean appendValues(TransactionalMap<K, List<V>> map, K key, List<V> values) {
- List<V> oldValues = map.get(key);
+ List<V> oldValues = map.putIfAbsent(key, new ArrayList<>(values));
if (oldValues == null) {
- return map.replace(key, oldValues, new ArrayList<>(values));
+ return true;
}
LinkedHashSet<V> oldSet = new LinkedHashSet<>(oldValues);
@@ -329,7 +321,8 @@ public class ConsistentResourceStore implements ResourceStore {
private <K, V> boolean removeValues(TransactionalMap<K, List<V>> map, K key, List<V> values) {
List<V> oldValues = map.get(key);
if (oldValues == null) {
- return map.replace(key, oldValues, new ArrayList<>());
+ map.put(key, new ArrayList<>());
+ return true;
}
LinkedHashSet<V> oldSet = new LinkedHashSet<>(oldValues);
@@ -351,7 +344,7 @@ public class ConsistentResourceStore implements ResourceStore {
*/
private boolean isRegistered(TransactionalMap<ResourcePath, List<ResourcePath>> map, ResourcePath resource) {
// root is always regarded to be registered
- if (resource.isRoot()) {
+ if (!resource.parent().isPresent()) {
return true;
}
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java
index c332ada5..351c7a5f 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentLinkResourceStore.java
@@ -59,7 +59,6 @@ import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.TransactionContext;
-import org.onosproject.store.service.TransactionException;
import org.onosproject.store.service.TransactionalMap;
import org.onosproject.store.service.Versioned;
@@ -73,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
@@ -294,7 +296,7 @@ public class ConsistentLinkResourceStore extends
intentAllocs.put(allocations.intentId(), allocations);
allocations.links().forEach(link -> allocateLinkResource(tx, link, allocations));
tx.commit();
- } catch (TransactionException | ResourceAllocationException e) {
+ } catch (ResourceAllocationException e) {
log.error("Exception thrown, rolling back", e);
tx.abort();
} catch (Exception e) {
@@ -407,12 +409,8 @@ public class ConsistentLinkResourceStore extends
after.remove(allocations);
linkAllocs.replace(linkId, before, after);
});
- tx.commit();
- success = true;
- } catch (TransactionException e) {
- log.debug("Transaction failed, retrying", e);
- tx.abort();
- } catch (Exception e) {
+ success = tx.commit();
+ } catch (Exception e) {
log.error("Exception thrown during releaseResource {}", allocations, e);
tx.abort();
throw e;
diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/device/impl/GossipDeviceStoreTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/device/impl/GossipDeviceStoreTest.java
index 3a168936..5cbf360a 100644
--- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/device/impl/GossipDeviceStoreTest.java
+++ b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/device/impl/GossipDeviceStoreTest.java
@@ -232,7 +232,7 @@ public class GossipDeviceStoreTest {
if (expected == actual) {
return;
}
- assertEquals(expected.deviceURI(), actual.deviceURI());
+ assertEquals(expected.deviceUri(), actual.deviceUri());
assertEquals(expected.hwVersion(), actual.hwVersion());
assertEquals(expected.manufacturer(), actual.manufacturer());
assertEquals(expected.serialNumber(), actual.serialNumber());
@@ -247,7 +247,7 @@ public class GossipDeviceStoreTest {
if (expected == actual) {
return;
}
- assertEquals(expected.deviceURI(), actual.deviceURI());
+ assertEquals(expected.deviceUri(), actual.deviceUri());
assertEquals(expected.hwVersion(), actual.hwVersion());
assertEquals(expected.manufacturer(), actual.manufacturer());
assertEquals(expected.serialNumber(), actual.serialNumber());
diff --git a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
index ccf6ee71..ef8d9924 100644
--- a/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
+++ b/framework/src/onos/core/store/dist/src/test/java/org/onosproject/store/ecmap/EventuallyConsistentMapImplTest.java
@@ -42,6 +42,7 @@ import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.NodeId;
import org.onosproject.event.AbstractEvent;
+import org.onosproject.persistence.impl.PersistenceManager;
import org.onosproject.store.Timestamp;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
@@ -81,6 +82,7 @@ public class EventuallyConsistentMapImplTest {
private EventuallyConsistentMap<String, String> ecMap;
+ private PersistenceManager persistenceService;
private ClusterService clusterService;
private ClusterCommunicationService clusterCommunicator;
private SequentialClockService<String, String> clockService;
@@ -136,6 +138,8 @@ public class EventuallyConsistentMapImplTest {
clusterCommunicator = createMock(ClusterCommunicationService.class);
+ persistenceService = new PersistenceManager();
+ persistenceService.activate();
// Add expectation for adding cluster message subscribers which
// delegate to our ClusterCommunicationService implementation. This
// allows us to get a reference to the map's internal cluster message
@@ -153,11 +157,12 @@ public class EventuallyConsistentMapImplTest {
.register(TestTimestamp.class);
ecMap = new EventuallyConsistentMapBuilderImpl<String, String>(
- clusterService, clusterCommunicator)
+ clusterService, clusterCommunicator, persistenceService)
.withName(MAP_NAME)
.withSerializer(serializer)
.withTimestampProvider((k, v) -> clockService.getTimestamp(k, v))
.withCommunicationExecutor(MoreExecutors.newDirectExecutorService())
+ .withPersistence()
.build();
// Reset ready for tests to add their own expectations
diff --git a/framework/src/onos/core/store/persistence/pom.xml b/framework/src/onos/core/store/persistence/pom.xml
index 555de11a..5692c531 100644
--- a/framework/src/onos/core/store/persistence/pom.xml
+++ b/framework/src/onos/core/store/persistence/pom.xml
@@ -50,7 +50,7 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>-->
- <dependency>
+ <dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<classifier>tests</classifier>
diff --git a/framework/src/onos/core/store/pom.xml b/framework/src/onos/core/store/pom.xml
index 219ae5d0..94c077a4 100644
--- a/framework/src/onos/core/store/pom.xml
+++ b/framework/src/onos/core/store/pom.xml
@@ -34,7 +34,7 @@
<modules>
<module>dist</module>
<module>persistence</module>
- <module>serializers</module>
+ <module>serializers</module>
</modules>
<dependencies>
diff --git a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 0312bafd..6f96498f 100644
--- a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -416,6 +416,8 @@ public final class KryoNamespaces {
BandwidthResourceAllocation.class,
LambdaResourceAllocation.class,
ResourcePath.class,
+ ResourcePath.Discrete.class,
+ ResourcePath.Continuous.class,
ResourceAllocation.class,
// Constraints
LambdaConstraint.class,
@@ -438,7 +440,7 @@ public final class KryoNamespaces {
DefaultTableStatisticsEntry.class
)
.register(new DefaultApplicationIdSerializer(), DefaultApplicationId.class)
- .register(new URISerializer(), URI.class)
+ .register(new UriSerializer(), URI.class)
.register(new NodeIdSerializer(), NodeId.class)
.register(new ProviderIdSerializer(), ProviderId.class)
.register(new DeviceIdSerializer(), DeviceId.class)
diff --git a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/URISerializer.java b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/UriSerializer.java
index 43969666..1d146a55 100644
--- a/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/URISerializer.java
+++ b/framework/src/onos/core/store/serializers/src/main/java/org/onosproject/store/serializers/UriSerializer.java
@@ -15,22 +15,22 @@
*/
package org.onosproject.store.serializers;
-import java.net.URI;
-
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
+import java.net.URI;
+
/**
* Serializer for {@link URI}.
*/
-public class URISerializer extends Serializer<URI> {
+public class UriSerializer extends Serializer<URI> {
/**
* Creates {@link URI} serializer instance.
*/
- public URISerializer() {
+ public UriSerializer() {
super(false);
}
diff --git a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
index 97ccb836..11a62d4e 100644
--- a/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
+++ b/framework/src/onos/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoSerializerTest.java
@@ -373,13 +373,13 @@ public class KryoSerializerTest {
@Test
public void testResourcePath() {
- testSerializedEquals(new ResourcePath(LinkKey.linkKey(CP1, CP2), VLAN1));
+ testSerializedEquals(ResourcePath.discrete(LinkKey.linkKey(CP1, CP2), VLAN1));
}
@Test
public void testResourceAllocation() {
testSerializedEquals(new org.onosproject.net.newresource.ResourceAllocation(
- new ResourcePath(LinkKey.linkKey(CP1, CP2), VLAN1),
+ ResourcePath.discrete(LinkKey.linkKey(CP1, CP2), VLAN1),
IntentId.valueOf(30)));
}