/* * 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 */ package org.opendaylight.groupbasedpolicy.renderer.faas; import static com.google.common.base.Preconditions.checkNotNull; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; 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.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.groupbasedpolicy.util.DataStoreHelper; import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.groupbasedpolicy.util.TenantUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Text; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Uuid; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.logical.routers.rev151013.logical.routers.container.logical.routers.LogicalRouterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.logical.switches.rev151013.logical.switches.container.logical.switches.LogicalSwitchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.ports.rev151013.PortLocationAttributes.LocationType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.LogicalNetworks; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.ScopeType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.ServiceCommunicationLayer; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.logical.networks.LogicalNetwork; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.logical.networks.LogicalNetworkBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.logical.networks.logical.network.ConsumerNetworkBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.logical.networks.logical.network.ProviderNetworkBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.MappedEntity; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.MappedEntityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.MappedTenant; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.MappedTenantBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedContract; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedSubnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.FollowedTenantBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.interests.followed.tenants.followed.tenant.FollowedEndpointGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.resolved.policies.ResolvedPolicy.ExternalImplicitGroup; 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; public class FaasPolicyManager implements DataChangeListener, 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 DataBroker dataProvider; final Map<Pair<EndpointGroupId, TenantId>, List<SubnetId>> epgSubnetsMap = new HashMap<>(); private final ConcurrentHashMap<TenantId, Uuid> mappedTenants = new ConcurrentHashMap<>(); final ConcurrentHashMap<TenantId, ArrayList<ListenerRegistration<DataChangeListener>>> registeredTenants = new ConcurrentHashMap<>(); public FaasPolicyManager(DataBroker dataBroker, ScheduledExecutorService 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); RendererBuilder rendBuilder = new RendererBuilder(); rendBuilder.setName(rendererName); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.rendererIid(rendererName), rendBuilder.build()); if (DataStoreHelper.submitToDs(wTx)) { LOG.debug("{} renderer registered with the multi-renderer manager", rendererName.getValue()); } else { LOG.error("{} renderer Failed to register with the multi-renderer manager", rendererName.getValue()); } } @Override public void close() throws Exception { synchronized (registeredTenants) { for (ArrayList<ListenerRegistration<DataChangeListener>> list : registeredTenants.values()) { list.forEach(ListenerRegistration::close); } registeredTenants.clear(); LOG.debug("Closed All Tenant Registerations"); } if (registerListener != null) registerListener.close(); } @Override public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) { executor.execute(new Runnable() { public void run() { executeEvent(change); } }); } 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); } } } // 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); } } } public void registerTenant(TenantId gbpTenantId) { registerTenant(gbpTenantId, null); } public void registerTenant(TenantId gbpTenantId, EndpointGroupId epgId) { if (registeredTenants.get(gbpTenantId) != null) { registerFollowedEndpointgroup(gbpTenantId, epgId); return; // already registered } synchronized (this) { if (registeredTenants.get(gbpTenantId) != null) { return; // already registered } /* * map tenant's required elements to faas logical networks */ Optional<MappedTenant> mTenantOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedTenantIid(gbpTenantId), dataProvider.newReadOnlyTransaction()); Uuid faasTenantId; if (mTenantOptional.isPresent()) { faasTenantId = mTenantOptional.get().getFaasTenantId(); } else { faasTenantId = getFaasTenantId(gbpTenantId); } // load tenant datastore info Tenant tenant = null; Optional<Tenant> tenantOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, TenantUtils.tenantIid(gbpTenantId), dataProvider.newReadOnlyTransaction()); if (tenantOptional.isPresent()) { tenant = tenantOptional.get(); } List<Contract> contracts = null; List<Subnet> subnets = null; if (tenant != null) { contracts = tenant.getPolicy().getContract(); subnets = tenant.getForwardingContext().getSubnet(); } Optional<MappedEntity> mEntityOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedEntityIid(gbpTenantId), dataProvider.newReadOnlyTransaction()); MappedEntity mappedEntity; if (mEntityOptional.isPresent()) { mappedEntity = mEntityOptional.get(); } else { // This is needed as a workaround of a datastore problem MappedEntityBuilder builder = new MappedEntityBuilder(); builder.setGbpTenantId(gbpTenantId); mappedEntity = builder.build(); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedEntityIid(gbpTenantId), mappedEntity); if (DataStoreHelper.submitToDs(wTx)) { LOG.debug("Initailized Mapped Entry in Datastore for tenant {}", gbpTenantId); } else { LOG.error("Couldn't Initailized Mapped Entry in Datastore for tenant {}", gbpTenantId); } } // contracts FaasContractManagerListener faasContractManagerListener = new FaasContractManagerListener(dataProvider, gbpTenantId, faasTenantId, executor); faasContractManagerListener.loadAll(contracts, mappedEntity.getMappedContract()); // subnets FaasSubnetManagerListener faasSubnetManagerListener = new FaasSubnetManagerListener(dataProvider, gbpTenantId, faasTenantId, executor); faasSubnetManagerListener.loadAll(subnets, mappedEntity.getMappedSubnet()); /* * tenant registrations */ ArrayList<ListenerRegistration<DataChangeListener>> list = new ArrayList<>(); ListenerRegistration<DataChangeListener> reg; // contracts reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, IidFactory.contractWildcardIid(gbpTenantId), faasContractManagerListener, DataChangeScope.SUBTREE); list.add(reg); // subnets reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetWildcardIid(gbpTenantId), faasSubnetManagerListener, DataChangeScope.SUBTREE); list.add(reg); // tenant reg = dataProvider.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, IidFactory.tenantIid(gbpTenantId), new FaasTenantManagerListener(this, gbpTenantId, faasTenantId, executor), DataChangeScope.BASE); list.add(reg); // Map previously resolved policy for this tenant mapAllTenantResolvedPolicies(gbpTenantId, null); registerFollowedTenant(gbpTenantId, epgId); // track all registrations registeredTenants.put(gbpTenantId, list); LOG.debug("Registered tenant {}", gbpTenantId); } } private void mapAllTenantResolvedPolicies(TenantId gbpTenantId, EndpointGroupId epgId) { Optional<ResolvedPolicies> resolvedPoliciesOptional = DataStoreHelper.readFromDs( LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(ResolvedPolicies.class).build(), dataProvider.newReadOnlyTransaction()); 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)) { if (epgId == null || epgId.equals(policy.getConsumerEpgId()) || epgId.equals(policy.getProviderEpgId())) { // if any epg or a specific epg policy updateLogicalNetwork(policy); } } } } private void registerFollowedTenant(TenantId gbpTenantId, EndpointGroupId epgId) { FollowedTenantBuilder fTenantBuilder = new FollowedTenantBuilder(); fTenantBuilder.setId(gbpTenantId); if (epgId != null) { List<FollowedEndpointGroup> epgs = new ArrayList<>(); epgs.add(new FollowedEndpointGroupBuilder().setId(epgId).build()); fTenantBuilder.setFollowedEndpointGroup(epgs); } WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.followedTenantIid(rendererName, gbpTenantId), fTenantBuilder.build()); if (DataStoreHelper.submitToDs(wTx)) { LOG.info("Tenant {} is followed by renderer {}", gbpTenantId.getValue(), rendererName.getValue()); } else { LOG.info("Couldn't register Tenant {} that is followed by renderer {}", gbpTenantId.getValue(), rendererName.getValue()); } } @VisibleForTesting void registerFollowedEndpointgroup(TenantId gbpTenantId, EndpointGroupId epgId) { if (epgId == null) { return; } FollowedEndpointGroupBuilder fEpgBuilder = new FollowedEndpointGroupBuilder(); fEpgBuilder.setId(epgId); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); wTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.followedEndpointgroupIid(rendererName, gbpTenantId, epgId), fEpgBuilder.build()); if (DataStoreHelper.submitToDs(wTx)) { LOG.trace("EPG {} in Tenant {} is followed by renderer {}", epgId.getValue(), gbpTenantId.getValue(), rendererName.getValue()); } else { LOG.info("Couldn't register EPG {} in Tenant {} that is followed by renderer {}", epgId.getValue(), gbpTenantId.getValue(), rendererName.getValue()); } } public Uuid getFaasTenantId(TenantId tenantId) { Uuid val = mappedTenants.get(tenantId); if (val != null) { return val; } Uuid faasTenantId; if (isUUid(tenantId.getValue())) { faasTenantId = new Uuid(tenantId.getValue()); } else { faasTenantId = new Uuid(UUID.randomUUID().toString()); } mappedTenants.putIfAbsent(tenantId, faasTenantId); val = mappedTenants.get(tenantId); MappedTenantBuilder builder = new MappedTenantBuilder(); builder.setFaasTenantId(val); builder.setGbpTenantId(tenantId); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); MappedTenant result = builder.build(); wTx.put(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedTenantIid(tenantId), result); if (DataStoreHelper.submitToDs(wTx)) { LOG.debug("Cached in Datastore Mapped Tenant {}", result); } else { LOG.error("Couldn't Cache in Datastore Mapped Tenant {}", result); } return val; } 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}")); } public void unregisterTenant(TenantId tenantId) { ArrayList<ListenerRegistration<DataChangeListener>> list = registeredTenants.remove(tenantId); if (list != null) { for (ListenerRegistration<DataChangeListener> reg : list) { if (reg != null) reg.close(); } LOG.debug("Unregistered tenant {}", tenantId); } registeredTenants.remove(tenantId); Uuid faasTenantId = mappedTenants.get(tenantId); if (faasTenantId != null) { removeTenantLogicalNetwork(tenantId, faasTenantId, false); } } public boolean isTenantRegistered(TenantId tenantId) { return registeredTenants.containsKey(tenantId); } @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( "Ignore Resolved Policy between Consumer EPG {} and Provider EPG {} becuase they belong to different Tenants", policy.getConsumerTenantId().getValue(), policy.getProviderTenantId().getValue()); return false; } return isTenantRegistered(policy.getConsumerTenantId()); } private boolean isEqualService(ResolvedPolicy newPolicy, ResolvedPolicy oldPolicy) { return oldPolicy != null && newPolicy.getConsumerEpgId().equals(oldPolicy.getConsumerEpgId()) && newPolicy.getProviderEpgId().equals(oldPolicy.getProviderEpgId()) && newPolicy.getConsumerTenantId().equals(oldPolicy.getConsumerTenantId()) && newPolicy.getProviderTenantId().equals(oldPolicy.getProviderTenantId()); } public void registerSubnetWithEpg(EndpointGroupId epgId, TenantId tenantId, SubnetId subnetId) { registerSubnetWithEpg(epgId, tenantId, subnetId, true); } private void registerSubnetWithEpg(EndpointGroupId epgId, TenantId tenantId, SubnetId subnetId, boolean updateLn) { synchronized (this) { List<SubnetId> subnets = cloneAndGetEpgSubnets(epgId, tenantId); if(subnets.contains(subnetId)){ return; } subnets.add(subnetId); epgSubnetsMap.put(new Pair<>(epgId, tenantId), subnets); LOG.debug("Registered Subnet {} with EPG {}", subnetId, epgId); if (updateLn) { mapAllTenantResolvedPolicies(tenantId, epgId); } } } @VisibleForTesting void removeLogicalNetwork(ResolvedPolicy oldPolicy) { if (oldPolicy == null) { return; } removeLogicalNetwork(oldPolicy.getConsumerEpgId(), oldPolicy.getConsumerTenantId(), getContractId(oldPolicy), oldPolicy.getProviderEpgId(), oldPolicy.getProviderTenantId()); } private void removeLogicalNetwork(EndpointGroupId consumerEpgId, TenantId consumerTenantId, ContractId contractId, EndpointGroupId providerEpgId, TenantId providerTenantId) { ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); Optional<LogicalNetwork> lnOp = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.logicalNetworkIid(consumerEpgId, consumerTenantId, contractId, providerEpgId, providerTenantId), rwTx); if (lnOp.isPresent()) { DataStoreHelper.submitToDs(rwTx); LogicalNetwork logicalNetwork = lnOp.get(); Uuid consTenantId = getFaasTenantId(logicalNetwork.getConsumerTenantId()); Uuid provTenantId = getFaasTenantId(logicalNetwork.getProviderTenantId()); UlnDatastoreApi.removeLogicalSwitchFromDsIfExists(consTenantId, logicalNetwork.getConsumerNetwork() .getLogicalSwitchId()); UlnDatastoreApi.removeLogicalSwitchFromDsIfExists(provTenantId, logicalNetwork.getProviderNetwork() .getLogicalSwitchId()); if (logicalNetwork.getConsumerNetwork().getLogicalRouterId() != null) { UlnDatastoreApi.removeLogicalRouterFromDsIfExists(consTenantId, logicalNetwork.getConsumerNetwork() .getLogicalRouterId()); } if (logicalNetwork.getProviderNetwork().getLogicalRouterId() != null) { UlnDatastoreApi.removeLogicalRouterFromDsIfExists(provTenantId, logicalNetwork.getProviderNetwork() .getLogicalRouterId()); } } } private synchronized void updateLogicalNetwork(ResolvedPolicy policy) { updateLogicalNetwork(policy.getConsumerEpgId(), getContractId(policy), policy.getProviderEpgId(), policy.getConsumerTenantId(), policy.getExternalImplicitGroup()); } private synchronized void updateLogicalNetwork(EndpointGroupId consumerEpgId, ContractId contractId, EndpointGroupId providerEpgId, TenantId tenantId, ExternalImplicitGroup externalImplicitGroup) { LOG.trace("Start updateLogicalNetwork: Consumer EPG {} Provider Epg {} Contract {}", consumerEpgId, providerEpgId, contractId); // Create Logical network EndpointGroup consEpg = readEndpointGroup(consumerEpgId, tenantId); if (consEpg == null) { LOG.error("Couldn't Creat Logical Network. Missing EPG {}", consumerEpgId); return; } List<SubnetId> consSubnetIds = cloneAndGetEpgSubnets(consEpg.getId(), tenantId); if (consSubnetIds.isEmpty()) { LOG.info("Couldn't Creat Logical Network. Missing Subnets for Consumer EPG {}", consumerEpgId); return; } EndpointGroup provEpg = readEndpointGroup(providerEpgId, tenantId); if (provEpg == null) { LOG.error("Couldn't Creat Logical Network. Missing EPG {}", providerEpgId); return; } List<SubnetId> provSubnetIds = cloneAndGetEpgSubnets(provEpg.getId(), tenantId); if (provSubnetIds.isEmpty()) { LOG.info("Couldn't Creat Logical Network. Missing Subnets for Provider EPG {}", providerEpgId); return; } ServiceCommunicationLayer comLayer = findLayerNetwork(tenantId, consSubnetIds, provSubnetIds); if (comLayer == null) { LOG.error( "Couldn't determine forwarding Context. Couldn't Process Logical Network for Consumer EPG {} Provider Epg {} Contract {}", consumerEpgId, providerEpgId, contractId); return; } if (needToCreateLogicalNetwork(comLayer, consSubnetIds, provSubnetIds, tenantId, contractId, provEpg, consEpg, externalImplicitGroup)) { if (comLayer == ServiceCommunicationLayer.Layer2) { createLayer2LogicalNetwork(consEpg, contractId, provEpg, tenantId, comLayer, externalImplicitGroup); } else if (comLayer == ServiceCommunicationLayer.Layer3) { createLayer3LogicalNetwork(consEpg, contractId, provEpg, tenantId, comLayer, externalImplicitGroup); } else { LOG.error("Couldn't find the communication layer.Consumer EPG {} Provider Epg {} Contract {}", consumerEpgId, providerEpgId, contractId); } } else { LOG.debug("No need to Create the Logical Network. Consumer EPG {} Provider Epg {} Contract {}", consumerEpgId, providerEpgId, contractId); } } private boolean isConsumerPublic(ExternalImplicitGroup externalImplicitGroup) { return externalImplicitGroup != null && externalImplicitGroup == ExternalImplicitGroup.ConsumerEpg; } private boolean isProviderPublic(ExternalImplicitGroup externalImplicitGroup) { return externalImplicitGroup != null && externalImplicitGroup == ExternalImplicitGroup.ProviderEpg; } private List<SubnetId> cloneAndGetEpgSubnets(EndpointGroupId epgId, TenantId tenantId) { synchronized (this) { List<SubnetId> list1 = epgSubnetsMap.get(new Pair<>(epgId, tenantId)); if (list1 == null) { return new ArrayList<>(); } List<SubnetId> list2 = new ArrayList<>(); for (SubnetId id : list1) { list2.add(new SubnetId(id)); } return list2; } } 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); LogicalNetworkBuilder lNetbuilder = buildLayer2LogicalNetwork(consEpg, provEpg, gbpTenantId, null, externalImplicitGroup); if (lNetbuilder == null) { LOG.error("Failed to create Logical Switchs layer on the Logical network"); return; } Uuid privateSecRulesId = getFaasSecRulesId(contractId, gbpTenantId); if (privateSecRulesId == null) { LOG.error( "Couldn't Create Logical Network because unable to find FAAS Security Rules Id based on GBP Contract {}", contractId); return; } Uuid faasTenantId = getFaasTenantId(gbpTenantId); LogicalRouterBuilder consLR = initLogicalRouterBuilder(consEpg, faasTenantId, isConsumerPublic(externalImplicitGroup)); LogicalRouterBuilder provLR = initLogicalRouterBuilder(provEpg, faasTenantId, isProviderPublic(externalImplicitGroup)); if (!UlnDatastoreApi.attachAndSubmitToDs(consLR, provLR, new Pair<>(null, privateSecRulesId), null)) { LOG.error("Failed to join Logical Routers in a Logical Network"); return; } if (!UlnDatastoreApi.attachAndSubmitToDs(consLR.getUuid(), lNetbuilder.getConsumerNetwork() .getLogicalSwitchId(), faasTenantId, new Pair<>(LocationType.RouterType, LocationType.SwitchType))) { LOG.error("Failed to join Consumer Logical Router to Logical Switch in a Logical Network"); return; } LOG.debug("Attached Consumer Router {} to Consumer Switch {}", consLR.getUuid().getValue(), lNetbuilder.getConsumerNetwork().getLogicalSwitchId().getValue()); if (!UlnDatastoreApi.attachAndSubmitToDs(provLR.getUuid(), lNetbuilder.getProviderNetwork() .getLogicalSwitchId(), faasTenantId, new Pair<>(LocationType.RouterType, LocationType.SwitchType))) { LOG.error("Failed to join Provider Logical Router to Logical Switch in a Logical Network"); return; } LOG.debug("Attached Provider Router {} to Provider Switch {}", provLR.getUuid().getValue(), lNetbuilder.getProviderNetwork().getLogicalSwitchId().getValue()); ConsumerNetworkBuilder cNetBuilder = new ConsumerNetworkBuilder(lNetbuilder.getConsumerNetwork()); cNetBuilder.setLogicalRouterId(consLR.getUuid()); lNetbuilder.setConsumerNetwork(cNetBuilder.build()); ProviderNetworkBuilder pNetBuilder = new ProviderNetworkBuilder(lNetbuilder.getProviderNetwork()); pNetBuilder.setLogicalRouterId(provLR.getUuid()); lNetbuilder.setProviderNetwork(pNetBuilder.build()); lNetbuilder.setContractId(contractId); lNetbuilder.setContractTenantId(gbpTenantId); LogicalNetwork result = lNetbuilder.build(); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); InstanceIdentifier<LogicalNetwork> iid = FaasIidFactory.logicalNetworkIid( consEpg.getId(), gbpTenantId, contractId, provEpg.getId(), gbpTenantId); wTx.put(LogicalDatastoreType.OPERATIONAL, iid, result); if (DataStoreHelper.submitToDs(wTx)) { LOG.debug("Cached in Datastore Mapped Logical Network {}", result); } else { LOG.error("Couldn't Cache in Datastore Mapped Logical Network {}", result); } LOG.debug("Created Layer 3 Logical network consEpg {}, contractId {}, provEpg {}", consEpg.getId().getValue(), contractId.getValue(), provEpg.getId().getValue()); } 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); Uuid secRulesId = getFaasSecRulesId(contractId, gbpTenantId); if (secRulesId == null) { LOG.error( "Couldn't Create Logical Network because unable to find FAAS Security Rules Id based on GBP Contract {}", contractId); return; } LogicalNetworkBuilder lNetbuilder = buildLayer2LogicalNetwork(consEpg, provEpg, gbpTenantId, secRulesId, externalImplicitGroup); if (lNetbuilder == null) { LOG.error("Failed to create Logical Switchs layer on the Logical network"); return; } if (isConsumerPublic(externalImplicitGroup)) { Uuid faasTenantId = getFaasTenantId(gbpTenantId); LogicalRouterBuilder consLR = initLogicalRouterBuilder(consEpg, faasTenantId, true); UlnDatastoreApi.submitLogicalRouterToDs(consLR.build()); ConsumerNetworkBuilder cNetBuilder = new ConsumerNetworkBuilder(lNetbuilder.getConsumerNetwork()); cNetBuilder.setLogicalRouterId(consLR.getUuid()); lNetbuilder.setConsumerNetwork(cNetBuilder.build()); if (!UlnDatastoreApi.attachAndSubmitToDs(consLR.getUuid(), lNetbuilder.getConsumerNetwork() .getLogicalSwitchId(), faasTenantId, new Pair<>(LocationType.RouterType, LocationType.SwitchType), null, null)) { LOG.error("Failed to join Consumer Public Logical Router to Logical Switch in a Logical Network"); } LOG.debug("Attached Consumer Public Router {} to Consumer Switch {}", consLR.getUuid().getValue(), lNetbuilder.getConsumerNetwork().getLogicalSwitchId().getValue()); } if (isProviderPublic(externalImplicitGroup)) { Uuid faasTenantId = getFaasTenantId(gbpTenantId); LogicalRouterBuilder provLR = initLogicalRouterBuilder(provEpg, faasTenantId, true); provLR.setPublic(true); UlnDatastoreApi.submitLogicalRouterToDs(provLR.build()); ProviderNetworkBuilder cNetBuilder = new ProviderNetworkBuilder(lNetbuilder.getProviderNetwork()); cNetBuilder.setLogicalRouterId(provLR.getUuid()); lNetbuilder.setProviderNetwork(cNetBuilder.build()); if (!UlnDatastoreApi.attachAndSubmitToDs(provLR.getUuid(), lNetbuilder.getProviderNetwork() .getLogicalSwitchId(), faasTenantId, new Pair<>(LocationType.RouterType, LocationType.SwitchType), null, null)) { LOG.error("Failed to join Provider Public Logical Router to Logical Switch in a Logical Network"); } LOG.debug("Attached Provider Public Router {} to Provider Switch {}", provLR.getUuid().getValue(), lNetbuilder.getProviderNetwork().getLogicalSwitchId().getValue()); } lNetbuilder.setContractId(contractId); lNetbuilder.setContractTenantId(gbpTenantId); LogicalNetwork result = lNetbuilder.build(); WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); InstanceIdentifier<LogicalNetwork> iid = FaasIidFactory.logicalNetworkIid( consEpg.getId(), gbpTenantId, contractId, provEpg.getId(), gbpTenantId); wTx.put(LogicalDatastoreType.OPERATIONAL, iid, result); if (DataStoreHelper.submitToDs(wTx)) { LOG.debug("Cached in Datastore Mapped Logical Network {}", result); } else { LOG.error("Couldn't Cache in Datastore Mapped Logical Network {}", result); } LOG.debug("Created Layer 2 Logical network consEpg {}, contractId {}, provEpg {}", consEpg.getId().getValue(), contractId.getValue(), provEpg.getId().getValue()); } private LogicalNetworkBuilder buildLayer2LogicalNetwork(EndpointGroup consEpg, EndpointGroup provEpg, TenantId gbpTenantId, Uuid layer2SecRulesId, ExternalImplicitGroup externalImplicitGroup) { LOG.trace("Start buildLayer2LogicalNetwork: Consumer EPG {} Provider Epg {}", consEpg.getId().getValue(), provEpg.getId().getValue()); List<SubnetId> consSubnetIds = cloneAndGetEpgSubnets(consEpg.getId(), gbpTenantId); List<Uuid> consFaasSubnetIds = new ArrayList<>(); for (SubnetId subnetId : consSubnetIds) { Uuid id = getFaasSubnetId(subnetId, gbpTenantId); if (id != null) { LOG.trace("Added to Consumer Network Faas Subnet {}", id.getValue()); consFaasSubnetIds.add(id); } } if (consFaasSubnetIds.isEmpty()) { LOG.error("Couldn't find Faas subnets based on EPG {} -- Unable to create Layer2 Logical Network", consEpg.getId().getValue()); return null; } List<SubnetId> provSubnetIds = cloneAndGetEpgSubnets(provEpg.getId(), gbpTenantId); List<Uuid> provFaasSubnetIds = new ArrayList<>(); for (SubnetId subnetId : provSubnetIds) { Uuid id = getFaasSubnetId(subnetId, gbpTenantId); if (id != null) { LOG.trace("Added to Provider Network Faas Subnet {}", id.getValue()); provFaasSubnetIds.add(id); } } if (provFaasSubnetIds.isEmpty()) { LOG.error("Couldn't find Faas subnets based on EPG {} -- Unable to create Layer2 Logical Network", provEpg.getId().getValue()); return null; } Uuid faasTenantId = getFaasTenantId(gbpTenantId); LogicalSwitchBuilder consLS = initLogicalSwitchBuilder(consEpg, faasTenantId); LogicalSwitchBuilder provLS = initLogicalSwitchBuilder(provEpg, faasTenantId); if (layer2SecRulesId != null) { if (!UlnDatastoreApi.attachAndSubmitToDs(consLS, provLS, new Pair<Uuid, Uuid>(null, layer2SecRulesId))) { LOG.error("Failed to join Logical Switches in a Logical Network"); return null; } } else { UlnDatastoreApi.submitLogicalSwitchToDs(consLS.build()); UlnDatastoreApi.submitLogicalSwitchToDs(provLS.build()); } for (Uuid subnetId : consFaasSubnetIds) { if (!UlnDatastoreApi.attachAndSubmitToDs(consLS.getUuid(), subnetId, consLS.getTenantId(), new Pair<>( LocationType.SwitchType, LocationType.SubnetType))) { LOG.error("Failed to join Consumer Logical Switch with Subnet {} in a Logical Network", subnetId); return null; } LOG.debug("Attached Consumer Switch {} to Subnet {}", consLS.getUuid().getValue(), subnetId.getValue()); } for (Uuid subnetId : provFaasSubnetIds) { if (!UlnDatastoreApi.attachAndSubmitToDs(provLS.getUuid(), subnetId, provLS.getTenantId(), new Pair<>( LocationType.SwitchType, LocationType.SubnetType))) { LOG.error("Failed to join Provider Logical Switch with Subnet {} in a Logical Network", subnetId); return null; } LOG.debug("Attached Provider Switch {} to Subnet {}", provLS.getUuid().getValue(), subnetId.getValue()); } LogicalNetworkBuilder lNetbuilder = new LogicalNetworkBuilder(); lNetbuilder.setConsumerEpgId(consEpg.getId()); lNetbuilder.setConsumerTenantId(gbpTenantId); lNetbuilder.setContractTenantId(gbpTenantId); lNetbuilder.setProviderEpgId(provEpg.getId()); lNetbuilder.setProviderTenantId(gbpTenantId); ConsumerNetworkBuilder cNetBuilder = new ConsumerNetworkBuilder(); cNetBuilder.setLogicalSwitchId(consLS.getUuid()); cNetBuilder.setGbpSubnetId(consSubnetIds); if (isConsumerPublic(externalImplicitGroup)) { cNetBuilder.setNetworkScopeType(ScopeType.Public); } else { cNetBuilder.setNetworkScopeType(ScopeType.Private); } lNetbuilder.setConsumerNetwork(cNetBuilder.build()); ProviderNetworkBuilder pNetBuilder = new ProviderNetworkBuilder(); pNetBuilder.setLogicalSwitchId(provLS.getUuid()); pNetBuilder.setGbpSubnetId(provSubnetIds); if (isProviderPublic(externalImplicitGroup)) { pNetBuilder.setNetworkScopeType(ScopeType.Public); } else { pNetBuilder.setNetworkScopeType(ScopeType.Private); } lNetbuilder.setProviderNetwork(pNetBuilder.build()); return lNetbuilder; } private Uuid getFaasSubnetId(SubnetId subnetId, TenantId gbpTenantId) { if (subnetId != null) { Optional<MappedSubnet> mSubnetOp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedSubnetIid(gbpTenantId, subnetId), dataProvider.newReadOnlyTransaction()); if (mSubnetOp.isPresent()) { return mSubnetOp.get().getFaasSubnetId(); } } return null; } protected Uuid getFaasSecRulesId(ContractId contractId, TenantId gbpTenantId) { if (contractId != null) { Optional<MappedContract> mContractOp = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedContractIid(gbpTenantId, contractId), dataProvider.newReadOnlyTransaction()); if (mContractOp.isPresent()) { return mContractOp.get().getFaasSecurityRulesId(); } } return null; } private LogicalRouterBuilder initLogicalRouterBuilder(EndpointGroup epg, Uuid tenantId, boolean isPublic) { LogicalRouterBuilder builder = new LogicalRouterBuilder(); builder.setAdminStateUp(true); builder.setName(new Text(epg.getId().getValue())); if (epg.getDescription() != null) builder.setDescription(new Text("gbp-epg: " + epg.getDescription().getValue())); else builder.setDescription(new Text("gbp-epg")); builder.setPublic(isPublic); builder.setTenantId(tenantId); builder.setUuid(new Uuid(UUID.randomUUID().toString())); return builder; } private LogicalSwitchBuilder initLogicalSwitchBuilder(EndpointGroup epg, Uuid tenantId) { LogicalSwitchBuilder builder = new LogicalSwitchBuilder(); builder.setAdminStateUp(true); builder.setName(new Text(epg.getId().getValue())); if (epg.getDescription() != null) builder.setDescription(new Text("gbp-epg: " + epg.getDescription().getValue())); else builder.setDescription(new Text("gbp-epg")); builder.setTenantId(tenantId); builder.setUuid(new Uuid(UUID.randomUUID().toString())); return builder; } @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, FaasIidFactory.logicalNetworkIid(consumerEpg.getId(), tenantId, contractId, providerEpg.getId(), tenantId), dataProvider.newReadOnlyTransaction()); if (!lnOp.isPresent()) { return true; } LogicalNetwork logicalNet = lnOp.get(); if (!comLayer.equals(logicalNet.getCommunicationLayer())) { return true; } boolean isConsPublic = logicalNet.getConsumerNetwork().getNetworkScopeType() != null && logicalNet.getConsumerNetwork().getNetworkScopeType() == ScopeType.Public; if (isConsumerPublic(externalImplicitGroup) != isConsPublic) { return true; } boolean isProvPublic = logicalNet.getProviderNetwork().getNetworkScopeType() != null && logicalNet.getProviderNetwork().getNetworkScopeType() == ScopeType.Public; if (isProviderPublic(externalImplicitGroup) != isProvPublic) { return true; } Set<SubnetId> lnConsSubnets = new HashSet<>(logicalNet.getConsumerNetwork().getGbpSubnetId()); if (lnConsSubnets.size() != consSubnetIds.size() || !lnConsSubnets.containsAll(consSubnetIds)) { return true; } Set<SubnetId> lnProvSubnets = new HashSet<>(logicalNet.getProviderNetwork().getGbpSubnetId()); return lnProvSubnets.size() != provSubnetIds.size() || !lnProvSubnets.containsAll( provSubnetIds); } private ServiceCommunicationLayer findLayerNetwork(TenantId tenantId, List<SubnetId> consSubnetIds, List<SubnetId> provSubnetIds) { Subnet consSubnet = null; Subnet provSubnet = null; ContextId contextId = null; for (SubnetId subnetId : consSubnetIds) { consSubnet = readSubnet(subnetId, tenantId); if (consSubnet == null) { LOG.error("Couldn't find subnet {} in datastore", subnetId); return null; } if (consSubnet.getParent() == null) { LOG.error("Flood domain is set to NULL in subnet " + consSubnet.getId()); return null; } if (contextId == null) { contextId = consSubnet.getParent(); } else if (!contextId.equals(consSubnet.getParent())) { LOG.error("Flood domain is not the same for all Network domains in the Consumer EPG "); return null; } } contextId = null; for (SubnetId subnetId : provSubnetIds) { provSubnet = readSubnet(subnetId, tenantId); if (provSubnet == null) { LOG.error("Couldn't find subnet {} in datastore", subnetId); return null; } if (provSubnet.getParent() == null) { LOG.error("Flood domain is set to NULL in subnet " + provSubnet.getId()); return null; } if (contextId == null) { contextId = provSubnet.getParent(); } else if (!contextId.equals(provSubnet.getParent())) { LOG.error("Flood domain is not the same for all Network domains in the Provider EPG "); return null; } } if (consSubnet == null || provSubnet == null) { LOG.error("Couldn't find Consumer and/or Provider subnets"); return null; } L2FloodDomainId consL2FldId = new L2FloodDomainId(consSubnet.getParent().getValue()); L2FloodDomain consFloodDomain = readL2FloodDomain(consL2FldId, tenantId); if (consFloodDomain == null) { LOG.error("Couldn't find flood domain instance in datastore with id " + consL2FldId); return null; } L2FloodDomainId provL2FldId = new L2FloodDomainId(provSubnet.getParent().getValue()); L2FloodDomain provFloodDomain = readL2FloodDomain(provL2FldId, tenantId); if (provFloodDomain == null) { LOG.error("Couldn't find flood domain instance in datastore with id " + provL2FldId); return null; } if (consFloodDomain.equals(provFloodDomain)) { return ServiceCommunicationLayer.Layer2; } if (consFloodDomain.getParent() == null) { LOG.error("Bridge domain is set to NULL in flood domain " + consFloodDomain.getId()); return null; } if (provFloodDomain.getParent() == null) { LOG.error("Bridge domain is set to NULL in flood domain " + provFloodDomain.getId()); return null; } L2BridgeDomain consBridgeDomain = readL2BridgeDomainInstance(tenantId, consFloodDomain.getParent()); if (consBridgeDomain == null) { LOG.error("Couldn't find bridge domain instance in datastore with id " + consFloodDomain.getParent()); return null; } L2BridgeDomain provBridgeDomain = readL2BridgeDomainInstance(tenantId, provFloodDomain.getParent()); if (provBridgeDomain == null) { LOG.error("Couldn't find bridge domain instance in datastore with id " + provFloodDomain.getParent()); return null; } if (consBridgeDomain.equals(provBridgeDomain)) { return ServiceCommunicationLayer.Layer2; } L3Context consL3ContextDomain = readL3ContextInstance(tenantId, consBridgeDomain.getParent()); if (consL3ContextDomain == null) { LOG.error("Couldn't find L3 context instance in datastore with id " + consBridgeDomain.getParent()); return null; } L3Context provL3ContextDomain = readL3ContextInstance(tenantId, provBridgeDomain.getParent()); if (provL3ContextDomain == null) { LOG.error("Couldn't find L3 context instance in datastore with id " + provBridgeDomain.getParent()); return null; } if (consL3ContextDomain.equals(provL3ContextDomain)) { return ServiceCommunicationLayer.Layer3; } return null; } @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); if (!l2Op.isPresent()) { LOG.error("Couldn't find L3 Context Domain {} which belongs to Tenant {}", l3cId, tenantId); rTx.close(); return null; } return l2Op.get(); } @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); if (!l2Op.isPresent()) { LOG.error("Couldn't find L2 Brdge Domain {} which belongs to Tenant {}", l2bId, tenantId); rTx.close(); return null; } return l2Op.get(); } @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); if (!l2Op.isPresent()) { LOG.error("Couldn't find L2 Flood Domain {} which belongs to Tenant {}", l2fId, tenantId); rTx.close(); return null; } return l2Op.get(); } public Subnet readSubnet(SubnetId subnetId, TenantId tenantId) { ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction(); InstanceIdentifier<Subnet> iid = IidFactory.subnetIid(tenantId, subnetId); Optional<Subnet> subnetOp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx); if (!subnetOp.isPresent()) { LOG.warn("Couldn't find Subnet {} which belongs to Tenant {}", subnetId, tenantId); rTx.close(); return null; } return subnetOp.get(); } public EndpointGroup readEndpointGroup(EndpointGroupId epgId, TenantId tenantId) { ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction(); InstanceIdentifier<EndpointGroup> iid = IidFactory.endpointGroupIid(tenantId, epgId); Optional<EndpointGroup> epgOp = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rTx); if (!epgOp.isPresent()) { LOG.warn("Couldn't find EPG {} which belongs to Tenant {}", epgId, tenantId); rTx.close(); return null; } return epgOp.get(); } private ContractId getContractId(ResolvedPolicy policy) { for (PolicyRuleGroupWithEndpointConstraints prgwec : policy.getPolicyRuleGroupWithEndpointConstraints()) { for (PolicyRuleGroup prg : prgwec.getPolicyRuleGroup()) { return prg.getContractId(); } } return null; } public void removeTenantLogicalNetwork(TenantId gbpTenantId, Uuid faasTenantId) { removeTenantLogicalNetwork(gbpTenantId, faasTenantId, true); } @VisibleForTesting void removeTenantLogicalNetwork(TenantId gbpTenantId, Uuid faasTenantId, boolean unregister) { UlnDatastoreApi.removeTenantFromDsIfExists(faasTenantId); synchronized (this) { mappedTenants.remove(gbpTenantId); Optional<LogicalNetworks> op3 = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.logicalNetworksIid(), dataProvider.newReadOnlyTransaction()); if (op3.isPresent()) { LogicalNetworks logicalNetworks = op3.get(); for (LogicalNetwork ln : logicalNetworks.getLogicalNetwork()) { if (ln.getConsumerTenantId().equals(gbpTenantId) || ln.getProviderTenantId().equals(gbpTenantId)) { removeLogicalNetwork(ln.getConsumerEpgId(), ln.getConsumerTenantId(), ln.getContractId(), ln.getProviderEpgId(), ln.getProviderTenantId()); } } } boolean toSubmit = false; ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); Optional<MappedEntity> op1 = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedEntityIid(gbpTenantId), rwTx); if (op1.isPresent()) { toSubmit = true; } Optional<MappedTenant> op2 = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL, FaasIidFactory.mappedTenantIid(gbpTenantId), rwTx); if (op2.isPresent()) { toSubmit = true; } if (toSubmit) { DataStoreHelper.submitToDs(rwTx); } if (unregister) { unregisterTenant(gbpTenantId); } } } }