diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/hz/STxMap.java b/core/store/dist/src/main/java/org/onlab/onos/store/hz/STxMap.java
new file mode 100644
index 0000000..0f2737a
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/hz/STxMap.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2014 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.onlab.onos.store.hz;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.onlab.onos.store.serializers.StoreSerializer;
+
+import com.hazelcast.core.TransactionalMap;
+import com.hazelcast.query.Predicate;
+
+// TODO: implement Predicate, etc. if we need them.
+/**
+ * Wrapper around TransactionalMap&lt;byte[], byte[]&gt; which serializes/deserializes
+ * key and value using StoreSerializer.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ */
+public class STxMap<K, V> implements TransactionalMap<K, V> {
+
+    private final TransactionalMap<byte[], byte[]> m;
+    private final StoreSerializer serializer;
+
+    /**
+     * Creates a STxMap instance.
+     *
+     * @param baseMap base IMap to use
+     * @param serializer serializer to use for both key and value
+     */
+    public STxMap(TransactionalMap<byte[], byte[]> baseMap, StoreSerializer serializer) {
+        this.m = checkNotNull(baseMap);
+        this.serializer = checkNotNull(serializer);
+    }
+
+    @Override
+    public int size() {
+        return m.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return m.isEmpty();
+    }
+
+    @Deprecated
+    @Override
+    public Object getId() {
+        return m.getId();
+    }
+
+    @Override
+    public String getPartitionKey() {
+        return m.getPartitionKey();
+    }
+
+    @Override
+    public String getName() {
+        return m.getName();
+    }
+
+    @Override
+    public String getServiceName() {
+        return m.getServiceName();
+    }
+
+    @Override
+    public void destroy() {
+        m.destroy();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return m.containsKey(serializeKey(key));
+    }
+
+    @Override
+    public V get(Object key) {
+        return deserializeVal(m.get(serializeKey(key)));
+    }
+
+    @Override
+    public V getForUpdate(Object key) {
+        // TODO Auto-generated method stub
+        return deserializeVal(m.getForUpdate(serializeKey(key)));
+    }
+
+    @Override
+    public V put(K key, V value) {
+        return deserializeVal(m.put(serializeKey(key), serializeVal(value)));
+    }
+
+    @Override
+    public V remove(Object key) {
+        return deserializeVal(m.remove(serializeKey(key)));
+    }
+
+    @Override
+    public boolean remove(Object key, Object value) {
+        return m.remove(serializeKey(key), serializeVal(value));
+    }
+
+    @Override
+    public void delete(Object key) {
+        m.delete(serializeKey(key));
+    }
+
+    @Override
+    public V put(K key, V value, long ttl, TimeUnit timeunit) {
+        return deserializeVal(m.put(serializeKey(key), serializeVal(value), ttl, timeunit));
+    }
+
+    @Override
+    public V putIfAbsent(K key, V value) {
+        return deserializeVal(m.putIfAbsent(serializeKey(key), serializeVal(value)));
+    }
+
+    @Override
+    public boolean replace(K key, V oldValue, V newValue) {
+        return m.replace(serializeKey(key), serializeVal(oldValue), serializeVal(newValue));
+    }
+
+    @Override
+    public V replace(K key, V value) {
+        return deserializeVal(m.replace(serializeKey(key), serializeVal(value)));
+    }
+
+    @Override
+    public void set(K key, V value) {
+        m.set(serializeKey(key), serializeVal(value));
+    }
+
+
+    @Override
+    public Set<K> keySet() {
+        return deserializeKeySet(m.keySet());
+    }
+
+    @Override
+    public Collection<V> values() {
+        return deserializeVals(m.values());
+    }
+
+    @Deprecated // marking method not implemented
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Set<K> keySet(Predicate predicate) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated // marking method not implemented
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Collection<V> values(Predicate predicate) {
+        throw new UnsupportedOperationException();
+    }
+
+    private byte[] serializeKey(Object key) {
+        return serializer.encode(key);
+    }
+
+    private K deserializeKey(byte[] key) {
+        return serializer.decode(key);
+    }
+
+    private byte[] serializeVal(Object val) {
+        return serializer.encode(val);
+    }
+
+    private V deserializeVal(byte[] val) {
+        if (val == null) {
+            return null;
+        }
+        return serializer.decode(val.clone());
+    }
+
+    private Set<K> deserializeKeySet(Set<byte[]> keys) {
+        Set<K> dsk = new HashSet<>(keys.size());
+        for (byte[] key : keys) {
+            dsk.add(deserializeKey(key));
+        }
+        return dsk;
+    }
+
+    private Collection<V> deserializeVals(Collection<byte[]> vals) {
+        Collection<V> dsl = new ArrayList<>(vals.size());
+        for (byte[] val : vals) {
+            dsl.add(deserializeVal(val));
+        }
+        return dsl;
+    }
+}
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStore.java
new file mode 100644
index 0000000..4729a84
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStore.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2014 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.onlab.onos.store.resource.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.LinkKey;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.resource.Bandwidth;
+import org.onlab.onos.net.resource.BandwidthResourceAllocation;
+import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceEvent;
+import org.onlab.onos.net.resource.LinkResourceStore;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceType;
+import org.onlab.onos.store.StoreDelegate;
+import org.onlab.onos.store.hz.AbstractHazelcastStore;
+import org.onlab.onos.store.hz.STxMap;
+import org.slf4j.Logger;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.hazelcast.core.TransactionalMap;
+import com.hazelcast.transaction.TransactionContext;
+import com.hazelcast.transaction.TransactionException;
+import com.hazelcast.transaction.TransactionOptions;
+import com.hazelcast.transaction.TransactionOptions.TransactionType;
+
+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 Hazelcast.
+ */
+@Component(immediate = true, enabled = false)
+@Service
+public class HazelcastLinkResourceStore
+    extends AbstractHazelcastStore<LinkResourceEvent, StoreDelegate<LinkResourceEvent>>
+    implements LinkResourceStore {
+
+
+    private final Logger log = getLogger(getClass());
+
+    // FIXME: what is the Bandwidth unit?
+    private static final Bandwidth DEFAULT_BANDWIDTH = Bandwidth.valueOf(1_000);
+
+    private static final Bandwidth EMPTY_BW = Bandwidth.valueOf(0);
+
+    // table to store current allocations
+    /** LinkKey -> List<LinkResourceAllocations>. */
+    private static final String LINK_RESOURCE_ALLOCATIONS = "LinkResourceAllocations";
+
+    /** IntentId -> LinkResourceAllocations. */
+    private static final String INTENT_ALLOCATIONS = "IntentAllocations";
+
+
+    // TODO make this configurable
+    // number of retries to attempt on allocation failure, due to
+    // concurrent update
+    private static int maxAllocateRetries = 5;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    // Link annotation key name to use as bandwidth
+    private String bandwidthAnnotation = "bandwidth";
+    // Link annotation key name to use as max lambda
+    private String wavesAnnotation = "optical.waves";
+
+    @Override
+    @Activate
+    public void activate() {
+        super.activate();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    private STxMap<IntentId, LinkResourceAllocations> getIntentAllocs(TransactionContext tx) {
+        TransactionalMap<byte[], byte[]> raw = tx.getMap(INTENT_ALLOCATIONS);
+        return new STxMap<>(raw, serializer);
+    }
+
+    private STxMap<LinkKey, List<LinkResourceAllocations>> getLinkAllocs(TransactionContext tx) {
+        TransactionalMap<byte[], byte[]> raw = tx.getMap(LINK_RESOURCE_ALLOCATIONS);
+        return new STxMap<>(raw, serializer);
+    }
+
+    private Set<? extends ResourceAllocation> getResourceCapacity(ResourceType type, Link link) {
+        // TODO: plugin/provider mechanism to add resource type in the future?
+        if (type == ResourceType.BANDWIDTH) {
+            return ImmutableSet.of(getBandwidthResourceCapacity(link));
+        }
+        if (type == ResourceType.LAMBDA) {
+            return getLambdaResourceCapacity(link);
+        }
+        return null;
+    }
+
+    private Set<LambdaResourceAllocation> getLambdaResourceCapacity(Link link) {
+        // FIXME enumerate all the possible link/port lambdas
+        Set<LambdaResourceAllocation> allocations = new HashSet<>();
+        try {
+            final int waves = Integer.parseInt(link.annotations().value(wavesAnnotation));
+            for (int i = 1; i <= waves; i++) {
+                allocations.add(new LambdaResourceAllocation(Lambda.valueOf(i)));
+            }
+        } catch (NumberFormatException e) {
+            log.debug("No {} annotation on link %s", wavesAnnotation, link);
+        }
+        return allocations;
+    }
+
+    private BandwidthResourceAllocation getBandwidthResourceCapacity(Link link) {
+
+        // if Link annotation exist, use them
+        // if all fails, use DEFAULT_BANDWIDTH
+
+        Bandwidth bandwidth = null;
+        String strBw = link.annotations().value(bandwidthAnnotation);
+        if (strBw != null) {
+            try {
+                bandwidth = Bandwidth.valueOf(Double.parseDouble(strBw));
+            } catch (NumberFormatException e) {
+                // do nothings
+                bandwidth = null;
+            }
+        }
+
+        if (bandwidth == null) {
+            // fall back, use fixed default
+            bandwidth = DEFAULT_BANDWIDTH;
+        }
+        return new BandwidthResourceAllocation(bandwidth);
+    }
+
+    private Map<ResourceType, Set<? extends ResourceAllocation>> getResourceCapacity(Link link) {
+        Map<ResourceType, Set<? extends ResourceAllocation>> caps = new HashMap<>();
+        for (ResourceType type : ResourceType.values()) {
+            Set<? extends ResourceAllocation> cap = getResourceCapacity(type, link);
+            if (cap != null) {
+                caps.put(type, cap);
+            }
+        }
+        return caps;
+    }
+
+    @Override
+    public Set<ResourceAllocation> getFreeResources(Link link) {
+        Map<ResourceType, Set<? extends ResourceAllocation>> freeResources = getFreeResourcesEx(link);
+        Set<ResourceAllocation> allFree = new HashSet<>();
+        for (Set<? extends ResourceAllocation> r:freeResources.values()) {
+            allFree.addAll(r);
+        }
+        return allFree;
+    }
+
+    private Map<ResourceType, Set<? extends ResourceAllocation>> getFreeResourcesEx(Link link) {
+        // returns capacity - allocated
+
+        checkNotNull(link);
+        Map<ResourceType, Set<? extends ResourceAllocation>> free = new HashMap<>();
+        final Map<ResourceType, Set<? extends ResourceAllocation>> caps = getResourceCapacity(link);
+        final Iterable<LinkResourceAllocations> allocations = getAllocations(link);
+
+        for (ResourceType type : ResourceType.values()) {
+            // there should be class/category of resources
+            switch (type) {
+            case BANDWIDTH:
+            {
+                Set<? extends ResourceAllocation> bw = caps.get(ResourceType.BANDWIDTH);
+                if (bw == null || bw.isEmpty()) {
+                    bw = Sets.newHashSet(new BandwidthResourceAllocation(EMPTY_BW));
+                }
+
+                BandwidthResourceAllocation cap = (BandwidthResourceAllocation) bw.iterator().next();
+                double freeBw = cap.bandwidth().toDouble();
+
+                // enumerate current allocations, subtracting resources
+                for (LinkResourceAllocations alloc : allocations) {
+                    Set<ResourceAllocation> types = alloc.getResourceAllocation(link);
+                    for (ResourceAllocation a : types) {
+                        if (a instanceof BandwidthResourceAllocation) {
+                            BandwidthResourceAllocation bwA = (BandwidthResourceAllocation) a;
+                            freeBw -= bwA.bandwidth().toDouble();
+                        }
+                    }
+                }
+
+                free.put(type, Sets.newHashSet(new BandwidthResourceAllocation(Bandwidth.valueOf(freeBw))));
+                break;
+            }
+
+            case LAMBDA:
+            {
+                Set<? extends ResourceAllocation> lmd = caps.get(type);
+                if (lmd == null || lmd.isEmpty()) {
+                    // nothing left
+                    break;
+                }
+                Set<LambdaResourceAllocation> freeL = new HashSet<>();
+                for (ResourceAllocation r : lmd) {
+                    if (r instanceof LambdaResourceAllocation) {
+                        freeL.add((LambdaResourceAllocation) r);
+                    }
+                }
+
+                // enumerate current allocations, removing resources
+                for (LinkResourceAllocations alloc : allocations) {
+                    Set<ResourceAllocation> types = alloc.getResourceAllocation(link);
+                    for (ResourceAllocation a : types) {
+                        if (a instanceof LambdaResourceAllocation) {
+                            freeL.remove(a);
+                        }
+                    }
+                }
+
+                free.put(type, freeL);
+                break;
+            }
+
+            default:
+                break;
+            }
+        }
+        return free;
+    }
+
+    @Override
+    public void allocateResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+
+        for (int i = 0; i < maxAllocateRetries; ++i) {
+            TransactionContext tx = theInstance.newTransactionContext();
+            tx.beginTransaction();
+            try {
+
+                STxMap<IntentId, LinkResourceAllocations> intentAllocs = getIntentAllocs(tx);
+                // should this be conditional write?
+                intentAllocs.put(allocations.intendId(), allocations);
+
+                for (Link link : allocations.links()) {
+                    allocateLinkResource(tx, link, allocations);
+                }
+
+                tx.commitTransaction();
+                return;
+            } catch (TransactionException e) {
+                log.debug("Failed to commit allocations for {}. [retry={}]",
+                          allocations.intendId(), i);
+                log.trace(" details {} ", allocations, e);
+                continue;
+            } catch (Exception e) {
+                log.error("Exception thrown, rolling back", e);
+                tx.rollbackTransaction();
+                throw e;
+            }
+        }
+    }
+
+    private void allocateLinkResource(TransactionContext tx, Link link,
+                                      LinkResourceAllocations allocations) {
+
+        // requested resources
+        Set<ResourceAllocation> reqs = allocations.getResourceAllocation(link);
+
+        Map<ResourceType, Set<? extends ResourceAllocation>> available = getFreeResourcesEx(link);
+        for (ResourceAllocation req : reqs) {
+            Set<? extends ResourceAllocation> avail = available.get(req.type());
+            if (req instanceof BandwidthResourceAllocation) {
+                // check if allocation should be accepted
+                if (avail.isEmpty()) {
+                    checkState(!avail.isEmpty(),
+                               "There's no Bandwidth resource on %s?",
+                               link);
+                }
+                BandwidthResourceAllocation bw = (BandwidthResourceAllocation) avail.iterator().next();
+                double bwLeft = bw.bandwidth().toDouble();
+                bwLeft -= ((BandwidthResourceAllocation) req).bandwidth().toDouble();
+                if (bwLeft < 0) {
+                    // FIXME throw appropriate Exception
+                    checkState(bwLeft >= 0,
+                               "There's no Bandwidth left on %s. %s",
+                               link, bwLeft);
+                }
+            } else if (req instanceof LambdaResourceAllocation) {
+
+                // check if allocation should be accepted
+                if (!avail.contains(req)) {
+                    // requested lambda was not available
+                    // FIXME throw appropriate exception
+                    checkState(avail.contains(req),
+                               "Allocating %s on %s failed",
+                               req, link);
+                }
+            }
+        }
+        // all requests allocatable => add allocation
+        final LinkKey linkKey = LinkKey.linkKey(link);
+        STxMap<LinkKey, List<LinkResourceAllocations>> linkAllocs = getLinkAllocs(tx);
+        final List<LinkResourceAllocations> before = linkAllocs.get(linkKey);
+        List<LinkResourceAllocations> after = new ArrayList<>(before.size() + 1);
+        after.addAll(before);
+        after.add(allocations);
+        linkAllocs.replace(linkKey, before, after);
+    }
+
+    @Override
+    public LinkResourceEvent releaseResources(LinkResourceAllocations allocations) {
+        checkNotNull(allocations);
+
+        final IntentId intendId = allocations.intendId();
+        final Collection<Link> links = allocations.links();
+
+        boolean success = false;
+        do {
+            // TODO: smaller tx unit to lower the chance of collisions?
+            TransactionContext tx = theInstance.newTransactionContext();
+            tx.beginTransaction();
+            try {
+                STxMap<IntentId, LinkResourceAllocations> intentAllocs = getIntentAllocs(tx);
+                intentAllocs.remove(intendId);
+
+                STxMap<LinkKey, List<LinkResourceAllocations>> linkAllocs = getLinkAllocs(tx);
+
+                for (Link link : links) {
+                    final LinkKey linkId = LinkKey.linkKey(link);
+
+                    List<LinkResourceAllocations> before = linkAllocs.get(linkId);
+                    if (before == null || before.isEmpty()) {
+                        // something is wrong, but it is already freed
+                        log.warn("There was no resource left to release on {}", linkId);
+                        continue;
+                    }
+                    List<LinkResourceAllocations> after = new ArrayList<>(before);
+                    after.remove(allocations);
+                    linkAllocs.replace(linkId, before, after);
+                }
+
+                tx.commitTransaction();
+                success = true;
+            } catch (TransactionException e) {
+                log.debug("Transaction failed, retrying");
+            } catch (Exception e) {
+                log.error("Exception thrown during releaseResource {}",
+                          allocations, e);
+                tx.rollbackTransaction();
+                throw e;
+            }
+        } while (!success);
+
+        // Issue events to force recompilation of intents.
+        final List<LinkResourceAllocations> releasedResources =
+                ImmutableList.of(allocations);
+        return new LinkResourceEvent(
+                LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
+                releasedResources);
+    }
+
+    @Override
+    public LinkResourceAllocations getAllocations(IntentId intentId) {
+        checkNotNull(intentId);
+        TransactionOptions opt = new TransactionOptions();
+        // read-only and will never be commited, thus does not need durability
+        opt.setTransactionType(TransactionType.LOCAL);
+        TransactionContext tx = theInstance.newTransactionContext(opt);
+        tx.beginTransaction();
+        try {
+            STxMap<IntentId, LinkResourceAllocations> intentAllocs = getIntentAllocs(tx);
+            return intentAllocs.get(intentId);
+        } finally {
+            tx.rollbackTransaction();
+        }
+    }
+
+    @Override
+    public List<LinkResourceAllocations> getAllocations(Link link) {
+        checkNotNull(link);
+        final LinkKey key = LinkKey.linkKey(link);
+
+        TransactionOptions opt = new TransactionOptions();
+        // read-only and will never be commited, thus does not need durability
+        opt.setTransactionType(TransactionType.LOCAL);
+        TransactionContext tx = theInstance.newTransactionContext(opt);
+        tx.beginTransaction();
+        List<LinkResourceAllocations> res = null;
+        try {
+            STxMap<LinkKey, List<LinkResourceAllocations>> linkAllocs = getLinkAllocs(tx);
+            res = linkAllocs.get(key);
+        } finally {
+            tx.rollbackTransaction();
+        }
+
+        if (res == null) {
+            // try to add empty list
+            TransactionContext tx2 = theInstance.newTransactionContext();
+            tx2.beginTransaction();
+            try {
+                res = getLinkAllocs(tx2).putIfAbsent(key, new ArrayList<>());
+                tx2.commitTransaction();
+                if (res == null) {
+                    return Collections.emptyList();
+                } else {
+                    return res;
+                }
+            } catch (TransactionException e) {
+                // concurrently added?
+                return getAllocations(link);
+            } catch (Exception e) {
+                tx.rollbackTransaction();
+            }
+        }
+        return res;
+
+    }
+
+    @Override
+    public Iterable<LinkResourceAllocations> getAllocations() {
+        TransactionContext tx = theInstance.newTransactionContext();
+        tx.beginTransaction();
+        try {
+            STxMap<IntentId, LinkResourceAllocations> intentAllocs = getIntentAllocs(tx);
+            return intentAllocs.values();
+        } finally {
+            tx.rollbackTransaction();
+        }
+    }
+}
diff --git a/core/store/dist/src/test/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStoreTest.java b/core/store/dist/src/test/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStoreTest.java
new file mode 100644
index 0000000..b6c63a7
--- /dev/null
+++ b/core/store/dist/src/test/java/org/onlab/onos/store/resource/impl/HazelcastLinkResourceStoreTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2014 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.onlab.onos.store.resource.impl;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.onos.net.AnnotationKeys;
+import org.onlab.onos.net.Annotations;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.DefaultAnnotations;
+import org.onlab.onos.net.DefaultLink;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.net.resource.Bandwidth;
+import org.onlab.onos.net.resource.BandwidthResourceAllocation;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceStore;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceType;
+import org.onlab.onos.store.hz.StoreService;
+import org.onlab.onos.store.hz.TestStoreManager;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.core.Hazelcast;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.Link.Type.DIRECT;
+import static org.onlab.onos.net.PortNumber.portNumber;
+
+/**
+ * Test of the simple LinkResourceStore implementation.
+ */
+public class HazelcastLinkResourceStoreTest {
+
+    private LinkResourceStore store;
+    private HazelcastLinkResourceStore storeImpl;
+    private Link link1;
+    private Link link2;
+    private Link link3;
+    private TestStoreManager storeMgr;
+
+    /**
+     * Returns {@link Link} object.
+     *
+     * @param dev1 source device
+     * @param port1 source port
+     * @param dev2 destination device
+     * @param port2 destination port
+     * @return created {@link Link} object
+     */
+    private Link newLink(String dev1, int port1, String dev2, int port2) {
+        Annotations annotations = DefaultAnnotations.builder()
+                .set(AnnotationKeys.OPTICAL_WAVES, "80")
+                .set(AnnotationKeys.BANDWIDTH, "1000000")
+                .build();
+        return new DefaultLink(
+                new ProviderId("of", "foo"),
+                new ConnectPoint(deviceId(dev1), portNumber(port1)),
+                new ConnectPoint(deviceId(dev2), portNumber(port2)),
+                DIRECT, annotations);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+
+        Config config = TestStoreManager.getTestConfig();
+
+        storeMgr = new TestStoreManager(Hazelcast.newHazelcastInstance(config));
+        storeMgr.activate();
+
+
+        storeImpl = new TestHazelcastLinkResourceStore(storeMgr);
+        storeImpl.activate();
+        store = storeImpl;
+
+        link1 = newLink("of:1", 1, "of:2", 2);
+        link2 = newLink("of:2", 1, "of:3", 2);
+        link3 = newLink("of:3", 1, "of:4", 2);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        storeImpl.deactivate();
+
+        storeMgr.deactivate();
+    }
+
+    /**
+     * Tests constructor and activate method.
+     */
+    @Test
+    public void testConstructorAndActivate() {
+        final Iterable<LinkResourceAllocations> allAllocations = store.getAllocations();
+        assertNotNull(allAllocations);
+        assertFalse(allAllocations.iterator().hasNext());
+
+        final Iterable<LinkResourceAllocations> linkAllocations =
+                store.getAllocations(link1);
+        assertNotNull(linkAllocations);
+        assertFalse(linkAllocations.iterator().hasNext());
+
+        final Set<ResourceAllocation> res = store.getFreeResources(link2);
+        assertNotNull(res);
+    }
+
+    /**
+     * Picks up and returns one of bandwidth allocations from a given set.
+     *
+     * @param resources the set of {@link ResourceAllocation}s
+     * @return {@link BandwidthResourceAllocation} object if found, null
+     *         otherwise
+     */
+    private BandwidthResourceAllocation getBandwidthObj(Set<ResourceAllocation> resources) {
+        for (ResourceAllocation res : resources) {
+            if (res.type() == ResourceType.BANDWIDTH) {
+                return ((BandwidthResourceAllocation) res);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns all lambda allocations from a given set.
+     *
+     * @param resources the set of {@link ResourceAllocation}s
+     * @return a set of {@link LambdaResourceAllocation} objects
+     */
+    private Set<LambdaResourceAllocation> getLambdaObjs(Set<ResourceAllocation> resources) {
+        Set<LambdaResourceAllocation> lambdaResources = new HashSet<>();
+        for (ResourceAllocation res : resources) {
+            if (res.type() == ResourceType.LAMBDA) {
+                lambdaResources.add((LambdaResourceAllocation) res);
+            }
+        }
+        return lambdaResources;
+    }
+
+    /**
+     * Tests initial free bandwidth for a link.
+     */
+    @Test
+    public void testInitialBandwidth() {
+        final Set<ResourceAllocation> freeRes = store.getFreeResources(link1);
+        assertNotNull(freeRes);
+
+        final BandwidthResourceAllocation alloc = getBandwidthObj(freeRes);
+        assertNotNull(alloc);
+
+        assertEquals(Bandwidth.valueOf(1000000.0), alloc.bandwidth());
+    }
+
+    /**
+     * Tests initial free lambda for a link.
+     */
+    @Test
+    public void testInitialLambdas() {
+        final Set<ResourceAllocation> freeRes = store.getFreeResources(link3);
+        assertNotNull(freeRes);
+
+        final Set<LambdaResourceAllocation> res = getLambdaObjs(freeRes);
+        assertNotNull(res);
+        assertEquals(80, res.size());
+    }
+
+    public static final class TestHazelcastLinkResourceStore
+            extends HazelcastLinkResourceStore {
+
+        public TestHazelcastLinkResourceStore(StoreService storeMgr) {
+            super.storeService = storeMgr;
+        }
+
+    }
+}
