Merge "Revert "Add support for karaf.debug and karaf.keep.unpack""
[neutron.git] / transcriber / src / main / java / org / opendaylight / neutron / transcriber / AbstractNeutronInterface.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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.neutron.transcriber;
10
11 import java.lang.reflect.Method;
12 import java.util.ArrayList;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16
17 import java.util.concurrent.ExecutionException;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
27 import org.opendaylight.yangtools.yang.binding.DataObject;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import com.google.common.base.Optional;
33 import com.google.common.base.Preconditions;
34 import com.google.common.util.concurrent.CheckedFuture;
35
36 import org.opendaylight.neutron.spi.INeutronCRUD;
37 import org.opendaylight.neutron.spi.INeutronObject;
38
39 public abstract class AbstractNeutronInterface<T extends DataObject, S extends INeutronObject> implements AutoCloseable, INeutronCRUD<S> {
40     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNeutronInterface.class);
41     private static final int DEDASHED_UUID_LENGTH = 32;
42     private static final int DEDASHED_UUID_START = 0;
43     private static final int DEDASHED_UUID_DIV1 = 8;
44     private static final int DEDASHED_UUID_DIV2 = 12;
45     private static final int DEDASHED_UUID_DIV3 = 16;
46     private static final int DEDASHED_UUID_DIV4 = 20;
47
48     private DataBroker db;
49
50     AbstractNeutronInterface(ProviderContext providerContext) {
51         this.db = providerContext.getSALService(DataBroker.class);
52     }
53
54     public DataBroker getDataBroker() {
55         return db;
56     }
57
58     protected abstract InstanceIdentifier<T> createInstanceIdentifier(T item);
59
60     protected abstract T toMd(S neutronObject);
61
62     protected abstract T toMd(String uuid);
63
64     protected abstract S fromMd(T dataObject);
65
66     protected <T extends DataObject> T readMd(InstanceIdentifier<T> path) {
67         T result = null;
68         final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
69         CheckedFuture<Optional<T>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
70         if (future != null) {
71             Optional<T> optional;
72             try {
73                 optional = future.checkedGet();
74                 if (optional.isPresent()) {
75                     result = optional.get();
76                 }
77             } catch (ReadFailedException e) {
78                 LOGGER.warn("Failed to read {}", path, e);
79             }
80         }
81         transaction.close();
82         return result;
83     }
84
85     protected boolean addMd(S neutronObject) {
86         // TODO think about adding existence logic
87         return updateMd(neutronObject);
88     }
89
90     protected boolean updateMd(S neutronObject) {
91         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
92         T item = toMd(neutronObject);
93         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
94         transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
95         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
96         try {
97             future.get();
98         } catch (InterruptedException | ExecutionException e) {
99             LOGGER.warn("Transation failed ",e);
100             return false;
101         }
102         return true;
103     }
104
105     protected boolean removeMd(T item) {
106         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
107         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
108         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
109         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
110         try {
111             future.get();
112         } catch (InterruptedException | ExecutionException e) {
113             LOGGER.warn("Transation failed ",e);
114             return false;
115         }
116         return true;
117     }
118
119     protected Uuid toUuid(String uuid) {
120         Preconditions.checkNotNull(uuid);
121         Uuid result;
122         try {
123             result = new Uuid(uuid);
124         } catch(IllegalArgumentException e) {
125             // OK... someone didn't follow RFC 4122... lets try this the hard way
126             String dedashed = uuid.replace("-", "");
127             if(dedashed.length() == DEDASHED_UUID_LENGTH) {
128                 String redashed = dedashed.substring(DEDASHED_UUID_START, DEDASHED_UUID_DIV1)
129                         + "-"
130                         + dedashed.substring(DEDASHED_UUID_DIV1, DEDASHED_UUID_DIV2)
131                         + "-"
132                         + dedashed.substring(DEDASHED_UUID_DIV2, DEDASHED_UUID_DIV3)
133                         + "-"
134                         + dedashed.substring(DEDASHED_UUID_DIV3, DEDASHED_UUID_DIV4)
135                         + "-"
136                         + dedashed.substring(DEDASHED_UUID_DIV4, DEDASHED_UUID_LENGTH);
137                 result = new Uuid(redashed);
138             } else {
139                 throw e;
140             }
141         }
142         return result;
143     }
144
145     // this method uses reflection to update an object from it's delta.
146
147     protected boolean overwrite(Object target, Object delta) {
148         Method[] methods = target.getClass().getMethods();
149
150         for(Method toMethod: methods){
151             if(toMethod.getDeclaringClass().equals(target.getClass())
152                     && toMethod.getName().startsWith("set")){
153
154                 String toName = toMethod.getName();
155                 String fromName = toName.replace("set", "get");
156
157                 try {
158                     Method fromMethod = delta.getClass().getMethod(fromName);
159                     Object value = fromMethod.invoke(delta, (Object[])null);
160                     if(value != null){
161                         toMethod.invoke(target, value);
162                     }
163                 } catch (Exception e) {
164                     LOGGER.error("Error in overwrite", e);
165                     return false;
166                 }
167             }
168         }
169         return true;
170     }
171
172     @Override
173     public void close() throws Exception {
174         // TODO Auto-generated method stub
175
176     }
177
178     public boolean exists(String uuid) {
179         T dataObject = readMd(createInstanceIdentifier(toMd(uuid)));
180         return dataObject != null;
181     }
182
183     public S get(String uuid) {
184         T dataObject = readMd(createInstanceIdentifier(toMd(uuid)));
185         if (dataObject == null) {
186             return null;
187         }
188         return fromMd(dataObject);
189     }
190
191     public abstract List<S> getAll();
192
193     public boolean add(S input) {
194         if (exists(input.getID())) {
195             return false;
196         }
197         addMd(input);
198         return true;
199     }
200
201     public boolean remove(String uuid) {
202         if (!exists(uuid)) {
203             return false;
204         }
205         return removeMd(toMd(uuid));
206     }
207
208     public boolean update(String uuid, S delta) {
209         if (!exists(uuid)) {
210             return false;
211         }
212         updateMd(delta);
213         return true;
214     }
215
216     public boolean inUse(String uuid) {
217         return false;
218     }
219 }