38b0d6e344dccdddf3f824e8fbcda199d9660a60
[vpnservice.git] / nexthopmgr / nexthopmgr-impl / src / main / java / org / opendaylight / vpnservice / nexthopmgr / NexthopManager.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. 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.vpnservice.nexthopmgr;
9
10
11 import com.google.common.base.Optional;
12 import java.util.concurrent.Future;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.FutureCallback;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.yangtools.yang.binding.DataObject;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
19 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
20 import org.opendaylight.yangtools.yang.common.RpcResult;
21
22 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInstances;
25 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
26 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstanceKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstance1;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.*;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.*;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.tunnelnexthops.*;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.l3nexthop.rev150409.l3nexthop.vpnnexthops.*;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 public class NexthopManager implements L3nexthopService, AutoCloseable {
36     private static final Logger LOG = LoggerFactory.getLogger(NexthopManager.class);
37     private final DataBroker broker;
38
39     private static final FutureCallback<Void> DEFAULT_CALLBACK =
40         new FutureCallback<Void>() {
41             public void onSuccess(Void result) {
42                 LOG.info("Success in Datastore write operation");
43             }
44             public void onFailure(Throwable error) {
45                 LOG.error("Error in Datastore write operation", error);
46             };
47         };
48
49     /**
50     * Provides nexthop functions
51     * Creates group ID pool
52     *
53     * @param db - dataBroker reference
54     */
55     public NexthopManager(final DataBroker db) {
56         // create nexhhop ID pool
57       //  getIdManager.createIdPool("nextHopGroupIdPool", 10000, 100000);
58         broker = db;
59     }
60
61
62     @Override
63     public void close() throws Exception {
64         LOG.info("NextHop Manager Closed");
65     }
66
67
68     public void createLocalNextHop(String ifName, String vpnName, String ipAddress)
69     {
70         String nhKey = new String("nexthop." + vpnName + ipAddress);
71         int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
72
73         long vpnId = getVpnId(vpnName);
74         VpnNexthop nexthop = getVpnNexthop(vpnId, ipAddress);
75         if (nexthop == null) {
76
77          /*   List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
78             List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
79             BucketInfo bucket = new BucketInfo(listActionInfo);
80             // MAC re-write??
81             listBucketInfo.add(bucket);
82             GroupEntity groupEntity = MDSALUtil.buildGroupEntity
83                 (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
84             getMdsalApiManager().installGroup(groupEntity, objTransaction???);
85             */
86
87             //update MD-SAL DS
88             addVpnNexthopToDS(vpnId, ipAddress, groupId);
89         } else {
90             //check update
91         }
92     }
93
94     private long getVpnId(String vpnName) {
95         InstanceIdentifierBuilder<VpnInstance> idBuilder = InstanceIdentifier.builder(VpnInstances.class)
96                 .child(VpnInstance.class, new VpnInstanceKey(vpnName));
97
98         InstanceIdentifier<VpnInstance> id = idBuilder.build();
99         InstanceIdentifier<VpnInstance1> idx = id.augmentation(VpnInstance1.class);
100         Optional<VpnInstance1> vpn = read(LogicalDatastoreType.CONFIGURATION, idx);
101
102         if (vpn.isPresent()) return vpn.get().getVpnId();
103         else return 0;
104     }
105
106     private long getDpnId(String ifName) {
107         return 1;
108     }
109
110     public void createRemoteNextHop(String ifName, String ipAddress)
111     {
112         String nhKey = new String("nexthop." + ifName + ipAddress);
113         int groupId = 1;//getIdManager().getUniqueId("nextHopGroupIdPool", nhKey);
114
115         long dpnId = getDpnId(ifName);
116         TunnelNexthop nexthop = getTunnelNexthop(dpnId, ipAddress);
117         if (nexthop == null) {
118
119          /*   List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
120             List<ActionInfo> listActionInfo = interfacemgr.getEgressGroupActions(ifName);
121             BucketInfo bucket = new BucketInfo(listActionInfo);
122             // MAC re-write??
123             listBucketInfo.add(bucket);
124             GroupEntity groupEntity = MDSALUtil.buildGroupEntity
125                 (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
126             getMdsalApiManager().installGroup(groupEntity, objTransaction???);
127             */
128
129             //update MD-SAL DS
130             addTunnelNexthopToDS(dpnId, ipAddress, groupId);
131         } else {
132             //check update
133         }
134     }
135
136     private void addVpnNexthopToDS(long vpnId, String ipPrefix, long egressPointer){
137
138
139         InstanceIdentifierBuilder<VpnNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
140                 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId));
141
142         // check if vpn node is there or to be created
143         InstanceIdentifier<VpnNexthops> id = idBuilder.build();
144         Optional<VpnNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
145         if (!nexthops.isPresent()) {
146             // create a new node
147             VpnNexthops node = new VpnNexthopsBuilder().setKey(new VpnNexthopsKey(vpnId)).setVpnId(vpnId).build();
148             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
149         }
150
151         // Add nexthop to vpn node
152         VpnNexthop nh = new VpnNexthopBuilder().
153                 setKey(new VpnNexthopKey(ipPrefix)).
154                 setIpAddress(ipPrefix).
155                 setEgressPointer(egressPointer).build();
156
157         InstanceIdentifier<VpnNexthop> id1 = idBuilder
158                 .child(VpnNexthop.class, new VpnNexthopKey(ipPrefix)).build();
159
160         asyncWrite(LogicalDatastoreType.OPERATIONAL, id1, nh, DEFAULT_CALLBACK);
161
162     }
163
164     private void addTunnelNexthopToDS(long dpnId, String ipPrefix, long egressPointer){
165         InstanceIdentifierBuilder<TunnelNexthops> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
166                 .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId));
167
168         // check if dpn node is there or to be created
169         InstanceIdentifier<TunnelNexthops> id = idBuilder.build();
170         Optional<TunnelNexthops> nexthops = read(LogicalDatastoreType.CONFIGURATION, id);
171         if (!nexthops.isPresent()) {
172             // create a new node
173             TunnelNexthops node = new TunnelNexthopsBuilder().setKey(new TunnelNexthopsKey(dpnId)).setDpnId(dpnId).build();
174             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, node, DEFAULT_CALLBACK);
175         }
176
177         // Add nexthop to dpn node
178         TunnelNexthop nh = new TunnelNexthopBuilder().
179                 setKey(new TunnelNexthopKey(ipPrefix)).
180                 setIpAddress(ipPrefix).
181                 setEgressPointer(egressPointer).build();
182
183         InstanceIdentifier<TunnelNexthop> id1 = idBuilder
184                 .child(TunnelNexthop.class, new TunnelNexthopKey(ipPrefix)).build();
185
186         asyncWrite(LogicalDatastoreType.OPERATIONAL, id1, nh, DEFAULT_CALLBACK);
187
188     }
189
190     private VpnNexthop getVpnNexthop(long vpnId, String ipAddress) {
191
192         InstanceIdentifierBuilder<VpnNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
193                 .child(VpnNexthops.class, new VpnNexthopsKey(vpnId))
194                 .child(VpnNexthop.class, new VpnNexthopKey(ipAddress));
195         InstanceIdentifier<VpnNexthop> id = idBuilder.build();
196         Optional<VpnNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
197
198         if(nextHop.isPresent()) return nextHop.get();
199         else return null;
200     }
201
202     private TunnelNexthop getTunnelNexthop(long dpnId, String ipAddress) {
203         InstanceIdentifierBuilder<TunnelNexthop> idBuilder = InstanceIdentifier.builder(L3nexthop.class)
204                 .child(TunnelNexthops.class, new TunnelNexthopsKey(dpnId))
205                 .child(TunnelNexthop.class, new TunnelNexthopKey(ipAddress));
206         InstanceIdentifier<TunnelNexthop> id = idBuilder.build();
207         Optional<TunnelNexthop> nextHop = read(LogicalDatastoreType.CONFIGURATION, id);
208
209         if(nextHop.isPresent()) return nextHop.get();
210         else return null;
211     }
212
213     public long getNextHopPointer(long dpnId, long vpnId, String prefixIp, String nextHopIp) {
214         String endpointIp = "10.10.10.1";//interfaceManager.getLocalEndpointIp(dpnId);
215         if (nextHopIp.equals(endpointIp)) {
216             VpnNexthop vpnNextHop = getVpnNexthop(vpnId, prefixIp);
217             return vpnNextHop.getEgressPointer();
218         } else {
219             TunnelNexthop tunnelNextHop = getTunnelNexthop(dpnId, nextHopIp);
220             return tunnelNextHop.getEgressPointer();
221         }
222     }
223
224     public void removeRemoteNextHop(String ifname, String IpAddress)
225     {
226         String nhKey = new String("nexthop" + ifname + IpAddress);
227         int groupId = 1;//getIdManager().getUniqueId(L3Constants.L3NEXTHOP_GROUPID_POOL, nhKey);
228
229 /*        if (getNextHop(groupId) != Null){
230             List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
231             List<ActionInfo> listActionInfo = null;//nextHop.getActions({output to port});
232             BucketInfo bucket = new BucketInfo(listActionInfo);
233             listBucketInfo.add(bucket);
234             //GroupEntity groupEntity = MDSALUtil.buildGroupEntity
235               (dpId, groupId, IPAddress, GroupTypes.GroupIndirect, listBucketInfo);
236             //getMdsalApiManager().removeGroup(groupEntity, objTransaction???);
237
238             //update MD-SAL DS
239             removeNextHopFromDS(dpId, vpn, ipAddress);
240         }else{
241             //check update
242         }*/
243     }
244
245     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
246             InstanceIdentifier<T> path) {
247
248         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
249
250         Optional<T> result = Optional.absent();
251         try {
252             result = tx.read(datastoreType, path).get();
253         } catch (Exception e) {
254             throw new RuntimeException(e);
255         }
256
257         return result;
258     }
259
260     private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
261             InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
262         WriteTransaction tx = broker.newWriteOnlyTransaction();
263         tx.put(datastoreType, path, data, true);
264         Futures.addCallback(tx.submit(), callback);
265     }
266
267
268     @Override
269     public Future<RpcResult<GetEgressPointerOutput>> getEgressPointer(
270             GetEgressPointerInput input) {
271         long egressGroupId =
272                 getNextHopPointer(input.getDpnId(), input.getVpnId(), input.getIpPrefix(), input.getNexthopIp());
273
274         GetEgressPointerOutputBuilder output = new GetEgressPointerOutputBuilder();
275         output.setEgressPointer(egressGroupId);
276
277         /*RpcResult<GetEgressPointerOutput> result = Rpcs.<GetEgressPointerOutput> getRpcResult(false, output.build());
278         return Futures.immediateFuture(result);*/
279         return null;
280     }
281
282 }