2 * Copyright IBM Corporation, 2013. All rights reserved.
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 package org.opendaylight.controller.samples.loadbalancer.policies;
10 import java.util.ArrayList;
11 import java.util.HashMap;
13 import org.opendaylight.controller.samples.loadbalancer.ConfigManager;
14 import org.opendaylight.controller.samples.loadbalancer.entities.Client;
15 import org.opendaylight.controller.samples.loadbalancer.entities.Pool;
16 import org.opendaylight.controller.samples.loadbalancer.entities.PoolMember;
17 import org.opendaylight.controller.samples.loadbalancer.entities.VIP;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
22 * This class implements the round robin load balancing policy.
25 public class RoundRobinLBPolicy implements ILoadBalancingPolicy{
30 private static final Logger rrLogger = LoggerFactory.getLogger(RoundRobinLBPolicy.class);
33 * Reference to the configuration manager. This reference is passed from load balancer
36 private ConfigManager cmgr;
39 * Mapping between the client and the pool member that serves all traffic for that client.
41 private HashMap<Client, PoolMember> clientMemberMap;
44 * Maintains the next pool member counter for the VIPs.
45 * More than one VIP can be attached to one pool, so each VIP
46 * will have its own counter for the next pool member from
49 private HashMap<VIP,Integer> nextItemFromPool;
51 @SuppressWarnings("unused")
52 private RoundRobinLBPolicy(){}
54 public RoundRobinLBPolicy(ConfigManager cmgr){
56 this.clientMemberMap = new HashMap<Client, PoolMember>();
57 this.nextItemFromPool = new HashMap<VIP, Integer>();
61 public String getPoolMemberForClient(Client source, VIP dest){
63 rrLogger.info("Received traffic from client : {} for VIP : {} ",source, dest);
65 syncWithLoadBalancerData();
69 if(this.clientMemberMap.containsKey(source)){
71 pm= this.clientMemberMap.get(source);
72 rrLogger.info("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
76 if(nextItemFromPool.containsKey(dest)){
78 int memberNum = nextItemFromPool.get(dest).intValue();
79 rrLogger.debug("Packet is from new client for VIP {}",dest);
80 pool = this.cmgr.getPool(dest.getPoolName());
81 pm = pool.getAllMembers().get(memberNum);
82 this.clientMemberMap.put(source, pm );
83 rrLogger.info("New client's packet will be directed to pool member {}",pm);
86 if(memberNum > pool.getAllMembers().size()-1){
89 rrLogger.debug("Next pool member for new client of VIP is set to {}",pool.getAllMembers().get(memberNum));
91 this.nextItemFromPool.put(dest, new Integer(memberNum));
93 rrLogger.debug("Network traffic for VIP : {} has appeared first time from client {}",dest,source);
94 pool = this.cmgr.getPool(dest.getPoolName());
95 pm = pool.getAllMembers().get(0);
96 this.clientMemberMap.put(source, pm);
98 rrLogger.info("Network traffic from client {} will be directed to pool member {}",pm);
99 this.nextItemFromPool.put(dest, new Integer(1));
100 rrLogger.debug("Next pool member for new client of VIP is set to {}",pool.getAllMembers().get(1));
107 * This method does the clean up. Whenever a new client packet arrives with a given VIP,
108 * this method checks the current configuration to see if any pool members have been deleted and
109 * cleans up the metadata stored by this loadbalancing algorithm.
111 private void syncWithLoadBalancerData(){
112 rrLogger.debug("[Client - PoolMember] table before cleanup : {}",this.clientMemberMap.toString());
113 ArrayList<Client> removeClient = new ArrayList<Client>();
115 if(this.clientMemberMap.size() != 0){
116 for(Client client : this.clientMemberMap.keySet()){
117 if(!this.cmgr.memberExists(this.clientMemberMap.get(client).getName(),
118 this.clientMemberMap.get(client).getPoolName())){
120 removeClient.add(client);
125 for(Client client : removeClient){
126 this.clientMemberMap.remove(client);
128 rrLogger.debug("Removed client : {} ",client);
130 rrLogger.debug("[Client - PoolMember] table after cleanup : {}",this.clientMemberMap.toString());
132 rrLogger.debug("[VIP- NextMember] table before cleanup : {}",this.nextItemFromPool.toString());
134 ArrayList<VIP> resetVIPPoolMemberCount= new ArrayList<VIP>();
136 if(this.nextItemFromPool.size() != 0){
138 for(VIP vip:this.nextItemFromPool.keySet()){
139 if(this.nextItemFromPool.get(vip).intValue() > this.cmgr.getPool(vip.getPoolName()).getAllMembers().size()-1){
141 resetVIPPoolMemberCount.add(vip);
146 for(VIP vip:resetVIPPoolMemberCount){
147 rrLogger.debug("VIP next pool member counter reset to 0");
148 this.nextItemFromPool.put(vip, new Integer(0));
151 rrLogger.debug("[VIP- NextMember] table after cleanup : {}",this.nextItemFromPool.toString());