Introduced neutron-mapper
[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.UUID;
13
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.DataStoreHelper;
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.IidFactory;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
21 import org.opendaylight.neutron.spi.INeutronNetworkAware;
22 import org.opendaylight.neutron.spi.NeutronNetwork;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import com.google.common.base.Optional;
45
46 public class NeutronNetworkAware implements INeutronNetworkAware {
47
48     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
49     private final DataBroker dataProvider;
50
51     public NeutronNetworkAware(DataBroker dataProvider) {
52         this.dataProvider = checkNotNull(dataProvider);
53     }
54
55     /**
56      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canCreateNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
57      */
58     @Override
59     public int canCreateNetwork(NeutronNetwork network) {
60         LOG.trace("canCreateNetwork - {}", network);
61         // nothing to consider
62         return StatusCode.OK;
63     }
64
65     /**
66      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkCreated(org.opendaylight.neutron.spi.NeutronNetwork)
67      */
68     @Override
69     public void neutronNetworkCreated(NeutronNetwork network) {
70         LOG.trace("neutronNetworkCreated - {}", network);
71         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
72         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
73         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
74         addEpgDhcpIfMissing(tenantId, rwTx);
75         addEpgRouterIfMissing(tenantId, rwTx);
76         Description domainDescription = new Description(MappingUtils.NEUTRON_NETWORK__ + network.getID());
77         Name name = null;
78         if (network.getNetworkName() != null) {
79             name = new Name(network.getNetworkName());
80         }
81         L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
82         L3Context l3Context = new L3ContextBuilder().setId(l3ContextId)
83             .setDescription(domainDescription)
84             .setName(name)
85             .build();
86         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
87
88         L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
89         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId)
90             .setParent(l3ContextId)
91             .setDescription(domainDescription)
92             .setName(name)
93             .build();
94         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
95
96         L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId)
97             .setParent(l2BdId)
98             .setDescription(domainDescription)
99             .setName(name)
100             .build();
101         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
102
103         NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
104             .setL2BridgeDomainId(l2BdId)
105             .setL3ContextId(l3ContextId)
106             .build();
107         rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.networkMappingIid(l2FdId), networkMapping, true);
108
109         DataStoreHelper.submitToDs(rwTx);
110     }
111
112     private void addEpgDhcpIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
113         InstanceIdentifier<EndpointGroup> epgDhcpIid = IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_DHCP_ID);
114         Optional<EndpointGroup> potentialDhcpEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
115                 epgDhcpIid, rwTx);
116         if (!potentialDhcpEpg.isPresent()) {
117             EndpointGroup epgDhcp = new EndpointGroupBuilder().setId(MappingUtils.EPG_DHCP_ID)
118                 .setName(new Name("DHCP_group"))
119                 .setDescription(new Description("Group where are all DHCP endpoints."))
120                 .build();
121             rwTx.put(LogicalDatastoreType.CONFIGURATION, epgDhcpIid, epgDhcp);
122         }
123     }
124
125     private void addEpgRouterIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
126         Optional<EndpointGroup> potentialEpgRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
127                 IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
128         if (potentialEpgRouter.isPresent()) {
129             EndpointGroup epgRouter = new EndpointGroupBuilder().setId(MappingUtils.EPG_ROUTER_ID)
130                 .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + "epg_routers"))
131                 .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
132                 .build();
133             rwTx.put(LogicalDatastoreType.CONFIGURATION,
134                     IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), epgRouter);
135         }
136     }
137
138     /**
139      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
140      *      org.opendaylight.neutron.spi.NeutronNetwork)
141      */
142     @Override
143     public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original) {
144         LOG.trace("canUpdateNetwork - delta: {} original: {}", delta, original);
145         // nothing to consider
146         return StatusCode.OK;
147     }
148
149     /**
150      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkUpdated(org.opendaylight.neutron.spi.NeutronNetwork)
151      */
152     @Override
153     public void neutronNetworkUpdated(NeutronNetwork network) {
154         LOG.trace("neutronNetworkUpdated - {}", network);
155         // TODO we could update just name
156     }
157
158     /**
159      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canDeleteNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
160      */
161     @Override
162     public int canDeleteNetwork(NeutronNetwork network) {
163         LOG.trace("canDeleteNetwork - {}", network);
164         // nothing to consider
165         return StatusCode.OK;
166     }
167
168     /**
169      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkDeleted(org.opendaylight.neutron.spi.NeutronNetwork)
170      */
171     @Override
172     public void neutronNetworkDeleted(NeutronNetwork network) {
173         LOG.trace("neutronNetworkDeleted - {}", network);
174         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
175         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
176         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
177         Optional<NetworkMapping> potentionalNetworkMapping = DataStoreHelper.readFromDs(
178                 LogicalDatastoreType.OPERATIONAL, IidFactory.networkMappingIid(l2FdId), rwTx);
179         if (!potentionalNetworkMapping.isPresent()) {
180             LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
181             rwTx.cancel();
182             return;
183         }
184
185         NetworkMapping networkMapping = potentionalNetworkMapping.get();
186         L2BridgeDomainId l2BdId = networkMapping.getL2BridgeDomainId();
187         L3ContextId l3ContextId = networkMapping.getL3ContextId();
188         if (l2BdId == null || l3ContextId == null) {
189             LOG.warn("Illegal state - network-mapping {} is not valid.", networkMapping);
190             rwTx.cancel();
191             return;
192         }
193
194         Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
195                 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
196         if (!potentialL2Fd.isPresent()) {
197             LOG.warn("Illegal state - l2-flood-domain {} does not exist.", l2FdId.getValue());
198             rwTx.cancel();
199             return;
200         }
201
202         Optional<L2BridgeDomain> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
203                 IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
204         if (!potentialL2Bd.isPresent()) {
205             LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
206             rwTx.cancel();
207             return;
208         }
209
210         Optional<L3Context> potentialL3Context = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
211                 IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
212         if (!potentialL3Context.isPresent()) {
213             LOG.warn("Illegal state - l3-context {} does not exist.", l3ContextId.getValue());
214             rwTx.cancel();
215             return;
216         }
217
218         DataStoreHelper.submitToDs(rwTx);
219     }
220
221 }