Java tutorial
/* * Copyright 2016-present 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.icona.domainmgr.impl; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Reference; import org.onlab.util.Identifier; import org.onlab.util.KryoNamespace; import org.onosproject.icona.domainmgr.api.DomainId; import org.onosproject.icona.domainmgr.api.DomainEvent; import org.onosproject.icona.domainmgr.api.DomainStore; import org.onosproject.icona.domainmgr.api.DomainStoreDelegate; import org.onosproject.net.DeviceId; import org.onosproject.net.HostId; import org.onosproject.net.PortNumber; import org.onosproject.net.Link; import org.onosproject.net.ConnectPoint; import org.onosproject.store.AbstractStore; import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.StorageService; import org.onosproject.store.service.DistributedSet; import org.onosproject.store.service.ConsistentMap; import org.onosproject.store.service.SetEventListener; import org.onosproject.store.service.SetEvent; import org.onosproject.store.service.Serializer; import org.slf4j.Logger; import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.onosproject.icona.domainmgr.api.DomainEvent.Type; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static org.onosproject.icona.domainmgr.api.DomainEvent.Type.DOMAIN_ADDED; import static org.onosproject.icona.domainmgr.api.DomainEvent.Type.DOMAIN_REMOVED; import static org.slf4j.LoggerFactory.getLogger; /** * Distributed domain store implementation. */ @Component(immediate = true) @Service public class DistributedDomainStore extends AbstractStore<DomainEvent, DomainStoreDelegate> implements DomainStore { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected StorageService storageService; private final Logger log = getLogger(getClass()); private DistributedSet<DomainId> domainIds; private final SetEventListener<DomainId> domainIdSetEventListener = new InternalMapListener(); private ConsistentMap<DomainId, Set<DeviceId>> domainIdDeviceIdsConsistentMap; private Map<DomainId, Set<DeviceId>> domainIdDeviceIdsMap; private ConsistentMap<DomainId, Set<HostId>> domainIdHostsIdsConsistentMap; private Map<DomainId, Set<HostId>> domainIdHostIdsMap; private ConsistentMap<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetConsistentMap; private Map<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetMap; private ConsistentMap<DeviceId, Map<PortNumber, ConnectPoint>> virtualPortToLocalHostConsistentMap; private Map<DeviceId, Map<PortNumber, ConnectPoint>> virtualPortToLocalHostMap; private static final Serializer SERIALIZER = Serializer .using(new KryoNamespace.Builder().register(KryoNamespaces.API).register(Identifier.class) .register(DomainId.class).register(ImmutablePair.class).build()); @Activate public void activate() { domainIds = storageService.<DomainId>setBuilder().withSerializer(SERIALIZER).withName("onos-domainId") .withRelaxedReadConsistency().build().asDistributedSet(); domainIds.addListener(domainIdSetEventListener); domainIdDeviceIdsConsistentMap = storageService.<DomainId, Set<DeviceId>>consistentMapBuilder() .withSerializer(SERIALIZER).withName("onos-domain-device-ids").withRelaxedReadConsistency().build(); domainIdDeviceIdsMap = domainIdDeviceIdsConsistentMap.asJavaMap(); domainIdHostsIdsConsistentMap = storageService.<DomainId, Set<HostId>>consistentMapBuilder() .withSerializer(SERIALIZER).withName("onos-domain-host-ids").withRelaxedReadConsistency().build(); domainIdHostIdsMap = domainIdHostsIdsConsistentMap.asJavaMap(); domainIdLinkSetConsistentMap = storageService.<Pair<DomainId, DomainId>, Set<Link>>consistentMapBuilder() .withSerializer(SERIALIZER).withName("onos-domain-links").withRelaxedReadConsistency().build(); domainIdLinkSetMap = domainIdLinkSetConsistentMap.asJavaMap(); virtualPortToLocalHostConsistentMap = storageService .<DeviceId, Map<PortNumber, ConnectPoint>>consistentMapBuilder().withSerializer(SERIALIZER) .withName("onos-virtual-port-host-mapping").withRelaxedReadConsistency().build(); virtualPortToLocalHostMap = virtualPortToLocalHostConsistentMap.asJavaMap(); log.info("Started"); } @Deactivate public void deactivate() { domainIds.removeListener(domainIdSetEventListener); log.info("Stopped"); } @Override public Set<DomainId> getDomainIds() { return ImmutableSet.copyOf(domainIds); } @Override public Set<DeviceId> getDeviceIds(DomainId domainId) { checkState(domainExists(domainId), "Domain id unknown"); return ImmutableSet.copyOf(domainIdDeviceIdsMap.get(domainId)); } @Override public void addDomain(DomainId domainId) { domainIds.add(domainId); } @Override public void removeDomain(DomainId domainId) { domainIds.remove(domainId); clear(domainId); } @Override public void addDevice(DomainId domainId, DeviceId deviceId) { checkState(domainExists(domainId), "Domain id unknown"); domainIdDeviceIdsMap.compute(domainId, (k, set) -> { if (set == null) { set = new HashSet<>(); } set.add(deviceId); return set; }); } @Override public void removeDevice(DomainId domainId, DeviceId deviceId) { checkState(domainExists(domainId), "Domain id unknown"); domainIdDeviceIdsMap.computeIfPresent(domainId, (k, existingSet) -> { if (existingSet.contains(deviceId)) { existingSet.remove(deviceId); return existingSet; } else { return existingSet; } }); } @Override public Set<HostId> getHostIds(DomainId domainId) { checkState(domainExists(domainId), "Domain id unknown"); return ImmutableSet.copyOf(domainIdHostIdsMap.get(domainId)); } @Override public void addHost(DomainId domainId, HostId hostId) { checkState(domainExists(domainId), "Domain id unknown"); domainIdHostIdsMap.compute(domainId, (k, set) -> { if (set == null) { set = new HashSet<>(); } set.add(hostId); return set; }); } @Override public void removeHost(DomainId domainId, HostId hostId) { checkState(domainExists(domainId), "Domain id unknown"); domainIdHostIdsMap.computeIfPresent(domainId, (k, existingSet) -> { if (existingSet.contains(hostId)) { existingSet.remove(hostId); return existingSet; } else { return existingSet; } }); } @Override public Set<Link> getInterLinks(Pair<DomainId, DomainId> endDomains) { checkState(domainExists(endDomains.getLeft()), "Domain id unknown"); checkState(domainExists(endDomains.getRight()), "Domain id unknown"); return ImmutableSet.copyOf(domainIdLinkSetMap.get(endDomains)); } @Override public void addOrUpdateInterLink(Pair<DomainId, DomainId> endDomains, Link link) { checkState(domainExists(endDomains.getLeft()), "Domain id unknown"); checkState(domainExists(endDomains.getRight()), "Domain id unknown"); domainIdLinkSetMap.compute(endDomains, (k, set) -> { if (set == null) { set = new HashSet<>(); } set.add(link); return set; }); } @Override public void removeInterLink(Pair<DomainId, DomainId> endDomains, Link link) { checkState(domainExists(endDomains.getLeft()), "Domain id unknown"); checkState(domainExists(endDomains.getRight()), "Domain id unknown"); domainIdLinkSetMap.computeIfPresent(endDomains, (k, existingSet) -> { if (existingSet.contains(link)) { existingSet.remove(link); return existingSet; } else { return existingSet; } }); } @Override public void setVirtualPortToPortMapping(DeviceId deviceId, Map<PortNumber, ConnectPoint> map) { virtualPortToLocalHostMap.put(deviceId, map); } @Override public Map<PortNumber, ConnectPoint> getVirtualPortToPortMapping(DeviceId deviceId) { return ImmutableMap.copyOf(virtualPortToLocalHostMap.get(deviceId)); } private void clear(DomainId domainId) { Set<Pair<DomainId, DomainId>> domainPairs = new HashSet<>(); // find all domains connected with the one to be removed and remove related links domainIdLinkSetMap.keySet().forEach(endDomains -> { if (endDomains.getLeft().equals(domainId) || endDomains.getRight().equals(domainId)) { domainPairs.add(endDomains); } }); domainPairs.forEach(pair -> domainIdLinkSetMap.remove(pair)); domainIdDeviceIdsMap.remove(domainId); domainIdHostIdsMap.remove(domainId); } private class InternalMapListener implements SetEventListener<DomainId> { @Override public void event(SetEvent<DomainId> event) { Type type; switch (event.type()) { case ADD: type = DOMAIN_ADDED; break; case REMOVE: type = DOMAIN_REMOVED; break; default: log.error("Unsupported event type: " + event.type()); return; } notifyDelegate(new DomainEvent(type, event.entry())); } } private boolean domainExists(DomainId domainId) { checkNotNull(domainId, "domain identifier is null"); return domainIds.contains(domainId); } }