Formalize and document ConsistentResourceStore internal interfaces. This is cleanup in preparation for changes coming in ONOS-4859
Change-Id: I23077352f428d83848bee48666957a43642d3665
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
index 887b35b..79aed3b 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
@@ -37,7 +37,12 @@
import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
-class ConsistentContinuousResourceSubStore {
+
+/**
+ * Consistent substore for continuous resources.
+ */
+class ConsistentContinuousResourceSubStore implements ConsistentResourceSubStore
+ <ContinuousResourceId, ContinuousResource, TransactionalContinuousResourceSubStore> {
private ConsistentMap<ContinuousResourceId, ContinuousResourceAllocation> consumers;
private ConsistentMap<DiscreteResourceId, Set<ContinuousResource>> childMap;
@@ -54,12 +59,14 @@
childMap.put(Resource.ROOT.id(), new LinkedHashSet<>());
}
- TransactionalContinuousResourceSubStore transactional(TransactionContext tx) {
+ @Override
+ public TransactionalContinuousResourceSubStore transactional(TransactionContext tx) {
return new TransactionalContinuousResourceSubStore(tx);
}
// computational complexity: O(n) where n is the number of the existing allocations for the resource
- List<ResourceAllocation> getResourceAllocations(ContinuousResourceId resource) {
+ @Override
+ public List<ResourceAllocation> getResourceAllocations(ContinuousResourceId resource) {
Versioned<ContinuousResourceAllocation> allocations = consumers.get(resource);
if (allocations == null) {
return ImmutableList.of();
@@ -70,7 +77,8 @@
.collect(GuavaCollectors.toImmutableList());
}
- Set<ContinuousResource> getChildResources(DiscreteResourceId parent) {
+ @Override
+ public Set<ContinuousResource> getChildResources(DiscreteResourceId parent) {
Versioned<Set<ContinuousResource>> children = childMap.get(parent);
if (children == null) {
@@ -80,13 +88,15 @@
return children.value();
}
- <T> Set<ContinuousResource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
+ @Override
+ public Set<ContinuousResource> getChildResources(DiscreteResourceId parent, Class<?> cls) {
// naive implementation
return getChildResources(parent).stream()
.filter(x -> x.isTypeOf(cls))
.collect(Collectors.toCollection(LinkedHashSet::new));
}
+ @Override
public boolean isAvailable(ContinuousResource resource) {
// check if it's registered or not.
Versioned<Set<ContinuousResource>> children = childMap.get(resource.parent().get().id());
@@ -114,7 +124,8 @@
return allocation.value().hasEnoughResource(resource);
}
- <T> Stream<ContinuousResource> getAllocatedResources(DiscreteResourceId parent, Class<T> cls) {
+ @Override
+ public Stream<ContinuousResource> getAllocatedResources(DiscreteResourceId parent, Class<?> cls) {
Set<ContinuousResource> children = getChildResources(parent);
if (children.isEmpty()) {
return Stream.of();
@@ -135,7 +146,8 @@
});
}
- Stream<ContinuousResource> getResources(ResourceConsumerId consumerId) {
+ @Override
+ public Stream<ContinuousResource> getResources(ResourceConsumerId consumerId) {
return consumers.values().stream()
.flatMap(x -> x.value().allocations().stream())
.filter(x -> x.consumerId().equals(consumerId))
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
index d036c5f..738b8d1 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
@@ -35,7 +35,11 @@
import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
-class ConsistentDiscreteResourceSubStore {
+/**
+ * Consistent substore for discrete resources.
+ */
+class ConsistentDiscreteResourceSubStore implements ConsistentResourceSubStore
+ <DiscreteResourceId, DiscreteResource, TransactionalDiscreteResourceSubStore> {
private ConsistentMap<DiscreteResourceId, ResourceConsumerId> consumers;
private ConsistentMap<DiscreteResourceId, DiscreteResources> childMap;
@@ -52,12 +56,14 @@
childMap.put(Resource.ROOT.id(), DiscreteResources.empty());
}
- TransactionalDiscreteResourceSubStore transactional(TransactionContext tx) {
+ @Override
+ public TransactionalDiscreteResourceSubStore transactional(TransactionContext tx) {
return new TransactionalDiscreteResourceSubStore(tx);
}
// computational complexity: O(1)
- List<ResourceAllocation> getResourceAllocations(DiscreteResourceId resource) {
+ @Override
+ public List<ResourceAllocation> getResourceAllocations(DiscreteResourceId resource) {
Versioned<ResourceConsumerId> consumerId = consumers.get(resource);
if (consumerId == null) {
return ImmutableList.of();
@@ -66,7 +72,8 @@
return ImmutableList.of(new ResourceAllocation(Resources.discrete(resource).resource(), consumerId.value()));
}
- Set<DiscreteResource> getChildResources(DiscreteResourceId parent) {
+ @Override
+ public Set<DiscreteResource> getChildResources(DiscreteResourceId parent) {
Versioned<DiscreteResources> children = childMap.get(parent);
if (children == null) {
@@ -76,7 +83,8 @@
return children.value().values();
}
- <T> Set<DiscreteResource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
+ @Override
+ public Set<DiscreteResource> getChildResources(DiscreteResourceId parent, Class<?> cls) {
Versioned<DiscreteResources> children = childMap.get(parent);
if (children == null) {
@@ -86,11 +94,13 @@
return children.value().valuesOf(cls);
}
- boolean isAvailable(DiscreteResource resource) {
+ @Override
+ public boolean isAvailable(DiscreteResource resource) {
return getResourceAllocations(resource.id()).isEmpty();
}
- <T> Stream<DiscreteResource> getAllocatedResources(DiscreteResourceId parent, Class<T> cls) {
+ @Override
+ public Stream<DiscreteResource> getAllocatedResources(DiscreteResourceId parent, Class<?> cls) {
Set<DiscreteResource> children = getChildResources(parent);
if (children.isEmpty()) {
return Stream.of();
@@ -101,7 +111,8 @@
.filter(x -> consumers.containsKey(x.id()));
}
- Stream<DiscreteResource> getResources(ResourceConsumerId consumerId) {
+ @Override
+ public Stream<DiscreteResource> getResources(ResourceConsumerId consumerId) {
return consumers.entrySet().stream()
.filter(x -> x.getValue().value().equals(consumerId))
.map(Map.Entry::getKey)
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
index 70c9b5b..9d040f5 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
@@ -15,6 +15,17 @@
*/
package org.onosproject.store.resource.impl;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Activate;
@@ -46,17 +57,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.resource.ResourceEvent.Type.RESOURCE_ADDED;
@@ -249,11 +249,11 @@
ResourceConsumerId consumerId = allocation.consumerId();
if (resource instanceof DiscreteResource) {
- if (!discreteTxStore.release((DiscreteResource) resource, consumerId)) {
+ if (!discreteTxStore.release(consumerId, (DiscreteResource) resource)) {
return abortTransaction(tx);
}
} else if (resource instanceof ContinuousResource) {
- if (!continuousTxStore.release((ContinuousResource) resource, consumerId)) {
+ if (!continuousTxStore.release(consumerId, (ContinuousResource) resource)) {
return abortTransaction(tx);
}
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceSubStore.java
new file mode 100644
index 0000000..89ac7f7
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceSubStore.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2017-present 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.store.resource.impl;
+
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceConsumerId;
+import org.onosproject.net.resource.ResourceId;
+import org.onosproject.store.service.TransactionContext;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+/**
+ * Interface for consistent resource substores.
+ */
+interface ConsistentResourceSubStore
+ <T extends ResourceId, U extends Resource, V extends TransactionalResourceSubStore> {
+
+ /**
+ * Returns a new transactional substore.
+ *
+ * @param tx the transaction context
+ * @return a transactional resource substore
+ */
+ V transactional(TransactionContext tx);
+
+ /**
+ * Returns a list of resource allocations for the given resource ID.
+ *
+ * @param resourceId the resource ID
+ * @return a list of resource allocations for the given ID
+ */
+ List<ResourceAllocation> getResourceAllocations(T resourceId);
+
+ /**
+ * Returns a set of child resources for the given discrete resource.
+ *
+ * @param resourceId the parent resource ID
+ * @return a set of child resources for the given discrete parent
+ */
+ Set<U> getChildResources(DiscreteResourceId resourceId);
+
+ /**
+ * Returns a set of child resources cast to the given type.
+ *
+ * @param resourceId the parent resource ID
+ * @param type the type to which to cast resources
+ * @return a set of child resources for the given discrete parent
+ */
+ Set<U> getChildResources(DiscreteResourceId resourceId, Class<?> type);
+
+ /**
+ * Returns a boolean indicating whether the given resource is available.
+ *
+ * @param resource the resource to check
+ * @return indicates whether the given resource is available
+ */
+ boolean isAvailable(U resource);
+
+ /**
+ * Returns a stream of allocated resources for the given parent.
+ *
+ * @param parent the parent resource ID for which to return allocated resources
+ * @param type the type to which to cast allocated resources
+ * @return a stream of allocated resources for the given parent
+ */
+ Stream<U> getAllocatedResources(DiscreteResourceId parent, Class<?> type);
+
+ /**
+ * Returns a stream of resources for the given consumer.
+ *
+ * @param consumerId the consumer ID for which to return resources
+ * @return a stream of resources for the given consumer
+ */
+ Stream<U> getResources(ResourceConsumerId consumerId);
+
+}
\ No newline at end of file
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalContinuousResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalContinuousResourceSubStore.java
index a875608..bf15461 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalContinuousResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalContinuousResourceSubStore.java
@@ -35,7 +35,11 @@
import static com.google.common.base.Preconditions.checkArgument;
import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
-class TransactionalContinuousResourceSubStore {
+/**
+ * Transactional substore for continuous resources.
+ */
+class TransactionalContinuousResourceSubStore
+ implements TransactionalResourceSubStore<ContinuousResourceId, ContinuousResource> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final TransactionalMap<DiscreteResourceId, Set<ContinuousResource>> childMap;
private final TransactionalMap<ContinuousResourceId, ContinuousResourceAllocation> consumers;
@@ -46,7 +50,8 @@
}
// iterate over the values in the set: O(n) operation
- Optional<ContinuousResource> lookup(ContinuousResourceId id) {
+ @Override
+ public Optional<ContinuousResource> lookup(ContinuousResourceId id) {
// continuous resource always has its parent
checkArgument(id.parent().isPresent());
@@ -60,7 +65,8 @@
.findFirst();
}
- boolean register(DiscreteResourceId parent, Set<ContinuousResource> resources) {
+ @Override
+ public boolean register(DiscreteResourceId parent, Set<ContinuousResource> resources) {
// short-circuit: receiving empty resource is regarded as success
if (resources.isEmpty()) {
return true;
@@ -92,7 +98,8 @@
return childMap.replace(parent, oldValues, newValues);
}
- boolean unregister(DiscreteResourceId parent, Set<ContinuousResource> resources) {
+ @Override
+ public boolean unregister(DiscreteResourceId parent, Set<ContinuousResource> resources) {
// short-circuit: receiving empty resource is regarded as success
if (resources.isEmpty()) {
return true;
@@ -123,12 +130,14 @@
return childMap.replace(parent, oldValues, newValues);
}
- private boolean isAllocated(ContinuousResourceId id) {
+ @Override
+ public boolean isAllocated(ContinuousResourceId id) {
ContinuousResourceAllocation allocations = consumers.get(id);
return allocations != null && !allocations.allocations().isEmpty();
}
- boolean allocate(ResourceConsumerId consumerId, ContinuousResource request) {
+ @Override
+ public boolean allocate(ResourceConsumerId consumerId, ContinuousResource request) {
// if the resource is not registered, then abort
Optional<ContinuousResource> lookedUp = lookup(request.id());
if (!lookedUp.isPresent()) {
@@ -159,7 +168,8 @@
return consumers.replace(original.id(), oldValue, newValue);
}
- boolean release(ContinuousResource resource, ResourceConsumerId consumerId) {
+ @Override
+ public boolean release(ResourceConsumerId consumerId, ContinuousResource resource) {
ContinuousResourceAllocation oldAllocation = consumers.get(resource.id());
ContinuousResourceAllocation newAllocation = oldAllocation.release(resource, consumerId);
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
index 600f73d..199fc34 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
@@ -15,6 +15,9 @@
*/
package org.onosproject.store.resource.impl;
+import java.util.Optional;
+import java.util.Set;
+
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.DiscreteResourceId;
import org.onosproject.net.resource.Resource;
@@ -24,12 +27,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Optional;
-import java.util.Set;
-
import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
-class TransactionalDiscreteResourceSubStore {
+/**
+ * Transactional substore for discrete resources.
+ */
+class TransactionalDiscreteResourceSubStore
+ implements TransactionalResourceSubStore<DiscreteResourceId, DiscreteResource> {
private final Logger log = LoggerFactory.getLogger(getClass());
private final TransactionalMap<DiscreteResourceId, DiscreteResources> childMap;
private final TransactionalMap<DiscreteResourceId, ResourceConsumerId> consumers;
@@ -40,7 +44,8 @@
}
// check the existence in the set: O(1) operation
- Optional<DiscreteResource> lookup(DiscreteResourceId id) {
+ @Override
+ public Optional<DiscreteResource> lookup(DiscreteResourceId id) {
if (!id.parent().isPresent()) {
return Optional.of(Resource.ROOT);
}
@@ -53,7 +58,8 @@
return values.lookup(id);
}
- boolean register(DiscreteResourceId parent, Set<DiscreteResource> resources) {
+ @Override
+ public boolean register(DiscreteResourceId parent, Set<DiscreteResource> resources) {
// short-circuit: receiving empty resource is regarded as success
if (resources.isEmpty()) {
return true;
@@ -76,7 +82,8 @@
return childMap.replace(parent, oldValues, newValues);
}
- boolean unregister(DiscreteResourceId parent, Set<DiscreteResource> resources) {
+ @Override
+ public boolean unregister(DiscreteResourceId parent, Set<DiscreteResource> resources) {
// short-circuit: receiving empty resource is regarded as success
if (resources.isEmpty()) {
return true;
@@ -107,11 +114,13 @@
return childMap.replace(parent, oldValues, newValues);
}
- private boolean isAllocated(DiscreteResourceId id) {
+ @Override
+ public boolean isAllocated(DiscreteResourceId id) {
return consumers.get(id) != null;
}
- boolean allocate(ResourceConsumerId consumerId, DiscreteResource resource) {
+ @Override
+ public boolean allocate(ResourceConsumerId consumerId, DiscreteResource resource) {
// if the resource is not registered, then abort
Optional<DiscreteResource> lookedUp = lookup(resource.id());
if (!lookedUp.isPresent()) {
@@ -122,13 +131,10 @@
return oldValue == null;
}
- boolean release(DiscreteResource resource, ResourceConsumerId consumerId) {
+ @Override
+ public boolean release(ResourceConsumerId consumerId, DiscreteResource resource) {
// if this single release fails (because the resource is allocated to another consumer)
// the whole release fails
- if (!consumers.remove(resource.id(), consumerId)) {
- return false;
- }
-
- return true;
+ return consumers.remove(resource.id(), consumerId);
}
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalResourceSubStore.java
new file mode 100644
index 0000000..796e1c6
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalResourceSubStore.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017-present 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.store.resource.impl;
+
+import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceConsumerId;
+import org.onosproject.net.resource.ResourceId;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Interface for transaction resource substores.
+ */
+interface TransactionalResourceSubStore<T extends ResourceId, U extends Resource> {
+
+ /**
+ * Reads the given resource from the substore.
+ *
+ * @param resourceId the resource ID
+ * @return an optional containing the resource if it exists
+ */
+ Optional<U> lookup(T resourceId);
+
+ /**
+ * Registers the given set of resources for the given parent.
+ *
+ * @param parent the parent for which to register the resources
+ * @param resources the resources to register
+ * @return indicates whether the registration was successful
+ */
+ boolean register(DiscreteResourceId parent, Set<U> resources);
+
+ /**
+ * Unregisters the given set of resources for the given parent.
+ *
+ * @param parent the parent for which to unregister the resources
+ * @param resources the resources to register
+ * @return indicates whether the unregistration was successful
+ */
+ boolean unregister(DiscreteResourceId parent, Set<U> resources);
+
+ /**
+ * Returns a boolean indicating whether the given resource is allocated.
+ *
+ * @param resourceId the resource ID
+ * @return indicates whether the given resource is allocated
+ */
+ boolean isAllocated(T resourceId);
+
+ /**
+ * Allocates the given resource for the given consumer.
+ *
+ * @param consumerId the consumer ID
+ * @param resource the resource
+ * @return indicates whether the allocation was successful
+ */
+ boolean allocate(ResourceConsumerId consumerId, U resource);
+
+ /**
+ * Releases the given resource from the given consumer.
+ *
+ * @param consumerId the consumer ID
+ * @param resource the resource
+ * @return indicates whether the release was successful
+ */
+ boolean release(ResourceConsumerId consumerId, U resource);
+
+}
\ No newline at end of file