ONOS-1793  Moved trivial stores to onos-core-common/src/test; onos-core-trivial is no longer.

Change-Id: Ie4824db36e3a7eb6db3b953ee1f2786d3e22194f
diff --git a/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java b/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
new file mode 100644
index 0000000..58b446c
--- /dev/null
+++ b/core/common/src/test/java/org/onosproject/store/trivial/SimpleLinkResourceStore.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2014-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.store.trivial;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.Service;
+import org.onlab.util.Bandwidth;
+import org.onlab.util.PositionalParameterStringFormatter;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Link;
+import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.resource.link.BandwidthResource;
+import org.onosproject.net.resource.link.BandwidthResourceAllocation;
+import org.onosproject.net.resource.link.LambdaResource;
+import org.onosproject.net.resource.link.LambdaResourceAllocation;
+import org.onosproject.net.resource.link.LinkResourceAllocations;
+import org.onosproject.net.resource.link.LinkResourceEvent;
+import org.onosproject.net.resource.link.LinkResourceStore;
+import org.onosproject.net.resource.ResourceAllocation;
+import org.onosproject.net.resource.ResourceAllocationException;
+import org.onosproject.net.resource.ResourceType;
+import org.slf4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages link resources using trivial in-memory structures implementation.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleLinkResourceStore implements LinkResourceStore {
+    private static final BandwidthResource DEFAULT_BANDWIDTH = new BandwidthResource(Bandwidth.mbps(1_000));
+    private final Logger log = getLogger(getClass());
+
+    private Map<IntentId, LinkResourceAllocations> linkResourceAllocationsMap;
+    private Map<Link, Set<LinkResourceAllocations>> allocatedResources;
+    private Map<Link, Set<ResourceAllocation>> freeResources;
+
+    @Activate
+    public void activate() {
+        linkResourceAllocationsMap = new HashMap<>();
+        allocatedResources = new HashMap<>();
+        freeResources = new HashMap<>();
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    /**
+     * Returns free resources for a given link obtaining from topology
+     * information.
+     *
+     * @param link the target link
+     * @return free resources
+     */
+    private synchronized Set<ResourceAllocation> readOriginalFreeResources(Link link) {
+        Annotations annotations = link.annotations();
+        Set<ResourceAllocation> allocations = new HashSet<>();
+
+        try {
+            int waves = Integer.parseInt(annotations.value(AnnotationKeys.OPTICAL_WAVES));
+            for (int i = 1; i <= waves; i++) {
+                allocations.add(new LambdaResourceAllocation(LambdaResource.valueOf(i)));
+            }
+        } catch (NumberFormatException e) {
+            log.debug("No optical.wave annotation on link %s", link);
+        }
+
+        BandwidthResource bandwidth = DEFAULT_BANDWIDTH;
+        try {
+            bandwidth = new BandwidthResource(
+                    Bandwidth.mbps((Double.parseDouble(annotations.value(AnnotationKeys.BANDWIDTH)))));
+        } catch (NumberFormatException e) {
+            log.debug("No bandwidth annotation on link %s", link);
+        }
+        allocations.add(
+                new BandwidthResourceAllocation(bandwidth));
+        return allocations;
+    }
+
+    /**
+     * Finds and returns {@link BandwidthResourceAllocation} object from a given
+     * set.
+     *
+     * @param freeRes a set of ResourceAllocation object.
+     * @return {@link BandwidthResourceAllocation} object if found, otherwise
+     *         {@link BandwidthResourceAllocation} object with 0 bandwidth
+     *
+     */
+    private synchronized BandwidthResourceAllocation getBandwidth(
+            Set<ResourceAllocation> freeRes) {
+        for (ResourceAllocation res : freeRes) {
+            if (res.type() == ResourceType.BANDWIDTH) {
+                return (BandwidthResourceAllocation) res;
+            }
+        }
+        return new BandwidthResourceAllocation(new BandwidthResource(Bandwidth.bps(0)));
+    }
+
+    /**
+     * Subtracts given resources from free resources for given link.
+     *
+     * @param link the target link
+     * @param allocations the resources to be subtracted
+     */
+    private synchronized void subtractFreeResources(Link link,
+            LinkResourceAllocations allocations) {
+        // TODO Use lock or version for updating freeResources.
+        checkNotNull(link);
+        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+        Set<ResourceAllocation> subRes = allocations.getResourceAllocation(link);
+        for (ResourceAllocation res : subRes) {
+            switch (res.type()) {
+            case BANDWIDTH:
+                BandwidthResourceAllocation ba = getBandwidth(freeRes);
+                double requestedBandwidth =
+                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+                double newBandwidth = ba.bandwidth().toDouble() - requestedBandwidth;
+                if (newBandwidth < 0.0) {
+                    throw new ResourceAllocationException(
+                            PositionalParameterStringFormatter.format(
+                            "Unable to allocate bandwidth for link {} "
+                            + "requested amount is {} current allocation is {}",
+                                    link,
+                                    requestedBandwidth,
+                                    ba));
+                }
+                freeRes.remove(ba);
+                freeRes.add(new BandwidthResourceAllocation(
+                        new BandwidthResource(Bandwidth.bps(newBandwidth))));
+                break;
+            case LAMBDA:
+                final boolean lambdaAvailable = freeRes.remove(res);
+                if (!lambdaAvailable) {
+                    int requestedLambda =
+                            ((LambdaResourceAllocation) res).lambda().toInt();
+                    throw new ResourceAllocationException(
+                            PositionalParameterStringFormatter.format(
+                                    "Unable to allocate lambda for link {} lambda is {}",
+                                    link,
+                                    requestedLambda));
+                }
+                break;
+            default:
+                break;
+            }
+        }
+        freeResources.put(link, freeRes);
+
+    }
+
+    /**
+     * Adds given resources to free resources for given link.
+     *
+     * @param link the target link
+     * @param allocations the resources to be added
+     */
+    private synchronized void addFreeResources(Link link,
+            LinkResourceAllocations allocations) {
+        // TODO Use lock or version for updating freeResources.
+        Set<ResourceAllocation> freeRes = new HashSet<>(getFreeResources(link));
+        Set<ResourceAllocation> addRes = allocations.getResourceAllocation(link);
+        for (ResourceAllocation res : addRes) {
+            switch (res.type()) {
+            case BANDWIDTH:
+                BandwidthResourceAllocation ba = getBandwidth(freeRes);
+                double requestedBandwidth =
+                        ((BandwidthResourceAllocation) res).bandwidth().toDouble();
+                double newBandwidth = ba.bandwidth().toDouble() + requestedBandwidth;
+                freeRes.remove(ba);
+                freeRes.add(new BandwidthResourceAllocation(
+                        new BandwidthResource(Bandwidth.bps(newBandwidth))));
+                break;
+            case LAMBDA:
+                checkState(freeRes.add(res));
+                break;
+            default:
+                break;
+            }
+        }
+        freeResources.put(link, freeRes);
+    }
+
+    @Override
+    public synchronized Set<ResourceAllocation> getFreeResources(Link link) {
+        checkNotNull(link);
+        Set<ResourceAllocation> freeRes = freeResources.get(link);
+        if (freeRes == null) {
+            freeRes = readOriginalFreeResources(link);
+        }
+
+        return freeRes;
+    }
+
+    @Override
+    public synchronized void allocateResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+        linkResourceAllocationsMap.put(allocations.intentId(), allocations);
+        for (Link link : allocations.links()) {
+            subtractFreeResources(link, allocations);
+            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+            if (linkAllocs == null) {
+                linkAllocs = new HashSet<>();
+            }
+            linkAllocs.add(allocations);
+            allocatedResources.put(link, linkAllocs);
+        }
+    }
+
+    @Override
+    public synchronized LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+        linkResourceAllocationsMap.remove(allocations.intentId());
+        for (Link link : allocations.links()) {
+            addFreeResources(link, allocations);
+            Set<LinkResourceAllocations> linkAllocs = allocatedResources.get(link);
+            if (linkAllocs == null) {
+                log.error("Missing resource allocation.");
+            } else {
+                linkAllocs.remove(allocations);
+            }
+            allocatedResources.put(link, linkAllocs);
+        }
+
+        final List<LinkResourceAllocations> releasedResources =
+                ImmutableList.of(allocations);
+
+        return new LinkResourceEvent(
+                LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
+                releasedResources);
+    }
+
+    @Override
+    public synchronized LinkResourceAllocations getAllocations(IntentId intentId) {
+        checkNotNull(intentId);
+        return linkResourceAllocationsMap.get(intentId);
+    }
+
+    @Override
+    public synchronized Iterable<LinkResourceAllocations> getAllocations(Link link) {
+        checkNotNull(link);
+        Set<LinkResourceAllocations> result = allocatedResources.get(link);
+        if (result == null) {
+            result = Collections.emptySet();
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    @Override
+    public synchronized Iterable<LinkResourceAllocations> getAllocations() {
+        return Collections.unmodifiableCollection(linkResourceAllocationsMap.values());
+    }
+
+
+}