X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fsamples%2Floadbalancer%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsamples%2Floadbalancer%2Finternal%2FLoadBalancerService.java;h=ddfde38931f5db3544ef323dab11ec8222cd629d;hb=e2f7aaa41e482815ca1d4495eb85c8653cd903ab;hp=7eaa8b4ec03377cf429c67d670341dd74d20aa57;hpb=541d0a36997f292bb037a2199463431eee538358;p=controller.git diff --git a/opendaylight/samples/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerService.java b/opendaylight/samples/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerService.java index 7eaa8b4ec0..ddfde38931 100644 --- a/opendaylight/samples/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerService.java +++ b/opendaylight/samples/loadbalancer/src/main/java/org/opendaylight/controller/samples/loadbalancer/internal/LoadBalancerService.java @@ -56,78 +56,78 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * This class is the main class that represents the load balancer service. - * This is a sample load balancer application that balances traffic to backend servers - * based on the source address and source port on each incoming packet. The service + * This class is the main class that represents the load balancer service. + * This is a sample load balancer application that balances traffic to backend servers + * based on the source address and source port on each incoming packet. The service * reactively installs OpenFlow rules to direct all packets with a specific source address - * and source port to one of the appropriate backend servers. The servers may be chosen - * using a round robin policy or a random policy. This service can be configured via a + * and source port to one of the appropriate backend servers. The servers may be chosen + * using a round robin policy or a random policy. This service can be configured via a * REST APIs which are similar to the OpenStack Quantum LBaaS (Load-balancer-as-a-Service) * v1.0 API proposal (http://wiki.openstack.org/Quantum/LBaaS) - * + * * To use this service, a virtual IP (or VIP) should be exposed to the clients of this service * and used as the destination address. A VIP is a entity that comprises of a virtual IP, port * and protocol (TCP or UDP). * Assumptions: * 1. One or more VIPs may be mapped to the same server pool. All VIPs that share the same * pool must also share the same load balancing policy (random or round robin). - * + * * 2. Only one server pool can be be assigned to a VIP. - * + * * 3. All flow rules are installed with an idle timeout of 5 seconds. - * + * * 4. Packets to a VIP must leave the OpenFlow cluster from the same switch from where * it entered it. - * + * * 5. When you delete a VIP or a server pool or a server from a pool, the service does not * delete the flow rules it has already installed. The flow rules should automatically - * time out after the idle timeout of 5 seconds. + * time out after the idle timeout of 5 seconds. * */ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ - + /* * Logger instance */ private static Logger lbsLogger = LoggerFactory.getLogger(LoadBalancerService.class); - + /* * Single instance of the configuration manager. Application passes this reference to all * the new policies implemented for load balancing. */ private static ConfigManager configManager = new ConfigManager(); - + /* * Round robing policy instance. Need to implement factory patterns to get * policy instance. */ private static RoundRobinLBPolicy rrLBMethod= new RoundRobinLBPolicy(configManager); - + /* * Random policy instance. */ private static RandomLBPolicy ranLBMethod= new RandomLBPolicy(configManager); - + /* * Reference to the data packet service */ private IDataPacketService dataPacketService = null; - + /* * Reference to the host tracker service */ private IfIptoHost hostTracker; - + /* * Reference to the forwarding manager */ private IForwardingRulesManager ruleManager; - + /* * Reference to the routing service */ private IRouting routing; - + /* * Load balancer application installs all flows with priority 2. */ @@ -139,7 +139,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ private String containerName = null; /* - * Set/unset methods for the service instance that load balancer + * Set/unset methods for the service instance that load balancer * service requires */ public String getContainerName() { @@ -147,7 +147,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ return GlobalConstants.DEFAULT.toString(); return containerName; } - + void setDataPacketService(IDataPacketService s) { this.dataPacketService = s; } @@ -157,7 +157,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ this.dataPacketService = null; } } - + public void setRouting(IRouting routing) { this.routing = routing; } @@ -169,7 +169,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ } public void setHostTracker(IfIptoHost hostTracker) { - lbsLogger.debug("Setting HostTracker"); + lbsLogger.debug("Setting HostTracker"); this.hostTracker = hostTracker; } @@ -181,7 +181,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ public void setForwardingRulesManager( IForwardingRulesManager forwardingRulesManager) { - lbsLogger.debug("Setting ForwardingRulesManager"); + lbsLogger.debug("Setting ForwardingRulesManager"); this.ruleManager = forwardingRulesManager; } @@ -194,68 +194,68 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ /** * This method receives first packet of flows for which there is no - * matching flow rule installed on the switch. IP addresses used for VIPs + * matching flow rule installed on the switch. IP addresses used for VIPs * are not supposed to be used by any real/virtual host in the network. * Hence, any forwarding/routing service will not install any flows rules matching * these VIPs. This ensures that all the flows destined for VIPs will not find a match * in the switch and will be forwarded to the load balancing service. - * Service will decide where to route this traffic based on the load balancing - * policy of the VIP's attached pool and will install appropriate flow rules - * in a reactive manner. + * Service will decide where to route this traffic based on the load balancing + * policy of the VIP's attached pool and will install appropriate flow rules + * in a reactive manner. */ @Override public PacketResult receiveDataPacket(RawPacket inPkt){ - + if (inPkt == null) { return PacketResult.IGNORED; } - + Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt); - + if (formattedPak instanceof Ethernet) { byte[] vipMacAddr = ((Ethernet) formattedPak).getDestinationMACAddress(); Object ipPkt = formattedPak.getPayload(); - + if (ipPkt instanceof IPv4) { - + lbsLogger.debug("Packet recieved from switch : {}",inPkt.getIncomingNodeConnector().getNode().toString()); IPv4 ipv4Pkt = (IPv4)ipPkt; if(IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.TCP.toString()) || IPProtocols.getProtocolName(ipv4Pkt.getProtocol()).equals(IPProtocols.UDP.toString())){ - + lbsLogger.debug("Packet protocol : {}",IPProtocols.getProtocolName(ipv4Pkt.getProtocol())); Client client = new LBUtil().getClientFromPacket(ipv4Pkt); VIP vip = new LBUtil().getVIPFromPacket(ipv4Pkt); - + if(configManager.vipExists(vip)){ VIP vipWithPoolName = configManager.getVIPWithPoolName(vip); String poolMemberIp = null; if(configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod().equalsIgnoreCase(LBConst.ROUND_ROBIN_LB_METHOD)){ - + poolMemberIp = rrLBMethod.getPoolMemberForClient(client,vipWithPoolName); } - + if(configManager.getPool(vipWithPoolName.getPoolName()).getLbMethod().equalsIgnoreCase(LBConst.RANDOM_LB_METHOD)){ poolMemberIp = ranLBMethod.getPoolMemberForClient(client,vipWithPoolName); } - + try { - + Node clientNode = inPkt.getIncomingNodeConnector().getNode(); HostNodeConnector hnConnector = this.hostTracker.hostFind(InetAddress.getByName(poolMemberIp)); - + Node destNode = hnConnector.getnodeconnectorNode(); - + lbsLogger.debug("Client is connected to switch : {}",clientNode.toString()); lbsLogger.debug("Destination pool machine is connected to switch : {}",destNode.toString()); - + //Get path between both the nodes Path route = this.routing.getRoute(clientNode, destNode); - + lbsLogger.info("Path between source (client) and destination switch nodes : {}",route.toString()); - + NodeConnector forwardPort = route.getEdges().get(0).getTailNodeConnector(); - + if(installLoadBalancerFlow(client, vip, clientNode, @@ -268,7 +268,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ }else{ lbsLogger.error("Not able to route traffic from client : {}",client ); } - + if(installLoadBalancerFlow(client, vip, clientNode, @@ -291,7 +291,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ } return PacketResult.IGNORED; } - + /* * This method installs the flow rule for routing the traffic between two hosts. * @param source Traffic is sent by this source @@ -301,21 +301,21 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ * @param destMachineMac MAC address of the pool member where traffic needs to be routed * @param outport Use this port to send out traffic * @param flowDirection FORWARD_DIRECTION_LB_FLOW or REVERSE_DIRECTION_LB_FLOW - * @return true If flow installation was successful - * false else + * @return true If flow installation was successful + * false else * @throws UnknownHostException */ private boolean installLoadBalancerFlow(Client source, VIP dest, Node sourceSwitch, String destMachineIp, - byte[] destMachineMac, + byte[] destMachineMac, NodeConnector outport, int flowDirection) throws UnknownHostException{ - + Match match = new Match(); List actions = new ArrayList(); - + if(flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW){ match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue()); match.setField(MatchType.NW_SRC, InetAddress.getByName(source.getIp())); @@ -323,11 +323,11 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(dest.getProtocol())); match.setField(MatchType.TP_SRC, source.getPort()); match.setField(MatchType.TP_DST, dest.getPort()); - + actions.add(new SetNwDst(InetAddress.getByName(destMachineIp))); actions.add(new SetDlDst(destMachineMac)); } - + if(flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW){ match.setField(MatchType.DL_TYPE, EtherTypes.IPv4.shortValue()); match.setField(MatchType.NW_SRC, InetAddress.getByName(destMachineIp)); @@ -335,37 +335,37 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ match.setField(MatchType.NW_PROTO, IPProtocols.getProtocolNumberByte(source.getProtocol())); match.setField(MatchType.TP_SRC, dest.getPort()); match.setField(MatchType.TP_DST,source.getPort()); - + actions.add(new SetNwSrc(InetAddress.getByName(dest.getIp()))); actions.add(new SetDlSrc(destMachineMac)); } - + actions.add(new Output(outport)); - + // Make sure the priority for IP switch entries is // set to a level just above default drop entries - + Flow flow = new Flow(match, actions); flow.setIdleTimeout((short) 5); flow.setHardTimeout((short) 0); flow.setPriority(LB_IPSWITCH_PRIORITY); - + String policyName = source.getIp()+":"+source.getProtocol()+":"+source.getPort(); String flowName =null; - + if(flowDirection == LBConst.FORWARD_DIRECTION_LB_FLOW){ flowName = "["+policyName+":"+source.getIp() + ":"+dest.getIp()+"]"; } - + if(flowDirection == LBConst.REVERSE_DIRECTION_LB_FLOW){ - + flowName = "["+policyName+":"+dest.getIp() + ":"+source.getIp()+"]"; } - + FlowEntry fEntry = new FlowEntry(policyName, flowName, flow, sourceSwitch); - + lbsLogger.info("Install flow entry {} on node {}",fEntry.toString(),sourceSwitch.toString()); - + if(!this.ruleManager.checkFlowEntryConflict(fEntry)){ if(this.ruleManager.installFlowEntry(fEntry).isSuccess()){ return true; @@ -377,7 +377,7 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ } return false; } - + /** * Function called by the dependency manager when all the required * dependencies are satisfied @@ -387,16 +387,16 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ Dictionary props = c.getServiceProperties(); if (props != null) { this.containerName = (String) props.get("containerName"); - + lbsLogger.info("Running container name:" + this.containerName); }else { - + // In the Global instance case the containerName is empty this.containerName = ""; } lbsLogger.info(configManager.toString()); } - + /** * Function called by the dependency manager when at least one * dependency become unsatisfied or when the component is shutting @@ -426,106 +426,106 @@ public class LoadBalancerService implements IListenDataPacket, IConfigManager{ /* * All the methods below are just proxy methods to direct the REST API requests to configuration - * manager. We need this redirection as currently, opendaylight supports only one - * implementation of the service. + * manager. We need this redirection as currently, opendaylight supports only one + * implementation of the service. */ @Override public Set getAllVIPs() { return configManager.getAllVIPs(); } - + @Override public boolean vipExists(String name, String ip, String protocol, short protocolPort, String poolName) { return configManager.vipExists(name, ip, protocol, protocolPort, poolName); } - + @Override public boolean vipExists(VIP vip) { return configManager.vipExists(vip); } - + @Override public VIP createVIP(String name, String ip, String protocol, short protocolPort, String poolName) { return configManager.createVIP(name, ip, protocol, protocolPort, poolName); } - + @Override public VIP updateVIP(String name, String poolName) { return configManager.updateVIP(name, poolName); } - + @Override public VIP deleteVIP(String name) { return configManager.deleteVIP(name); } - + @Override public boolean memberExists(String name, String memberIP, String poolName) { return configManager.memberExists(name, memberIP, poolName); } - + @Override public Set getAllPoolMembers(String poolName) { - + return configManager.getAllPoolMembers(poolName); } - + @Override - public PoolMember addPoolMember(String name, + public PoolMember addPoolMember(String name, String memberIP, String poolName) { return configManager.addPoolMember(name, memberIP, poolName); } - + @Override public PoolMember removePoolMember(String name, String poolName) { - + return configManager.removePoolMember(name, poolName); } - + @Override public Set getAllPools() { - + return configManager.getAllPools(); } - + @Override public Pool getPool(String poolName) { return configManager.getPool(poolName); } - + @Override public boolean poolExists(String name, String lbMethod) { return configManager.poolExists(name, lbMethod); } - + @Override public Pool createPool(String name, String lbMethod) { return configManager.createPool(name, lbMethod); } - + @Override public Pool deletePool(String poolName) { return configManager.deletePool(poolName); } - + @Override public boolean vipExists(String name) { return configManager.vipExists(name); } - + @Override public boolean memberExists(String name, String poolName) { return configManager.memberExists(name, poolName); } - + @Override public boolean poolExists(String name) { return configManager.poolExists(name); } - + @Override public String getVIPAttachedPool(String name) { return configManager.getVIPAttachedPool(name);