Sho SHIMIZU
Committed by Gerrit Code Review

ONOS-2692: Implement methods to unregister resources

Change-Id: Iae88207c5edecf6645aeff3c15875178b5266634
...@@ -48,4 +48,28 @@ public interface ResourceAdminService { ...@@ -48,4 +48,28 @@ public interface ResourceAdminService {
48 * succeeds when each resource is not registered or unallocated. 48 * succeeds when each resource is not registered or unallocated.
49 */ 49 */
50 <T> boolean registerResources(ResourcePath parent, List<T> children); 50 <T> boolean registerResources(ResourcePath parent, List<T> children);
51 +
52 + /**
53 + * Unregister resources as the children of the parent resource path.
54 + *
55 + * @param parent parent resource path under which the resource are unregistered
56 + * @param children resources to be unregistered as the children of the parent
57 + * @param <T> type of resources
58 + * @return true if unregistration is successfully done, false otherwise. Unregistration
59 + * succeeds when each resource is not registered or unallocated.
60 + */
61 + default <T> boolean unregisterResources(ResourcePath parent, T... children) {
62 + return unregisterResources(parent, Arrays.asList(children));
63 + }
64 +
65 + /**
66 + * Unregister resources as the children of the parent resource path.
67 + *
68 + * @param parent parent resource path under which the resource are unregistered
69 + * @param children resources to be unregistered as the children of the parent
70 + * @param <T> type of resources
71 + * @return true if unregistration is successfully done, false otherwise. Unregistration
72 + * succeeds when each resource is not registered or unallocated.
73 + */
74 + <T> boolean unregisterResources(ResourcePath parent, List<T> children);
51 } 75 }
......
...@@ -25,6 +25,18 @@ public interface ResourceStore { ...@@ -25,6 +25,18 @@ public interface ResourceStore {
25 boolean register(ResourcePath parent, List<ResourcePath> children); 25 boolean register(ResourcePath parent, List<ResourcePath> children);
26 26
27 /** 27 /**
28 + * Unregisters the resources as children of the parent resource in transactional way.
29 + * The state after completion of this method is all the resources are unregistered,
30 + * or no resource is unregistered. The whole unregistration fails when any one of the
31 + * resource can't be unregistered.
32 + *
33 + * @param parent resource which is the parent of the resource to be unregistered
34 + * @param children resources to be unregistered
35 + * @return true if the registration succeeds, false otherwise
36 + */
37 + boolean unregister(ResourcePath parent, List<ResourcePath> children);
38 +
39 + /**
28 * Allocates the specified resources to the specified consumer in transactional way. 40 * Allocates the specified resources to the specified consumer in transactional way.
29 * The state after completion of this method is all the resources are allocated to the consumer, 41 * The state after completion of this method is all the resources are allocated to the consumer,
30 * or no resource is allocated to the consumer. The whole allocation fails when any one of 42 * or no resource is allocated to the consumer. The whole allocation fails when any one of
......
...@@ -130,4 +130,10 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ ...@@ -130,4 +130,10 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
130 List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x)); 130 List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
131 return store.register(parent, resources); 131 return store.register(parent, resources);
132 } 132 }
133 +
134 + @Override
135 + public <T> boolean unregisterResources(ResourcePath parent, List<T> children) {
136 + List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
137 + return store.unregister(parent, resources);
138 + }
133 } 139 }
......
...@@ -121,6 +121,37 @@ public class ConsistentResourceStore implements ResourceStore { ...@@ -121,6 +121,37 @@ public class ConsistentResourceStore implements ResourceStore {
121 } 121 }
122 122
123 @Override 123 @Override
124 + public boolean unregister(ResourcePath resource, List<ResourcePath> children) {
125 + checkNotNull(resource);
126 + checkNotNull(children);
127 +
128 + TransactionContext tx = service.transactionContextBuilder().build();
129 + tx.begin();
130 +
131 + try {
132 + TransactionalMap<ResourcePath, List<ResourcePath>> childTxMap =
133 + tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
134 + TransactionalMap<ResourcePath, ResourceConsumer> consumerTxMap =
135 + tx.getTransactionalMap(CONSUMER_MAP, SERIALIZER);
136 +
137 + // even if one of the resources is allocated to a consumer,
138 + // all unregistrations are regarded as failure
139 + if (children.stream().anyMatch(x -> consumerTxMap.get(x) != null)) {
140 + return abortTransaction(tx);
141 + }
142 +
143 + if (!removeValues(childTxMap, resource, children)) {
144 + return abortTransaction(tx);
145 + }
146 +
147 + return commitTransaction(tx);
148 + } catch (TransactionException e) {
149 + log.error("Exception thrown, abort the transaction", e);
150 + return abortTransaction(tx);
151 + }
152 + }
153 +
154 + @Override
124 public boolean allocate(List<ResourcePath> resources, ResourceConsumer consumer) { 155 public boolean allocate(List<ResourcePath> resources, ResourceConsumer consumer) {
125 checkNotNull(resources); 156 checkNotNull(resources);
126 checkNotNull(consumer); 157 checkNotNull(consumer);
...@@ -260,6 +291,30 @@ public class ConsistentResourceStore implements ResourceStore { ...@@ -260,6 +291,30 @@ public class ConsistentResourceStore implements ResourceStore {
260 } 291 }
261 292
262 /** 293 /**
294 + * Removes teh values from the existing values associated with the specified key.
295 + *
296 + * @param map map holding multiple values for a key
297 + * @param key key specifying values
298 + * @param values values to be removed
299 + * @param <K> type of the key
300 + * @param <V> type of the element of the list
301 + * @return true if the operation succeeds, false otherwise
302 + */
303 + private <K, V> boolean removeValues(TransactionalMap<K, List<V>> map, K key, List<V> values) {
304 + List<V> oldValues = map.get(key);
305 + List<V> newValues;
306 + if (oldValues == null) {
307 + newValues = new ArrayList<>();
308 + } else {
309 + LinkedHashSet<V> newSet = new LinkedHashSet<>(oldValues);
310 + newSet.removeAll(values);
311 + newValues = new ArrayList<>(newSet);
312 + }
313 +
314 + return map.replace(key, oldValues, newValues);
315 + }
316 +
317 + /**
263 * Checks if the specified resource is registered as a child of a resource in the map. 318 * Checks if the specified resource is registered as a child of a resource in the map.
264 * 319 *
265 * @param map map storing parent - child relationship of resources 320 * @param map map storing parent - child relationship of resources
......