Add INFO.yaml for GBP
[groupbasedpolicy.git] / renderers / faas / src / main / java / org / opendaylight / groupbasedpolicy / renderer / faas / FaasSubnetManagerListener.java
1 /*
2  * Copyright (c) 2015 Huawei Technologies 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.renderer.faas;
9
10 import com.google.common.base.Optional;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.List;
14 import java.util.UUID;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.Executor;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.faas.uln.datastore.api.UlnDatastoreUtil;
25 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
26 import org.opendaylight.groupbasedpolicy.util.IetfModelCodec;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Text;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Uuid;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.SubnetBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.subnet.ExternalGateways;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.subnet.ExternalGatewaysBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedSubnet;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedSubnetBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.subnet.Gateways;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.subnet.gateways.Prefixes;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 public class FaasSubnetManagerListener implements DataTreeChangeListener<Subnet> {
43
44     private static final Logger LOG = LoggerFactory.getLogger(FaasSubnetManagerListener.class);
45     private final ConcurrentHashMap<SubnetId, Uuid> mappedSubnets = new ConcurrentHashMap<>();
46     private final Executor executor;
47     private final DataBroker dataProvider;
48     private final TenantId gbpTenantId;
49     private final Uuid faasTenantId;
50     private final UlnDatastoreUtil ulnDatastoreUtil;
51
52     public FaasSubnetManagerListener(DataBroker dataProvider, TenantId gbpTenantId, Uuid faasTenantId,
53             Executor executor, UlnDatastoreUtil ulnDatastoreUtil) {
54         this.executor = executor;
55         this.faasTenantId = faasTenantId;
56         this.gbpTenantId = gbpTenantId;
57         this.dataProvider = dataProvider;
58         this.ulnDatastoreUtil = ulnDatastoreUtil;
59     }
60
61     @Override
62     public void onDataTreeChanged(Collection<DataTreeModification<Subnet>> changes) {
63         executor.execute(() -> executeEvent(changes));
64     }
65
66     private void executeEvent(final Collection<DataTreeModification<Subnet>> changes) {
67         for (DataTreeModification<Subnet> change: changes) {
68             DataObjectModification<Subnet> rootNode = change.getRootNode();
69             switch (rootNode.getModificationType()) {
70                 case SUBTREE_MODIFIED:
71                 case WRITE:
72                     Subnet updatedSubnet = rootNode.getDataAfter();
73                     LOG.debug("Subnet {} is Updated.", updatedSubnet.getId().getValue());
74                     ulnDatastoreUtil.submitSubnetToDs(initSubnetBuilder(updatedSubnet).build());
75                     break;
76                 case DELETE:
77                     Subnet deletedSubnet = rootNode.getDataBefore();
78                     ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
79                     Optional<MappedSubnet> op = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
80                             FaasIidFactory.mappedSubnetIid(gbpTenantId, deletedSubnet.getId()), rwTx);
81                     if (op.isPresent()) {
82                         DataStoreHelper.submitToDs(rwTx);
83                     }
84                     Uuid faasSubnetId = mappedSubnets.remove(deletedSubnet.getId());
85                     if (faasSubnetId != null) {
86                         ulnDatastoreUtil.removeSubnetFromDsIfExists(faasTenantId, faasSubnetId);
87                     }
88                     break;
89                 default:
90                     break;
91             }
92         }
93     }
94
95     public void loadAll(List<Subnet> subnets, List<MappedSubnet> mpSubnets) {
96         if (mpSubnets != null) {
97             for (MappedSubnet mpSubnet : mpSubnets) {
98                 mappedSubnets.putIfAbsent(mpSubnet.getGbpSubnetId(), mpSubnet.getFaasSubnetId());
99             }
100         }
101         if (subnets != null) {
102             for (Subnet subnet : subnets) {
103                 LOG.debug("Loading Subnet {}", subnet.getId().getValue());
104                 ulnDatastoreUtil.submitSubnetToDs(initSubnetBuilder(subnet).build());
105             }
106         }
107     }
108
109     protected SubnetBuilder initSubnetBuilder(Subnet gbpSubnet) {
110         SubnetBuilder builder = new SubnetBuilder();
111         if (gbpSubnet.getGateways() != null) {
112             List<ExternalGateways> gateways = new ArrayList<>();
113             for (Gateways gw : gbpSubnet.getGateways()) {
114                 ExternalGatewaysBuilder eb = new ExternalGatewaysBuilder();
115                 eb.setExternalGateway(IetfModelCodec.ipAddress2013(gw.getGateway()));
116                 if (gw.getPrefixes() != null) {
117                     List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix> ipPrefixes = new ArrayList<>();
118                     for (Prefixes px : gw.getPrefixes()) {
119                         ipPrefixes.add(IetfModelCodec.ipPrefix2013(px.getPrefix()));
120                     }
121                     eb.setPrefixes(ipPrefixes);
122                 }
123                 gateways.add(eb.build());
124             }
125             builder.setExternalGateways(gateways);
126         }
127
128         builder.setIpPrefix(IetfModelCodec.ipPrefix2013(gbpSubnet.getIpPrefix()));
129         builder.setUuid(getFaasSubnetId(gbpSubnet.getId()));
130         builder.setName(new Text(gbpSubnet.getId().getValue()));
131         if (gbpSubnet.getDescription() != null) {
132             builder.setDescription(new Text("gbp-subnet: " + gbpSubnet.getDescription().getValue()));
133         } else {
134             builder.setDescription(new Text("gbp-subnet"));
135         }
136         builder.setTenantId(faasTenantId);
137         builder.setVirtualRouterIp(IetfModelCodec.ipAddress2013(gbpSubnet.getVirtualRouterIp()));
138         // TODO DNS servers
139         builder.setDnsNameservers(null);
140         // TODO DHCP server
141         builder.setEnableDhcp(false);
142         return builder;
143     }
144
145     private Uuid getFaasSubnetId(SubnetId subnetId) {
146         Uuid val = mappedSubnets.get(subnetId);
147         if (val != null) {
148             return val;
149         }
150         Uuid faasSubnetId = null;
151         if (FaasPolicyManager.isUUid(subnetId.getValue())) {
152             faasSubnetId = new Uuid(subnetId.getValue());
153         } else {
154             faasSubnetId = new Uuid(UUID.randomUUID().toString());
155         }
156         mappedSubnets.putIfAbsent(subnetId, faasSubnetId);
157         val = mappedSubnets.get(subnetId);
158         MappedSubnetBuilder builder = new MappedSubnetBuilder();
159         builder.setFaasSubnetId(val);
160         builder.setGbpSubnetId(subnetId);
161         WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
162         MappedSubnet result = builder.build();
163         wTx.put(LogicalDatastoreType.OPERATIONAL,
164                 FaasIidFactory.mappedSubnetIid(gbpTenantId, subnetId), result);
165         if (DataStoreHelper.submitToDs(wTx)) {
166             LOG.debug("Cached in Datastore Mapped Subnet {}", result);
167         } else {
168             LOG.error("Couldn't Cache in Datastore Mapped Subnet {}", result);
169         }
170         return val;
171     }
172 }