2 * Copyright (c) 2015 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
9 package org.opendaylight.idmanager;
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.yangtools.concepts.ListenerRegistration;
20 import org.opendaylight.yangtools.yang.binding.DataObject;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
22 import org.opendaylight.yangtools.yang.common.RpcResult;
23 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.*;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.*;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.pools.id.pool.*;
30 import java.math.BigInteger;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.concurrent.Future;
36 public class IdManager implements IdManagerService, AutoCloseable{
37 private static final Logger LOG = LoggerFactory.getLogger(IdManager.class);
38 private ListenerRegistration<DataChangeListener> listenerRegistration;
39 private final DataBroker broker;
44 public void close() throws Exception {
45 if (listenerRegistration != null) {
47 listenerRegistration.close();
48 } catch (final Exception e) {
49 LOG.error("Error when cleaning up DataChangeListener.", e);
51 listenerRegistration = null;
53 LOG.info("IDManager Closed");
56 public IdManager(final DataBroker db) {
60 private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
61 InstanceIdentifier<T> path) {
63 ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
65 Optional<T> result = Optional.absent();
67 result = tx.read(datastoreType, path).get();
68 } catch (Exception e) {
69 throw new RuntimeException(e);
75 protected <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
76 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
77 WriteTransaction tx = broker.newWriteOnlyTransaction();
78 tx.put(datastoreType, path, data, true);
79 Futures.addCallback(tx.submit(), callback);
82 protected <T extends DataObject> void asyncUpdate(LogicalDatastoreType datastoreType,
83 InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
84 WriteTransaction tx = broker.newWriteOnlyTransaction();
85 tx.merge(datastoreType, path, data, true);
86 Futures.addCallback(tx.submit(), callback);
90 public Future<RpcResult<Void>> createIdPool(CreateIdPoolInput input)
93 String poolName = input.getPoolName();
94 long startIndx = input.getIdStart();
95 long poolSize = input.getPoolSize().longValue();
96 RpcResultBuilder<Void> rpcResultBuilder;
98 LOG.debug("poolName: {}, startIndx: {} , poolSize: {} ", poolName, startIndx, poolSize);
101 InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
102 InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
103 InstanceIdentifier<IdPool> id = idBuilder.build();
104 Optional<IdPool> pool = read(LogicalDatastoreType.OPERATIONAL, id);
105 if (!pool.isPresent()) {
106 LOG.debug("Creating a new global pool: {} ", poolName);
107 IdPool newPool = getPoolInterface(poolName, startIndx, poolSize);
108 LOG.debug("NewPool: {}", newPool);
109 asyncWrite(LogicalDatastoreType.OPERATIONAL, id, newPool, DEFAULT_CALLBACK);
113 rpcResultBuilder = RpcResultBuilder.success();
116 LOG.error("Creation of global pool {} failed due to {}" ,poolName, e);
117 rpcResultBuilder = RpcResultBuilder.failed();
120 return Futures.immediateFuture(rpcResultBuilder.build());
125 public Future<RpcResult<GetUniqueIdOutput>> getUniqueId(GetUniqueIdInput input){
127 String poolName = input.getPoolName();
128 String idKey = input.getIdKey();
130 LOG.debug("poolName: {} ,idKey: {}", poolName, idKey);
131 RpcResultBuilder<GetUniqueIdOutput> rpcResultBuilder;
134 InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
135 InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
136 InstanceIdentifier<IdPool> id = idBuilder.build();
137 Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id);
138 GetUniqueIdOutputBuilder output = new GetUniqueIdOutputBuilder();
139 Long newIdValue = null;
140 GeneratedIds newGenId = null;
141 if (globalPool.isPresent()) {
142 IdPool pool = globalPool.get();
143 List<GeneratedIds> generatedIds = pool.getGeneratedIds();
145 if (generatedIds == null) {
146 generatedIds = new ArrayList<GeneratedIds>();
148 if (!generatedIds.isEmpty()) {
149 for (GeneratedIds genId : generatedIds) {
150 if (genId.getIdKey().equals(idKey)) {
151 newIdValue = genId.getIdValue();
152 LOG.debug("Existing id {} for the key {} ", idKey, newIdValue);
157 synchronized (this) {
158 if (newIdValue == null) {
159 newIdValue = (long) generatedIds.size() + 1;
160 LOG.debug("Creating a new id {} for the pool: {} ", newIdValue, poolName);
161 newGenId = getIdsInterface(idKey, newIdValue);
162 generatedIds.add(newGenId);
163 pool = new IdPoolBuilder(pool).setGeneratedIds(generatedIds).build();
164 asyncUpdate(LogicalDatastoreType.OPERATIONAL, id, pool, DEFAULT_CALLBACK);
167 output.setIdValue(newIdValue);
170 rpcResultBuilder = RpcResultBuilder.success();
171 rpcResultBuilder.withResult(output.build());
174 LOG.error("Creation of id for the key {} , global pool {} failed due to {}" ,idKey, poolName, e);
175 rpcResultBuilder = RpcResultBuilder.failed();
177 return Futures.immediateFuture(rpcResultBuilder.build());
181 private IdPool getPoolInterface(String poolName, long startIndx, long poolSize) {
182 BigInteger size = BigInteger.valueOf(poolSize);
183 return new IdPoolBuilder().setKey(new IdPoolKey(poolName)).setPoolName(poolName).setIdStart(startIndx)
184 .setPoolSize(size).build();
187 private GeneratedIds getIdsInterface(String idKey, long newIdVal) {
188 return new GeneratedIdsBuilder().setKey(new GeneratedIdsKey(idKey)).setIdKey(idKey)
189 .setIdValue(newIdVal).build();
192 private static final FutureCallback<Void> DEFAULT_CALLBACK =
193 new FutureCallback<Void>() {
194 public void onSuccess(Void result) {
195 LOG.debug("Success in Datastore write operation");
198 public void onFailure(Throwable error) {
199 LOG.error("Error in Datastore write operation", error);