Add blueprint wiring for vpnmanager
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / VpnRpcServiceImpl.java
1 /*
2  * Copyright (c) 2016 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.netvirt.vpnmanager;
9
10 import com.google.common.util.concurrent.SettableFuture;
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
13 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.vpn.rpc.rev160201.*;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.inter.vpn.link.rev160311.inter.vpn.links.InterVpnLink;
17 import org.opendaylight.yangtools.yang.common.RpcError;
18 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
19 import org.opendaylight.yangtools.yang.common.RpcResult;
20 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.concurrent.Future;
28
29 public class VpnRpcServiceImpl implements VpnRpcService {
30     private static final Logger LOG = LoggerFactory.getLogger(VpnRpcServiceImpl.class);
31     private final DataBroker dataBroker;
32     private final IdManagerService idManager;
33     private final VpnInterfaceManager vpnInterfaceMgr;
34     private final IFibManager fibManager;
35
36     public VpnRpcServiceImpl(final DataBroker dataBroker, final IdManagerService idManager,
37                              final VpnInterfaceManager vpnIfaceMgr, final IFibManager fibManager) {
38         this.dataBroker = dataBroker;
39         this.idManager = idManager;
40         this.vpnInterfaceMgr = vpnIfaceMgr;
41         this.fibManager = fibManager;
42     }
43
44     /**
45      * to generate label for the given ip prefix from the associated VPN
46      *
47      */
48     @Override
49     public Future<RpcResult<GenerateVpnLabelOutput>> generateVpnLabel(GenerateVpnLabelInput input) {
50         String vpnName = input.getVpnName();
51         String ipPrefix = input.getIpPrefix();
52         SettableFuture<RpcResult<GenerateVpnLabelOutput>> futureResult = SettableFuture.create();
53         String rd = VpnUtil.getVpnRd(dataBroker, vpnName);
54         long label = VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
55                         VpnUtil.getNextHopLabelKey((rd != null) ? rd : vpnName, ipPrefix));
56         if (label == 0) {
57             String msg = String.format("Could not retrieve the label for prefix {} in VPN {}", ipPrefix, vpnName);
58             LOG.error(msg);
59             futureResult.set(RpcResultBuilder.<GenerateVpnLabelOutput>failed().withError(ErrorType.APPLICATION, msg)
60                                                                               .build());
61         } else {
62             GenerateVpnLabelOutput output = new GenerateVpnLabelOutputBuilder().setLabel(label).build();
63             futureResult.set(RpcResultBuilder.success(output).build());
64         }
65         return futureResult;
66     }
67
68     /**
69      * to remove label for the given ip prefix from the associated VPN
70      *
71      */
72     @Override
73     public Future<RpcResult<Void>> removeVpnLabel(RemoveVpnLabelInput input) {
74         String vpnName = input.getVpnName();
75         String ipPrefix = input.getIpPrefix();
76         String rd = VpnUtil.getVpnRd(dataBroker, vpnName);
77         SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
78         VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
79                 VpnUtil.getNextHopLabelKey((rd != null) ? rd : vpnName, ipPrefix));
80         futureResult.set(RpcResultBuilder.<Void>success().build());
81         return futureResult;
82     }
83
84     private Collection<RpcError> validateAddStaticRouteInput(AddStaticRouteInput input) {
85         Collection<RpcError> rpcErrors = new ArrayList<RpcError>();
86         String destination = input.getDestination();
87         String vpnInstanceName = input.getVpnInstanceName();
88         String nexthop = input.getNexthop();
89         if ( destination == null || destination.isEmpty() ) {
90             String message = "destination parameter is mandatory";
91             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "addStaticRoute", message));
92         }
93         if ( vpnInstanceName == null || vpnInstanceName.isEmpty() ) {
94             String message = "vpnInstanceName parameter is mandatory";
95             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "addStaticRoute", message));
96         }
97         if ( nexthop == null || nexthop.isEmpty() ) {
98             String message = "nexthop parameter is mandatory";
99             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "addStaticRoute", message));
100         }
101         return rpcErrors;
102     }
103
104     @Override
105     public Future<RpcResult<AddStaticRouteOutput>> addStaticRoute(AddStaticRouteInput input) {
106
107         SettableFuture<RpcResult<AddStaticRouteOutput>> result = SettableFuture.create();
108         String destination = input.getDestination();
109         String vpnInstanceName = input.getVpnInstanceName();
110         String nexthop = input.getNexthop();
111         Long label = input.getLabel();
112         LOG.info("Adding static route for Vpn {} with destination {}, nexthop {} and label {}",
113                  vpnInstanceName, destination, nexthop, label);
114
115         Collection<RpcError> rpcErrors = validateAddStaticRouteInput(input);
116         if ( !rpcErrors.isEmpty() ) {
117             result.set(RpcResultBuilder.<AddStaticRouteOutput>failed().withRpcErrors(rpcErrors).build());
118             return result;
119         }
120
121         if ( label == null || label == 0 ) {
122             label = (long) VpnUtil.getUniqueId(idManager, VpnConstants.VPN_IDPOOL_NAME,
123                                                VpnUtil.getNextHopLabelKey(vpnInstanceName, destination));
124             if ( label == 0 ) {
125                 String message = "Unable to retrieve a new Label for the new Route";
126                 result.set(RpcResultBuilder.<AddStaticRouteOutput>failed().withError(RpcError.ErrorType.APPLICATION,
127                                                                                      message).build());
128                 return result;
129             }
130         }
131
132         String vpnRd = VpnUtil.getVpnRd(dataBroker, input.getVpnInstanceName());
133         if ( vpnRd == null ) {
134             String message = "Could not find Route-Distinguisher for VpnName " + vpnInstanceName;
135             result.set(RpcResultBuilder.<AddStaticRouteOutput>failed().withError(RpcError.ErrorType.APPLICATION,
136                                                                                  message).build());
137             return result;
138         }
139
140         InterVpnLink interVpnLink = VpnUtil.getInterVpnLinkByEndpointIp(dataBroker, nexthop);
141         if ( interVpnLink != null ) {
142             // A static route pointing to an InterVpnLink endpoint: just write the VrfEntry
143             fibManager.addOrUpdateFibEntry(dataBroker, vpnRd, destination, Arrays.asList(nexthop), label.intValue(), RouteOrigin.STATIC, null);
144         } else {
145             vpnInterfaceMgr.addExtraRoute(destination, nexthop, vpnRd, null /*routerId */, label.intValue(),
146                                           null /* intfName */);
147         }
148
149         AddStaticRouteOutput labelOutput = new AddStaticRouteOutputBuilder().setLabel(label).build();
150         result.set(RpcResultBuilder.success(labelOutput).build());
151         return result;
152     }
153
154     private Collection<RpcError> validateRemoveStaticRouteInput(RemoveStaticRouteInput input) {
155         Collection<RpcError> rpcErrors = new ArrayList<RpcError>();
156         String destination = input.getDestination();
157         String vpnInstanceName = input.getVpnInstanceName();
158         String nexthop = input.getNexthop();
159         if ( destination == null || destination.isEmpty() ) {
160             String message = "destination parameter is mandatory";
161             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "removeStaticRoute", message));
162         }
163         if ( vpnInstanceName == null || vpnInstanceName.isEmpty() ) {
164             String message = "vpnInstanceName parameter is mandatory";
165             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "removeStaticRoute", message));
166         }
167         if ( nexthop == null || nexthop.isEmpty() ) {
168             String message = "nexthop parameter is mandatory";
169             rpcErrors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, "removeStaticRoute", message));
170         }
171         return rpcErrors;
172     }
173
174     @Override
175     public Future<RpcResult<Void>> removeStaticRoute(RemoveStaticRouteInput input) {
176
177         SettableFuture<RpcResult<Void>> result = SettableFuture.create();
178
179         String destination = input.getDestination();
180         String vpnInstanceName = input.getVpnInstanceName();
181         String nexthop = input.getNexthop();
182         LOG.info("Removing static route with destination={}, nexthop={} in VPN={}",
183                  destination, nexthop, vpnInstanceName);
184         Collection<RpcError> rpcErrors = validateRemoveStaticRouteInput(input);
185         if ( !rpcErrors.isEmpty() ) {
186             result.set(RpcResultBuilder.<Void>failed().withRpcErrors(rpcErrors).build());
187             return result;
188         }
189
190         String vpnRd = VpnUtil.getVpnRd(dataBroker, input.getVpnInstanceName());
191         if ( vpnRd == null ) {
192             String message = "Could not find Route-Distinguisher for VpnName " + vpnInstanceName;
193             result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, message).build());
194             return result;
195         }
196
197         InterVpnLink interVpnLink = VpnUtil.getInterVpnLinkByEndpointIp(dataBroker, nexthop);
198         if ( interVpnLink != null ) {
199             // A static route pointing to an InterVpnLink endpoint: just remove the VrfEntry from DS
200             fibManager.removeOrUpdateFibEntry(dataBroker,  vpnRd, destination, nexthop, null);
201         } else {
202             vpnInterfaceMgr.delExtraRoute(destination, nexthop, vpnRd, null /*routerId*/, null /*intfName*/);
203         }
204         result.set(RpcResultBuilder.<Void>success().build());
205
206         return result;
207     }
208
209 }