IdManager implementation
[vpnservice.git] / idmanager / idmanager-impl / src / main / java / org / opendaylight / idmanager / IdManager.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.idmanager;
10
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.RpcError;
23 import org.opendaylight.yangtools.yang.common.RpcResult;
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.*;
29
30 import java.math.BigInteger;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.concurrent.Future;
35
36
37 public class IdManager implements IdManagerService, AutoCloseable{
38     private static final Logger LOG = LoggerFactory.getLogger(IdManager.class);
39     private ListenerRegistration<DataChangeListener> listenerRegistration;
40     private final DataBroker broker;
41
42
43
44     @Override
45     public void close() throws Exception {
46         if (listenerRegistration != null) {
47             try {
48                 listenerRegistration.close();
49             } catch (final Exception e) {
50                 LOG.error("Error when cleaning up DataChangeListener.", e);
51             }
52             listenerRegistration = null;
53         }
54         LOG.info("IDManager Closed");
55     }
56
57     public IdManager(final DataBroker db) {
58        broker = db;
59     }
60
61     private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
62                                                     InstanceIdentifier<T> path) {
63
64         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
65
66         Optional<T> result = Optional.absent();
67         try {
68             result = tx.read(datastoreType, path).get();
69         } catch (Exception e) {
70             throw new RuntimeException(e);
71         }
72
73         return result;
74     }
75
76     private <T extends DataObject> void asyncWrite(LogicalDatastoreType datastoreType,
77                                                    InstanceIdentifier<T> path, T data, FutureCallback<Void> callback) {
78         WriteTransaction tx = broker.newWriteOnlyTransaction();
79         tx.put(datastoreType, path, data, true);
80         Futures.addCallback(tx.submit(), callback);
81     }
82
83     @Override
84     public Future<RpcResult<Void>> createIdPool(CreateIdPoolInput input)
85     {
86
87         String poolName = input.getPoolName();
88         long startIndx = input.getIdStart();
89         long poolSize = input.getPoolSize().longValue();
90
91         LOG.debug("poolName: %s, startIndx: %d , poolSize: %d ", poolName, startIndx,  poolSize);
92
93         InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
94                 InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
95         InstanceIdentifier<IdPool> id = idBuilder.build();
96         Optional<IdPool> pool = read(LogicalDatastoreType.OPERATIONAL, id);
97         if (!pool.isPresent()) {
98             LOG.debug("Creating a new global pool: %s " ,poolName);
99             IdPool newPool = getPoolInterface(poolName, startIndx, poolSize);
100             asyncWrite(LogicalDatastoreType.OPERATIONAL, id, newPool, DEFAULT_CALLBACK);
101
102         }
103
104        // return Futures.immediateFuture(RpcResult<Void>);
105         return null;
106     }
107
108
109     @Override
110     public Future<RpcResult<GetUniqueIdOutput>> getUniqueId(GetUniqueIdInput input){
111
112         String poolName = input.getPoolName();
113         String idKey = input.getIdKey();
114
115         LOG.debug("poolName: %s ,idKey: %s", poolName, idKey);
116
117         InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idBuilder =
118                 InstanceIdentifier.builder(Pools.class).child(IdPool.class, new IdPoolKey(poolName));
119         InstanceIdentifier<IdPool> id = idBuilder.build();
120         Optional<IdPool> globalPool = read(LogicalDatastoreType.OPERATIONAL, id);
121         Long newIdValue = null;
122         GeneratedIds newGenId = null;
123         if (globalPool.isPresent()) {
124             IdPool pool = globalPool.get();
125             List<GeneratedIds> generatedIds = pool.getGeneratedIds();
126
127             if (!generatedIds.isEmpty()) {
128                 for (GeneratedIds gen_id : generatedIds) {
129                     if (gen_id.getIdKey().equals(idKey)) {
130                         newIdValue = gen_id.getIdValue();
131                         LOG.debug("Existing id for the key %s ", idKey);
132                     }
133
134                 }
135             }
136             synchronized(this){
137                 if (newIdValue == null) {
138                     LOG.debug("Creating a new id for the pool: %s ", poolName);
139                     newIdValue = (long) generatedIds.size() + 1;
140                     newGenId = getIdsInterface(idKey, newIdValue);
141                     generatedIds.add(newGenId);
142                     asyncWrite(LogicalDatastoreType.OPERATIONAL, id, pool, DEFAULT_CALLBACK);
143                 }
144             }
145
146             GetUniqueIdOutputBuilder output = new GetUniqueIdOutputBuilder();
147             output.setIdValue(newIdValue);
148
149         }
150         /*            Collection<RpcError> errors = Collections.emptyList();
151             RpcResult<GetUniqueIdOutput> result = Rpcs.getRpcResult(true, output.build(), errors);
152             return Futures.immediateFuture(result);*/
153         return null;
154     }
155
156
157     private IdPool getPoolInterface(String poolName, long startIndx, long poolSize) {
158         BigInteger size = BigInteger.valueOf(poolSize);
159         return new IdPoolBuilder().setKey(new IdPoolKey(poolName)).setPoolName(poolName).setIdStart(startIndx)
160                 .setPoolSize(size).build();
161     }
162
163     private GeneratedIds getIdsInterface(String idKey, long newIdVal) {
164         return new GeneratedIdsBuilder().setKey(new GeneratedIdsKey(idKey)).setIdKey(idKey)
165                 .setIdValue(newIdVal).build();
166     }
167
168     private static final FutureCallback<Void> DEFAULT_CALLBACK =
169             new FutureCallback<Void>() {
170                 public void onSuccess(Void result) {
171                     LOG.debug("Success in Datastore write operation");
172                 }
173
174                 public void onFailure(Throwable error) {
175                     LOG.error("Error in Datastore write operation", error);
176                 };
177             };
178
179 }