Skip to content
Snippets Groups Projects
Unverified Commit c470bf47 authored by David Bohn's avatar David Bohn
Browse files

Made Configurations actors

parent a4428494
Branches
No related tags found
1 merge request!5Configuration system
package fucoin; package fucoin;
import akka.actor.ActorSystem; import akka.actor.ActorSystem;
import akka.actor.Props;
import com.google.common.collect.Sets;
import com.typesafe.config.Config; import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigFactory;
import fucoin.configurations.AbstractConfiguration; import fucoin.configurations.AbstractConfiguration;
import fucoin.configurations.internal.ConfigurationSelection;
import fucoin.setup.NetworkInterfaceReader; import fucoin.setup.NetworkInterfaceReader;
import org.reflections.ReflectionUtils;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner; import org.reflections.scanners.ResourcesScanner;
import org.reflections.scanners.SubTypesScanner; import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeElementsScanner;
import org.reflections.util.ClasspathHelper; import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder; import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder; import org.reflections.util.FilterBuilder;
...@@ -15,10 +20,7 @@ import org.reflections.util.FilterBuilder; ...@@ -15,10 +20,7 @@ import org.reflections.util.FilterBuilder;
import javax.swing.*; import javax.swing.*;
import java.io.File; import java.io.File;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class Main { public class Main {
...@@ -43,42 +45,42 @@ public class Main { ...@@ -43,42 +45,42 @@ public class Main {
} }
public static void main(String[] args) throws InterruptedException, IllegalAccessException, InstantiationException { public static void main(String[] args) throws InterruptedException, IllegalAccessException, InstantiationException {
List<AbstractConfiguration> configurations = getAbstractConfigurations(); List<ConfigurationSelection> configurations = getAbstractConfigurations();
AbstractConfiguration[] configs = new AbstractConfiguration[configurations.size()]; ConfigurationSelection[] configs = new ConfigurationSelection[configurations.size()];
configurations.toArray(configs); configurations.toArray(configs);
AbstractConfiguration selectedConfig = (AbstractConfiguration) JOptionPane.showInputDialog(null, "Select a configuration to run", "Configuration Selection", JOptionPane.QUESTION_MESSAGE, null, configs, configurations.get(0)); ConfigurationSelection selectedConfig = (ConfigurationSelection) JOptionPane.showInputDialog(null, "Select a configuration to run", "Configuration Selection", JOptionPane.QUESTION_MESSAGE, null, configs, configurations.get(0));
if (selectedConfig != null) { if (selectedConfig != null) {
selectedConfig.setSystem(cSystem); Props theProps = AbstractConfiguration.props(selectedConfig.getConfigurationClass());
selectedConfig.run();
cSystem.actorOf(theProps, "Configuration");
} else { } else {
cSystem.terminate(); cSystem.terminate();
} }
} }
private static List<AbstractConfiguration> getAbstractConfigurations() throws InstantiationException, IllegalAccessException { private static List<ConfigurationSelection> getAbstractConfigurations() throws InstantiationException, IllegalAccessException {
List<ClassLoader> classLoadersList = new LinkedList<>(); List<ClassLoader> classLoadersList = new LinkedList<>();
classLoadersList.add(ClasspathHelper.contextClassLoader()); classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader()); classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder() Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false), new ResourcesScanner()) .setScanners(new SubTypesScanner(false), new ResourcesScanner(), new TypeElementsScanner())
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))) .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("fucoin.configurations")))); .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("fucoin.configurations"))));
Set<Class<? extends Object>> allClasses = Set<String> typeSet = reflections.getStore().get("TypeElementsScanner").keySet();
reflections.getSubTypesOf(Object.class); HashSet<Class<?>> allClasses = Sets.newHashSet(ReflectionUtils.forNames(typeSet, reflections
.getConfiguration().getClassLoaders()));
List<AbstractConfiguration> configurations = new ArrayList<>(); List<ConfigurationSelection> configurations = new ArrayList<>();
for (Class<? extends Object> oneClass: allClasses){ allClasses.stream().filter(oneClass -> !Modifier.isAbstract(oneClass.getModifiers()) && AbstractConfiguration.class.isAssignableFrom(oneClass)).forEach(oneClass -> {
if (!Modifier.isAbstract(oneClass.getModifiers())) { ConfigurationSelection cfg = new ConfigurationSelection((Class<AbstractConfiguration>) oneClass);
AbstractConfiguration cfg = (AbstractConfiguration)oneClass.newInstance();
cfg.setSystem(cSystem);
configurations.add(cfg); configurations.add(cfg);
} });
}
return configurations; return configurations;
} }
} }
package fucoin.actions.control;
import akka.actor.ActorRef;
import akka.actor.UntypedActorContext;
import fucoin.actions.ClientAction;
import fucoin.wallet.AbstractWallet;
/**
*
*/
public class ActionWalletSendMoney extends ClientAction {
protected String address;
protected int amount;
public ActionWalletSendMoney(String address, int amount) {
this.address = address;
this.amount = amount;
}
@Override
protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, AbstractWallet abstractNode) {
abstractNode.send(address, amount);
}
}
package fucoin.configurations; package fucoin.configurations;
import akka.actor.ActorRef; import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props; import akka.actor.Props;
import fucoin.AbstractNode;
import fucoin.actions.join.ActionTellSupervisor; import fucoin.actions.join.ActionTellSupervisor;
import fucoin.configurations.internal.ConfigurationCreator;
import fucoin.supervisor.SuperVisorImpl; import fucoin.supervisor.SuperVisorImpl;
import fucoin.wallet.WalletImpl; import fucoin.wallet.WalletImpl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/** /**
* *
*/ */
public abstract class AbstractConfiguration { public abstract class AbstractConfiguration extends AbstractNode {
protected ActorSystem cSystem;
protected ActorRef superVisor; protected ActorRef superVisor;
protected final List<ActorRef> activeActors = new ArrayList<>(); protected final List<ActorRef> activeActors = new ArrayList<>();
public void setSystem(ActorSystem system) { public static Props props(Class configurationClass) {
cSystem = system;
return Props.create(new ConfigurationCreator(configurationClass));
} }
public ActorRef spawnWallet(String name, boolean createGUI) { public ActorRef spawnWallet(String name, boolean createGUI) {
...@@ -33,7 +35,7 @@ public abstract class AbstractConfiguration { ...@@ -33,7 +35,7 @@ public abstract class AbstractConfiguration {
props = WalletImpl.props(activeActors.get(numOfWallets - 1), name, createGUI); props = WalletImpl.props(activeActors.get(numOfWallets - 1), name, createGUI);
} }
ActorRef actorRef = cSystem.actorOf(props, name); ActorRef actorRef = context().actorOf(props, name);
activeActors.add(actorRef); activeActors.add(actorRef);
...@@ -52,8 +54,12 @@ public abstract class AbstractConfiguration { ...@@ -52,8 +54,12 @@ public abstract class AbstractConfiguration {
} }
} }
public ActorRef getRandomWallet() {
return activeActors.get(ThreadLocalRandom.current().nextInt(activeActors.size()));
}
public ActorRef initSupervisor() { public ActorRef initSupervisor() {
superVisor = cSystem.actorOf(SuperVisorImpl.props(), "SuperVisorImpl"); superVisor = context().actorOf(SuperVisorImpl.props(), "SuperVisorImpl");
// Don't ask. // Don't ask.
try { try {
...@@ -64,6 +70,13 @@ public abstract class AbstractConfiguration { ...@@ -64,6 +70,13 @@ public abstract class AbstractConfiguration {
return superVisor; return superVisor;
} }
@Override
public void preStart() throws Exception {
super.preStart();
this.run();
}
public abstract void run(); public abstract void run();
public abstract String getName(); public abstract String getName();
......
package fucoin.configurations; package fucoin.configurations;
import akka.actor.ActorRef;
import fucoin.actions.control.ActionWalletSendMoney;
import fucoin.configurations.internal.ConfigurationName;
/** /**
* *
*/ */
@ConfigurationName("Default Configuration")
public class DefaultConfiguration extends AbstractConfiguration { public class DefaultConfiguration extends AbstractConfiguration {
@Override @Override
public void run() { public void run() {
initSupervisor(); initSupervisor();
spawnWallets(2, true);
ActorRef wallet1 = spawnWallet("Wallet0", false);
ActorRef wallet2 = spawnWallet("Wallet1", false);
// TODO: this should be solved differently
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
wallet1.tell(new ActionWalletSendMoney("Wallet1", 50), wallet1);
} }
@Override @Override
public String getName() { public String getName() {
return "Default Configuration"; return "Default Configuration";
} }
@Override
public void onReceive(Object message) {
}
} }
...@@ -14,4 +14,9 @@ public class MassWalletConfiguration extends AbstractConfiguration { ...@@ -14,4 +14,9 @@ public class MassWalletConfiguration extends AbstractConfiguration {
public String getName() { public String getName() {
return "Lots of wallets"; return "Lots of wallets";
} }
@Override
public void onReceive(Object message) {
}
} }
package fucoin.configurations.internal;
import akka.japi.Creator;
import fucoin.configurations.AbstractConfiguration;
/**
*
*/
public class ConfigurationCreator implements Creator<AbstractConfiguration> {
private Class configurationClass;
public ConfigurationCreator(Class configurationClass) {
this.configurationClass = configurationClass;
}
@Override
public AbstractConfiguration create() throws Exception {
return (AbstractConfiguration) this.configurationClass.newInstance();
}
}
package fucoin.configurations.internal;
/**
*
*/
public @interface ConfigurationName {
String value();
}
package fucoin.configurations.internal;
import fucoin.configurations.AbstractConfiguration;
import java.util.Arrays;
/**
*
*/
public class ConfigurationSelection {
private Class<AbstractConfiguration> configurationClass;
public ConfigurationSelection(Class<AbstractConfiguration> configurationClass) {
this.configurationClass = configurationClass;
}
public Class<AbstractConfiguration> getConfigurationClass() {
return configurationClass;
}
@Override
public String toString() {
System.out.println(configurationClass.isAnnotationPresent(ConfigurationName.class));
return configurationClass.getSimpleName();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment