Drop unused exceptions in dhcpservice
[netvirt.git] / dhcpservice / impl / src / main / java / org / opendaylight / netvirt / dhcpservice / DhcpAllocationPoolManager.java
1 /*
2  * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.dhcpservice;
9
10 import com.google.common.base.Optional;
11 import java.math.BigInteger;
12 import java.util.EventListener;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.Future;
17 import java.util.stream.Collectors;
18 import javax.annotation.PostConstruct;
19 import javax.annotation.PreDestroy;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.genius.mdsalutil.MDSALDataStoreUtils;
25 import org.opendaylight.genius.mdsalutil.MDSALUtil;
26 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
27 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.DhcpAllocationPool;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.Network;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.NetworkKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.dhcp_allocation_pool.rev161214.dhcp_allocation_pool.network.AllocationPool;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanDpnInterfaces;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesList;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.ElanDpnInterfacesListKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.config.rev150710.DhcpserviceConfig;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.opendaylight.yangtools.yang.common.RpcResult;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 @Singleton
57 public class DhcpAllocationPoolManager implements AutoCloseable, EventListener {
58     private static final Logger LOG = LoggerFactory.getLogger(DhcpAllocationPoolManager.class);
59
60     private DhcpAllocationPoolListener dhcpAllocationPoolListener;
61
62     private final DataBroker dataBroker;
63     private final IdManagerService idManager;
64     private final DhcpserviceConfig config;
65     private final JobCoordinator jobCoordinator;
66
67     @Inject
68     public DhcpAllocationPoolManager(final DataBroker dataBroker, final IdManagerService idManager,
69             final DhcpserviceConfig config, final JobCoordinator jobCoordinator) {
70         this.dataBroker = dataBroker;
71         this.idManager = idManager;
72         this.config = config;
73         this.jobCoordinator = jobCoordinator;
74     }
75
76     @PostConstruct
77     public void init() {
78         if (config.isDhcpDynamicAllocationPoolEnabled()) {
79             dhcpAllocationPoolListener = new DhcpAllocationPoolListener(this, dataBroker, jobCoordinator);
80             LOG.info("DHCP Allocation Pool Service initialized");
81         }
82     }
83
84     @Override
85     @PreDestroy
86     public void close() {
87         LOG.info("{} close", getClass().getSimpleName());
88         if (dhcpAllocationPoolListener != null) {
89             dhcpAllocationPoolListener.close();
90         }
91     }
92
93     public IpAddress getIpAllocation(String networkId, AllocationPool pool, String macAddress) {
94         String poolIdKey = getPoolKeyIdByAllocationPool(networkId, pool);
95         long allocatedIpLong = createIdAllocation(poolIdKey, macAddress);
96         LOG.debug("allocated id {} for mac {}, from pool {}", allocatedIpLong, macAddress, poolIdKey);
97         IpAddress allocatedIpAddress = allocatedIpLong != 0 ? DhcpServiceUtils.convertLongToIp(allocatedIpLong)
98                 : null;
99         return allocatedIpAddress;
100     }
101
102     public void releaseIpAllocation(String networkId, AllocationPool pool, String macAddress) {
103         String poolIdKey = getPoolKeyIdByAllocationPool(networkId, pool);
104         LOG.debug("going to release id for mac {}, from pool {}", macAddress, poolIdKey);
105         releaseIdAllocation(poolIdKey, macAddress);
106     }
107
108     public AllocationPool getAllocationPoolByNetwork(String networkId) {
109         InstanceIdentifier<Network> network = InstanceIdentifier.builder(DhcpAllocationPool.class)
110                 .child(Network.class, new NetworkKey(networkId)).build();
111         Optional<Network> optionalNetworkConfData = MDSALDataStoreUtils.read(dataBroker,
112                 LogicalDatastoreType.CONFIGURATION, network);
113         if (!optionalNetworkConfData.isPresent()) {
114             LOG.info("No network configuration data for network {}", networkId);
115             return null;
116         }
117         Network networkConfData = optionalNetworkConfData.get();
118         List<AllocationPool> allocationPoolList = networkConfData.getAllocationPool();
119         // if network has allocation pool list - get the first element
120         // as we have no info about a specific subnet
121         if (allocationPoolList != null && !allocationPoolList.isEmpty()) {
122             return allocationPoolList.get(0);
123         } else {
124             LOG.warn("No allocation pools for network {}", networkId);
125             return null;
126         }
127     }
128
129     public Map<BigInteger, List<String>> getElanDpnInterfacesByName(DataBroker broker, String elanInstanceName) {
130         InstanceIdentifier<ElanDpnInterfacesList> elanDpnIfacesIid = InstanceIdentifier.builder(ElanDpnInterfaces.class)
131                 .child(ElanDpnInterfacesList.class, new ElanDpnInterfacesListKey(elanInstanceName)).build();
132         Optional<ElanDpnInterfacesList> elanDpnIfacesOpc = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
133                 elanDpnIfacesIid);
134         if (!elanDpnIfacesOpc.isPresent()) {
135             LOG.warn("Could not find DpnInterfaces for elan {}", elanInstanceName);
136             return null;
137         }
138
139         return elanDpnIfacesOpc.get().getDpnInterfaces().stream()
140                 .collect(Collectors.toMap(DpnInterfaces::getDpId, DpnInterfaces::getInterfaces));
141     }
142
143     public AllocationPool getAllocationPoolByPort(String portUuid) {
144         String elanInstanceName = getNetworkByPort(portUuid);
145         AllocationPool allocPool = elanInstanceName != null ? getAllocationPoolByNetwork(elanInstanceName) : null;
146         return allocPool;
147     }
148
149     public String getNetworkByPort(String portUuid) {
150         InstanceIdentifier<ElanInterface> elanInterfaceName = InstanceIdentifier.builder(ElanInterfaces.class)
151                 .child(ElanInterface.class, new ElanInterfaceKey(portUuid)).build();
152         Optional<ElanInterface> optionalElanInterface = MDSALDataStoreUtils.read(dataBroker,
153                 LogicalDatastoreType.CONFIGURATION, elanInterfaceName);
154         if (!optionalElanInterface.isPresent()) {
155             LOG.info("No elan interface data for port {}", portUuid);
156             return null;
157         }
158         ElanInterface elanInterface = optionalElanInterface.get();
159         return elanInterface.getElanInstanceName();
160     }
161
162     private String getPoolKeyIdByAllocationPool(String networkId, AllocationPool pool) {
163         return "dhcpAllocationPool." + networkId + "." + String.valueOf(pool.getSubnet().getValue());
164     }
165
166     private long createIdAllocation(String groupIdKey, String idKey) {
167         AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(groupIdKey).setIdKey(idKey).build();
168         try {
169             Future<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
170             RpcResult<AllocateIdOutput> rpcResult = result.get();
171             return rpcResult.getResult().getIdValue();
172         } catch (NullPointerException | InterruptedException | ExecutionException e) {
173             LOG.trace("Failed to allocate id for DHCP Allocation Pool Service", e);
174         }
175         return 0;
176     }
177
178     private void releaseIdAllocation(String groupIdKey, String idKey) {
179         ReleaseIdInput getIdInput = new ReleaseIdInputBuilder().setPoolName(groupIdKey).setIdKey(idKey).build();
180         JdkFutures.addErrorLogging(idManager.releaseId(getIdInput), LOG, "Release Id");
181     }
182
183     protected void createIdAllocationPool(String networkId, AllocationPool pool) {
184         String poolName = getPoolKeyIdByAllocationPool(networkId, pool);
185         long low = DhcpServiceUtils.convertIpToLong(pool.getAllocateFrom());
186         long high = DhcpServiceUtils.convertIpToLong(pool.getAllocateTo());
187         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(poolName).setLow(low).setHigh(high)
188                 .build();
189         try {
190             Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
191             if (result != null && result.get().isSuccessful()) {
192                 LOG.info("DHCP Allocation Pool Service : Created IdPool name {}", poolName);
193             } else {
194                 LOG.error("DHCP Allocation Pool Service : Unable to create IdPool name {}", poolName);
195             }
196         } catch (InterruptedException | ExecutionException e) {
197             LOG.error("Failed to create Pool for DHCP Allocation Pool Service", e);
198         }
199     }
200
201     protected void releaseIdAllocationPool(String networkId, AllocationPool pool) {
202         String poolName = getPoolKeyIdByAllocationPool(networkId, pool);
203         DeleteIdPoolInput deletePool = new DeleteIdPoolInputBuilder().setPoolName(poolName).build();
204         try {
205             Future<RpcResult<Void>> result = idManager.deleteIdPool(deletePool);
206             if (result != null && result.get().isSuccessful()) {
207                 LOG.info("DHCP Allocation Pool Service : Deleted IdPool name {}", poolName);
208             } else {
209                 LOG.error("DHCP Allocation Pool Service : Unable to delete IdPool name {}", poolName);
210             }
211         } catch (InterruptedException | ExecutionException e) {
212             LOG.error("Failed to delete Pool for DHCP Allocation Pool Service", e);
213         }
214     }
215 }