Skip to content

Commit

Permalink
Develop tests to NoFMemberPicker and make Member picker configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
giovannifs committed Mar 30, 2015
1 parent 2264a8d commit 771ee46
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 15 deletions.
5 changes: 5 additions & 0 deletions manager.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ image_storage_appliance_tmp_storage=/tmp/
image_storage_static_fogbow-linux-x86=55d938ef-57d1-44ea-8155-6036d170780a
image_storage_static_fogbow-ubuntu-1204=81765250-a4e4-440d-a215-43c9c0849120

member_picker_class=org.fogbowcloud.manager.core.RoundRobinMemberPicker
#If you are using NoFMemberPicker class
nof_trustworthy=false


compute_class=org.fogbowcloud.manager.core.plugins.openstack.OpenStackNovaV2ComputePlugin
compute_novav2_url=http://localhost:8774
compute_glancev2_url=http://localhost:9292
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/fogbowcloud/manager/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import org.apache.log4j.Logger;
import org.fogbowcloud.manager.core.ConfigurationConstants;
import org.fogbowcloud.manager.core.DefaultMemberValidator;
import org.fogbowcloud.manager.core.FederationMemberPicker;
import org.fogbowcloud.manager.core.FederationMemberValidator;
import org.fogbowcloud.manager.core.ManagerController;
import org.fogbowcloud.manager.core.RoundRobinMemberPicker;
import org.fogbowcloud.manager.core.plugins.AccountingPlugin;
import org.fogbowcloud.manager.core.plugins.AuthorizationPlugin;
import org.fogbowcloud.manager.core.plugins.BenchmarkingPlugin;
Expand Down Expand Up @@ -115,6 +117,16 @@ public static void main(String[] args) throws Exception {
accountingPlugin = new FCUAccountingPlugin(properties, benchmarkingPlugin);
LOGGER.warn("Accounting plugin not specified in properties. Using the default one.", e);
}

FederationMemberPicker memberPickerPlugin = null;
try {
memberPickerPlugin = (FederationMemberPicker) createInstanceWithAccoutingPlugin(
ConfigurationConstants.MEMBER_PICKER_PLUGIN_CLASS_KEY, properties,
accountingPlugin);
} catch (Exception e) {
memberPickerPlugin = new RoundRobinMemberPicker(properties, accountingPlugin);
LOGGER.warn("Member picker plugin not specified in properties. Using the default one.", e);
}

ManagerController facade = new ManagerController(properties);
facade.setComputePlugin(computePlugin);
Expand All @@ -125,6 +137,7 @@ public static void main(String[] args) throws Exception {
facade.setValidator(validator);
facade.setBenchmarkingPlugin(benchmarkingPlugin);
facade.setAccountingPlugin(accountingPlugin);
facade.setMemberPickerPlugin(memberPickerPlugin);

ManagerXmppComponent xmpp = new ManagerXmppComponent(
properties.getProperty(ConfigurationConstants.XMPP_JID_KEY),
Expand Down Expand Up @@ -191,6 +204,13 @@ private static Object createInstanceWithBenchmarkingPlugin(
return Class.forName(properties.getProperty(propName)).getConstructor(Properties.class, BenchmarkingPlugin.class)
.newInstance(properties, benchmarkingPlugin);
}

private static Object createInstanceWithAccoutingPlugin(
String propName, Properties properties,
AccountingPlugin accoutingPlugin) throws Exception {
return Class.forName(properties.getProperty(propName)).getConstructor(Properties.class, AccountingPlugin.class)
.newInstance(properties, accoutingPlugin);
}

private static void configureLog4j() {
ConsoleAppender console = new ConsoleAppender();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@ public class ConfigurationConstants {

//Green
public static final String GREEN_SITTER_JID = "greensitter_jid";

//member picker
public static final String MEMBER_PICKER_PLUGIN_CLASS_KEY = "member_picker_class";
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class ManagerController {
private Token federationUserToken;
private final List<FederationMember> members = Collections.synchronizedList(new LinkedList<FederationMember>());
private RequestRepository requests = new RequestRepository();
private FederationMemberPicker memberPicker = new RoundRobinMemberPicker();
private FederationMemberPicker memberPicker;

private BenchmarkingPlugin benchmarkingPlugin;
private AccountingPlugin accountingPlugin;
Expand Down Expand Up @@ -116,6 +116,10 @@ public ManagerController(Properties properties, ScheduledExecutorService executo
this.accountingUpdaterTimer = new ManagerTimer(executor);
}
}

public void setMemberPickerPlugin(FederationMemberPicker memberPicker) {
this.memberPicker = memberPicker;
}

public void setBenchmarkingPlugin(BenchmarkingPlugin benchmarkingPlugin) {
this.benchmarkingPlugin = benchmarkingPlugin;
Expand Down
42 changes: 29 additions & 13 deletions src/main/java/org/fogbowcloud/manager/core/NoFMemberPicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.fogbowcloud.manager.core.model.FederationMember;
import org.fogbowcloud.manager.core.plugins.AccountingPlugin;
import org.fogbowcloud.manager.core.plugins.accounting.ResourceUsage;
Expand All @@ -15,10 +16,18 @@ public class NoFMemberPicker implements FederationMemberPicker {

private AccountingPlugin accoutingPlugin;
private String localMemberId;
private boolean trustworthy = false;

private static final Logger LOGGER = Logger.getLogger(NoFMemberPicker.class);

public NoFMemberPicker(Properties properties, AccountingPlugin accoutingPlugin) {
this.accoutingPlugin = accoutingPlugin;
this.localMemberId = properties.getProperty(ConfigurationConstants.XMPP_JID_KEY);
try {
this.trustworthy = Boolean.valueOf(properties.getProperty("nof_trustworthy"));
} catch (Exception e) {
LOGGER.error("Error while getting boolean valued from ", e);
}
}

@Override
Expand All @@ -33,38 +42,41 @@ public FederationMember pick(ManagerController facade) {
continue;
}

double reputation = 0d;
double debt = 0d;
if (membersUsage.containsKey(memberId)) {
reputation = membersUsage.get(memberId).getConsumed()
- membersUsage.get(memberId).getDonated()
+ Math.sqrt(membersUsage.get(memberId).getDonated());
debt = membersUsage.get(memberId).getConsumed()
- membersUsage.get(memberId).getDonated();
if (!trustworthy) {
debt = Math.max(0,
debt + Math.sqrt(membersUsage.get(memberId).getDonated()));
}
}
reputableMembers.add(new ReputableFederationMember(currentMember, reputation));
reputableMembers.add(new ReputableFederationMember(currentMember, debt));
}

if (reputableMembers.isEmpty()) {
return null;
}
Collections.sort(reputableMembers, new ReputableFederationMemberComparator());
return reputableMembers.getLast().getMember();
return reputableMembers.getFirst().getMember();
}

class ReputableFederationMember {

private FederationMember member;
private double reputation;
private double debt;

public ReputableFederationMember(FederationMember member, double reputation) {
public ReputableFederationMember(FederationMember member, double debt) {
this.member = member;
this.reputation = reputation;
this.debt = debt;
}

public FederationMember getMember() {
return member;
}

public double getReputation() {
return reputation;
public double getDebt() {
return debt;
}
}

Expand All @@ -73,9 +85,13 @@ class ReputableFederationMemberComparator implements Comparator<ReputableFederat
public int compare(ReputableFederationMember firstReputableMember,
ReputableFederationMember secondReputableMember) {

return new Double(firstReputableMember.getReputation()).compareTo(new Double(
secondReputableMember.getReputation()));
return new Double(firstReputableMember.getDebt()).compareTo(new Double(
secondReputableMember.getDebt()));
}
}

public boolean getTrustworthy() {
return trustworthy;
}
}

Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package org.fogbowcloud.manager.core;

import java.util.List;
import java.util.Properties;

import org.fogbowcloud.manager.core.model.FederationMember;
import org.fogbowcloud.manager.core.plugins.AccountingPlugin;

public class RoundRobinMemberPicker implements FederationMemberPicker {

private int current = -1;

public RoundRobinMemberPicker(Properties properties, AccountingPlugin accountingPlugin) {
}

@Override
public FederationMember pick(ManagerController facade) {
List<FederationMember> members = facade.getMembers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,12 @@ private void checkRequestPerUserToken(Token token) {
public void testSubmitToGreenSitter() {
AsyncPacketSender packetSender = Mockito.mock(AsyncPacketSender.class);
managerController.setPacketSender(packetSender);


FederationMemberPicker memberPickerPlugin = Mockito.mock(FederationMemberPicker.class);
Mockito.when(memberPickerPlugin.pick(Mockito.any(ManagerController.class)))
.thenReturn(null);
managerController.setMemberPickerPlugin(memberPickerPlugin);

ComputePlugin computePlugin = Mockito.mock(ComputePlugin.class);

ResourcesInfo localResourcesInfo = new ResourcesInfo("", "", "", "", null);
Expand Down Expand Up @@ -1729,6 +1734,7 @@ public void testInstanceIsBeingUsedByDeletedRequest(){
+ Request.SEPARATOR_GLOBAL_ID + "remote-manager.test.com"));
}

@SuppressWarnings("unchecked")
@Test
public void testInstanceIsNotBeingUsedButRequestWasForwarded(){
AsyncPacketSender packetSender = Mockito.mock(AsyncPacketSender.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public void setUp(){
properties = new Properties();
properties.put(ConfigurationConstants.XMPP_JID_KEY,
DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL);
properties.put("nof_trustworthy", "false");

accoutingPlugin = Mockito.mock(AccountingPlugin.class);

Expand All @@ -40,6 +41,7 @@ public void testEmptyMembers() {

NoFMemberPicker nofPicker = new NoFMemberPicker(properties, accoutingPlugin);
Assert.assertNull(nofPicker.pick(facade));
Assert.assertFalse(nofPicker.getTrustworthy());
}

@Test
Expand All @@ -56,6 +58,7 @@ public void testOnlyLocalMember() {

NoFMemberPicker nofPicker = new NoFMemberPicker(properties, accoutingPlugin);
Assert.assertNull(nofPicker.pick(facade));
Assert.assertFalse(nofPicker.getTrustworthy());
}

@Test
Expand All @@ -81,5 +84,39 @@ public void testOneRemoteMember() {

NoFMemberPicker nofPicker = new NoFMemberPicker(properties, accoutingPlugin);
Assert.assertEquals(remoteMember, nofPicker.pick(facade));
Assert.assertFalse(nofPicker.getTrustworthy());
}

@Test
public void testTwoRemoteMembers() {
// mocking facade
FederationMember localMember = new FederationMember(new ResourcesInfo(
DefaultDataTestHelper.LOCAL_MANAGER_COMPONENT_URL, "", "", "", "", null));
FederationMember remoteMember1 = new FederationMember(new ResourcesInfo(
DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "1", "", "", "", "", null));
FederationMember remoteMember2 = new FederationMember(new ResourcesInfo(
DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "2", "", "", "", "", null));
ArrayList<FederationMember> membersToReturn = new ArrayList<FederationMember>();
membersToReturn.add(localMember);
membersToReturn.add(remoteMember1);
membersToReturn.add(remoteMember2);
Mockito.when(facade.getMembers()).thenReturn(membersToReturn);

// mocking accounting
HashMap<String, ResourceUsage> membersUsageToReturn = new HashMap<String, ResourceUsage>();
ResourceUsage resUsage1 = new ResourceUsage(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "1");
resUsage1.addConsumption(4);
resUsage1.addDonation(16);
membersUsageToReturn.put(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "1", resUsage1);
ResourceUsage resUsage2 = new ResourceUsage(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "2");
resUsage2.addConsumption(10);
resUsage2.addDonation(16);
membersUsageToReturn.put(DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL + "2", resUsage2);
Mockito.when(accoutingPlugin.getMembersUsage()).thenReturn(
membersUsageToReturn);

NoFMemberPicker nofPicker = new NoFMemberPicker(properties, accoutingPlugin);
Assert.assertEquals(remoteMember1, nofPicker.pick(facade));
Assert.assertFalse(nofPicker.getTrustworthy());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.dom4j.Element;
import org.fogbowcloud.manager.core.ConfigurationConstants;
import org.fogbowcloud.manager.core.DefaultMemberValidator;
import org.fogbowcloud.manager.core.FederationMemberPicker;
import org.fogbowcloud.manager.core.ManagerController;
import org.fogbowcloud.manager.core.model.FederationMember;
import org.fogbowcloud.manager.core.model.Flavor;
Expand Down Expand Up @@ -60,6 +61,7 @@ public class ManagerTestHelper extends DefaultDataTestHelper {
private AuthorizationPlugin authorizationPlugin;
private BenchmarkingPlugin benchmarkingPlugin;
private AccountingPlugin accountingPlugin;
private FederationMemberPicker memberPickerPlugin;
private Token defaultUserToken;
private Token defaultFederationToken;
private FakeXMPPServer fakeServer = new FakeXMPPServer();
Expand Down Expand Up @@ -380,13 +382,19 @@ public ManagerController createDefaultManagerController() {

accountingPlugin = Mockito.mock(AccountingPlugin.class);

memberPickerPlugin = Mockito.mock(FederationMemberPicker.class);
Mockito.when(memberPickerPlugin.pick(Mockito.any(ManagerController.class))).thenReturn(
new FederationMember(new ResourcesInfo(
DefaultDataTestHelper.REMOTE_MANAGER_COMPONENT_URL, "", "", "", null)));

managerController.setAuthorizationPlugin(authorizationPlugin);
managerController.setLocalIdentityPlugin(identityPlugin);
managerController.setFederationIdentityPlugin(federationIdentityPlugin);
managerController.setComputePlugin(computePlugin);
managerController.setBenchmarkingPlugin(benchmarkingPlugin);
managerController.setAccountingPlugin(accountingPlugin);
managerController.setValidator(new DefaultMemberValidator(null));
managerController.setMemberPickerPlugin(memberPickerPlugin);
return managerController;
}

Expand Down

0 comments on commit 771ee46

Please sign in to comment.