c2afcc9459e2ddf18f626691c1ca77322bb3baf5
[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 java.util.ArrayList;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.UUID;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.concurrent.ScheduledExecutorService;
16
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
19 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.faas.uln.datastore.api.UlnDatastoreApi;
24 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
25 import org.opendaylight.groupbasedpolicy.util.IetfModelCodec;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Text;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.common.rev151013.Uuid;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.SubnetBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.subnet.ExternalGateways;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.faas.logical.faas.subnets.rev151013.subnets.container.subnets.subnet.ExternalGatewaysBuilder;
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.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedSubnet;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.faas.rev151009.mapped.tenants.entities.mapped.entity.MappedSubnetBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.Subnet;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.subnet.Gateways;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.subnet.gateways.Prefixes;
38 import org.opendaylight.yangtools.yang.binding.DataObject;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 import com.google.common.annotations.VisibleForTesting;
44 import com.google.common.base.Optional;
45
46 public class FaasSubnetManagerListener implements DataChangeListener {
47
48     private static final Logger LOG = LoggerFactory.getLogger(FaasSubnetManagerListener.class);
49     private ConcurrentHashMap<SubnetId, Uuid> mappedSubnets = new ConcurrentHashMap<>();
50     private final ScheduledExecutorService executor;
51     private final DataBroker dataProvider;
52     private final TenantId gbpTenantId;
53     private final Uuid faasTenantId;
54
55     public FaasSubnetManagerListener(DataBroker dataProvider, TenantId gbpTenantId, Uuid faasTenantId,
56             ScheduledExecutorService executor) {
57         this.executor = executor;
58         this.faasTenantId = faasTenantId;
59         this.gbpTenantId = gbpTenantId;
60         this.dataProvider = dataProvider;
61     }
62
63     @Override
64     public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
65         executor.execute(new Runnable() {
66
67             public void run() {
68                 executeEvent(change);
69             }
70         });
71     }
72
73     @VisibleForTesting
74     void executeEvent(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
75         // Create
76         for (DataObject dao : change.getCreatedData().values()) {
77             if (dao instanceof Subnet) {
78                 Subnet subnet = (Subnet) dao;
79                 LOG.debug("Subnet {} is Created.", subnet.getId().getValue());
80                 UlnDatastoreApi.submitSubnetToDs(initSubnetBuilder(subnet).build());
81             }
82         }
83         // Update
84         Map<InstanceIdentifier<?>, DataObject> dao = change.getUpdatedData();
85         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : dao.entrySet()) {
86             if (entry.getValue() instanceof Subnet) {
87                 Subnet subnet = (Subnet) entry.getValue();
88                 LOG.debug("Subnet {} is Updated.", subnet.getId().getValue());
89                 UlnDatastoreApi.submitSubnetToDs(initSubnetBuilder(subnet).build());
90             }
91         }
92         // Remove
93         for (InstanceIdentifier<?> iid : change.getRemovedPaths()) {
94             DataObject old = change.getOriginalData().get(iid);
95             if (old == null) {
96                 continue;
97             }
98             if (old instanceof Subnet) {
99                 Subnet subnet = (Subnet) old;
100                 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
101                 Optional<MappedSubnet> op = DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
102                         FaasIidFactory.mappedSubnetIid(gbpTenantId, subnet.getId()), rwTx);
103                 if (op.isPresent()) {
104                     DataStoreHelper.submitToDs(rwTx);
105                 }
106                 Uuid faasSubnetId = mappedSubnets.remove(subnet.getId());
107                 if (faasSubnetId != null) {
108                     UlnDatastoreApi.removeSubnetFromDsIfExists(faasTenantId, faasSubnetId);
109                 }
110             }
111         }
112     }
113
114     public void loadAll(List<Subnet> subnets, List<MappedSubnet> mpSubnets) {
115         if (mpSubnets != null) {
116             for (MappedSubnet mpSubnet : mpSubnets) {
117                 mappedSubnets.putIfAbsent(mpSubnet.getGbpSubnetId(), mpSubnet.getFaasSubnetId());
118             }
119         }
120         if (subnets != null) {
121             for (Subnet subnet : subnets) {
122                 LOG.debug("Loading Subnet {}", subnet.getId().getValue());
123                 UlnDatastoreApi.submitSubnetToDs(initSubnetBuilder(subnet).build());
124             }
125         }
126     }
127
128     protected SubnetBuilder initSubnetBuilder(Subnet gbpSubnet) {
129         SubnetBuilder builder = new SubnetBuilder();
130         if (gbpSubnet.getGateways() != null) {
131             List<ExternalGateways> gateways = new ArrayList<>();
132             for (Gateways gw : gbpSubnet.getGateways()) {
133                 ExternalGatewaysBuilder eb = new ExternalGatewaysBuilder();
134                 eb.setExternalGateway(IetfModelCodec.ipAddress2013(gw.getGateway()));
135                 if (gw.getPrefixes() != null) {
136                     List<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix> ipPrefixes = new ArrayList<>();
137                     for (Prefixes px : gw.getPrefixes()) {
138                         ipPrefixes.add(IetfModelCodec.ipPrefix2013(px.getPrefix()));
139                     }
140                     eb.setPrefixes(ipPrefixes);
141                 }
142                 gateways.add(eb.build());
143             }
144             builder.setExternalGateways(gateways);
145         }
146
147         builder.setIpPrefix(IetfModelCodec.ipPrefix2013(gbpSubnet.getIpPrefix()));
148         builder.setUuid(getFaasSubnetId(gbpSubnet.getId()));
149         builder.setName(new Text(gbpSubnet.getId().getValue()));
150         if (gbpSubnet.getDescription() != null)
151             builder.setDescription(new Text("gbp-subnet: " + gbpSubnet.getDescription().getValue()));
152         else
153             builder.setDescription(new Text("gbp-subnet"));
154         builder.setTenantId(faasTenantId);
155         builder.setVirtualRouterIp(IetfModelCodec.ipAddress2013(gbpSubnet.getVirtualRouterIp()));
156         // TODO DNS servers
157         builder.setDnsNameservers(null);
158         // TODO DHCP server
159         builder.setEnableDhcp(false);
160         return builder;
161     }
162
163     private Uuid getFaasSubnetId(SubnetId subnetId) {
164         Uuid val = mappedSubnets.get(subnetId);
165         if (val != null) {
166             return val;
167         }
168         Uuid faasSubnetId = null;
169         if (FaasPolicyManager.isUUid(subnetId.getValue())) {
170             faasSubnetId = new Uuid(subnetId.getValue());
171         } else {
172             faasSubnetId = new Uuid(UUID.randomUUID().toString());
173         }
174         mappedSubnets.putIfAbsent(subnetId, faasSubnetId);
175         val = mappedSubnets.get(subnetId);
176         MappedSubnetBuilder builder = new MappedSubnetBuilder();
177         builder.setFaasSubnetId(val);
178         builder.setGbpSubnetId(subnetId);
179         WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
180         MappedSubnet result = builder.build();
181         wTx.put(LogicalDatastoreType.OPERATIONAL,
182                 FaasIidFactory.mappedSubnetIid(gbpTenantId, subnetId), result);
183         if (DataStoreHelper.submitToDs(wTx)) {
184             LOG.debug("Cached in Datastore Mapped Subnet {}", result);
185         } else {
186             LOG.error("Couldn't Cache in Datastore Mapped Subnet {}", result);
187         }
188         return val;
189     }
190
191 }