Properties lbaasHandlerProperties = new Properties();
lbaasHandlerProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER);
- c.setInterface(new String[] {INeutronLoadBalancerAware.class.getName()},
- lbaasHandlerProperties);
+ c.setInterface(new String[] {INeutronLoadBalancerAware.class.getName(),
+ IInventoryListener.class.getName(),
+ AbstractHandler.class.getName()},
+ lbaasHandlerProperties);
c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true));
c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true));
Properties lbaasPoolMemberHandlerProperties = new Properties();
lbaasPoolMemberHandlerProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER_POOL_MEMBER);
- c.setInterface(new String[] {INeutronLoadBalancerPoolMemberAware.class.getName()},
- lbaasPoolMemberHandlerProperties);
+ c.setInterface(new String[] {INeutronLoadBalancerPoolMemberAware.class.getName(),
+ AbstractHandler.class.getName()},
+ lbaasPoolMemberHandlerProperties);
c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true));
c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true));
return HttpURLConnection.HTTP_OK;
}
- /**
- * Assuming that the pool information is fully populated before this call is made,
- * we go with creating the LoadBalancerConfiguration object for this call with
- * all information that is necessary to insert flow_mods
- */
@Override
public void neutronLoadBalancerCreated(NeutronLoadBalancer neutronLB) {
logger.debug("Neutron LB Creation : {}", neutronLB.toString());
enqueueEvent(new NorthboundEvent(neutronLB, Action.ADD));
}
+ /**
+ * Assuming that the pool information is fully populated before this call is made,
+ * we go with creating the LoadBalancerConfiguration object for this call with
+ * all information that is necessary to insert flow_mods
+ */
private void doNeutronLoadBalancerCreate(NeutronLoadBalancer neutronLB) {
Preconditions.checkNotNull(loadBalancerProvider);
LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
if (!lbConfig.isValid()) {
logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+ } else if (this.switchManager.getNodes().size() == 0) {
+ logger.trace("Noop with LB {} creation because no nodes available.", lbConfig.getName());
} else {
for (Node node: this.switchManager.getNodes())
loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.ADD);
@Override
public int canUpdateNeutronLoadBalancer(NeutronLoadBalancer delta, NeutronLoadBalancer original) {
- return HttpURLConnection.HTTP_OK;
+ LoadBalancerConfiguration lbConfig = extractLBConfiguration(delta);
+ if (!lbConfig.isValid())
+ return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
+ else
+ return HttpURLConnection.HTTP_OK;
}
@Override
public void neutronLoadBalancerUpdated(NeutronLoadBalancer neutronLB) {
+ logger.debug("Neutron LB Update : {}", neutronLB.toString());
enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
- return;
}
@Override
public int canDeleteNeutronLoadBalancer(NeutronLoadBalancer neutronLB) {
LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
- if (!lbConfig.isValid())
+ if (lbConfig == null)
return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
else
return HttpURLConnection.HTTP_OK;
if (!lbConfig.isValid()) {
logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+ } else if (this.switchManager.getNodes().size() == 0) {
+ logger.trace("Noop with LB {} deletion because no nodes available.", lbConfig.getName());
} else {
for (Node node: this.switchManager.getNodes())
loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
*/
@Override
public void processEvent(AbstractEvent abstractEvent) {
+ logger.debug("Processing Loadbalancer event " + abstractEvent);
if (!(abstractEvent instanceof NorthboundEvent)) {
logger.error("Unable to process abstract event " + abstractEvent);
return;
switch (ev.getAction()) {
case ADD:
doNeutronLoadBalancerCreate(ev.getLoadBalancer());
+ break;
case DELETE:
+ try {
doNeutronLoadBalancerDelete(ev.getLoadBalancer());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ break;
case UPDATE:
/**
* Currently member update requires delete and re-adding
String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
- String memberID, memberIP, memberMAC, memberProtocol;
+ String memberID, memberIP, memberMAC, memberProtocol, memberSubnetID;
Integer memberPort;
+ Boolean memberAdminStateIsUp;
for (NeutronLoadBalancerPool neutronLBPool: neutronLBPoolCache.getAllNeutronLoadBalancerPools()) {
- List<? extends NeutronLoadBalancerPoolMember> members =
- (List<? extends NeutronLoadBalancerPoolMember>)neutronLBPool.getLoadBalancerPoolMembers();
+ List<NeutronLoadBalancerPoolMember> members = neutronLBPool.getLoadBalancerPoolMembers();
memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
+ if (memberProtocol == null)
+ continue;
/*
* Only HTTP and HTTPS are supported as of this version
* TODO: Support all TCP load-balancers
memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
continue;
for (NeutronLoadBalancerPoolMember neutronLBPoolMember: members) {
- if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID) &&
- neutronLBPoolMember.getPoolMemberAdminStateIsUp()) {
+ memberAdminStateIsUp = neutronLBPoolMember.getPoolMemberAdminStateIsUp();
+ memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
+ if (memberSubnetID == null || memberAdminStateIsUp == null)
+ continue;
+ else if (memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp.booleanValue()) {
memberID = neutronLBPoolMember.getPoolMemberID();
memberIP = neutronLBPoolMember.getPoolMemberAddress();
memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
logger.debug("notifyNode: Node {} update {} from Controller's inventory Service", node, type);
Preconditions.checkNotNull(loadBalancerProvider);
- if (type.equals(UpdateType.ADDED)) {
- for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
- LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
- if (!lbConfig.isValid())
- logger.trace("Neutron LB configuration invalid for {} ", lbConfig.getName());
- else
+ for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
+ LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
+ if (!lbConfig.isValid())
+ logger.trace("Neutron LB configuration invalid for {} ", lbConfig.getName());
+ else {
+ if (type.equals(UpdateType.ADDED))
loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.ADD);
+ else if (type.equals(UpdateType.REMOVED))
+ loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
}
}
}
import com.google.common.base.Preconditions;
import java.net.HttpURLConnection;
-import java.util.List;
/**
* Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
return HttpURLConnection.HTTP_OK;
}
- /**
- * Assuming that the pool information is fully populated before this call is made,
- * we go with creating the LoadBalancerConfiguration object for this call with
- * all information that is necessary to insert flow_mods
- */
@Override
public void neutronLoadBalancerPoolMemberCreated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
logger.debug("Neutron LB Pool Member Creation : {}", neutronLBPoolMember.toString());
enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.ADD));
}
+ /**
+ * Assuming that the pool information is fully populated before this call is made,
+ * we go with creating the LoadBalancerConfiguration object for this call with
+ * all information that is necessary to insert flow_mods
+ */
private void doNeutronLoadBalancerPoolMemberCreate(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
Preconditions.checkNotNull(loadBalancerProvider);
LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
if (lbConfig == null) {
logger.trace("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
- }
- else if (!lbConfig.isValid()) {
+ } else if (lbConfig.getVip() == null) {
+ logger.trace("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+ } else if (!lbConfig.isValid()) {
logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+ } else if (this.switchManager.getNodes().size() == 0) {
+ logger.trace("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getPoolMemberID());
} else {
for (Node node: this.switchManager.getNodes())
loadBalancerProvider.programLoadBalancerPoolMemberRules(node, lbConfig,
@Override
public int canUpdateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember delta, NeutronLoadBalancerPoolMember original) {
- return HttpURLConnection.HTTP_OK;
+ LoadBalancerConfiguration lbConfig = extractLBConfiguration(delta);
+ if (lbConfig == null)
+ return HttpURLConnection.HTTP_BAD_REQUEST;
+ else if (!lbConfig.isValid())
+ return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
+ else
+ return HttpURLConnection.HTTP_OK;
}
@Override
public void neutronLoadBalancerPoolMemberUpdated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
+ logger.debug("Neutron LB Pool Member Update : {}", neutronLBPoolMember.toString());
enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.UPDATE));
- return;
}
@Override
@Override
public void neutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
logger.debug("Neutron LB Pool Member Deletion : {}", neutronLBPoolMember.toString());
-
- /* As of now, deleting a member involves recomputing member indices.
- * This is best done through a complete update of the load balancer instance.
- */
- for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
- String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
- if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
- enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
- break;
- }
- }
+ enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.DELETE));
}
/**
switch (ev.getAction()) {
case ADD:
doNeutronLoadBalancerPoolMemberCreate(ev.getLoadBalancerPoolMember());
+ break;
case DELETE:
- logger.warn("Load balancer pool member delete event should not have been triggered");
+ /* As of now, deleting a member involves recomputing member indices.
+ * This is best done through a complete update of the load balancer instance.
+ */
+ for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
+ String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
+ if (ev.getLoadBalancerPoolMember()
+ .getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
+ enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
+ break;
+ }
+ }
+ break;
case UPDATE:
/**
* Typical upgrade involves changing weights. Since weights are not
* configuration from the neutron LB cache based on member info
*/
public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
+ String memberID = neutronLBPoolMember.getPoolMemberID();
String memberIP = neutronLBPoolMember.getPoolMemberAddress();
String memberMAC = NeutronCacheUtils.getMacAddress(neutronPortsCache, memberIP);
- if (memberMAC == null)
+ if (memberMAC == null) {
+ logger.trace("Neutron LB pool member {} MAC address unavailable", memberID);
return null;
-
- String memberID = neutronLBPoolMember.getPoolMemberID();
+ }
+ String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
+ String memberPoolID = neutronLBPoolMember.getPoolID();
String memberProtocol = null;
- boolean found = false;
-
- for (NeutronLoadBalancerPool neutronLBPool: neutronLBPoolCache.getAllNeutronLoadBalancerPools()) {
- List<? extends NeutronLoadBalancerPoolMember> members =
- (List<? extends NeutronLoadBalancerPoolMember>)neutronLBPool.getLoadBalancerPoolMembers();
- for (NeutronLoadBalancerPoolMember member: members) {
- //TODO: Allow member to be present in more than 1 pool
- if (member.getPoolMemberID().equals(neutronLBPoolMember.getPoolMemberID())) {
- found = true;
- memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
- if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
- memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
- memberProtocol = null;
- break;
- }
- }
- if (found)
- break;
+
+ if (memberSubnetID == null || memberID == null || memberPoolID == null) {
+ logger.trace("Neutron LB pool member details incomplete [id={}, pool_id={},subnet_id={}",
+ memberID, memberPoolID, memberSubnetID);
+ return null;
}
- if (memberProtocol == null)
+ NeutronLoadBalancerPool neutronLBPool = neutronLBPoolCache.getNeutronLoadBalancerPool(memberPoolID);
+ memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
+ if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
+ memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
return null;
- String loadBalancerSubnetID, loadBalancerVip, loadBalancerName;
+ String loadBalancerSubnetID, loadBalancerVip=null, loadBalancerName=null;
for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
- if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
+ if (memberSubnetID.equals(loadBalancerSubnetID)) {
loadBalancerName = neutronLB.getLoadBalancerName();
loadBalancerVip = neutronLB.getLoadBalancerVipAddress();
- LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
- lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);
- return lbConfig;
+ break;
}
}
- return null;
+ /**
+ * It is possible that the VIP has not been created yet.
+ * In that case, we create dummy configuration that will not program rules.
+ */
+ LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+ lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);
+ return lbConfig;
}
}
+ ", routerInterface=" + routerInterface
+ ", floatingIP=" + neutronFloatingIP
+ ", network=" + neutronNetwork
+ + ", loadBalancer=" + loadBalancer
+ + ", loadBalancerPool=" + loadBalancerPool
+ + ", loadBalancerPoolMember=" + loadBalancerPoolMember
+ "]";
}
public String getName() {
return this.name;
}
+
+ @Override
+ public String toString() {
+ return "LoadBalancerConfiguration [name=" + name + ", vip=" + vip +
+ ", members=" + members + "]";
+ }
}