2 * Copyright (C) 2014 SDN Hub, LLC.
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
8 * Authors : Srini Seetharaman
11 package org.opendaylight.ovsdb.openstack.netvirt;
13 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
14 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
15 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware;
16 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
17 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
18 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
19 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
20 import org.opendaylight.controller.sal.core.Node;
21 import org.opendaylight.controller.switchmanager.ISwitchManager;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
23 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
24 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerProvider;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import com.google.common.base.Preconditions;
30 import java.net.HttpURLConnection;
31 import java.util.List;
34 * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
35 * /v2.0/pools/{pool_id}/members
38 public class LBaaSPoolMemberHandler extends AbstractHandler
39 implements INeutronLoadBalancerPoolMemberAware {
41 private static final Logger logger = LoggerFactory.getLogger(LBaaSPoolMemberHandler.class);
43 // The implementation for each of these services is resolved by the OSGi Service Manager
44 private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache;
45 private volatile INeutronLoadBalancerCRUD neutronLBCache;
46 private volatile INeutronPortCRUD neutronPortsCache;
47 private volatile LoadBalancerProvider loadBalancerProvider;
48 private volatile ISwitchManager switchManager;
51 public int canCreateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
52 LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
54 return HttpURLConnection.HTTP_BAD_REQUEST;
55 else if (!lbConfig.isValid())
56 return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
58 return HttpURLConnection.HTTP_OK;
62 * Assuming that the pool information is fully populated before this call is made,
63 * we go with creating the LoadBalancerConfiguration object for this call with
64 * all information that is necessary to insert flow_mods
67 public void neutronLoadBalancerPoolMemberCreated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
68 logger.debug("Neutron LB Pool Member Creation : {}", neutronLBPoolMember.toString());
69 enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.ADD));
72 private void doNeutronLoadBalancerPoolMemberCreate(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
73 Preconditions.checkNotNull(loadBalancerProvider);
74 LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
75 if (lbConfig == null) {
76 logger.trace("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
78 else if (!lbConfig.isValid()) {
79 logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
81 for (Node node: this.switchManager.getNodes())
82 loadBalancerProvider.programLoadBalancerMemberRules(node, lbConfig,
83 lbConfig.getMembers().get(neutronLBPoolMember.getPoolMemberID()), Action.ADD);
88 public int canUpdateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember delta, NeutronLoadBalancerPoolMember original) {
89 return HttpURLConnection.HTTP_OK;
93 public void neutronLoadBalancerPoolMemberUpdated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
94 enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.UPDATE));
99 public int canDeleteNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
100 LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
101 if (lbConfig == null)
102 return HttpURLConnection.HTTP_BAD_REQUEST;
103 else if (!lbConfig.isValid())
104 return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
106 return HttpURLConnection.HTTP_OK;
110 public void neutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
111 logger.debug("Neutron LB Pool Member Deletion : {}", neutronLBPoolMember.toString());
112 enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.DELETE));
115 private void doNeutronLoadBalancerPoolMemberDelete(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
116 Preconditions.checkNotNull(loadBalancerProvider);
117 LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
118 if (lbConfig == null) {
119 logger.trace("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
121 else if (!lbConfig.isValid()) {
122 logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
124 for (Node node: this.switchManager.getNodes())
125 loadBalancerProvider.programLoadBalancerMemberRules(node, lbConfig,
126 lbConfig.getMembers().get(neutronLBPoolMember.getPoolMemberID()), Action.DELETE);
133 * @param abstractEvent the {@link org.opendaylight.ovsdb.openstack.netvirt.AbstractEvent} event to be handled.
134 * @see org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher
137 public void processEvent(AbstractEvent abstractEvent) {
138 if (!(abstractEvent instanceof NorthboundEvent)) {
139 logger.error("Unable to process abstract event " + abstractEvent);
142 NorthboundEvent ev = (NorthboundEvent) abstractEvent;
143 switch (ev.getAction()) {
145 doNeutronLoadBalancerPoolMemberCreate(ev.getLoadBalancerPoolMember());
147 doNeutronLoadBalancerPoolMemberDelete(ev.getLoadBalancerPoolMember());
150 * Currently member update requires delete and re-adding
151 * Also, weights and weight updates are not supported
153 doNeutronLoadBalancerPoolMemberDelete(ev.getLoadBalancerPoolMember());
154 doNeutronLoadBalancerPoolMemberCreate(ev.getLoadBalancerPoolMember());
157 logger.warn("Unable to process event action " + ev.getAction());
163 * Useful utility for extracting the loadbalancer instance
164 * configuration from the neutron LB cache based on member info
166 public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
167 String memberIP = neutronLBPoolMember.getPoolMemberAddress();
168 String memberMAC = NeutronCacheUtils.getMacAddress(neutronPortsCache, memberIP);
169 if (memberMAC == null)
172 String memberID = neutronLBPoolMember.getPoolMemberID();
173 Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
174 String memberProtocol = null;
175 boolean found = false;
177 for (NeutronLoadBalancerPool neutronLBPool: neutronLBPoolCache.getAllNeutronLoadBalancerPools()) {
178 List<? extends NeutronLoadBalancerPoolMember> members =
179 (List<? extends NeutronLoadBalancerPoolMember>)neutronLBPool.getLoadBalancerPoolMembers();
180 for (NeutronLoadBalancerPoolMember member: members) {
181 //TODO: Allow member to be present in more than 1 pool
182 if (member.getPoolMemberID().equals(neutronLBPoolMember.getPoolMemberID())) {
184 memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
185 if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
186 memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
187 memberProtocol = null;
194 if (memberProtocol == null)
197 String loadBalancerSubnetID, loadBalancerVip, loadBalancerName;
198 for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
199 loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
200 if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
201 loadBalancerName = neutronLB.getLoadBalancerName();
202 loadBalancerVip = neutronLB.getLoadBalancerVipAddress();
203 LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
204 lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);