Remove redundant names in paths
[netvirt.git] / neutronvpn / impl / src / main / java / org / opendaylight / netvirt / neutronvpn / evpn / manager / NeutronEvpnManager.java
1 /*
2  * Copyright © 2017 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.neutronvpn.evpn.manager;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.SettableFuture;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
18 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
19 import org.opendaylight.netvirt.neutronvpn.NeutronvpnManager;
20 import org.opendaylight.netvirt.neutronvpn.NeutronvpnUtils;
21 import org.opendaylight.netvirt.vpnmanager.api.VpnHelper;
22 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.af.config.vpntargets.VpnTarget;
23 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.instances.VpnInstance;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.CreateEVPNOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteEVPNInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteEVPNOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.DeleteEVPNOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetEVPNInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetEVPNOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.GetEVPNOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.createevpn.input.Evpn;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getevpn.output.EvpnInstances;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.getevpn.output.EvpnInstancesBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.opendaylight.yangtools.yang.common.RpcError;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48 public class NeutronEvpnManager {
49     private static final Logger LOG = LoggerFactory.getLogger(NeutronEvpnManager.class);
50     private final DataBroker dataBroker;
51     private final NeutronvpnManager neutronvpnManager;
52     private final NeutronvpnUtils neutronvpnUtils;
53
54     public NeutronEvpnManager(DataBroker dataBroker, NeutronvpnManager neutronvpnManager,
55             NeutronvpnUtils neutronvpnUtils) {
56         this.dataBroker = dataBroker;
57         this.neutronvpnManager = neutronvpnManager;
58         this.neutronvpnUtils = neutronvpnUtils;
59     }
60
61     @SuppressWarnings("checkstyle:IllegalCatch")
62     public Future<RpcResult<CreateEVPNOutput>> createEVPN(CreateEVPNInput input) {
63         CreateEVPNOutputBuilder opBuilder = new CreateEVPNOutputBuilder();
64         SettableFuture<RpcResult<CreateEVPNOutput>> result = SettableFuture.create();
65         List<RpcError> errorList = new ArrayList<>();
66         int failurecount = 0;
67         int warningcount = 0;
68         List<String> existingRDs = neutronvpnUtils.getExistingRDs();
69
70         List<Evpn> vpns = input.getEvpn();
71         for (Evpn vpn : vpns) {
72             if (vpn.getRouteDistinguisher() == null || vpn.getImportRT() == null || vpn.getExportRT() == null) {
73                 String msg = String.format("Creation of EVPN failed for VPN %s due to absence of RD/iRT/eRT input",
74                         vpn.getId().getValue());
75                 LOG.warn(msg);
76                 RpcError error = RpcResultBuilder.newWarning(RpcError.ErrorType.PROTOCOL, "invalid-input", msg);
77                 errorList.add(error);
78                 warningcount++;
79                 continue;
80             }
81             VpnInstance.Type vpnInstanceType = VpnInstance.Type.L2;
82             if (vpn.getRouteDistinguisher().size() > 1) {
83                 String msg = String.format("Creation of EVPN failed for VPN %s due to multiple RD input %s",
84                         vpn.getId().getValue(), vpn.getRouteDistinguisher());
85                 LOG.warn(msg);
86                 RpcError error = RpcResultBuilder.newWarning(RpcError.ErrorType.PROTOCOL, "invalid-input", msg);
87                 errorList.add(error);
88                 warningcount++;
89                 continue;
90             }
91             if (existingRDs.contains(vpn.getRouteDistinguisher().get(0))) {
92                 String msg = String.format("Creation of EVPN failed for VPN %s as another VPN with "
93                         + "the same RD %s is already configured",
94                         vpn.getId().getValue(), vpn.getRouteDistinguisher().get(0));
95                 LOG.warn(msg);
96                 RpcError error = RpcResultBuilder.newWarning(RpcError.ErrorType.PROTOCOL, "invalid-input", msg);
97                 errorList.add(error);
98                 warningcount++;
99                 continue;
100             }
101             try {
102                 neutronvpnManager.createVpn(vpn.getId(), vpn.getName(), vpn.getTenantId(), vpn.getRouteDistinguisher(),
103                         vpn.getImportRT(), vpn.getExportRT(), null /*router-id*/, null /*network-id*/,
104                         vpnInstanceType, 0 /*l2vni*/);
105             } catch (Exception ex) {
106                 String msg = String.format("Creation of EVPN failed for VPN %s", vpn.getId().getValue());
107                 LOG.error(msg, ex);
108                 RpcError error = RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, msg, ex.getMessage());
109                 errorList.add(error);
110                 failurecount++;
111             }
112         }
113         if (failurecount != 0) {
114             result.set(RpcResultBuilder.<CreateEVPNOutput>failed().withRpcErrors(errorList).build());
115         } else {
116             List<String> errorResponseList = new ArrayList<>();
117             if (!errorList.isEmpty()) {
118                 for (RpcError rpcError : errorList) {
119                     String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
120                             .getErrorType(), rpcError.getTag(), rpcError.getMessage());
121                     errorResponseList.add(errorResponse);
122                 }
123             } else {
124                 errorResponseList.add("EVPN creation successful with no errors");
125             }
126             opBuilder.setResponse(errorResponseList);
127             result.set(RpcResultBuilder.<CreateEVPNOutput>success().withResult(opBuilder.build()).build());
128         }
129         return result;
130     }
131
132     public Future<RpcResult<GetEVPNOutput>> getEVPN(GetEVPNInput input) {
133         GetEVPNOutputBuilder opBuilder = new GetEVPNOutputBuilder();
134         SettableFuture<RpcResult<GetEVPNOutput>> result = SettableFuture.create();
135         Uuid inputVpnId = input.getId();
136         List<VpnInstance> vpns = new ArrayList<>();
137         if (inputVpnId == null) {
138             vpns = VpnHelper.getAllVpnInstances(dataBroker);
139             if (!vpns.isEmpty()) {
140                 for (VpnInstance vpn : vpns) {
141                     if (vpn.getIpv4Family().getRouteDistinguisher() != null
142                             && vpn.getType() == VpnInstance.Type.L2) {
143                         vpns.add(vpn);
144                     }
145                 }
146             } else {
147                 // No VPN present
148                 result.set(RpcResultBuilder.<GetEVPNOutput>success().withResult(opBuilder.build()).build());
149                 return result;
150             }
151         } else {
152             String name = inputVpnId.getValue();
153             VpnInstance vpnInstance = VpnHelper.getVpnInstance(dataBroker, name);
154             if (vpnInstance != null && vpnInstance.getIpv4Family().getRouteDistinguisher() != null
155                     && vpnInstance.getType() == VpnInstance.Type.L2) {
156                 vpns.add(vpnInstance);
157             } else {
158                 String message = String.format("GetEVPN failed because VPN %s is not present", name);
159                 LOG.error(message);
160                 result.set(RpcResultBuilder.<GetEVPNOutput>failed().withWarning(RpcError.ErrorType.PROTOCOL,
161                         "invalid-value", message).build());
162             }
163         }
164         List<EvpnInstances> evpnList = new ArrayList<>();
165         for (VpnInstance vpnInstance : vpns) {
166             Uuid vpnId = new Uuid(vpnInstance.getVpnInstanceName());
167             InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap
168                     .class, new VpnMapKey(vpnId)).build();
169             EvpnInstancesBuilder evpn = new EvpnInstancesBuilder();
170             List<String> rd = vpnInstance.getIpv4Family().getRouteDistinguisher();
171             List<VpnTarget> vpnTargetList = vpnInstance.getIpv4Family().getVpnTargets().getVpnTarget();
172             List<String> ertList = new ArrayList<>();
173             List<String> irtList = new ArrayList<>();
174             for (VpnTarget vpnTarget : vpnTargetList) {
175                 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ExportExtcommunity) {
176                     ertList.add(vpnTarget.getVrfRTValue());
177                 }
178                 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.ImportExtcommunity) {
179                     irtList.add(vpnTarget.getVrfRTValue());
180                 }
181                 if (vpnTarget.getVrfRTType() == VpnTarget.VrfRTType.Both) {
182                     ertList.add(vpnTarget.getVrfRTValue());
183                     irtList.add(vpnTarget.getVrfRTValue());
184                 }
185             }
186             evpn.setId(vpnId).setRouteDistinguisher(rd).setImportRT(irtList).setExportRT(ertList);
187             try {
188                 Optional<VpnMap> optionalVpnMap =
189                         SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
190                                 vpnMapIdentifier);
191                 if (optionalVpnMap.isPresent()) {
192                     VpnMap vpnMap = optionalVpnMap.get();
193                     evpn.setTenantId(vpnMap.getTenantId()).setName(vpnMap.getName());
194                 }
195             } catch (ReadFailedException e) {
196                 LOG.error("Error reading the VPN map for {}", vpnMapIdentifier, e);
197                 result.set(RpcResultBuilder.<GetEVPNOutput>failed().withError(RpcError.ErrorType.APPLICATION,
198                         "Error reading the VPN map for " + vpnMapIdentifier, e).build());
199                 return result;
200             }
201             evpnList.add(evpn.build());
202         }
203
204         opBuilder.setEvpnInstances(evpnList);
205         result.set(RpcResultBuilder.<GetEVPNOutput>success().withResult(opBuilder.build()).build());
206         return result;
207     }
208
209     public Future<RpcResult<DeleteEVPNOutput>> deleteEVPN(DeleteEVPNInput input) {
210         DeleteEVPNOutputBuilder opBuilder = new DeleteEVPNOutputBuilder();
211         SettableFuture<RpcResult<DeleteEVPNOutput>> result = SettableFuture.create();
212         List<RpcError> errorList = new ArrayList<>();
213
214         int failurecount = 0;
215         int warningcount = 0;
216         List<Uuid> vpns = input.getId();
217         for (Uuid vpn : vpns) {
218             RpcError error;
219             String msg;
220             VpnInstance vpnInstance = VpnHelper.getVpnInstance(dataBroker, vpn.getValue());
221             if (vpnInstance != null) {
222                 neutronvpnManager.removeVpn(vpn);
223             } else {
224                 msg = String.format("EVPN with vpnid: %s does not exist", vpn.getValue());
225                 LOG.warn(msg);
226                 error = RpcResultBuilder.newWarning(RpcError.ErrorType.PROTOCOL, "invalid-value", msg);
227                 errorList.add(error);
228                 warningcount++;
229             }
230         }
231         if (failurecount != 0) {
232             result.set(RpcResultBuilder.<DeleteEVPNOutput>failed().withRpcErrors(errorList).build());
233         } else {
234             List<String> errorResponseList = new ArrayList<>();
235             if (!errorList.isEmpty()) {
236                 for (RpcError rpcError : errorList) {
237                     String errorResponse = String.format("ErrorType: %s, ErrorTag: %s, ErrorMessage: %s", rpcError
238                             .getErrorType(), rpcError.getTag(), rpcError.getMessage());
239                     errorResponseList.add(errorResponse);
240                 }
241             } else {
242                 errorResponseList.add("Deletion of EVPN operation successful");
243             }
244             opBuilder.setResponse(errorResponseList);
245             result.set(RpcResultBuilder.<DeleteEVPNOutput>success().withResult(opBuilder.build()).build());
246         }
247         return result;
248     }
249 }