Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.gemini.provision.loadbalancer.openstack; import com.gemini.domain.common.AdminState; import com.gemini.domain.common.LoadBalancerAlgorithm; import com.gemini.domain.common.Protocol; import com.gemini.domain.common.ProvisionState; import com.gemini.domain.model.GeminiApplication; import com.gemini.domain.model.GeminiEnvironment; import com.gemini.domain.model.GeminiLoadBalancer; import com.gemini.domain.model.GeminiLoadBalancerHealthMonitor; import com.gemini.domain.model.GeminiLoadBalancerPool; import com.gemini.domain.model.GeminiNetwork; import com.gemini.domain.model.GeminiPoolMember; import com.gemini.domain.model.GeminiSubnet; import com.gemini.domain.model.GeminiTenant; import com.gemini.domain.model.GeminiVip; import com.gemini.provision.base.ProvisioningProviderResponseType; import com.gemini.provision.loadbalancer.base.LoadBalancerProvider; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.gemini.provision.loadbalancer.utils.GeminiLBUtils; import com.gemini.provision.network.base.NetworkProvider; import com.google.inject.Inject; import jersey.repackaged.com.google.common.net.InetAddresses; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.openstack4j.api.Builders; import org.openstack4j.api.OSClient; import org.openstack4j.api.exceptions.ClientResponseException; import org.openstack4j.model.compute.ActionResponse; import org.openstack4j.model.network.ext.*; import org.openstack4j.openstack.OSFactory; import org.pmw.tinylog.Logger; /** * * @author schari */ public class LoadBalancerProviderOpenStackImpl implements LoadBalancerProvider { @Inject private NetworkProvider networkProvider; @Override public List<GeminiLoadBalancer> listAllVIPs(GeminiTenant tenant, GeminiEnvironment env) { List<GeminiLoadBalancer> vips = Collections.synchronizedList(new ArrayList()); //authenticate the session with the OpenStack installation OSClient os = OSFactory.builder().endpoint(env.getEndPoint()) .credentials(env.getAdminUserName(), env.getAdminPassword()).tenantName(tenant.getName()) .authenticate(); if (os == null) { Logger.error("Failed to authenticate Tenant: {}", ToStringBuilder.reflectionToString(tenant, ToStringStyle.MULTI_LINE_STYLE)); return null; } //try to get the list of VIP's List<? extends Vip> osVips; try { osVips = os.networking().loadbalancers().vip().list(); } catch (ClientResponseException e) { Logger.error("Cloud failure - could not retrieve load balancer Vips. Exception: {}", e); return null; } //copy them to the gemini load balancer objects osVips.stream().filter(v -> v != null).forEach(v -> { GeminiLoadBalancer newLB = new GeminiLoadBalancer(); //the simple stuff newLB.setCloudID(v.getId()); newLB.setVirtualPvtIP(InetAddresses.forString(v.getAddress())); //Load balancer object references a subnet - this subnet must be //previously created and therefore MSUT BE AVAILABLE in the environment //scan the environment networks and find the subnet GeminiSubnet subnet = env.getApplications().stream().map(GeminiApplication::getNetworks) .flatMap(List::stream).map(GeminiNetwork::getSubnets).flatMap(List::stream) .filter(s -> s.getCloudID().equals(v.getId())).findFirst().get(); if (subnet == null) { Logger.info( "Load Balancer cloud ID {} references a subnet not available in environment {} Subnet ID: {}", v.getId(), env.getName(), v.getSubnetId()); } else { newLB.setVirtualPvtSubnet(subnet); } //now the pool String poolID = v.getPoolId(); String protocol = v.getProtocol(); vips.add(newLB); }); return vips; } @Override public ProvisioningProviderResponseType createVIP(GeminiTenant tenant, GeminiEnvironment env, GeminiVip lb) { OSClient os = getOSClient(tenant, env); Vip vip = GeminiLBUtils.getOpenStackVip(lb, tenant); Vip resultVip = os.networking().loadbalancers().vip().create(vip); return getResponseType(resultVip, tenant, env, "Virtual IP create"); } @Override public GeminiVip getVIP(GeminiTenant tenant, GeminiEnvironment env, String vipID) { OSClient os = getOSClient(tenant, env); Vip vip = os.networking().loadbalancers().vip().get(vipID); //check if the subnet id is already in application GeminiSubnet geminiSubnet = env.getSubnets().stream() .filter(subnet -> subnet.getCloudID().equals(vip.getSubnetId())).findFirst().get(); GeminiVip geminiVip = GeminiLBUtils.getAsGeminiVip(vip, tenant); if (geminiSubnet == null) { //fetch from controller geminiSubnet = networkProvider.getSubnet(tenant, env, vip.getSubnetId()); } GeminiLoadBalancerPool geminiLoadBalancerPool = env.getLoadBalancerPools().stream() .filter(pool -> pool.getCloudID().equals(vip.getPoolId())).findFirst().get(); if (geminiLoadBalancerPool == null) { //fetch from controller geminiLoadBalancerPool = getPool(tenant, env, vip.getPoolId()); } geminiVip.setGeminiLoadBalancerPool(geminiLoadBalancerPool); geminiVip.setGeminiSubnet(geminiSubnet); return geminiVip; } @Override public ProvisioningProviderResponseType updateVIP(GeminiTenant tenant, GeminiEnvironment env, GeminiVip geminiVip) { OSClient os = getOSClient(tenant, env); Vip vipUpdate = os.networking().loadbalancers().vip().update(geminiVip.getCloudID(), GeminiLBUtils.getVipUpdate(geminiVip)); return getResponseType(vipUpdate, tenant, env, "Virtual IP update"); } @Override public ProvisioningProviderResponseType deleteVIP(GeminiTenant tenant, GeminiEnvironment env, GeminiVip lb) { OSClient os = getOSClient(tenant, env); ActionResponse actionResponse = os.networking().loadbalancers().vip().delete(lb.getCloudID()); return getResponseType(actionResponse, lb, tenant, env, "Deleted"); } @Override public List<GeminiLoadBalancerHealthMonitor> listAllHealthMonitors(GeminiTenant tenant, GeminiEnvironment env) { List<GeminiLoadBalancerHealthMonitor> gHealthMonitors = new ArrayList<>(); OSClient os = getOSClient(tenant, env); List<? extends HealthMonitor> healthMonitors = os.networking().loadbalancers().healthMonitor().list(); healthMonitors.stream().filter(healthMonitor -> healthMonitor != null).forEach(healthMonitor -> { GeminiLoadBalancerHealthMonitor gHealthMonitor = GeminiLBUtils.getAsGeminiHealthMonitor(healthMonitor); gHealthMonitors.add(gHealthMonitor); }); return gHealthMonitors; } @Override public GeminiLoadBalancerHealthMonitor getHealthMonitor(GeminiTenant tenant, GeminiEnvironment env, String lb) { OSClient os = getOSClient(tenant, env); HealthMonitor healthMonitor = os.networking().loadbalancers().healthMonitor().get(lb); return GeminiLBUtils.getAsGeminiHealthMonitor(healthMonitor); } @Override public ProvisioningProviderResponseType createHealthMonitor(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerHealthMonitor hm) { OSClient os = getOSClient(tenant, env); HealthMonitor healthMonitor = os.networking().loadbalancers().healthMonitor() .create(GeminiLBUtils.createHealthMonitor(hm, tenant)); return getResponseType(healthMonitor, tenant, env, "created"); } @Override public ProvisioningProviderResponseType updateHealthMonitor(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerHealthMonitor hm) { OSClient os = getOSClient(tenant, env); HealthMonitor healthMonitor = os.networking().loadbalancers().healthMonitor().update(hm.getCloudID(), GeminiLBUtils.healthMonitorUpdate(hm)); return getResponseType(healthMonitor, tenant, env, "updated"); } @Override public ProvisioningProviderResponseType deleteHealthMonitor(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerHealthMonitor hm) { OSClient os = getOSClient(tenant, env); ActionResponse actionResponse = os.networking().loadbalancers().healthMonitor().delete(hm.getCloudID()); return getResponseType(actionResponse, hm, tenant, env, "Deleted"); } @Override public List<GeminiLoadBalancerPool> listAllPools(GeminiTenant tenant, GeminiEnvironment env) { List<GeminiLoadBalancerPool> lbPools = Collections.synchronizedList(new ArrayList()); //authenticate the session with the OpenStack installation OSClient os = OSFactory.builder().endpoint(env.getEndPoint()) .credentials(env.getAdminUserName(), env.getAdminPassword()).tenantName(tenant.getName()) .authenticate(); if (os == null) { Logger.error("Failed to authenticate Tenant: {}", ToStringBuilder.reflectionToString(tenant, ToStringStyle.MULTI_LINE_STYLE)); return null; } List<? extends LbPool> osLbPools = os.networking().loadbalancers().lbPool().list(); osLbPools.stream().filter(lbPool -> lbPool != null).forEach(lbPool -> { GeminiLoadBalancerPool loadBalancerPool = new GeminiLoadBalancerPool(); loadBalancerPool.setCloudID(lbPool.getId()); loadBalancerPool.setName(lbPool.getName()); loadBalancerPool.setDescription(lbPool.getDescription()); //TODO get the VpId from the pool loadBalancerPool.setVipID(lbPool.getVipId()); loadBalancerPool.setProtocol(Protocol.fromString(lbPool.getProtocol())); loadBalancerPool.setLoadBalancerAlgorithm(LoadBalancerAlgorithm.fromString(lbPool.getLbMethod())); //TODO set the pool member loadBalancerPool.setAdminState(lbPool.isAdminStateUp() ? AdminState.ADMIN_UP : AdminState.ADMIN_DOWN); GeminiSubnet subnet = env.getApplications().stream().map(GeminiApplication::getNetworks) .flatMap(List::stream).map(GeminiNetwork::getSubnets).flatMap(List::stream) .filter(s -> s.getCloudID().equals(lbPool.getId())).findFirst().get(); if (subnet == null) { Logger.info( "Load Balancer cloud ID {} references a subnet not available in environment {} Subnet ID: {}", lbPool.getId(), env.getName(), lbPool.getSubnetId()); } else { loadBalancerPool.setGeminiSubnet(subnet); } lbPools.add(loadBalancerPool); }); return lbPools; } @Override public GeminiLoadBalancerPool getPool(GeminiTenant tenant, GeminiEnvironment env, String poolID) { OSClient os = getOSClient(tenant, env); LbPool lbPool = os.networking().loadbalancers().lbPool().get(poolID); return GeminiLBUtils.getAsGeminiLoadBalancerPool(lbPool, env); } @Override public ProvisioningProviderResponseType createLBPool(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool geminiLoadBalancerPool) { OSClient os = getOSClient(tenant, env); LbPool lbPool = os.networking().loadbalancers().lbPool() .create(GeminiLBUtils.createLBPool(geminiLoadBalancerPool, tenant)); return getResponseType(lbPool, tenant, env, "LB Pool created"); } @Override public ProvisioningProviderResponseType updateLBPool(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool geminiLbPool) { OSClient os = getOSClient(tenant, env); LbPool lbPool = os.networking().loadbalancers().lbPool().update(geminiLbPool.getCloudID(), GeminiLBUtils.updateLBPool(geminiLbPool)); return getResponseType(lbPool, tenant, env, "updated"); } @Override public ProvisioningProviderResponseType deleteLBPool(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool lbPool) { OSClient os = getOSClient(tenant, env); ActionResponse actionResponse = os.networking().loadbalancers().lbPool().delete(lbPool.getCloudID()); return getResponseType(actionResponse, lbPool, tenant, env, "deleted"); } @Override public ProvisioningProviderResponseType associateHealthMonitorToPool(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool lbPool, GeminiLoadBalancerHealthMonitor hm) { OSClient os = getOSClient(tenant, env); HealthMonitorAssociate associate = Builders.lbPoolAssociateHealthMonitor().id(hm.getCloudID()).build(); HealthMonitor result = os.networking().loadbalancers().lbPool().associateHealthMonitor(lbPool.getCloudID(), associate); return getResponseType(result, tenant, env, "Health monitor associated "); } @Override public ProvisioningProviderResponseType disassociateHealthMonitorFromPool(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool lbPool, GeminiLoadBalancerHealthMonitor hm) { OSClient os = getOSClient(tenant, env); ActionResponse actionResponse = os.networking().loadbalancers().lbPool() .disAssociateHealthMonitor(lbPool.getCloudID(), hm.getCloudID()); return getResponseType(actionResponse, lbPool, tenant, env, "Health monitor dissociated"); } @Override public List<GeminiPoolMember> getPoolMembers(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool pool) { List<GeminiPoolMember> lbPools = Collections.synchronizedList(new ArrayList()); //authenticate the session with the OpenStack installation OSClient os = getOSClient(tenant, env); if (os == null) { Logger.error("Failed to authenticate Tenant: {}", ToStringBuilder.reflectionToString(tenant, ToStringStyle.MULTI_LINE_STYLE)); return null; } List<? extends Member> members = os.networking().loadbalancers().member().list(); members.stream().filter(member -> member != null).forEach(member -> { GeminiPoolMember geminiPoolMember = new GeminiPoolMember(); geminiPoolMember.setCloudID(member.getId()); geminiPoolMember.setAdminState(member.isAdminStateUp() ? AdminState.ADMIN_UP : AdminState.ADMIN_DOWN); geminiPoolMember.setProvisionState(ProvisionState.fromString(member.getStatus())); geminiPoolMember.setIpAddress(member.getAddress()); geminiPoolMember.setProtocolPort(member.getProtocolPort()); geminiPoolMember.setWeight(member.getWeight()); geminiPoolMember.setPoolId(member.getPoolId()); lbPools.add(geminiPoolMember); }); return lbPools; } @Override public ProvisioningProviderResponseType addPoolMember(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool pool, GeminiPoolMember poolMember) { OSClient os = getOSClient(tenant, env); Member member = Builders.member().address(poolMember.getIpAddress()) .adminStateUp(poolMember.getAdminState() == AdminState.ADMIN_DOWN ? false : true) .poolId(poolMember.getPoolId()).protocolPort(poolMember.getProtocolPort()) .weight(poolMember.getWeight()).tenantId(tenant.getTenantID()).weight(poolMember.getWeight()) .build(); Member newMember = os.networking().loadbalancers().member().create(member); return getResponseType(newMember, tenant, env, "created"); } @Override public GeminiPoolMember getPoolMember(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool pool, String poolMemberID) { OSClient os = getOSClient(tenant, env); Member member = os.networking().loadbalancers().member().get(poolMemberID); return GeminiLBUtils.getAsGeminiPoolMember(member); } @Override public ProvisioningProviderResponseType updatePoolMember(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool pool, GeminiPoolMember poolMember) { OSClient os = getOSClient(tenant, env); Member updatedMember = os.networking().loadbalancers().member().update(poolMember.getCloudID(), GeminiLBUtils.updatePoolMember(poolMember)); return getResponseType(updatedMember, tenant, env, "updated"); } @Override public ProvisioningProviderResponseType deletePoolMember(GeminiTenant tenant, GeminiEnvironment env, GeminiLoadBalancerPool pool, GeminiPoolMember poolMember) { OSClient os = getOSClient(tenant, env); ActionResponse actionResponse = os.networking().loadbalancers().member().delete(poolMember.getCloudID()); return getResponseType(actionResponse, poolMember, tenant, env, "deleted"); } public OSClient getOSClient(GeminiTenant tenant, GeminiEnvironment env) { //authenticate the session with the OpenStack installation OSClient os = OSFactory.builder().endpoint(env.getEndPoint()) .credentials(env.getAdminUserName(), env.getAdminPassword()).tenantName(tenant.getName()) .authenticate(); return os; } public ProvisioningProviderResponseType getResponseType(Object object, GeminiTenant tenant, GeminiEnvironment env, String operation) { if (object == null) { Logger.error("Failed to {}, failure in Cloud provider. Tenant: {} Environment: {} Network: {}", operation, tenant.getName(), env.getName(), ToStringBuilder.reflectionToString(object, ToStringStyle.MULTI_LINE_STYLE)); return ProvisioningProviderResponseType.CLOUD_FAILURE; } Logger.debug("Successfully {} {} - Tenant: {} Environment: {} Network: {}", operation, object.getClass().getName(), tenant.getName(), env.getName(), ToStringBuilder.reflectionToString(object, ToStringStyle.MULTI_LINE_STYLE)); return ProvisioningProviderResponseType.SUCCESS; } public ProvisioningProviderResponseType getResponseType(ActionResponse actionResponse, Object object, GeminiTenant tenant, GeminiEnvironment env, String operation) { if (!actionResponse.isSuccess()) { Logger.error("Failed to {} {}, failure in Cloud provider. Tenant: {} Environment: {} Network: {}", operation, object.getClass().getName(), tenant.getName(), env.getName(), ToStringBuilder.reflectionToString(object, ToStringStyle.MULTI_LINE_STYLE)); return ProvisioningProviderResponseType.CLOUD_FAILURE; } Logger.debug("Successfully {} {} - Tenant: {} Environment: {} Network: {}", operation, object.getClass().getName(), tenant.getName(), env.getName(), ToStringBuilder.reflectionToString(object, ToStringStyle.MULTI_LINE_STYLE)); return ProvisioningProviderResponseType.SUCCESS; } }