2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import java.util.HashSet;
14 import java.util.UUID;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.Router;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
26 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
27 import org.opendaylight.groupbasedpolicy.util.IidFactory;
28 import org.opendaylight.neutron.spi.INeutronNetworkAware;
29 import org.opendaylight.neutron.spi.NeutronNetwork;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomain;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomainBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 import com.google.common.base.Optional;
54 public class NeutronNetworkAware implements INeutronNetworkAware {
56 private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
57 private final DataBroker dataProvider;
58 private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
60 public NeutronNetworkAware(DataBroker dataProvider) {
61 this.dataProvider = checkNotNull(dataProvider);
65 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canCreateNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
68 public int canCreateNetwork(NeutronNetwork network) {
69 LOG.trace("canCreateNetwork - {}", network);
70 // nothing to consider
75 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkCreated(org.opendaylight.neutron.spi.NeutronNetwork)
78 public void neutronNetworkCreated(NeutronNetwork network) {
79 LOG.trace("neutronNetworkCreated - {}", network);
80 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
81 L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
82 TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
84 if (network.getNetworkName() != null) {
86 name = new Name(network.getNetworkName());
87 } catch (Exception e) {
89 LOG.info("Name of Neutron Network '{}' is ignored.", network.getNetworkName());
90 LOG.debug("Name exception", e);
94 L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
95 L3Context l3Context = new L3ContextBuilder().setId(l3ContextId).setName(name).build();
96 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
98 L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
99 L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3ContextId).setName(name).build();
100 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
102 L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId).setParent(l2BdId).setName(name).build();
103 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
105 NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
106 .setL2BridgeDomainId(l2BdId)
107 .setL3ContextId(l3ContextId)
109 rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping,
112 if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
113 tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
114 Router.writeRouterEntitiesToTenant(tenantId, rwTx);
115 Router.writeRouterClauseWithConsProvEic(tenantId, null, rwTx);
116 NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
117 NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
118 NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
119 NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
120 NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
121 NetworkClient.writeConsumerNamedSelector(tenantId, Router.CONTRACT_CONSUMER_SELECTOR, rwTx);
122 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
123 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
124 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
126 if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
127 addEpgExternalIfMissing(tenantId, rwTx);
128 addExternalNetworkIfMissing(l2Fd.getId(), rwTx);
130 DataStoreHelper.submitToDs(rwTx);
133 private void addExternalNetworkIfMissing(L2FloodDomainId l2FdId, ReadWriteTransaction rwTx) {
134 InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid =
135 NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
136 Optional<ExternalNetworkByL2FloodDomain> externalPresent =
137 DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, iid, rwTx);
138 if (!externalPresent.isPresent()) {
139 ExternalNetworkByL2FloodDomainBuilder builder =
140 new ExternalNetworkByL2FloodDomainBuilder().setL2FloodDomainId(l2FdId);
141 rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId),
142 builder.build(), true);
146 private void addEpgExternalIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
147 Optional<EndpointGroup> potentialEpgExternal = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
148 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), rwTx);
149 if (!potentialEpgExternal.isPresent()) {
150 EndpointGroup epgExternal = new EndpointGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID)
151 .setName(new Name("EXTERNAL_group"))
152 .setDescription(new Description(MappingUtils.NEUTRON_EXTERNAL + "epg_external_networks"))
154 rwTx.put(LogicalDatastoreType.CONFIGURATION,
155 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), epgExternal, true);
160 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
161 * org.opendaylight.neutron.spi.NeutronNetwork)
164 public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original) {
165 LOG.trace("canUpdateNetwork - delta: {} original: {}", delta, original);
166 // nothing to consider
167 return StatusCode.OK;
171 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkUpdated(org.opendaylight.neutron.spi.NeutronNetwork)
174 public void neutronNetworkUpdated(NeutronNetwork network) {
175 LOG.trace("neutronNetworkUpdated - {}", network);
176 // TODO we could update just name
180 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canDeleteNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
183 public int canDeleteNetwork(NeutronNetwork network) {
184 LOG.trace("canDeleteNetwork - {}", network);
185 // nothing to consider
186 return StatusCode.OK;
190 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkDeleted(org.opendaylight.neutron.spi.NeutronNetwork)
193 public void neutronNetworkDeleted(NeutronNetwork network) {
194 LOG.trace("neutronNetworkDeleted - {}", network);
195 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
196 TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
197 L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
198 InstanceIdentifier<NetworkMapping> networkMappingIid = NeutronMapperIidFactory.networkMappingIid(l2FdId);
199 Optional<NetworkMapping> potentionalNetworkMapping =
200 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, networkMappingIid, rwTx);
201 if (!potentionalNetworkMapping.isPresent()) {
202 LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
207 NetworkMapping networkMapping = potentionalNetworkMapping.get();
208 L2BridgeDomainId l2BdId = networkMapping.getL2BridgeDomainId();
209 L3ContextId l3ContextId = networkMapping.getL3ContextId();
210 if (l2BdId == null || l3ContextId == null) {
211 LOG.warn("Illegal state - network-mapping {} is not valid.", networkMapping);
216 Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
217 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
218 if (!potentialL2Fd.isPresent()) {
219 LOG.warn("Illegal state - l2-flood-domain {} does not exist.", l2FdId.getValue());
224 Optional<L2BridgeDomain> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
225 IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
226 if (!potentialL2Bd.isPresent()) {
227 LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
232 Optional<L3Context> potentialL3Context = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
233 IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
234 if (!potentialL3Context.isPresent()) {
235 LOG.warn("Illegal state - l3-context {} does not exist.", l3ContextId.getValue());
240 rwTx.delete(LogicalDatastoreType.OPERATIONAL, networkMappingIid);
242 DataStoreHelper.submitToDs(rwTx);