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