5167289c530b3afbc4aab09bc8913b59fdd29a64
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronNetworkAware.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import java.util.HashSet;
13 import java.util.Set;
14 import java.util.UUID;
15
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;
51
52 import com.google.common.base.Optional;
53
54 public class NeutronNetworkAware implements INeutronNetworkAware {
55
56     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
57     private final DataBroker dataProvider;
58     private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
59
60     public NeutronNetworkAware(DataBroker dataProvider) {
61         this.dataProvider = checkNotNull(dataProvider);
62     }
63
64     /**
65      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canCreateNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
66      */
67     @Override
68     public int canCreateNetwork(NeutronNetwork network) {
69         LOG.trace("canCreateNetwork - {}", network);
70         // nothing to consider
71         return StatusCode.OK;
72     }
73
74     /**
75      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkCreated(org.opendaylight.neutron.spi.NeutronNetwork)
76      */
77     @Override
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()));
83         Name name = null;
84         if (network.getNetworkName() != null) {
85             try {
86                 name = new Name(network.getNetworkName());
87             } catch (Exception e) {
88                 name = null;
89                 LOG.info("Name of Neutron Network '{}' is ignored.",
90                         network.getNetworkName());
91                 LOG.debug("Name exception", e);
92             }
93         }
94
95         L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
96         L3Context l3Context = new L3ContextBuilder().setId(l3ContextId)
97             .setName(name)
98             .build();
99         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
100
101         L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
102         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId)
103             .setParent(l3ContextId)
104             .setName(name)
105             .build();
106         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
107
108         L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId)
109             .setParent(l2BdId)
110             .setName(name)
111             .build();
112         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
113
114         NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
115             .setL2BridgeDomainId(l2BdId)
116             .setL3ContextId(l3ContextId)
117             .build();
118         rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping, true);
119
120         if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
121             tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
122             Router.writeRouterEntitiesToTenant(tenantId, rwTx);
123             Router.writeRouterClauseWithConsProvEic(tenantId, null, rwTx);
124             NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
125             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
126             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
127             NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
128             NetworkClient.writeConsumerNamedSelector(tenantId, Router.CONTRACT_CONSUMER_SELECTOR, rwTx);
129             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
130             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
131         }
132         if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
133             addEpgExternalIfMissing(tenantId, rwTx);
134             addExternalNetworkIfMissing(l2Fd.getId(), rwTx);
135         }
136         DataStoreHelper.submitToDs(rwTx);
137     }
138
139     private void addExternalNetworkIfMissing(L2FloodDomainId l2FdId, ReadWriteTransaction rwTx) {
140         InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid = NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
141         Optional<ExternalNetworkByL2FloodDomain> externalPresent = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
142                 iid, rwTx);
143         if (!externalPresent.isPresent()) {
144             ExternalNetworkByL2FloodDomainBuilder builder = new ExternalNetworkByL2FloodDomainBuilder()
145                 .setL2FloodDomainId(l2FdId);
146             rwTx.put(LogicalDatastoreType.OPERATIONAL,
147                     NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId), builder.build(), true);
148         }
149     }
150
151     private void addEpgExternalIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
152         Optional<EndpointGroup> potentialEpgExternal = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
153                 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), rwTx);
154         if (!potentialEpgExternal.isPresent()) {
155             EndpointGroup epgExternal = new EndpointGroupBuilder()
156                 .setId(MappingUtils.EPG_EXTERNAL_ID)
157                 .setName(new Name("EXTERNAL_group"))
158                 .setDescription(new Description(MappingUtils.NEUTRON_EXTERNAL + "epg_external_networks"))
159                 .build();
160             rwTx.put(LogicalDatastoreType.CONFIGURATION,
161                     IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), epgExternal, true);
162         }
163     }
164
165     /**
166      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
167      *      org.opendaylight.neutron.spi.NeutronNetwork)
168      */
169     @Override
170     public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original) {
171         LOG.trace("canUpdateNetwork - delta: {} original: {}", delta, original);
172         // nothing to consider
173         return StatusCode.OK;
174     }
175
176     /**
177      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkUpdated(org.opendaylight.neutron.spi.NeutronNetwork)
178      */
179     @Override
180     public void neutronNetworkUpdated(NeutronNetwork network) {
181         LOG.trace("neutronNetworkUpdated - {}", network);
182         // TODO we could update just name
183     }
184
185     /**
186      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canDeleteNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
187      */
188     @Override
189     public int canDeleteNetwork(NeutronNetwork network) {
190         LOG.trace("canDeleteNetwork - {}", network);
191         // nothing to consider
192         return StatusCode.OK;
193     }
194
195     /**
196      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkDeleted(org.opendaylight.neutron.spi.NeutronNetwork)
197      */
198     @Override
199     public void neutronNetworkDeleted(NeutronNetwork network) {
200         LOG.trace("neutronNetworkDeleted - {}", network);
201         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
202         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
203         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
204         InstanceIdentifier<NetworkMapping> networkMappingIid = NeutronMapperIidFactory.networkMappingIid(l2FdId);
205         Optional<NetworkMapping> potentionalNetworkMapping = DataStoreHelper.readFromDs(
206                 LogicalDatastoreType.OPERATIONAL, networkMappingIid, rwTx);
207         if (!potentionalNetworkMapping.isPresent()) {
208             LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
209             rwTx.cancel();
210             return;
211         }
212
213         NetworkMapping networkMapping = potentionalNetworkMapping.get();
214         L2BridgeDomainId l2BdId = networkMapping.getL2BridgeDomainId();
215         L3ContextId l3ContextId = networkMapping.getL3ContextId();
216         if (l2BdId == null || l3ContextId == null) {
217             LOG.warn("Illegal state - network-mapping {} is not valid.", networkMapping);
218             rwTx.cancel();
219             return;
220         }
221
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());
226             rwTx.cancel();
227             return;
228         }
229
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());
234             rwTx.cancel();
235             return;
236         }
237
238         Optional<L3Context> potentialL3Context = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
239                 IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
240         if (!potentialL3Context.isPresent()) {
241             LOG.warn("Illegal state - l3-context {} does not exist.", l3ContextId.getValue());
242             rwTx.cancel();
243             return;
244         }
245
246         rwTx.delete(LogicalDatastoreType.OPERATIONAL, networkMappingIid);
247
248         DataStoreHelper.submitToDs(rwTx);
249     }
250 }