Merge "Bug 4284 - PolicyEnforcer could not find CI"
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronSubnetAware.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.HashMap;
13 import java.util.Map;
14
15 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
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.util.DataStoreHelper;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
23 import org.opendaylight.groupbasedpolicy.util.IidFactory;
24 import org.opendaylight.neutron.spi.INeutronSubnetAware;
25 import org.opendaylight.neutron.spi.NeutronSubnet;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
33 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;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import com.google.common.base.Optional;
41 import com.google.common.base.Strings;
42
43 public class NeutronSubnetAware implements INeutronSubnetAware {
44
45     private final static Logger LOG = LoggerFactory.getLogger(NeutronSubnetAware.class);
46     private final DataBroker dataProvider;
47
48     public NeutronSubnetAware(DataBroker dataProvider) {
49         this.dataProvider = checkNotNull(dataProvider);
50     }
51
52     /**
53      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canCreateSubnet(org.opendaylight.neutron.spi.NeutronSubnet)
54      */
55     @Override
56     public int canCreateSubnet(NeutronSubnet subnet) {
57         LOG.trace("canCreateSubnet - {}", subnet);
58         // nothing to consider
59         return StatusCode.OK;
60     }
61
62     /**
63      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetCreated(org.opendaylight.neutron.spi.NeutronSubnet)
64      */
65     @Override
66     public void neutronSubnetCreated(NeutronSubnet neutronSubnet) {
67         LOG.trace("neutronSubnetCreated - {}", neutronSubnet);
68         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
69         SubnetId subnetId = new SubnetId(Utils.normalizeUuid(neutronSubnet.getID()));
70         TenantId tenantId = new TenantId(Utils.normalizeUuid(neutronSubnet.getTenantID()));
71         Subnet subnet = createSubnet(neutronSubnet);
72         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetId), subnet, true);
73         DataStoreHelper.submitToDs(rwTx);
74         rwTx = dataProvider.newReadWriteTransaction();
75
76         L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
77         ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
78
79         if (isExternalNetwork(subnet.getParent(), rwTx)) {
80             LOG.trace("neutronSubnetCreated - adding L3 Endpoint");
81             IpAddress defaultGateway = Utils.createIpAddress(neutronSubnet.getGatewayIP());
82             //Create L3Endpoint for defaultGateway and write to externalGateways to L3Endpoints in neutron-gbp datastore
83             NetworkDomainId containment = new NetworkDomainId(neutronSubnet.getID());
84             NeutronPortAware.addL3EndpointForExternalGateway(tenantId, fwCtx.getL3Context().getId(), defaultGateway, containment ,rwTx);
85             DataStoreHelper.submitToDs(rwTx);
86         }
87     }
88
89     private Subnet createSubnet(NeutronSubnet neutronSubnet) {
90         SubnetBuilder subnetBuilder = new SubnetBuilder();
91         subnetBuilder.setId(new SubnetId(neutronSubnet.getID()));
92         subnetBuilder.setParent(new ContextId(neutronSubnet.getNetworkUUID()));
93         if (!Strings.isNullOrEmpty(neutronSubnet.getName())) {
94             subnetBuilder.setName(new Name(neutronSubnet.getName()));
95         }
96         subnetBuilder.setIpPrefix(Utils.createIpPrefix(neutronSubnet.getCidr()));
97         return subnetBuilder.build();
98     }
99
100
101     private boolean isExternalNetwork(ContextId context, ReadWriteTransaction rwTx) {
102         L2FloodDomainId l2FdId = new L2FloodDomainId(context.getValue());
103         LOG.trace("neutronSubnetCreated - Looking up L2FD: {}", l2FdId);
104         InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid = NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
105         Optional<ExternalNetworkByL2FloodDomain> external = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
106                 iid, rwTx);
107         if (external.isPresent()) {
108             return true;
109         }
110         return false;
111     }
112
113     /**
114      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canUpdateSubnet(org.opendaylight.neutron.spi.NeutronSubnet,
115      *      org.opendaylight.neutron.spi.NeutronSubnet)
116      */
117     @Override
118     public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
119         LOG.trace("canUpdateSubnet - delta: {} original: {}", delta, original);
120         // nothing to consider
121         return StatusCode.OK;
122     }
123
124     /**
125      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetUpdated(org.opendaylight.neutron.spi.NeutronSubnet)
126      */
127     @Override
128     public void neutronSubnetUpdated(NeutronSubnet subnet) {
129         LOG.trace("neutronSubnetUpdated - {}", subnet);
130         neutronSubnetCreated(subnet);
131     }
132
133     /**
134      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canDeleteSubnet(org.opendaylight.neutron.spi.NeutronSubnet)
135      */
136     @Override
137     public int canDeleteSubnet(NeutronSubnet subnet) {
138         LOG.trace("canDeleteSubnet - {}", subnet);
139         // nothing to consider
140         return StatusCode.OK;
141     }
142
143     /**
144      * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetDeleted(org.opendaylight.neutron.spi.NeutronSubnet)
145      */
146     @Override
147     public void neutronSubnetDeleted(NeutronSubnet neutronSubnet) {
148         LOG.trace("neutronSubnetDeleted - {}", neutronSubnet);
149         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
150         SubnetId subnetId = new SubnetId(Utils.normalizeUuid(neutronSubnet.getID()));
151         TenantId tenantId = new TenantId(Utils.normalizeUuid(neutronSubnet.getTenantID()));
152         Optional<Subnet> potentialSubnet = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
153                 IidFactory.subnetIid(tenantId, subnetId), rwTx);
154         if (!potentialSubnet.isPresent()) {
155             LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
156             rwTx.cancel();
157             return;
158         }
159         DataStoreHelper.submitToDs(rwTx);
160     }
161 }