Avoid exceptions with IPv6 subnets
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / 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.ovsdb.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.ovsdb.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 <T extends org.opendaylight.yangtools.yang.binding.DataObject> T readMd(InstanceIdentifier<T> path) {
59         T result = null;
60         final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
61         CheckedFuture<Optional<T>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
62         if (future != null) {
63             Optional<T> optional;
64             try {
65                 optional = future.checkedGet();
66                 if (optional.isPresent()) {
67                     result = optional.get();
68                 }
69             } catch (ReadFailedException e) {
70                 LOGGER.warn("Failed to read {}", path, e);
71             }
72         }
73         transaction.close();
74         return result;
75     }
76
77     protected boolean addMd(S neutronObject) {
78         // TODO think about adding existence logic
79         return updateMd(neutronObject);
80     }
81
82     protected boolean updateMd(S neutronObject) {
83         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
84         T item = toMd(neutronObject);
85         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
86         transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
87         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
88         try {
89             future.get();
90         } catch (InterruptedException | ExecutionException e) {
91             LOGGER.warn("Transation failed ",e);
92             return false;
93         }
94         return true;
95     }
96
97     protected boolean removeMd(T item) {
98         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
99         InstanceIdentifier<T> iid = createInstanceIdentifier(item);
100         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
101         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
102         try {
103             future.get();
104         } catch (InterruptedException | ExecutionException e) {
105             LOGGER.warn("Transation failed ",e);
106             return false;
107         }
108         return true;
109     }
110
111     protected Uuid toUuid(String uuid) {
112         Preconditions.checkNotNull(uuid);
113         Uuid result;
114         try {
115             result = new Uuid(uuid);
116         } catch(IllegalArgumentException e) {
117             // OK... someone didn't follow RFC 4122... lets try this the hard way
118             String dedashed = uuid.replace("-", "");
119             if(dedashed.length() == DEDASHED_UUID_LENGTH) {
120                 String redashed = dedashed.substring(DEDASHED_UUID_START, DEDASHED_UUID_DIV1)
121                         + "-"
122                         + dedashed.substring(DEDASHED_UUID_DIV1, DEDASHED_UUID_DIV2)
123                         + "-"
124                         + dedashed.substring(DEDASHED_UUID_DIV2, DEDASHED_UUID_DIV3)
125                         + "-"
126                         + dedashed.substring(DEDASHED_UUID_DIV3, DEDASHED_UUID_DIV4)
127                         + "-"
128                         + dedashed.substring(DEDASHED_UUID_DIV4, DEDASHED_UUID_LENGTH);
129                 result = new Uuid(redashed);
130             } else {
131                 throw e;
132             }
133         }
134         return result;
135     }
136
137     // this method uses reflection to update an object from it's delta.
138
139     protected boolean overwrite(Object target, Object delta) {
140         Method[] methods = target.getClass().getMethods();
141
142         for(Method toMethod: methods){
143             if(toMethod.getDeclaringClass().equals(target.getClass())
144                     && toMethod.getName().startsWith("set")){
145
146                 String toName = toMethod.getName();
147                 String fromName = toName.replace("set", "get");
148
149                 try {
150                     Method fromMethod = delta.getClass().getMethod(fromName);
151                     Object value = fromMethod.invoke(delta, (Object[])null);
152                     if(value != null){
153                         toMethod.invoke(target, value);
154                     }
155                 } catch (Exception e) {
156                     LOGGER.error("Error in overwrite", e);
157                     return false;
158                 }
159             }
160         }
161         return true;
162     }
163
164     @Override
165     public void close() throws Exception {
166         // TODO Auto-generated method stub
167
168     }
169
170 }