blob: 785613c718083a29f66859a760bd3505291ea8e1 [file] [log] [blame]
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.newresource.impl;
17
18import com.google.common.annotations.Beta;
19import com.google.common.collect.ImmutableList;
20import org.apache.felix.scr.annotations.Component;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.apache.felix.scr.annotations.Service;
24import org.onosproject.net.newresource.DefaultResource;
25import org.onosproject.net.newresource.DefaultResourceAllocation;
26import org.onosproject.net.newresource.Resource;
Sho SHIMIZU70ee1ee2015-08-06 11:11:52 -070027import org.onosproject.net.newresource.ResourceAdminService;
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -070028import org.onosproject.net.newresource.ResourceAllocation;
29import org.onosproject.net.newresource.ResourceConsumer;
30import org.onosproject.net.newresource.ResourceService;
31import org.onosproject.net.newresource.ResourceStore;
32
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.Collection;
36import java.util.List;
37import java.util.Optional;
Sho SHIMIZU70ee1ee2015-08-06 11:11:52 -070038import java.util.concurrent.ConcurrentHashMap;
39import java.util.concurrent.ConcurrentMap;
40import java.util.function.Predicate;
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -070041import java.util.stream.Collectors;
42
43import static com.google.common.base.Preconditions.checkNotNull;
44
45/**
46 * An implementation of ResourceService.
47 */
48@Component(immediate = true, enabled = false)
49@Service
50@Beta
Sho SHIMIZU70ee1ee2015-08-06 11:11:52 -070051public final class ResourceManager implements ResourceService, ResourceAdminService {
52
53 private final ConcurrentMap<Class<?>, Predicate<?>> boundaries = new ConcurrentHashMap<>();
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -070054
55 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
56 protected ResourceStore store;
57
58 @SuppressWarnings("unchecked")
59 @Override
60 public <S, T> Optional<ResourceAllocation<S, T>> allocate(ResourceConsumer consumer, Resource<S, T> resource) {
61 checkNotNull(consumer);
62 checkNotNull(resource);
63
64 List<ResourceAllocation<?, ?>> allocations = allocate(consumer, ImmutableList.of(resource));
65 if (allocations.isEmpty()) {
66 return Optional.empty();
67 }
68
69 assert allocations.size() == 1;
70
71 ResourceAllocation<?, ?> allocation = allocations.get(0);
72
73 assert allocation.subject().getClass() == resource.subject().getClass();
74 assert allocation.resource().getClass() == resource.resource().getClass();
75
76 // cast is ensured by the assertions above
77 return Optional.of((ResourceAllocation<S, T>) allocation);
78 }
79
80 @Override
81 public List<ResourceAllocation<?, ?>> allocate(ResourceConsumer consumer,
82 List<? extends Resource<?, ?>> resources) {
83 checkNotNull(consumer);
84 checkNotNull(resources);
85
86 if (resources.stream().anyMatch(x -> !isValid(x))) {
87 return ImmutableList.of();
88 }
89
90 // TODO: implement support of resource hierarchy
91 // allocation for a particular resource implies allocations for all of the sub-resources need to be done
92
93 boolean success = store.allocate(resources, consumer);
94 if (!success) {
95 return ImmutableList.of();
96 }
97
98 return resources.stream()
99 .map(x -> new DefaultResourceAllocation<>(x.subject(), x.resource(), consumer))
100 .collect(Collectors.toList());
101 }
102
103 @Override
104 public List<ResourceAllocation<?, ?>> allocate(ResourceConsumer consumer, Resource<?, ?>... resources) {
105 checkNotNull(consumer);
106 checkNotNull(resources);
107
108 return allocate(consumer, Arrays.asList(resources));
109 }
110
111 @Override
112 public <S, T> boolean release(ResourceAllocation<S, T> allocation) {
113 checkNotNull(allocation);
114
115 return release(ImmutableList.of(allocation));
116 }
117
118 @Override
119 public boolean release(List<? extends ResourceAllocation<?, ?>> allocations) {
120 checkNotNull(allocations);
121
122 List<DefaultResource<?, ?>> resources = allocations.stream()
123 .map(x -> new DefaultResource<>(x.subject(), x.resource()))
124 .collect(Collectors.toList());
125 List<ResourceConsumer> consumers = allocations.stream()
126 .map(ResourceAllocation::consumer)
127 .collect(Collectors.toList());
128
129 return store.release(resources, consumers);
130 }
131
132 @Override
133 public boolean release(ResourceAllocation<?, ?>... allocations) {
134 checkNotNull(allocations);
135
136 return release(ImmutableList.copyOf(allocations));
137 }
138
139 @Override
140 public boolean release(ResourceConsumer consumer) {
141 checkNotNull(consumer);
142
143 Collection<ResourceAllocation<?, ?>> allocations = getResourceAllocations(consumer);
144 return release(ImmutableList.copyOf(allocations));
145 }
146
147 @Override
148 public <S, T> Collection<ResourceAllocation<S, T>> getResourceAllocations(S subject, Class<T> cls) {
149 checkNotNull(subject);
150 checkNotNull(cls);
151
152 Collection<Resource<S, T>> resources = store.getAllocatedResources(subject, cls);
153 List<ResourceAllocation<S, T>> allocations = new ArrayList<>(resources.size());
154 for (Resource<S, T> resource: resources) {
155 // We access store twice in this method, then the store may be updated by others
156 Optional<ResourceConsumer> consumer = store.getConsumer(resource);
157 if (consumer.isPresent()) {
158 allocations.add(
159 new DefaultResourceAllocation<>(resource.subject(), resource.resource(), consumer.get()));
160 }
161 }
162
163 return allocations;
164 }
165
166 @Override
167 public Collection<ResourceAllocation<?, ?>> getResourceAllocations(ResourceConsumer consumer) {
168 checkNotNull(consumer);
169
170 Collection<Resource<?, ?>> resources = store.getResources(consumer);
171 return resources.stream()
172 .map(x -> new DefaultResourceAllocation<>(x.subject(), x.resource(), consumer))
173 .collect(Collectors.toList());
174 }
175
176 @Override
177 public <S, T> boolean isAvailable(Resource<S, T> resource) {
178 checkNotNull(resource);
179
180 Optional<ResourceConsumer> consumer = store.getConsumer(resource);
181 return !consumer.isPresent();
182 }
183
Sho SHIMIZU70ee1ee2015-08-06 11:11:52 -0700184 @Override
185 public <T> void defineResourceBoundary(Class<T> cls, Predicate<T> predicate) {
186 boundaries.put(cls, predicate);
187 }
188
189 /**
190 * Returns the predicate associated with the specified resource.
191 *
192 * @param resource resource whose associated predicate is to be returned
193 * @param <T> type of the resource
194 * @return predicate associated with the resource
195 * Null if the resource doesn't have an associated predicate.
196 */
197 @SuppressWarnings("unchecked")
198 private <T> Predicate<T> lookupPredicate(T resource) {
199 return (Predicate<T>) boundaries.get(resource.getClass());
200 }
201
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -0700202 /**
203 * Returns if the specified resource is in the resource range.
204 * E.g. VLAN ID against a link must be within 12 bit address space.
205 *
206 * @param resource resource to be checked if it is within the resource range
207 * @param <S> type of the subject
208 * @param <T> type of the resource
209 * @return true if the resource within the range, false otherwise
210 */
Sho SHIMIZU70ee1ee2015-08-06 11:11:52 -0700211 <S, T> boolean isValid(Resource<S, T> resource) {
212 Predicate<T> predicate = lookupPredicate(resource.resource());
213 if (predicate == null) {
214 return true;
215 }
216
217 return predicate.test(resource.resource());
Sho SHIMIZU78ee25c2015-07-16 15:54:14 -0700218 }
219}