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