5986d1400b6164c50073229532e2463c9704691b
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / netvirt / openstack / netvirt / translator / crud / impl / 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.netvirt.openstack.netvirt.translator.crud.impl;
10
11 import java.lang.reflect.Method;
12 import java.util.concurrent.ExecutionException;
13
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
19 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
20 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
21 import org.opendaylight.netvirt.openstack.netvirt.translator.INeutronObject;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
23 import org.opendaylight.yangtools.yang.binding.DataObject;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import com.google.common.base.Optional;
29 import com.google.common.base.Preconditions;
30 import com.google.common.util.concurrent.CheckedFuture;
31
32
33 public abstract class AbstractNeutronInterface<T extends DataObject, S extends INeutronObject> implements AutoCloseable {
34     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNeutronInterface.class);
35     private static final int DEDASHED_UUID_LENGTH = 32;
36     private static final int DEDASHED_UUID_START = 0;
37     private static final int DEDASHED_UUID_DIV1 = 8;
38     private static final int DEDASHED_UUID_DIV2 = 12;
39     private static final int DEDASHED_UUID_DIV3 = 16;
40     private static final int DEDASHED_UUID_DIV4 = 20;
41
42     private DataBroker db;
43
44     AbstractNeutronInterface(ProviderContext providerContext) {
45         this.db = providerContext.getSALService(DataBroker.class);
46     }
47
48     public DataBroker getDataBroker() {
49         return db;
50     }
51
52     protected abstract InstanceIdentifier<T> createInstanceIdentifier(T item);
53
54     protected abstract T toMd(S neutronObject);
55
56     protected abstract T toMd(String uuid);
57
58     protected <B extends org.opendaylight.yangtools.yang.binding.DataObject> B readMd(InstanceIdentifier<B> path) {
59         B result = null;
60         final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
61         CheckedFuture<Optional<B>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
62         if (future != null) {
63             try {
64                 result = future.checkedGet().orNull();
65             } catch (ReadFailedException e) {
66                 LOGGER.warn("Failed to read {}", path, e);
67             }
68         }
69         transaction.close();
70         return result;
71     }
72
73     protected boolean addMd(S neutronObject) {
74         // TODO think about adding existence logic
75         return updateMd(neutronObject);
76     }
77
78     protected boolean updateMd(S neutronObject) {
79         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
80         T item = toMd(neutronObject);
81         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
82         transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
83         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
84         try {
85             future.get();
86         } catch (InterruptedException | ExecutionException e) {
87             LOGGER.warn("Transation failed ",e);
88             return false;
89         }
90         return true;
91     }
92
93     protected boolean removeMd(T item) {
94         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
95         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
96         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
97         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
98         try {
99             future.get();
100         } catch (InterruptedException | ExecutionException e) {
101             LOGGER.warn("Transation failed ",e);
102             return false;
103         }
104         return true;
105     }
106
107     protected Uuid toUuid(String uuid) {
108         Preconditions.checkNotNull(uuid);
109         Uuid result;
110         try {
111             result = new Uuid(uuid);
112         } catch(IllegalArgumentException e) {
113             // OK... someone didn't follow RFC 4122... lets try this the hard way
114             String dedashed = uuid.replace("-", "");
115             if(dedashed.length() == DEDASHED_UUID_LENGTH) {
116                 String redashed = dedashed.substring(DEDASHED_UUID_START, DEDASHED_UUID_DIV1)
117                         + "-"
118                         + dedashed.substring(DEDASHED_UUID_DIV1, DEDASHED_UUID_DIV2)
119                         + "-"
120                         + dedashed.substring(DEDASHED_UUID_DIV2, DEDASHED_UUID_DIV3)
121                         + "-"
122                         + dedashed.substring(DEDASHED_UUID_DIV3, DEDASHED_UUID_DIV4)
123                         + "-"
124                         + dedashed.substring(DEDASHED_UUID_DIV4, DEDASHED_UUID_LENGTH);
125                 result = new Uuid(redashed);
126             } else {
127                 throw e;
128             }
129         }
130         return result;
131     }
132
133     // this method uses reflection to update an object from it's delta.
134
135     protected boolean overwrite(Object target, Object delta) {
136         Method[] methods = target.getClass().getMethods();
137
138         for(Method toMethod: methods){
139             if(toMethod.getDeclaringClass().equals(target.getClass())
140                     && toMethod.getName().startsWith("set")){
141
142                 String toName = toMethod.getName();
143                 String fromName = toName.replace("set", "get");
144
145                 try {
146                     Method fromMethod = delta.getClass().getMethod(fromName);
147                     Object value = fromMethod.invoke(delta, (Object[])null);
148                     if(value != null){
149                         toMethod.invoke(target, value);
150                     }
151                 } catch (Exception e) {
152                     LOGGER.error("Error in overwrite", e);
153                     return false;
154                 }
155             }
156         }
157         return true;
158     }
159
160     @Override
161     public void close() throws Exception {
162         // TODO Auto-generated method stub
163
164     }
165
166 }