Merge "Remove security group and security rule ConcurrentHashMaps"
[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, 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         Pool pool = readMd(createInstanceIdentifier(toMd(uuid)));
83         if (pool == null) {
84             return false;
85         }
86         return true;
87     }
88
89     @Override
90     public NeutronLoadBalancerPool getNeutronLoadBalancerPool(String uuid) {
91         Pool pool = readMd(createInstanceIdentifier(toMd(uuid)));
92         if (pool == null) {
93             return null;
94         }
95         return fromMd(pool);
96     }
97
98     @Override
99     public List<NeutronLoadBalancerPool> getAllNeutronLoadBalancerPools() {
100         Set<NeutronLoadBalancerPool> allLoadBalancerPools = new HashSet<NeutronLoadBalancerPool>();
101         Pools pools = readMd(createInstanceIdentifier());
102         if (pools != null) {
103             for (Pool pool: pools.getPool()) {
104                 allLoadBalancerPools.add(fromMd(pool));
105             }
106         }
107         LOGGER.debug("Exiting getLoadBalancerPools, Found {} OpenStackLoadBalancerPool", allLoadBalancerPools.size());
108         List<NeutronLoadBalancerPool> ans = new ArrayList<NeutronLoadBalancerPool>();
109         ans.addAll(allLoadBalancerPools);
110         return ans;
111     }
112
113     @Override
114     public boolean addNeutronLoadBalancerPool(NeutronLoadBalancerPool input) {
115         if (neutronLoadBalancerPoolExists(input.getID())) {
116             return false;
117         }
118         addMd(input);
119         //TODO: add code to find INeutronLoadBalancerPoolAware services and call newtorkCreated on them
120         return true;
121     }
122
123     @Override
124     public boolean removeNeutronLoadBalancerPool(String uuid) {
125         if (!neutronLoadBalancerPoolExists(uuid)) {
126             return false;
127         }
128         return removeMd(toMd(uuid));
129     }
130
131     @Override
132     public boolean updateNeutronLoadBalancerPool(String uuid, NeutronLoadBalancerPool delta) {
133         if (!neutronLoadBalancerPoolExists(uuid)) {
134             return false;
135         }
136         updateMd(delta);
137         return true;
138     }
139
140     @Override
141     public boolean neutronLoadBalancerPoolInUse(String loadBalancerPoolUUID) {
142         return !neutronLoadBalancerPoolExists(loadBalancerPoolUUID);
143     }
144
145     @Override
146     protected Pool toMd(String uuid) {
147         PoolBuilder poolBuilder = new PoolBuilder();
148         poolBuilder.setUuid(toUuid(uuid));
149         return poolBuilder.build();
150     }
151
152     @Override
153     protected InstanceIdentifier<Pool> createInstanceIdentifier(Pool pool) {
154         return InstanceIdentifier.create(Neutron.class)
155                 .child(Pools.class)
156                 .child(Pool.class, pool.getKey());
157     }
158
159     protected InstanceIdentifier<Pools> createInstanceIdentifier() {
160         return InstanceIdentifier.create(Neutron.class)
161                 .child(Pools.class);
162     }
163
164     @Override
165     protected Pool toMd(NeutronLoadBalancerPool pool) {
166         PoolBuilder poolBuilder = new PoolBuilder();
167         poolBuilder.setAdminStateUp(pool.getLoadBalancerPoolAdminIsStateIsUp());
168         if (pool.getLoadBalancerPoolDescription() != null) {
169             poolBuilder.setDescr(pool.getLoadBalancerPoolDescription());
170         }
171         if (pool.getNeutronLoadBalancerPoolHealthMonitorID() != null) {
172             poolBuilder.setHealthmonitorId(toUuid(pool.getNeutronLoadBalancerPoolHealthMonitorID()));
173         }
174         if (pool.getLoadBalancerPoolLbAlgorithm() != null) {
175             poolBuilder.setLbAlgorithm(pool.getLoadBalancerPoolLbAlgorithm());
176         }
177         if (pool.getLoadBalancerPoolListeners() != null) {
178             List<Uuid> listListener = new ArrayList<Uuid>();
179             for (Neutron_ID neutron_id : pool.getLoadBalancerPoolListeners()) {
180                 listListener.add(toUuid(neutron_id.getID()));
181             }
182             poolBuilder.setListeners(listListener);
183         }
184         // because members are another container, we don't want to copy
185         // it over, so just skip it here
186         if (pool.getLoadBalancerPoolName() != null) {
187             poolBuilder.setName(pool.getLoadBalancerPoolName());
188         }
189         if (pool.getLoadBalancerPoolProtocol() != null) {
190             ImmutableBiMap<String, Class<? extends ProtocolBase>> mapper =
191                 PROTOCOL_MAP.inverse();
192             poolBuilder.setProtocol((Class<? extends ProtocolBase>) mapper.get(pool.getLoadBalancerPoolProtocol()));
193         }
194         if (pool.getLoadBalancerPoolSessionPersistence() != null) {
195             NeutronLoadBalancer_SessionPersistence sessionPersistence = pool.getLoadBalancerPoolSessionPersistence();
196             SessionPersistenceBuilder sessionPersistenceBuilder = new SessionPersistenceBuilder();
197             sessionPersistenceBuilder.setCookieName(sessionPersistence.getCookieName());
198             sessionPersistenceBuilder.setType(sessionPersistence.getType());
199             poolBuilder.setSessionPersistence(sessionPersistenceBuilder.build());
200         }
201         if (pool.getLoadBalancerPoolTenantID() != null) {
202             poolBuilder.setTenantId(toUuid(pool.getLoadBalancerPoolTenantID()));
203         }
204         if (pool.getID() != null) {
205             poolBuilder.setUuid(toUuid(pool.getID()));
206         } else {
207             LOGGER.warn("Attempting to write neutron load balancer pool without UUID");
208         }
209         return poolBuilder.build();
210     }
211
212     protected NeutronLoadBalancerPool fromMd(Pool pool) {
213         NeutronLoadBalancerPool answer = new NeutronLoadBalancerPool();
214         if (pool.isAdminStateUp() != null) {
215             answer.setLoadBalancerPoolAdminStateIsUp(pool.isAdminStateUp());
216         }
217         if (pool.getDescr() != null) {
218             answer.setLoadBalancerPoolDescription(pool.getDescr());
219         }
220         if (pool.getHealthmonitorId() != null) {
221             answer.setNeutronLoadBalancerPoolHealthMonitorID(pool.getHealthmonitorId().getValue());
222         }
223         if (pool.getLbAlgorithm() != null) {
224             answer.setLoadBalancerPoolLbAlgorithm(pool.getLbAlgorithm());
225         }
226         if (pool.getListeners() != null) {
227             List<Neutron_ID> ids = new ArrayList<Neutron_ID>();
228             for (Uuid id : pool.getListeners()) {
229                 ids.add(new Neutron_ID(id.getValue()));
230             }
231             answer.setLoadBalancerPoolListeners(ids);
232         }
233         if (pool.getMembers() != null) {
234             List<NeutronLoadBalancerPoolMember> members = new ArrayList<NeutronLoadBalancerPoolMember>();
235             for (Member member: pool.getMembers().getMember()) {
236                 members.add(fromMemberMd(member));
237             }
238             answer.setLoadBalancerPoolMembers(members);
239         }
240         if (pool.getName() != null) {
241             answer.setLoadBalancerPoolName(pool.getName());
242         }
243         if (pool.getProtocol() != null) {
244             answer.setLoadBalancerPoolProtocol(PROTOCOL_MAP.get(pool.getProtocol()));
245         }
246         if (pool.getSessionPersistence() != null) {
247             NeutronLoadBalancer_SessionPersistence sessionPersistence = new NeutronLoadBalancer_SessionPersistence();
248             sessionPersistence.setCookieName(pool.getSessionPersistence().getCookieName());
249             sessionPersistence.setType(pool.getSessionPersistence().getType());
250             
251             answer.setLoadBalancerSessionPersistence(sessionPersistence);
252         }
253         if (pool.getTenantId() != null) {
254             answer.setLoadBalancerPoolTenantID(pool.getTenantId().getValue().replace("-",""));
255         }
256         if (pool.getUuid() != null) {
257             answer.setID(pool.getUuid().getValue());
258         }
259         return answer;
260     }
261
262     public static void registerNewInterface(BundleContext context,
263                                             ProviderContext providerContext,
264                                             List<ServiceRegistration<?>> registrations) {
265         NeutronLoadBalancerPoolInterface neutronLoadBalancerPoolInterface = new NeutronLoadBalancerPoolInterface(providerContext);
266         ServiceRegistration<INeutronLoadBalancerPoolCRUD> neutronLoadBalancerPoolInterfaceRegistration = context.registerService(INeutronLoadBalancerPoolCRUD.class, neutronLoadBalancerPoolInterface, null);
267         if(neutronLoadBalancerPoolInterfaceRegistration != null) {
268             registrations.add(neutronLoadBalancerPoolInterfaceRegistration);
269         }
270     }
271
272     public boolean neutronLoadBalancerPoolMemberExists(String poolUuid, String uuid) {
273         Member member = readMemberMd(
274                 createMemberInstanceIdentifier(toMd(poolUuid),
275                                                toMemberMd(uuid)));
276         if (member == null) {
277             return false;
278         }
279         return true;
280     }
281
282     public NeutronLoadBalancerPoolMember getNeutronLoadBalancerPoolMember(
283             String poolUuid, String uuid) {
284         Member member = readMemberMd(
285                 createMemberInstanceIdentifier(toMd(poolUuid),
286                                                toMemberMd(uuid)));
287         if (member == null) {
288             return null;
289         }
290         return fromMemberMd(member);
291     }
292
293     public List<NeutronLoadBalancerPoolMember> getAllNeutronLoadBalancerPoolMembers(String poolUuid) {
294         Set<NeutronLoadBalancerPoolMember> allLoadBalancerPoolMembers = new HashSet<NeutronLoadBalancerPoolMember>();
295         Members members = readMd(createMembersInstanceIdentifier(toMd(poolUuid)));
296         if (members != null) {
297             for (Member member: members.getMember()) {
298                 allLoadBalancerPoolMembers.add(fromMemberMd(member));
299             }
300         }
301         LOGGER.debug("Exiting getLoadBalancerPoolMembers, Found {} OpenStackLoadBalancerPoolMember",
302                 allLoadBalancerPoolMembers.size());
303         List<NeutronLoadBalancerPoolMember> ans = new ArrayList<NeutronLoadBalancerPoolMember>();
304         ans.addAll(allLoadBalancerPoolMembers);
305         return ans;
306     }
307
308     public boolean addNeutronLoadBalancerPoolMember(String poolUuid, NeutronLoadBalancerPoolMember input) {
309         if (neutronLoadBalancerPoolMemberExists(poolUuid, input.getID())) {
310             return false;
311         }
312         addMemberMd(toMd(poolUuid), input);
313         return true;
314     }
315
316     public boolean removeNeutronLoadBalancerPoolMember(String poolUuid, String uuid) {
317         if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) {
318             return false;
319         }
320         return removeMemberMd(toMd(poolUuid), toMemberMd(uuid));
321     }
322
323     public boolean updateNeutronLoadBalancerPoolMember(String poolUuid,
324             String uuid, NeutronLoadBalancerPoolMember delta) {
325         if (!neutronLoadBalancerPoolMemberExists(poolUuid, uuid)) {
326             return false;
327         }
328         updateMemberMd(toMd(poolUuid), delta);
329         return true;
330     }
331
332     public boolean neutronLoadBalancerPoolMemberInUse(String poolUuid,
333             String loadBalancerPoolMemberID) {
334         return !neutronLoadBalancerPoolMemberExists(poolUuid,
335                                                     loadBalancerPoolMemberID);
336     }
337
338     protected InstanceIdentifier<Member> createMemberInstanceIdentifier(Pool pool,
339             Member item) {
340         return InstanceIdentifier.create(Neutron.class)
341             .child(Pools.class)
342             .child(Pool.class, pool.getKey())
343             .child(Members.class)
344             .child(Member.class, item.getKey());
345     }
346
347     protected InstanceIdentifier<Members> createMembersInstanceIdentifier(Pool pool) {
348         return InstanceIdentifier.create(Neutron.class)
349             .child(Pools.class)
350             .child(Pool.class, pool.getKey())
351             .child(Members.class);
352     }
353
354     static NeutronLoadBalancerPoolMember fromMemberMd(Member member) {
355         NeutronLoadBalancerPoolMember answer = new NeutronLoadBalancerPoolMember();
356         if (member.isAdminStateUp() != null) {
357             answer.setPoolMemberAdminStateIsUp(member.isAdminStateUp());
358         }
359         if (member.getAddress() != null) {
360             answer.setPoolMemberAddress(String.valueOf(member.getAddress().getValue()));
361         }
362         if (member.getProtocolPort() != null) {
363             answer.setPoolMemberProtoPort(member.getProtocolPort());
364         }
365         if (member.getUuid() != null) {
366             answer.setID(member.getUuid().getValue());
367             answer.setPoolID(member.getUuid().getValue());
368         }
369         if (member.getSubnetId() != null) {
370             answer.setPoolMemberSubnetID(member.getSubnetId().getValue());
371         }
372         if (member.getTenantId() != null) {
373             answer.setPoolMemberTenantID(member.getTenantId().getValue().replace("-",""));
374         }
375         if (member.getWeight() != null) {
376             answer.setPoolMemberWeight(member.getWeight());
377         }
378         return answer;
379     }
380
381     protected Member toMemberMd(NeutronLoadBalancerPoolMember member) {
382         MemberBuilder memberBuilder = new MemberBuilder();
383         memberBuilder.setAdminStateUp(member.getPoolMemberAdminStateIsUp());
384         if (member.getPoolMemberAddress() != null) {
385             IpAddress ipAddress = new IpAddress(member.getPoolMemberAddress().toCharArray());
386             memberBuilder.setAddress(ipAddress);
387         }
388         if (member.getPoolMemberProtoPort() != null) {
389             memberBuilder.setProtocolPort(member.getPoolMemberProtoPort());
390         }
391         if (member.getID() != null) {
392             memberBuilder.setUuid(toUuid(member.getID()));
393         }
394         if (member.getPoolMemberSubnetID() != null) {
395             memberBuilder.setSubnetId(toUuid(member.getPoolMemberSubnetID()));
396         }
397         if (member.getPoolMemberTenantID() != null) {
398             memberBuilder.setTenantId(toUuid(member.getPoolMemberTenantID()));
399         }
400         if (member.getPoolMemberWeight() != null) {
401             memberBuilder.setWeight(member.getPoolMemberWeight());
402         }
403         return memberBuilder.build();
404     }
405
406     protected Member toMemberMd(String uuid) {
407         MemberBuilder memberBuilder = new MemberBuilder();
408         memberBuilder.setUuid(toUuid(uuid));
409         return memberBuilder.build();
410     }
411
412     protected <T extends org.opendaylight.yangtools.yang.binding.DataObject> T readMemberMd(InstanceIdentifier<T> path) {
413         T result = null;
414         final ReadOnlyTransaction transaction = getDataBroker().newReadOnlyTransaction();
415         CheckedFuture<Optional<T>, ReadFailedException> future = transaction.read(LogicalDatastoreType.CONFIGURATION, path);
416         if (future != null) {
417             Optional<T> optional;
418             try {
419                 optional = future.checkedGet();
420                 if (optional.isPresent()) {
421                     result = optional.get();
422                 }
423             } catch (ReadFailedException e) {
424                 LOGGER.warn("Failed to read {}", path, e);
425             }
426         }
427         transaction.close();
428         return result;
429     }
430
431     protected boolean addMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) {
432         // TODO think about adding existence logic
433         return updateMemberMd(pool, neutronObject);
434     }
435
436     protected boolean updateMemberMd(Pool pool, NeutronLoadBalancerPoolMember neutronObject) {
437         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
438         Member item = toMemberMd(neutronObject);
439         InstanceIdentifier<Member> iid = createMemberInstanceIdentifier(pool, item);
440         transaction.put(LogicalDatastoreType.CONFIGURATION, iid, item,true);
441         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
442         try {
443             future.get();
444         } catch (InterruptedException | ExecutionException e) {
445             LOGGER.warn("Transation failed ",e);
446             return false;
447         }
448         return true;
449     }
450
451     protected boolean removeMemberMd(Pool pool, Member item) {
452         WriteTransaction transaction = getDataBroker().newWriteOnlyTransaction();
453         InstanceIdentifier<Member> iid = createMemberInstanceIdentifier(pool, item);
454         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
455         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
456         try {
457             future.get();
458         } catch (InterruptedException | ExecutionException e) {
459             LOGGER.warn("Transation failed ",e);
460             return false;
461         }
462         return true;
463     }
464 }