2 * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.itm.impl;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.math.BigInteger;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.concurrent.ExecutionException;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18 import javax.annotation.PostConstruct;
19 import javax.annotation.PreDestroy;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
23 import org.apache.felix.service.command.CommandSession;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
27 import org.opendaylight.genius.itm.api.IITMProvider;
28 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
29 import org.opendaylight.genius.itm.cli.TepCommandHelper;
30 import org.opendaylight.genius.itm.cli.TepException;
31 import org.opendaylight.genius.itm.globals.ITMConstants;
32 import org.opendaylight.genius.itm.listeners.InterfaceStateListener;
33 import org.opendaylight.genius.itm.listeners.OvsdbNodeListener;
34 import org.opendaylight.genius.itm.listeners.TransportZoneListener;
35 import org.opendaylight.genius.itm.listeners.TunnelMonitorChangeListener;
36 import org.opendaylight.genius.itm.listeners.TunnelMonitorIntervalListener;
37 import org.opendaylight.genius.itm.listeners.VtepConfigSchemaListener;
38 import org.opendaylight.genius.itm.monitoring.ItmTunnelEventListener;
39 import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
40 import org.opendaylight.genius.mdsalutil.MDSALUtil;
41 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
42 import org.opendaylight.mdsal.eos.binding.api.Entity;
43 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
44 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
45 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInputBuilder;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.ops4j.pax.cdi.api.OsgiServiceProvider;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
68 public class ItmProvider implements AutoCloseable, IITMProvider /*,ItmStateService */ {
70 private static final Logger LOG = LoggerFactory.getLogger(ItmProvider.class);
72 private final DataBroker dataBroker;
73 private final ItmManagerRpcService itmRpcService ;
74 private final IdManagerService idManager;
75 private final TepCommandHelper tepCommandHelper;
76 private final TransportZoneListener tzChangeListener;
77 private final TunnelMonitorChangeListener tnlToggleListener;
78 private final TunnelMonitorIntervalListener tnlIntervalListener;
79 private final VtepConfigSchemaListener vtepConfigSchemaListener;
80 private final InterfaceStateListener ifStateListener;
81 private final EntityOwnershipService entityOwnershipService;
82 private RpcProviderRegistry rpcProviderRegistry;
83 private final ItmTunnelEventListener itmStateListener;
84 private final OvsdbNodeListener ovsdbChangeListener;
85 static short flag = 0;
86 private final TunnelMonitoringConfig tunnelMonitoringConfig;
87 private EntityOwnershipCandidateRegistration registryCandidate;
88 private final DpnTepStateCache dpnTepStateCache;
91 public ItmProvider(DataBroker dataBroker,
92 IdManagerService idManagerService,
93 InterfaceStateListener interfaceStateListener,
94 ItmManagerRpcService itmManagerRpcService,
95 ItmTunnelEventListener itmTunnelEventListener,
96 TepCommandHelper tepCommandHelper,
97 TunnelMonitorChangeListener tunnelMonitorChangeListener,
98 TunnelMonitorIntervalListener tunnelMonitorIntervalListener,
99 TransportZoneListener transportZoneListener,
100 VtepConfigSchemaListener vtepConfigSchemaListener,
101 OvsdbNodeListener ovsdbNodeListener,
102 TunnelMonitoringConfig tunnelMonitoringConfig,
103 EntityOwnershipService entityOwnershipService,
104 DpnTepStateCache dpnTepStateCache) {
105 LOG.info("ItmProvider Before register MBean");
106 this.dataBroker = dataBroker;
107 this.idManager = idManagerService;
108 this.ifStateListener = interfaceStateListener;
109 this.itmRpcService = itmManagerRpcService;
110 this.itmStateListener = itmTunnelEventListener;
111 this.tepCommandHelper = tepCommandHelper;
112 this.tnlToggleListener = tunnelMonitorChangeListener;
113 this.tnlIntervalListener = tunnelMonitorIntervalListener;
114 this.tzChangeListener = transportZoneListener;
115 this.vtepConfigSchemaListener = vtepConfigSchemaListener;
116 this.ovsdbChangeListener = ovsdbNodeListener;
117 this.tunnelMonitoringConfig = tunnelMonitoringConfig;
118 this.entityOwnershipService = entityOwnershipService;
119 this.dpnTepStateCache = dpnTepStateCache;
120 ITMBatchingUtils.registerWithBatchManager(this.dataBroker);
124 @SuppressWarnings("checkstyle:IllegalCatch")
125 public void start() {
128 registerEntityForOwnership();
129 LOG.info("ItmProvider Started");
130 } catch (Exception ex) {
131 LOG.info("ItmProvider failed to start");
135 private void registerEntityForOwnership() {
137 this.registryCandidate = entityOwnershipService
138 .registerCandidate(new Entity(ITMConstants.ITM_CONFIG_ENTITY, ITMConstants.ITM_CONFIG_ENTITY));
139 } catch (CandidateAlreadyRegisteredException e) {
140 LOG.error("failed to register entity {} for entity-ownership-service", e.getEntity());
146 public void close() {
147 if (tzChangeListener != null) {
148 tzChangeListener.close();
150 if (tnlIntervalListener != null) {
151 tnlIntervalListener.close();
153 if (tnlToggleListener != null) {
154 tnlToggleListener.close();
156 if (ovsdbChangeListener != null) {
157 ovsdbChangeListener.close();
159 if (registryCandidate != null) {
160 registryCandidate.close();
162 LOG.info("ItmProvider Closed");
165 private void createIdPool() {
166 CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
167 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
168 .setLow(ITMConstants.ITM_IDPOOL_START)
169 .setHigh(new BigInteger(ITMConstants.ITM_IDPOOL_SIZE).longValue())
172 ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
173 if (result != null && result.get().isSuccessful()) {
174 LOG.debug("Created IdPool for ITM Service");
176 } catch (InterruptedException | ExecutionException e) {
177 LOG.error("Failed to create idPool for ITM Service ", e);
182 public DataBroker getDataBroker() {
187 public void addExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
188 AddExternalTunnelEndpointInput addExternalTunnelEndpointInput =
189 new AddExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
190 .setDestinationIp(dcgwIP).build();
191 JdkFutures.addErrorLogging(itmRpcService.addExternalTunnelEndpoint(addExternalTunnelEndpointInput),
192 LOG, "addExternalTunnelEndpoint");
196 public void remExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
197 RemoveExternalTunnelEndpointInput removeExternalTunnelEndpointInput =
198 new RemoveExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
199 .setDestinationIp(dcgwIP).build();
200 JdkFutures.addErrorLogging(itmRpcService.removeExternalTunnelEndpoint(removeExternalTunnelEndpointInput),
201 LOG, "removeExternalTunnelEndpoint");
205 public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
206 String gatewayIp, String transportZone, CommandSession session) {
207 if (tepCommandHelper != null) {
209 tepCommandHelper.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask,
210 gatewayIp, transportZone, session);
211 } catch (TepException e) {
212 LOG.error("Create Local Cache failed", e);
215 LOG.trace("tepCommandHelper doesnt exist");
220 public void commitTeps() {
221 tepCommandHelper.deleteOnCommit();
222 tepCommandHelper.buildTeps();
226 public void showTeps(CommandSession session) {
228 tepCommandHelper.showTeps(tunnelMonitoringConfig.isTunnelMonitoringEnabled(),
229 tunnelMonitoringConfig.getMonitorInterval(), session);
230 } catch (TepException e) {
231 LOG.error("show teps failed", e);
236 public void showState(Collection<StateTunnelList> tunnels) {
237 if (tunnels != null) {
239 tepCommandHelper.showState(tunnels, tunnelMonitoringConfig.isTunnelMonitoringEnabled());
240 } catch (TepException e) {
241 LOG.error("show state failed", e);
244 LOG.debug("No tunnels available");
249 public void showCache(String cacheName) {
250 tepCommandHelper.showCache(cacheName);
254 public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
255 String gatewayIp, String transportZone, CommandSession session) {
257 tepCommandHelper.deleteVtep(dpnId, portName, vlanId, ipAddress,
258 subnetMask, gatewayIp, transportZone, session);
259 } catch (TepException e) {
260 LOG.error("Delete Vteps Failed", e);
265 public void configureTunnelType(String transportZone, String tunnelType) {
266 LOG .debug("ItmProvider: configureTunnelType {} for transportZone {}", tunnelType, transportZone);
267 tepCommandHelper.configureTunnelType(transportZone,tunnelType);
271 public void addVtepConfigSchema(VtepConfigSchema vtepConfigSchema) {
272 VtepConfigSchema validatedSchema = ItmUtils.validateForAddVtepConfigSchema(vtepConfigSchema,
273 getAllVtepConfigSchemas());
275 String schemaName = validatedSchema.getSchemaName();
276 VtepConfigSchema existingSchema = getVtepConfigSchema(schemaName);
277 if (existingSchema != null) {
278 Preconditions.checkArgument(false, String.format("VtepConfigSchema [%s] already exists!", schemaName));
280 MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
281 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), validatedSchema);
282 LOG.debug("Vtep config schema {} added to config DS", schemaName);
286 public VtepConfigSchema getVtepConfigSchema(String schemaName) {
287 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemaIdentifier(schemaName),
288 this.dataBroker).orNull();
292 public List<VtepConfigSchema> getAllVtepConfigSchemas() {
293 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemasIdentifier(),
294 this.dataBroker).toJavaUtil().map(VtepConfigSchemas::getVtepConfigSchema).orElse(null);
298 public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete) {
299 LOG.trace("Updating VTEP schema {} by adding DPN's {} and deleting DPN's {}.", schemaName, lstDpnsForAdd,
302 VtepConfigSchema schema = ItmUtils.validateForUpdateVtepSchema(schemaName, lstDpnsForAdd, lstDpnsForDelete,
304 VtepConfigSchemaBuilder builder = new VtepConfigSchemaBuilder(schema);
305 /* if (ItmUtils.getDpnIdList(schema.getDpnIds()).isEmpty()) {
306 builder.setDpnIds(schema.getDpnIds());
308 if (lstDpnsForAdd != null && !lstDpnsForAdd.isEmpty()) {
309 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds());
310 originalDpnList.addAll(lstDpnsForAdd) ;
311 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
313 if (lstDpnsForDelete != null && !lstDpnsForDelete.isEmpty()) {
314 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds());
315 originalDpnList.removeAll(lstDpnsForDelete) ;
316 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
317 // schema.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(ItmUtils.getDpnIdList(schema.getDpnIds())
318 // .removeAll(lstDpnsForAdd)));
321 schema = builder.build();
322 MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
323 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), schema);
324 LOG.debug("Vtep config schema {} updated to config DS with DPN's {}",
325 schemaName, ItmUtils.getDpnIdList(schema.getDpnIds()));
329 public void deleteAllVtepSchemas() {
330 List<VtepConfigSchema> lstSchemas = getAllVtepConfigSchemas();
331 if (lstSchemas != null && !lstSchemas.isEmpty()) {
332 for (VtepConfigSchema schema : lstSchemas) {
333 MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
334 ItmUtils.getVtepConfigSchemaIdentifier(schema.getSchemaName()));
337 LOG.debug("Deleted all Vtep schemas from config DS");
341 public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
342 tepCommandHelper.configureTunnelMonitorParams(monitorEnabled, monitorProtocol);
346 public void configureTunnelMonitorInterval(int interval) {
347 tepCommandHelper.configureTunnelMonitorInterval(interval);
351 public boolean validateIP(final String ip) {
352 if (ip == null || ip.isEmpty() || "null".equals(ip) || "0.0.0.0".equals(ip)) {
356 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
357 Pattern pattern = Pattern.compile(PTRN);
358 Matcher matcher = pattern.matcher(ip);
359 return matcher.matches();
363 public Interface getInterface(String tunnelName) {
364 return dpnTepStateCache.getInterfaceFromCache(tunnelName);