| /* |
| * Copyright 2016-present Open Networking Foundation |
| * |
| * 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.resource; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| |
| import org.onlab.packet.MplsLabel; |
| import org.onlab.packet.VlanId; |
| import org.onlab.util.Bandwidth; |
| import org.onlab.util.Tools; |
| import org.onosproject.net.TributarySlot; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| 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; |
| |
| public class MockResourceService implements ResourceService { |
| |
| private double bandwidth = 1000.0; |
| private final Map<Resource, ResourceConsumer> assignment = new HashMap<>(); |
| public Set<Short> availableVlanLabels = new HashSet<>(); |
| public Set<Integer> availableMplsLabels = new HashSet<>(); |
| public boolean filterAssignment = false; |
| |
| public MockResourceService(){} |
| |
| // To express a custom bandwidth available (in bps) |
| public static ResourceService makeCustomBandwidthResourceService(double bandwidth) { |
| return new MockResourceService(bandwidth); |
| } |
| |
| private MockResourceService(double bandwidth) { |
| this.bandwidth = bandwidth; |
| } |
| |
| @Override |
| public List<ResourceAllocation> allocate(ResourceConsumer consumer, List<? extends Resource> resources) { |
| assignment.putAll( |
| resources.stream().collect(Collectors.toMap(Function.identity(), x -> consumer)) |
| ); |
| |
| return resources.stream() |
| .map(x -> new ResourceAllocation(x, consumer)) |
| .collect(Collectors.toList()); |
| } |
| |
| @Override |
| public boolean release(List<ResourceAllocation> allocations) { |
| allocations.forEach(x -> assignment.remove(x.resource())); |
| |
| return true; |
| } |
| |
| @Override |
| public boolean release(ResourceConsumer consumer) { |
| List<Resource> resources = assignment.entrySet().stream() |
| .filter(x -> x.getValue().equals(consumer)) |
| .map(Map.Entry::getKey) |
| .collect(Collectors.toList()); |
| List<ResourceAllocation> allocations = resources.stream() |
| .map(x -> new ResourceAllocation(x, consumer)) |
| .collect(Collectors.toList()); |
| |
| return release(allocations); |
| } |
| |
| @Override |
| public List<ResourceAllocation> getResourceAllocations(ResourceId id) { |
| if (id instanceof ContinuousResourceId) { |
| return ImmutableList.of(); |
| } |
| DiscreteResource discrete = Resources.discrete((DiscreteResourceId) id).resource(); |
| return Optional.ofNullable(assignment.get(discrete)) |
| .map(x -> ImmutableList.of(new ResourceAllocation(discrete, x))) |
| .orElse(ImmutableList.of()); |
| } |
| |
| @Override |
| public <T> Collection<ResourceAllocation> getResourceAllocations(DiscreteResourceId parent, Class<T> cls) { |
| return assignment.entrySet().stream() |
| .filter(x -> x.getKey().parent().isPresent()) |
| .filter(x -> x.getKey().parent().get().id().equals(parent)) |
| .map(x -> new ResourceAllocation(x.getKey(), x.getValue())) |
| .collect(Collectors.toList()); |
| } |
| |
| @Override |
| public Collection<ResourceAllocation> getResourceAllocations(ResourceConsumer consumer) { |
| return assignment.entrySet().stream() |
| .filter(x -> x.getValue().equals(consumer)) |
| .map(x -> new ResourceAllocation(x.getKey(), x.getValue())) |
| .collect(Collectors.toList()); |
| } |
| |
| |
| /** |
| * Binds VLAN Ids to a parent resource, given a parent resource. |
| * |
| * @param parent the parent resource |
| * @return the VLAN Ids allocated |
| */ |
| private Collection<Resource> addVlanIds(DiscreteResourceId parent) { |
| Collection<Resource> resources = new HashSet<>(); |
| if (!this.availableVlanLabels.isEmpty()) { |
| this.availableVlanLabels.forEach(label -> { |
| if (label > VlanId.NO_VID && label < VlanId.MAX_VLAN) { |
| resources.add(Resources.discrete(parent).resource().child(VlanId.vlanId(label))); |
| } |
| }); |
| } else { |
| for (int i = VlanId.NO_VID + 1; i < 1000; i++) { |
| resources.add(Resources.discrete(parent).resource().child(VlanId.vlanId((short) i))); |
| } |
| } |
| return resources; |
| } |
| |
| /** |
| * Binds MPLS labels to a parent resource, given a parent resource. |
| * |
| * @param parent the parent resource |
| * @return the MPLS labels allocated |
| */ |
| private Collection<Resource> addMplsLabels(DiscreteResourceId parent) { |
| Collection<Resource> resources = new HashSet<>(); |
| if (!this.availableMplsLabels.isEmpty()) { |
| this.availableMplsLabels.forEach(label -> { |
| if (label < MplsLabel.MAX_MPLS) { |
| resources.add(Resources.discrete(parent).resource().child(MplsLabel.mplsLabel(label))); |
| } |
| }); |
| } else { |
| for (int i = 1; i < 1000; i++) { |
| resources.add(Resources.discrete(parent).resource().child(MplsLabel.mplsLabel(i))); |
| } |
| } |
| return resources; |
| } |
| |
| @Override |
| public Set<Resource> getAvailableResources(DiscreteResourceId parent) { |
| Collection<Resource> resources = new HashSet<>(); |
| resources.addAll(addVlanIds(parent)); |
| resources.addAll(addMplsLabels(parent)); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(1))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(2))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(3))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(4))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(5))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(6))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(7))); |
| resources.add(Resources.discrete(parent).resource().child(TributarySlot.of(8))); |
| return filterAssignment ? ImmutableSet.copyOf( |
| resources.stream().filter( |
| resource -> assignment.get(resource) == null |
| ).collect(Collectors.toSet()) |
| ) : ImmutableSet.copyOf(resources); |
| } |
| |
| @Override |
| public <T> Set<Resource> getAvailableResources(DiscreteResourceId parent, Class<T> cls) { |
| return getAvailableResources(parent).stream() |
| .filter(x -> x.isTypeOf(cls)) |
| .collect(Collectors.toSet()); |
| } |
| |
| @Override |
| public <T> Set<T> getAvailableResourceValues(DiscreteResourceId parent, Class<T> cls) { |
| return getAvailableResources(parent).stream() |
| .filter(x -> x.isTypeOf(cls)) |
| .flatMap(x -> Tools.stream(x.valueAs(cls))) |
| .collect(Collectors.toSet()); |
| } |
| |
| @Override |
| public Set<Resource> getRegisteredResources(DiscreteResourceId parent) { |
| return getAvailableResources(parent); |
| } |
| |
| @Override |
| public boolean isAvailable(Resource resource) { |
| if (resource.isTypeOf(Bandwidth.class)) { |
| // If there's is enough bandwidth available return true; false otherwise |
| Optional<Double> value = resource.valueAs(Double.class); |
| return value.filter(requested -> requested <= bandwidth).isPresent(); |
| } |
| return true; |
| } |
| |
| @Override |
| public void addListener(ResourceListener listener) {} |
| |
| @Override |
| public void removeListener(ResourceListener listener) {} |
| } |