2 * Copyright (c) 2015 Cisco Systems, Inc. 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.neutron.transcriber;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.CheckedFuture;
14 import java.lang.reflect.Method;
15 import java.util.ArrayList;
16 import java.util.HashSet;
17 import java.util.List;
19 import java.util.concurrent.ExecutionException;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
22 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
23 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
29 import org.opendaylight.neutron.spi.INeutronCRUD;
30 import org.opendaylight.neutron.spi.INeutronObject;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
32 import org.opendaylight.yangtools.yang.binding.Augmentable;
33 import org.opendaylight.yangtools.yang.binding.ChildOf;
34 import org.opendaylight.yangtools.yang.binding.DataObject;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 public abstract class AbstractNeutronInterface<T extends DataObject,
40 U extends ChildOf<? extends DataObject> & Augmentable<U>, S extends INeutronObject<S>>
41 implements AutoCloseable, INeutronCRUD<S> {
42 private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNeutronInterface.class);
43 private static final int DEDASHED_UUID_LENGTH = 32;
44 private static final int DEDASHED_UUID_START = 0;
45 private static final int DEDASHED_UUID_DIV1 = 8;
46 private static final int DEDASHED_UUID_DIV2 = 12;
47 private static final int DEDASHED_UUID_DIV3 = 16;
48 private static final int DEDASHED_UUID_DIV4 = 20;
50 private static final int RETRY_MAX = 2;
52 private final DataBroker db;
54 AbstractNeutronInterface(DataBroker db) {
55 this.db = Preconditions.checkNotNull(db);
58 public DataBroker getDataBroker() {
59 Preconditions.checkNotNull(db);
63 protected abstract InstanceIdentifier<T> createInstanceIdentifier(T item);
65 protected abstract InstanceIdentifier<U> createInstanceIdentifier();
67 protected abstract T toMd(S neutronObject);
69 protected abstract T toMd(String uuid);
71 protected abstract S fromMd(T dataObject);
73 private <T extends DataObject> T readMd(InstanceIdentifier<T> path, ReadTransaction tx) {
74 Preconditions.checkNotNull(tx);
76 final CheckedFuture<Optional<T>,
77 ReadFailedException> future = tx.read(LogicalDatastoreType.CONFIGURATION, path);
81 optional = future.checkedGet();
82 if (optional.isPresent()) {
83 result = optional.get();
85 } catch (final ReadFailedException e) {
86 LOGGER.warn("Failed to read {}", path, e);
92 protected <T extends DataObject> T readMd(InstanceIdentifier<T> path) {
93 try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) {
94 return readMd(path, tx);
98 private void addMd(S neutronObject, WriteTransaction tx) throws InterruptedException, ExecutionException {
99 // TODO think about adding existence logic
100 updateMd(neutronObject, tx);
103 protected boolean addMd(S neutronObject) {
105 final WriteTransaction tx = getDataBroker().newWriteOnlyTransaction();
106 addMd(neutronObject, tx);
108 } catch (InterruptedException | ExecutionException e) {
109 LOGGER.warn("Transaction failed", e);
114 private void updateMd(S neutronObject, WriteTransaction tx) throws InterruptedException, ExecutionException {
115 Preconditions.checkNotNull(tx);
117 final T item = toMd(neutronObject);
118 final InstanceIdentifier<T> iid = createInstanceIdentifier(item);
119 tx.put(LogicalDatastoreType.CONFIGURATION, iid, item, true);
120 final CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
121 future.get(); // Check if it's successfuly committed, otherwise exception will be thrown.
124 protected boolean updateMd(S neutronObject) {
125 int retries = RETRY_MAX;
126 while (retries-- >= 0) {
128 final WriteTransaction tx = getDataBroker().newWriteOnlyTransaction();
129 updateMd(neutronObject, tx);
131 } catch (InterruptedException | ExecutionException e) {
132 if (e.getCause() instanceof OptimisticLockFailedException) {
133 LOGGER.warn("Got OptimisticLockFailedException - {} {}", neutronObject, retries);
136 // TODO: rethrow exception. don't mask exception
137 LOGGER.error("Transaction failed", e);
144 private void removeMd(T item, WriteTransaction tx) throws InterruptedException, ExecutionException {
145 Preconditions.checkNotNull(tx);
146 final InstanceIdentifier<T> iid = createInstanceIdentifier(item);
147 tx.delete(LogicalDatastoreType.CONFIGURATION, iid);
148 final CheckedFuture<Void, TransactionCommitFailedException> future = tx.submit();
149 future.get(); // Check if it's successfuly committed, otherwise exception will be thrown.
152 protected boolean removeMd(T item) {
153 final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
157 } catch (InterruptedException | ExecutionException e) {
158 LOGGER.warn("Transaction failed", e);
163 protected Uuid toUuid(String uuid) {
164 Preconditions.checkNotNull(uuid);
167 result = new Uuid(uuid);
168 } catch (final IllegalArgumentException e) {
169 // OK... someone didn't follow RFC 4122... lets try this the hard way
170 final String dedashed = uuid.replace("-", "");
171 if (dedashed.length() == DEDASHED_UUID_LENGTH) {
172 final String redashed = dedashed.substring(DEDASHED_UUID_START, DEDASHED_UUID_DIV1) + "-"
173 + dedashed.substring(DEDASHED_UUID_DIV1, DEDASHED_UUID_DIV2) + "-"
174 + dedashed.substring(DEDASHED_UUID_DIV2, DEDASHED_UUID_DIV3) + "-"
175 + dedashed.substring(DEDASHED_UUID_DIV3, DEDASHED_UUID_DIV4) + "-"
176 + dedashed.substring(DEDASHED_UUID_DIV4, DEDASHED_UUID_LENGTH);
177 result = new Uuid(redashed);
185 // this method uses reflection to update an object from it's delta.
187 protected boolean overwrite(Object target, Object delta) {
188 final Method[] methods = target.getClass().getMethods();
190 for (final Method toMethod : methods) {
191 if (toMethod.getDeclaringClass().equals(target.getClass()) && toMethod.getName().startsWith("set")) {
193 final String toName = toMethod.getName();
194 final String fromName = toName.replace("set", "get");
197 final Method fromMethod = delta.getClass().getMethod(fromName);
198 final Object value = fromMethod.invoke(delta, (Object[]) null);
200 toMethod.invoke(target, value);
202 } catch (final Exception e) {
203 LOGGER.error("Error in overwrite", e);
212 public void close() throws Exception {
213 // TODO Auto-generated method stub
217 private boolean exists(String uuid, ReadTransaction tx) {
218 Preconditions.checkNotNull(tx);
219 final T dataObject = readMd(createInstanceIdentifier(toMd(uuid)), tx);
220 return dataObject != null;
224 public boolean exists(String uuid) {
225 try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) {
226 return exists(uuid, tx);
230 private S get(String uuid, ReadTransaction tx) {
231 Preconditions.checkNotNull(tx);
232 final T dataObject = readMd(createInstanceIdentifier(toMd(uuid)), tx);
233 if (dataObject == null) {
236 return fromMd(dataObject);
240 public S get(String uuid) {
241 try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) {
242 return get(uuid, tx);
246 protected abstract List<T> getDataObjectList(U dataObjects);
248 private List<S> getAll(ReadTransaction tx) {
249 Preconditions.checkNotNull(tx);
250 final Set<S> allNeutronObjects = new HashSet<S>();
251 final U dataObjects = readMd(createInstanceIdentifier(), tx);
252 if (dataObjects != null) {
253 for (final T dataObject : getDataObjectList(dataObjects)) {
254 allNeutronObjects.add(fromMd(dataObject));
257 LOGGER.debug("Exiting _getAll, Found {} OpenStackFirewall", allNeutronObjects.size());
258 final List<S> ans = new ArrayList<S>();
259 ans.addAll(allNeutronObjects);
264 public List<S> getAll() {
265 try (ReadOnlyTransaction tx = getDataBroker().newReadOnlyTransaction()) {
270 private boolean add(S input, ReadWriteTransaction tx) throws InterruptedException, ExecutionException {
271 Preconditions.checkNotNull(tx);
272 if (exists(input.getID(), tx)) {
281 public boolean add(S input) {
282 int retries = RETRY_MAX;
283 while (retries-- >= 0) {
284 final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
286 return add(input, tx);
287 } catch (InterruptedException | ExecutionException e) {
288 if (e.getCause() instanceof OptimisticLockFailedException) {
289 LOGGER.warn("Got OptimisticLockFailedException - {} {}", input, retries);
292 // TODO: rethrow exception. don't mask exception
293 LOGGER.error("Transaction failed", e);
300 private boolean remove(String uuid, ReadWriteTransaction tx) throws InterruptedException, ExecutionException {
301 Preconditions.checkNotNull(tx);
302 if (!exists(uuid, tx)) {
306 removeMd(toMd(uuid), tx);
311 public boolean remove(String uuid) {
312 int retries = RETRY_MAX;
313 while (retries-- >= 0) {
314 final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
316 return remove(uuid, tx);
317 } catch (InterruptedException | ExecutionException e) {
318 if (e.getCause() instanceof OptimisticLockFailedException) {
319 LOGGER.warn("Got OptimisticLockFailedException - {} {}", uuid, retries);
322 // TODO: rethrow exception. don't mask exception
323 LOGGER.error("Transaction failed", e);
330 private boolean update(String uuid, S delta, ReadWriteTransaction tx)
331 throws InterruptedException, ExecutionException {
332 Preconditions.checkNotNull(tx);
333 if (!exists(uuid, tx)) {
342 public boolean update(String uuid, S delta) {
343 int retries = RETRY_MAX;
344 while (retries-- >= 0) {
345 final ReadWriteTransaction tx = getDataBroker().newReadWriteTransaction();
347 return update(uuid, delta, tx);
348 } catch (InterruptedException | ExecutionException e) {
349 if (e.getCause() instanceof OptimisticLockFailedException) {
350 LOGGER.warn("Got OptimisticLockFailedException - {} {} {}", uuid, delta, retries);
353 // TODO: rethrow exception. don't mask exception
354 LOGGER.error("Transaction failed", e);
362 public boolean inUse(String uuid) {