Merge "Bug 4354 - neutron tenant_id doens't contain '-'(dash)"
[neutron.git] / transcriber / src / main / java / org / opendaylight / neutron / transcriber / NeutronLoadBalancerPoolInterface.java
1 /*
2  * Copyright (c) 2014, 2015 Red Hat, 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.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map.Entry;
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
26 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
27 import org.opendaylight.neutron.spi.INeutronLoadBalancerPoolCRUD;
28 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
29 import org.opendaylight.neutron.spi.NeutronLoadBalancerPool;
30 import org.opendaylight.neutron.spi.NeutronLoadBalancerPoolMember;
31 import org.opendaylight.neutron.spi.NeutronLoadBalancer_SessionPersistence;
32 import org.opendaylight.neutron.spi.Neutron_ID;
33
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
36
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.ProtocolBase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.ProtocolHttp;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.ProtocolHttps;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.ProtocolTcp;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.Pools;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.pools.Pool;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.pools.PoolBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.pools.pool.Members;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.pools.pool.members.Member;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.lbaas.attributes.pools.pool.members.MemberBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.lbaasv2.rev141002.pool.attributes.SessionPersistenceBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150325.Neutron;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.ServiceRegistration;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import com.google.common.base.Optional;
56 import com.google.common.collect.ImmutableBiMap;
57 import com.google.common.util.concurrent.CheckedFuture;
58
59 public class NeutronLoadBalancerPoolInterface extends AbstractNeutronInterface<Pool, Pools, NeutronLoadBalancerPool> implements INeutronLoadBalancerPoolCRUD {
60     private static final Logger LOGGER = LoggerFactory.getLogger(NeutronLoadBalancerPoolInterface.class);
61
62     private static final ImmutableBiMap<Class<? extends ProtocolBase>,String> PROTOCOL_MAP
63             = new ImmutableBiMap.Builder<Class<? extends ProtocolBase>,String>()
64             .put(ProtocolHttp.class,"HTTP")
65             .put(ProtocolHttps.class,"HTTPS")
66             .put(ProtocolTcp.class,"TCP")
67             .build();
68
69     private static final int DEDASHED_UUID_LENGTH = 32;
70     private static final int DEDASHED_UUID_START = 0;
71     private static final int DEDASHED_UUID_DIV1 = 8;
72     private static final int DEDASHED_UUID_DIV2 = 12;
73     private static final int DEDASHED_UUID_DIV3 = 16;
74     private static final int DEDASHED_UUID_DIV4 = 20;
75
76     NeutronLoadBalancerPoolInterface(ProviderContext providerContext) {
77         super(providerContext);
78     }
79
80     @Override
81     public boolean neutronLoadBalancerPoolExists(String uuid) {
82         return exists(uuid);
83     }
84
85     @Override
86     public NeutronLoadBalancerPool getNeutronLoadBalancerPool(String uuid) {
87         return get(uuid);
88     }
89
90     @Override
91     protected List<Pool> getDataObjectList(Pools pools) {
92         return pools.getPool();
93     }
94
95     @Override
96     public List<NeutronLoadBalancerPool> getAllNeutronLoadBalancerPools() {
97         return getAll();
98     }
99
100     @Override
101     public boolean addNeutronLoadBalancerPool(NeutronLoadBalancerPool input) {
102         //TODO: add code to find INeutronLoadBalancerPoolAware services and call newtorkCreated on them
103         return add(input);
104     }
105
106     @Override
107     public boolean removeNeutronLoadBalancerPool(String uuid) {
108         return remove(uuid);
109     }
110
111     @Override
112     public boolean updateNeutronLoadBalancerPool(String uuid, NeutronLoadBalancerPool delta) {
113         return update(uuid, delta);
114     }
115
116     @Override
117     public boolean neutronLoadBalancerPoolInUse(String loadBalancerPoolUUID) {
118         return !exists(loadBalancerPoolUUID);
119     }
120
121     @Override
122     protected Pool toMd(String uuid) {
123         PoolBuilder poolBuilder = new PoolBuilder();
124         poolBuilder.setUuid(toUuid(uuid));
125         return poolBuilder.build();
126     }
127
128     @Override
129     protected InstanceIdentifier<Pool> createInstanceIdentifier(Pool pool) {
130         return InstanceIdentifier.create(Neutron.class)
131                 .child(Pools.class)
132                 .child(Pool.class, pool.getKey());
133     }
134
135     @Override
136     protected InstanceIdentifier<Pools> createInstanceIdentifier() {
137         return InstanceIdentifier.create(Neutron.class)
138                 .child(Pools.class);
139     }
140
141     @Override
142     protected Pool toMd(NeutronLoadBalancerPool pool) {
143         PoolBuilder poolBuilder = new PoolBuilder();
144         poolBuilder.setAdminStateUp(pool.getLoadBalancerPoolAdminIsStateIsUp());
145         if (pool.getLoadBalancerPoolDescription() != null) {
146             poolBuilder.setDescr(pool.getLoadBalancerPoolDescription());
147         }
148         if (pool.getNeutronLoadBalancerPoolHealthMonitorID() != null) {
149             poolBuilder.setHealthmonitorId(toUuid(pool.getNeutronLoadBalancerPoolHealthMonitorID()));
150         }
151         if (pool.getLoadBalancerPoolLbAlgorithm() != null) {
152             poolBuilder.setLbAlgorithm(pool.getLoadBalancerPoolLbAlgorithm());
153         }
154         if (pool.getLoadBalancerPoolListeners() != null) {
155             List<Uuid> listListener = new ArrayList<Uuid>();
156             for (Neutron_ID neutron_id : pool.getLoadBalancerPoolListeners()) {
157                 listListener.add(toUuid(neutron_id.getID()));
158             }
159             poolBuilder.setListeners(listListener);
160         }
161         // because members are another container, we don't want to copy
162         // it over, so just skip it here
163         if (pool.getLoadBalancerPoolName() != null) {
164             poolBuilder.setName(pool.getLoadBalancerPoolName());
165         }
166         if (pool.getLoadBalancerPoolProtocol() != null) {
167             ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
168                 PROTOCOL_MAP.inverse();
169             poolBuilder.setProtocol((Class<? extends ProtocolBase>) mapper.get(pool.getLoadBalancerPoolProtocol()));
170         }
171         if (pool.getLoadBalancerPoolSessionPersistence() != null) {
172             NeutronLoadBalancer_SessionPersistence sessionPersistence = pool.getLoadBalancerPoolSessionPersistence();
173             SessionPersistenceBuilder sessionPersistenceBuilder = new SessionPersistenceBuilder();
174             sessionPersistenceBuilder.setCookieName(sessionPersistence.getCookieName());
175             sessionPersistenceBuilder.setType(sessionPersistence.getType());
176             poolBuilder.setSessionPersistence(sessionPersistenceBuilder.build());
177         }
178         if (pool.getTenantID() != null) {
179             poolBuilder.setTenantId(toUuid(pool.getTenantID()));
180         }
181         if (pool.getID() != null) {
182             poolBuilder.setUuid(toUuid(pool.getID()));
183         } else {
184             LOGGER.warn("Attempting to write neutron load balancer pool without UUID");
185         }
186         return poolBuilder.build();
187     }
188
189     protected NeutronLoadBalancerPool fromMd(Pool pool) {
190         NeutronLoadBalancerPool answer = new NeutronLoadBalancerPool();
191         if (pool.isAdminStateUp() != null) {
192             answer.setLoadBalancerPoolAdminStateIsUp(pool.isAdminStateUp());
193         }
194         if (pool.getDescr() != null) {
195             answer.setLoadBalancerPoolDescription(pool.getDescr());
196         }
197         if (pool.getHealthmonitorId() != null) {
198             answer.setNeutronLoadBalancerPoolHealthMonitorID(pool.getHealthmonitorId().getValue());
199         }
200         if (pool.getLbAlgorithm() != null) {
201             answer.setLoadBalancerPoolLbAlgorithm(pool.getLbAlgorithm());
202         }
203         if (pool.getListeners() != null) {
204             List<Neutron_ID> ids = new ArrayList<Neutron_ID>();
205             for (Uuid id : pool.getListeners()) {
206                 ids.add(new Neutron_ID(id.getValue()));
207             }
208             answer.setLoadBalancerPoolListeners(ids);
209         }
210         if (pool.getMembers() != null) {
211             List<NeutronLoadBalancerPoolMember> members = new ArrayList<NeutronLoadBalancerPoolMember>();
212             for (Member member: pool.getMembers().getMember()) {
213                 members.add(fromMemberMd(member));
214             }
215             answer.setLoadBalancerPoolMembers(members);
216         }
217         if (pool.getName() != null) {
218             answer.setLoadBalancerPoolName(pool.getName());
219         }
220         if (pool.getProtocol() != null) {
221             answer.setLoadBalancerPoolProtocol(PROTOCOL_MAP.get(pool.getProtocol()));
222         }
223         if (pool.getSessionPersistence() != null) {
224             NeutronLoadBalancer_SessionPersistence sessionPersistence = new NeutronLoadBalancer_SessionPersistence();
225             sessionPersistence.setCookieName(pool.getSessionPersistence().getCookieName());
226             sessionPersistence.setType(pool.getSessionPersistence().getType());
227             
228             answer.setLoadBalancerSessionPersistence(sessionPersistence);
229         }
230         if (pool.getTenantId() != null) {
231             answer.setTenantID(pool.getTenantId());
232         }
233         if (pool.getUuid() != null) {
234             answer.setID(pool.getUuid().getValue());
235         }
236         return answer;
237     }
238
239     public static void registerNewInterface(BundleContext context,
240                                             ProviderContext providerContext,
241                                             List<ServiceRegistration<?>> registrations) {
242         NeutronLoadBalancerPoolInterface neutronLoadBalancerPoolInterface = new NeutronLoadBalancerPoolInterface(providerContext);
243         ServiceRegistration<INeutronLoadBalancerPoolCRUD> neutronLoadBalancerPoolInterfaceRegistration = context.registerService(INeutronLoadBalancerPoolCRUD.class, neutronLoadBalancerPoolInterface, null);
244         if(neutronLoadBalancerPoolInterfaceRegistration != null) {
245             registrations.add(neutronLoadBalancerPoolInterfaceRegistration);
246         }
247     }
248
249     public boolean neutronLoadBalancerPoolMemberExists(String poolUuid, String uuid) {
250         Member member = readMemberMd(
251                 createMemberInstanceIdentifier(toMd(poolUuid),
252                                                toMemberMd(uuid)));
253         if (member == null) {
254             return false;
255         }
256         return true;
257     }
258
259     public NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(
260             String poolUuid, String uuid) {
261         Member member = readMemberMd(
262                 createMemberInstanceIdentifier(toMd(poolUuid),
263                                                toMemberMd(uuid)));
264         if (member == null) {
265             return null;
266         }
267         return fromMemberMd(member);
268     }
269
270     public List<NeutronLoadBalancerPoolMember> getAllNeutronLoadBalancerPoolMembers(String poolUuid) {
271         Set<NeutronLoadBalancerPoolMember> allLoadBalancerPoolMembers = new HashSet<NeutronLoadBalancerPoolMember>();
272         Members members = readMd(createMembersInstanceIdentifier(toMd(poolUuid)));
273         if (members != null) {
274             for (Member member: members.getMember()) {
275                 allLoadBalancerPoolMembers.add(fromMemberMd(member));
276             }
277         }
278         LOGGER.debug("Exiting getLoadBalancerPoolMembers, Found {} OpenStackLoadBalancerPoolMember",
279                 allLoadBalancerPoolMembers.size());
280         List<NeutronLoadBalancerPoolMember> ans = new ArrayList<NeutronLoadBalancerPoolMember>();
281         ans.addAll(allLoadBalancerPoolMembers);
282         return ans;
283     }
284
285     public boolean addNeutronLoadBalancerPoolMember(String poolUuid, NeutronLoadBalancerPoolMember input) {
286         if (neutronLoadBalancerPoolMemberExists(poolUuid, input.getID())) {
287             return false;
288         }
289         addMemberMd(toMd(poolUuid), input);
290         return true;
291     }
292
293     public boolean removeNeutronLoadBalancerPoolMember(String poolUuid, String uuid) {
294         if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) {
295             return false;
296         }
297         return removeMemberMd(toMd(poolUuid), toMemberMd(uuid));
298     }
299
300     public boolean updateNeutronLoadBalancerPoolMember(String poolUuid,
301             String uuid, NeutronLoadBalancerPoolMember delta) {
302         if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) {
303             return false;
304         }
305         updateMemberMd(toMd(poolUuid), delta);
306         return true;
307     }
308
309     public boolean neutronLoadBalancerPoolMemberInUse(String poolUuid,
310             String loadBalancerPoolMemberID) {
311         return !neutronLoadBalancerPoolMemberExists(poolUuid,
312                                                     loadBalancerPoolMemberID);
313     }
314
315     protected InstanceIdentifier<Member> createMemberInstanceIdentifier(Pool pool,
316             Member item) {
317         return InstanceIdentifier.create(Neutron.class)
318             .child(Pools.class)
319             .child(Pool.class, pool.getKey())
320             .child(Members.class)
321             .child(Member.class, item.getKey());
322     }
323
324     protected InstanceIdentifier<Members> createMembersInstanceIdentifier(Pool pool) {
325         return InstanceIdentifier.create(Neutron.class)
326             .child(Pools.class)
327             .child(Pool.class, pool.getKey())
328             .child(Members.class);
329     }
330
331     static NeutronLoadBalancerPoolMember fromMemberMd(Member member) {
332         NeutronLoadBalancerPoolMember answer = new NeutronLoadBalancerPoolMember();
333         if (member.isAdminStateUp() != null) {
334             answer.setPoolMemberAdminStateIsUp(member.isAdminStateUp());
335         }
336         if (member.getAddress() != null) {
337             answer.setPoolMemberAddress(String.valueOf(member.getAddress().getValue()));
338         }
339         if (member.getProtocolPort() != null) {
340             answer.setPoolMemberProtoPort(member.getProtocolPort());
341         }
342         if (member.getUuid() != null) {
343             answer.setID(member.getUuid().getValue());
344             answer.setPoolID(member.getUuid().getValue());
345         }
346         if (member.getSubnetId() != null) {
347             answer.setPoolMemberSubnetID(member.getSubnetId().getValue());
348         }
349         if (member.getTenantId() != null) {
350             answer.setTenantID(member.getTenantId());
351         }
352         if (member.getWeight() != null) {
353             answer.setPoolMemberWeight(member.getWeight());
354         }
355         return answer;
356     }
357
358     protected Member toMemberMd(NeutronLoadBalancerPoolMember member) {
359         MemberBuilder memberBuilder = new MemberBuilder();
360         memberBuilder.setAdminStateUp(member.getPoolMemberAdminStateIsUp());
361         if (member.getPoolMemberAddress() != null) {
362             IpAddress ipAddress = new IpAddress(member.getPoolMemberAddress().toCharArray());
363             memberBuilder.setAddress(ipAddress);
364         }
365         if (member.getPoolMemberProtoPort() != null) {
366             memberBuilder.setProtocolPort(member.getPoolMemberProtoPort());
367         }
368         if (member.getID() != null) {
369             memberBuilder.setUuid(toUuid(member.getID()));
370         }
371         if (member.getPoolMemberSubnetID() != null) {
372             memberBuilder.setSubnetId(toUuid(member.getPoolMemberSubnetID()));
373         }
374         if (member.getTenantID() != null) {
375             memberBuilder.setTenantId(toUuid(member.getTenantID()));
376         }
377         if (member.getPoolMemberWeight() != null) {
378             memberBuilder.setWeight(member.getPoolMemberWeight());
379         }
380         return memberBuilder.build();
381     }
382
383     protected Member toMemberMd(String uuid) {
384         MemberBuilder memberBuilder = new MemberBuilder();
385         memberBuilder.setUuid(toUuid(uuid));
386         return memberBuilder.build();
387     }
388
389     protected <T extends org.opendaylight.yangtools.yang.binding.DataObject> T readMemberMd(InstanceIdentifier<T> path) {
390         T result = null;
391         final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
392         CheckedFuture<Optional<T>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
393         if (future != null) {
394             Optional<T> optional;
395             try {
396                 optional = future.checkedGet();
397                 if (optional.isPresent()) {
398                     result = optional.get();
399                 }
400             } catch (ReadFailedException e) {
401                 LOGGER.warn("Failed to read {}", path, e);
402             }
403         }
404         transaction.close();
405         return result;
406     }
407
408     protected boolean addMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) {
409         // TODO think about adding existence logic
410         return updateMemberMd(pool, neutronObject);
411     }
412
413     protected boolean updateMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) {
414         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
415         Member item = toMemberMd(neutronObject);
416         InstanceIdentifier<Member> iid = createMemberInstanceIdentifier(pool, item);
417         transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
418         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
419         try {
420             future.get();
421         } catch (InterruptedException | ExecutionException e) {
422             LOGGER.warn("Transation failed ",e);
423             return false;
424         }
425         return true;
426     }
427
428     protected boolean removeMemberMd(Pool pool, Member item) {
429         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
430         InstanceIdentifier<Member> iid = createMemberInstanceIdentifier(pool, item);
431         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
432         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
433         try {
434             future.get();
435         } catch (InterruptedException | ExecutionException e) {
436             LOGGER.warn("Transation failed ",e);
437             return false;
438         }
439         return true;
440     }
441 }