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;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.groupbasedpolicy.domain_extension.l2_l3.util.L2L3IidFactory;
20 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.MetadataService;
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
26 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
27 import org.opendaylight.groupbasedpolicy.util.IidFactory;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
51 import com.google.common.base.Optional;
52 import com.google.common.base.Strings;
54 public class NeutronNetworkAware implements NeutronAware<Network> {
56 private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
57 public static final InstanceIdentifier<Network> NETWORK_WILDCARD_IID =
58 InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();
59 private final DataBroker dataProvider;
60 private final Set<TenantId> tenantsWithRouterAndNetworkServiceEntities = new HashSet<>();
61 private final long metadataTcpPort;
63 public NeutronNetworkAware(DataBroker dataProvider, long metadataPort) {
64 this.dataProvider = checkNotNull(dataProvider);
65 this.metadataTcpPort = metadataPort;
69 public void onCreated(Network network, Neutron neutron) {
70 LOG.trace("created network - {}", network);
71 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
72 TenantId tenantId = new TenantId(network.getTenantId().getValue());
74 ContextId ctxId = new ContextId(network.getUuid().getValue());
75 ForwardingContextBuilder fwdCtxBuilder = new ForwardingContextBuilder()
77 .setContextType(MappingUtils.L3_CONTEXT);
78 if (!Strings.isNullOrEmpty(network.getName())) {
80 name = new Name(network.getName());
81 fwdCtxBuilder.setName(name);
82 } catch (Exception e) {
83 LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
84 LOG.debug("Name exception", e);
88 ForwardingContext l3Context = fwdCtxBuilder.build();
90 fwdCtxBuilder.setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
92 .setParent(MappingUtils.createParent(ctxId, MappingUtils.L3_CONTEXT));
93 ForwardingContext l2Bd = fwdCtxBuilder.build();
95 fwdCtxBuilder.setContextType(MappingUtils.L2_FLOOD_DOMAIN).setParent(
96 MappingUtils.createParent(ctxId, MappingUtils.L2_BRDIGE_DOMAIN));
97 ForwardingContext l2Fd = fwdCtxBuilder.build();
99 rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l3ContextIid(tenantId, ctxId), l3Context, true);
100 rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, ctxId), l2Bd, true);
101 rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2FloodDomainIid(tenantId, ctxId), l2Fd, true);
103 createTenantNetworkDomains(network, tenantId, rwTx);
105 if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) {
106 tenantsWithRouterAndNetworkServiceEntities.add(tenantId);
107 NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
108 NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
109 NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
110 NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
111 NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
112 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
113 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
114 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
115 MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx);
116 if (metadataTcpPort != 0) {
117 MetadataService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataTcpPort);
118 MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx);
119 NetworkClient.writeConsumerNamedSelector(tenantId, MetadataService.METADATA_CONTRACT_CONSUMER_SELECTOR,
123 if (!NetworkUtils.getPhysicalNetwork(network).isEmpty() && !NetworkUtils.getSegmentationId(network).isEmpty()) {
124 addProviderPhysicalNetworkMapping(tenantId, ctxId, NetworkUtils.getSegmentationId(network), rwTx);
125 addProviderPhysicalNetworkMapping(tenantId, new L2FloodDomainId(ctxId.getValue()),
126 NetworkUtils.getSegmentationId(network), rwTx);
128 DataStoreHelper.submitToDs(rwTx);
132 private void createTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
134 L3ContextBuilder l3CtxBuilder = new L3ContextBuilder();
135 L2FloodDomainBuilder l2FdBuilder = new L2FloodDomainBuilder();
136 L2BridgeDomainBuilder l2BdBuilder = new L2BridgeDomainBuilder();
137 if (!Strings.isNullOrEmpty(network.getName())) {
139 name = new Name(network.getName());
140 l3CtxBuilder.setName(name);
141 l2FdBuilder.setName(name);
142 l2BdBuilder.setName(name);
143 } catch (Exception e) {
145 LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
146 LOG.debug("Name exception", e);
149 L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
150 L3ContextId l3ContextId = new L3ContextId(l2FdId);
151 L3Context l3Context = l3CtxBuilder.setId(l3ContextId).build();
152 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3Context.getId()), l3Context, true);
154 L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
155 L2BridgeDomain l2Bd = l2BdBuilder.setId(l2BdId).setParent(l3Context.getId()).build();
156 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
158 L2FloodDomain l2Fd = l2FdBuilder.setId(l2FdId).setParent(l2BdId).build();
159 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
162 private void addProviderPhysicalNetworkMapping(TenantId tenantId, ContextId ctxId, String segmentationId,
163 WriteTransaction wTx) {
164 ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder().setTenantId(
166 .setL2FloodDomainId(ctxId)
167 .setSegmentationId(segmentationId)
169 wTx.put(LogicalDatastoreType.OPERATIONAL,
170 NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, ctxId), provNetAsL2Fd);
174 private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
175 WriteTransaction wTx) {
176 org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder().setTenantId(
178 .setL2FloodDomainId(new L2FloodDomainId(l2FdId.getValue()))
179 .setSegmentationId(segmentationId)
181 wTx.put(LogicalDatastoreType.OPERATIONAL,
182 NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
186 public void onUpdated(Network oldItem, Network newItem, Neutron oldNeutron, Neutron newNeutron) {
187 LOG.trace("updated network - OLD: {} \nNEW: {}", oldItem, newItem);
188 // TODO only name can be updated
192 public void onDeleted(Network network, Neutron oldNeutron, Neutron newNeutron) {
193 LOG.trace("deleted network - {}", network);
194 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
195 TenantId tenantId = new TenantId(network.getTenantId().getValue());
196 ContextId id = new ContextId(network.getUuid().getValue());
197 Optional<ForwardingContext> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
198 L2L3IidFactory.l2FloodDomainIid(tenantId, id), rwTx);
199 if (!potentialL2Fd.isPresent()) {
200 LOG.warn("Illegal state - l2-flood-domain {} does not exist.", id.getValue());
203 Optional<ForwardingContext> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
204 L2L3IidFactory.l2BridgeDomainIid(tenantId, id), rwTx);
205 if (!potentialL2Bd.isPresent()) {
206 LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", id.getValue());
209 Optional<ForwardingContext> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
210 L2L3IidFactory.l3ContextIid(tenantId, id), rwTx);
211 if (!potentialL3Ctx.isPresent()) {
212 LOG.warn("Illegal state - l3-context {} does not exist.", id.getValue());
215 removeTenantNetworkDomains(network, tenantId, rwTx);
216 DataStoreHelper.submitToDs(rwTx);
220 private void removeTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
221 L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
222 Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
223 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
224 if (!potentialL2Fd.isPresent()) {
225 LOG.warn("Illegal state - l2-flood-domain {} does not exist.", l2FdId.getValue());
229 L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
230 Optional<L2BridgeDomain> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
231 IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
232 if (!potentialL2Bd.isPresent()) {
233 LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
236 L3ContextId l3CtxId = new L3ContextId(l2FdId);
237 Optional<L3Context> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
238 IidFactory.l3ContextIid(tenantId, l3CtxId), rwTx);
239 if (!potentialL3Ctx.isPresent()) {
240 LOG.warn("Illegal state - l3-context {} does not exist.", l3CtxId.getValue());