/*
* Copyright (c) 2015 Huawei Technologies and others. All rights reserved.
- *
+ *
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-
+import java.util.concurrent.Executor;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.faas.uln.datastore.api.Pair;
import org.opendaylight.faas.uln.datastore.api.UlnDatastoreApi;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.PolicyRuleGroupWithEndpointConstraints;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.resolved.policy.policy.rule.group.with.endpoint.constraints.PolicyRuleGroup;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
-public class FaasPolicyManager implements DataChangeListener, AutoCloseable {
+public class FaasPolicyManager implements DataTreeChangeListener<ResolvedPolicy>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(FaasPolicyManager.class);
private static final RendererName rendererName = new RendererName("faas");
- private final ListenerRegistration<DataChangeListener> registerListener;
- private final ScheduledExecutorService executor;
+ private final ListenerRegistration<?> registerListener;
+ private final Executor executor;
private final DataBroker dataProvider;
- private final Map<Pair<EndpointGroupId, TenantId>, List<SubnetId>> epgSubnetsMap = new HashMap<>();
+ final Map<Pair<EndpointGroupId, TenantId>, List<SubnetId>> epgSubnetsMap = new HashMap<>();
private final ConcurrentHashMap<TenantId, Uuid> mappedTenants = new ConcurrentHashMap<>();
- private final ConcurrentHashMap<TenantId, ArrayList<ListenerRegistration<DataChangeListener>>> registeredTenants = new ConcurrentHashMap<TenantId, ArrayList<ListenerRegistration<DataChangeListener>>>();
+ final ConcurrentHashMap<TenantId, ArrayList<ListenerRegistration<?>>> registeredTenants =
+ new ConcurrentHashMap<>();
- public FaasPolicyManager(DataBroker dataBroker, ScheduledExecutorService executor) {
+ public FaasPolicyManager(DataBroker dataBroker, Executor executor) {
this.dataProvider = dataBroker;
this.executor = executor;
- this.registerListener = checkNotNull(dataProvider).registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(ResolvedPolicies.class).child(ResolvedPolicy.class).build(), this,
- AsyncDataBroker.DataChangeScope.SUBTREE);
+ this.registerListener = checkNotNull(dataProvider).registerDataTreeChangeListener(new DataTreeIdentifier<>(
+ LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(ResolvedPolicies.class)
+ .child(ResolvedPolicy.class).build()), this);
RendererBuilder rendBuilder = new RendererBuilder();
rendBuilder.setName(rendererName);
@Override
public void close() throws Exception {
synchronized (registeredTenants) {
- for (ArrayList<ListenerRegistration<DataChangeListener>> list : registeredTenants.values()) {
- for (ListenerRegistration<DataChangeListener> reg : list) {
- reg.close();
- }
+ for (ArrayList<ListenerRegistration<?>> list : registeredTenants.values()) {
+ list.forEach(ListenerRegistration::close);
}
registeredTenants.clear();
LOG.debug("Closed All Tenant Registerations");
}
- if (registerListener != null)
+ if (registerListener != null) {
registerListener.close();
+ }
}
@Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- executor.execute(new Runnable() {
-
- public void run() {
- executeEvent(change);
- }
- });
+ public void onDataTreeChanged(Collection<DataTreeModification<ResolvedPolicy>> changes) {
+ executor.execute(() -> executeEvent(changes));
}
- private void executeEvent(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
- // Create
- for (DataObject dao : change.getCreatedData().values()) {
- if (dao instanceof ResolvedPolicy) {
- ResolvedPolicy newPolicy = (ResolvedPolicy) dao;
- if (handledPolicy(newPolicy)) {
- LOG.debug("Created Policy: Consumer EPG {}, Provider EPG {}", newPolicy.getConsumerEpgId(),
- newPolicy.getProviderEpgId());
- updateLogicalNetwork(newPolicy);
- }
- }
- }
- // Update
- Map<InstanceIdentifier<?>, DataObject> d = change.getUpdatedData();
- for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : d.entrySet()) {
- if (entry.getValue() instanceof ResolvedPolicy) {
- ResolvedPolicy newPolicy = (ResolvedPolicy) entry.getValue();
- ResolvedPolicy oldPolicy = (ResolvedPolicy) change.getOriginalData().get(entry.getKey());
- if (!isEqualService(newPolicy, oldPolicy)) {
- removeLogicalNetwork(oldPolicy);
- }
- if (handledPolicy(newPolicy)) {
- LOG.debug("Updated Policy: Consumer EPG {}, Provider EPG {}", newPolicy.getConsumerEpgId(),
- newPolicy.getProviderEpgId());
- updateLogicalNetwork(newPolicy);
- }
- }
- }
+ private void executeEvent(final Collection<DataTreeModification<ResolvedPolicy>> changes) {
+ for (DataTreeModification<ResolvedPolicy> change: changes) {
+ DataObjectModification<ResolvedPolicy> rootNode = change.getRootNode();
+ ResolvedPolicy oldPolicy = rootNode.getDataBefore();
+ switch (rootNode.getModificationType()) {
+ case SUBTREE_MODIFIED:
+ case WRITE:
+ ResolvedPolicy newPolicy = rootNode.getDataAfter();
+ if (!isEqualService(newPolicy, oldPolicy)) {
+ removeLogicalNetwork(oldPolicy);
+ }
- // Remove
- for (InstanceIdentifier<?> iid : change.getRemovedPaths()) {
- DataObject old = change.getOriginalData().get(iid);
- if (old != null && old instanceof ResolvedPolicy) {
- ResolvedPolicy oldPolicy = (ResolvedPolicy) old;
- LOG.debug("Removed Policy: Consumer EPG {}, Provider EPG {}", oldPolicy.getConsumerEpgId(),
- oldPolicy.getProviderEpgId());
- removeLogicalNetwork(oldPolicy);
+ if (handledPolicy(newPolicy)) {
+ LOG.debug("Updated Policy: Consumer EPG {}, Provider EPG {}", newPolicy.getConsumerEpgId(),
+ newPolicy.getProviderEpgId());
+ updateLogicalNetwork(newPolicy);
+ }
+ break;
+ case DELETE:
+ LOG.debug("Removed Policy: Consumer EPG {}, Provider EPG {}", oldPolicy.getConsumerEpgId(),
+ oldPolicy.getProviderEpgId());
+ removeLogicalNetwork(oldPolicy);
+ break;
+ default:
+ break;
}
}
}
/*
* tenant registrations
*/
- ArrayList<ListenerRegistration<DataChangeListener>> list = new ArrayList<ListenerRegistration<DataChangeListener>>();
- ListenerRegistration<DataChangeListener> reg;
+ ArrayList<ListenerRegistration<?>> list = new ArrayList<>();
+ ListenerRegistration<?> reg;
// contracts
- reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractWildcardIid(gbpTenantId), faasContractManagerListener, DataChangeScope.SUBTREE);
+ reg = dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<>(
+ LogicalDatastoreType.CONFIGURATION, IidFactory.contractWildcardIid(gbpTenantId)),
+ faasContractManagerListener);
list.add(reg);
// subnets
- reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- IidFactory.subnetWildcardIid(gbpTenantId), faasSubnetManagerListener, DataChangeScope.SUBTREE);
+ reg = dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<>(
+ LogicalDatastoreType.CONFIGURATION, IidFactory.subnetWildcardIid(gbpTenantId)),
+ faasSubnetManagerListener);
list.add(reg);
// tenant
- reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- IidFactory.tenantIid(gbpTenantId), new FaasTenantManagerListener(this, gbpTenantId, faasTenantId,
- executor), DataChangeScope.BASE);
+ reg = dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<>(
+ LogicalDatastoreType.CONFIGURATION, IidFactory.tenantIid(gbpTenantId)),
+ new FaasTenantManagerListener(this, gbpTenantId, faasTenantId, executor));
list.add(reg);
// Map previously resolved policy for this tenant
if (!resolvedPoliciesOptional.isPresent() || resolvedPoliciesOptional.get().getResolvedPolicy() == null) {
return;
}
+ //TODO forEach possible?
List<ResolvedPolicy> resolvedPolicies = resolvedPoliciesOptional.get().getResolvedPolicy();
for (ResolvedPolicy policy : resolvedPolicies) {
if (policy.getConsumerTenantId().equals(gbpTenantId)) {
}
}
- private void registerFollowedEndpointgroup(TenantId gbpTenantId, EndpointGroupId epgId) {
+ @VisibleForTesting
+ void registerFollowedEndpointgroup(TenantId gbpTenantId, EndpointGroupId epgId) {
if (epgId == null) {
return;
}
if (val != null) {
return val;
}
- Uuid faasTenantId = null;
+ Uuid faasTenantId;
if (isUUid(tenantId.getValue())) {
faasTenantId = new Uuid(tenantId.getValue());
} else {
}
public static boolean isUUid(String value) {
- return (value != null && value.matches("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"));
+ return value != null && value.matches("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}");
}
public void unregisterTenant(TenantId tenantId) {
- ArrayList<ListenerRegistration<DataChangeListener>> list = registeredTenants.remove(tenantId);
+ ArrayList<ListenerRegistration<?>> list = registeredTenants.remove(tenantId);
if (list != null) {
- for (ListenerRegistration<DataChangeListener> reg : list) {
- reg.close();
+ for (ListenerRegistration<?> reg : list) {
+ if (reg != null) {
+ reg.close();
+ }
}
LOG.debug("Unregistered tenant {}", tenantId);
}
return registeredTenants.containsKey(tenantId);
}
- private boolean handledPolicy(ResolvedPolicy policy) {
+ @VisibleForTesting
+ boolean handledPolicy(ResolvedPolicy policy) {
if (!policy.getConsumerTenantId().equals(policy.getProviderTenantId())) {
// FAAS always assumes consumer and provider EPGs belong to the same tenant
LOG.warn(
policy.getConsumerTenantId().getValue(), policy.getProviderTenantId().getValue());
return false;
}
- if (!isTenantRegistered(policy.getConsumerTenantId())) {
- return false;
- }
- return true;
+ return isTenantRegistered(policy.getConsumerTenantId());
}
private boolean isEqualService(ResolvedPolicy newPolicy, ResolvedPolicy oldPolicy) {
private void registerSubnetWithEpg(EndpointGroupId epgId, TenantId tenantId, SubnetId subnetId, boolean updateLn) {
synchronized (this) {
List<SubnetId> subnets = cloneAndGetEpgSubnets(epgId, tenantId);
- for (SubnetId id : subnets) {
- if (id.equals(subnetId)) {
- return;
- }
+ if(subnets.contains(subnetId)){
+ return;
}
subnets.add(subnetId);
epgSubnetsMap.put(new Pair<>(epgId, tenantId), subnets);
}
}
- private void removeLogicalNetwork(ResolvedPolicy oldPolicy) {
+ @VisibleForTesting
+ void removeLogicalNetwork(ResolvedPolicy oldPolicy) {
if (oldPolicy == null) {
return;
}
}
}
- private void createLayer3LogicalNetwork(EndpointGroup consEpg, ContractId contractId, EndpointGroup provEpg,
+ protected void createLayer3LogicalNetwork(EndpointGroup consEpg, ContractId contractId, EndpointGroup provEpg,
TenantId gbpTenantId, ServiceCommunicationLayer comLayer, ExternalImplicitGroup externalImplicitGroup) {
LOG.trace("Start createLayer3LogicalNetwork: Consumer EPG {} Provider Epg {} Contract {}", consEpg.getId()
.getValue(), provEpg.getId().getValue(), contractId);
LogicalRouterBuilder provLR = initLogicalRouterBuilder(provEpg, faasTenantId,
isProviderPublic(externalImplicitGroup));
- if (!UlnDatastoreApi.attachAndSubmitToDs(consLR, provLR, new Pair<Uuid, Uuid>(null, privateSecRulesId), null)) {
+ if (!UlnDatastoreApi.attachAndSubmitToDs(consLR, provLR, new Pair<>(null, privateSecRulesId), null)) {
LOG.error("Failed to join Logical Routers in a Logical Network");
return;
}
contractId.getValue(), provEpg.getId().getValue());
}
- private void createLayer2LogicalNetwork(EndpointGroup consEpg, ContractId contractId, EndpointGroup provEpg,
+ protected void createLayer2LogicalNetwork(EndpointGroup consEpg, ContractId contractId, EndpointGroup provEpg,
TenantId gbpTenantId, ServiceCommunicationLayer comLayer, ExternalImplicitGroup externalImplicitGroup) {
LOG.trace("Start createLayer2LogicalNetwork: Consumer EPG {} Provider Epg {} Contract {}", consEpg.getId()
.getValue(), provEpg.getId().getValue(), contractId);
return null;
}
- private Uuid getFaasSecRulesId(ContractId contractId, TenantId gbpTenantId) {
+ protected Uuid getFaasSecRulesId(ContractId contractId, TenantId gbpTenantId) {
if (contractId != null) {
Optional<MappedContract> mContractOp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
FaasIidFactory.mappedContractIid(gbpTenantId, contractId),
LogicalRouterBuilder builder = new LogicalRouterBuilder();
builder.setAdminStateUp(true);
builder.setName(new Text(epg.getId().getValue()));
- if (epg.getDescription() != null)
+ if (epg.getDescription() != null) {
builder.setDescription(new Text("gbp-epg: " + epg.getDescription().getValue()));
- else
+ } else {
builder.setDescription(new Text("gbp-epg"));
+ }
builder.setPublic(isPublic);
builder.setTenantId(tenantId);
builder.setUuid(new Uuid(UUID.randomUUID().toString()));
LogicalSwitchBuilder builder = new LogicalSwitchBuilder();
builder.setAdminStateUp(true);
builder.setName(new Text(epg.getId().getValue()));
- if (epg.getDescription() != null)
+ if (epg.getDescription() != null) {
builder.setDescription(new Text("gbp-epg: " + epg.getDescription().getValue()));
- else
+ } else {
builder.setDescription(new Text("gbp-epg"));
+ }
builder.setTenantId(tenantId);
builder.setUuid(new Uuid(UUID.randomUUID().toString()));
return builder;
}
- private boolean needToCreateLogicalNetwork(ServiceCommunicationLayer comLayer, List<SubnetId> consSubnetIds,
+ @VisibleForTesting
+ boolean needToCreateLogicalNetwork(ServiceCommunicationLayer comLayer, List<SubnetId> consSubnetIds,
List<SubnetId> provSubnetIds, TenantId tenantId, ContractId contractId, EndpointGroup providerEpg,
EndpointGroup consumerEpg, ExternalImplicitGroup externalImplicitGroup) {
Optional<LogicalNetwork> lnOp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
return true;
}
Set<SubnetId> lnProvSubnets = new HashSet<>(logicalNet.getProviderNetwork().getGbpSubnetId());
- if (lnProvSubnets.size() != provSubnetIds.size() || !lnProvSubnets.containsAll(provSubnetIds)) {
- return true;
- }
- return false;
+ return lnProvSubnets.size() != provSubnetIds.size() || !lnProvSubnets.containsAll(
+ provSubnetIds);
}
private ServiceCommunicationLayer findLayerNetwork(TenantId tenantId, List<SubnetId> consSubnetIds,
return null;
}
- private L3Context readL3ContextInstance(TenantId tenantId, L3ContextId l3cId) {
+ @VisibleForTesting
+ L3Context readL3ContextInstance(TenantId tenantId, L3ContextId l3cId) {
ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
InstanceIdentifier<L3Context> iid = IidFactory.l3ContextIid(tenantId, l3cId);
Optional<L3Context> l2Op = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx);
return l2Op.get();
}
- private L2BridgeDomain readL2BridgeDomainInstance(TenantId tenantId, L2BridgeDomainId l2bId) {
+ @VisibleForTesting
+ L2BridgeDomain readL2BridgeDomainInstance(TenantId tenantId, L2BridgeDomainId l2bId) {
ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
InstanceIdentifier<L2BridgeDomain> iid = IidFactory.l2BridgeDomainIid(tenantId, l2bId);
Optional<L2BridgeDomain> l2Op = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx);
return l2Op.get();
}
- private L2FloodDomain readL2FloodDomain(L2FloodDomainId l2fId, TenantId tenantId) {
+ @VisibleForTesting
+ L2FloodDomain readL2FloodDomain(L2FloodDomainId l2fId, TenantId tenantId) {
ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();
InstanceIdentifier<L2FloodDomain> iid = IidFactory.l2FloodDomainIid(tenantId, l2fId);
Optional<L2FloodDomain> l2Op = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx);
removeTenantLogicalNetwork(gbpTenantId, faasTenantId, true);
}
- private void removeTenantLogicalNetwork(TenantId gbpTenantId, Uuid faasTenantId, boolean unregister) {
+ @VisibleForTesting
+ void removeTenantLogicalNetwork(TenantId gbpTenantId, Uuid faasTenantId, boolean unregister) {
UlnDatastoreApi.removeTenantFromDsIfExists(faasTenantId);
synchronized (this) {
mappedTenants.remove(gbpTenantId);