Skip to content

Commit

Permalink
Refactor libvirt compute resource to use properties pojo
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelaferreira committed Jul 25, 2016
1 parent d9f5863 commit b78c036
Show file tree
Hide file tree
Showing 22 changed files with 1,328 additions and 803 deletions.
8 changes: 7 additions & 1 deletion cosmic-agent/pom.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-agent</artifactId>
<name>Cosmic Agent</name>
Expand Down Expand Up @@ -28,6 +29,11 @@
<groupId>commons-daemon</groupId>
<artifactId>commons-daemon</artifactId>
</dependency>
<dependency>
<groupId>cloud.cosmic</groupId>
<artifactId>cloud-plugin-hypervisor-kvm</artifactId>
<version>5.1.0.5-SNAPSHOT</version>
</dependency>
</dependencies>

<build>
Expand Down
34 changes: 2 additions & 32 deletions cosmic-agent/src/main/java/com/cloud/agent/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.channels.ClosedChannelException;
Expand Down Expand Up @@ -91,18 +89,12 @@ public class Agent implements HandlerFactory, IAgentControl {
private boolean _reconnectAllowed = true;
private final ExecutorService _executor;

public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backOffAlgorithm) throws ConfigurationException {
public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backOffAlgorithm, final ServerResource resource) throws ConfigurationException {
this.agentProperties = agentProperties;
this.backOffAlgorithm = backOffAlgorithm;
resource = loadServerResource(agentProperties.getResource());
this.resource = resource;
resource.setAgentControl(this);

if (!resource.configure(getResourceName(), agentProperties.buildPropertiesMap())) {
throw new ConfigurationException("Unable to configure " + resource.getName());
} else {
logger.info("Agent resource {} configured", resource.getName());
}

_connection = new NioClient("Agent", agentProperties.getHost(), agentProperties.getPort(), agentProperties.getWorkers(), this);

logger.debug("Adding shutdown hook");
Expand All @@ -119,28 +111,6 @@ public Agent(final AgentProperties agentProperties, final BackoffAlgorithm backO
+ agentProperties.getPod() + " : workers = " + agentProperties.getWorkers() + " : host = " + agentProperties.getHost() + " : port = " + agentProperties.getPort());
}

private ServerResource loadServerResource(final String resourceClassName) throws ConfigurationException {
final String[] names = resourceClassName.split("\\|");
for (final String name : names) {
final Class<?> impl;
try {
impl = Class.forName(name);
final Constructor<?> constructor = impl.getDeclaredConstructor();
constructor.setAccessible(true);
return (ServerResource) constructor.newInstance();
} catch (final ClassNotFoundException
| SecurityException
| NoSuchMethodException
| IllegalArgumentException
| InstantiationException
| IllegalAccessException
| InvocationTargetException e) {
throw new ConfigurationException("Failed to launch agent due to: " + e.getMessage());
}
}
throw new ConfigurationException("Could not find server resource class to load in: " + resourceClassName);
}

public String getResourceName() {
return resource.getClass().getSimpleName();
}
Expand Down
16 changes: 4 additions & 12 deletions cosmic-agent/src/main/java/com/cloud/agent/AgentConstants.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
package com.cloud.agent;

public class AgentConstants {
public static final String PROPERTY_KEY_HOST = "host";
public static final String PROPERTY_KEY_PORT = "port";
public static final String PROPERTY_KEY_WORKERS = "workers";
public static final String PROPERTY_KEY_ZONE = "zone";
public static final String PROPERTY_KEY_POD = "pod";
import com.cloud.utils.CloudConstants;

public class AgentConstants extends CloudConstants {
public static final String PROPERTY_KEY_PING_RETRIES = "ping.retries";
public static final String PROPERTY_KEY_DEVELOPER = "developer";
public static final String PROPERTY_KEY_GUID = "guid";
public static final String PROPERTY_KEY_RESOURCE = "resource";
public static final String PROPERTY_KEY_IPV6_DISABLED = "ipv6disabled";
public static final String PROPERTY_KEY_IPV6_PREFERRED = "ipv6prefer";
public static final String PROPERTY_KEY_INSTANCE = "instance";
public static final String PROPERTY_KEY_WORKERS = "workers";
public static final String PROPERTY_KEY_PID_DIR = "piddir";
public static final String PROPERTY_KEY_CONSOLE_PROXY_HTTP_PORT = "consoleproxy.httpListenPort";
public static final String PROPERTY_KEY_CONSOLE_VERSION = "version";

public static final int DEFAULT_PORT = 8250;
public static final int DEFAULT_CONSOLE_PROXY_HTTP_PORT = 443;
public static final int DEFAULT_NUMBER_OF_WORKERS = 5;
public static final int DEFAULT_NUMBER_OF_PING_RETRIES = 5;
public static final String DEFAULT_ZONE = "default";
public static final boolean DEFAULT_IPV6_DISABLED = false;
public static final boolean DEFAULT_IPV6_PREFERRED = false;
public static final String DEFAULT_PID_DIR = "/var/run";
Expand Down
26 changes: 11 additions & 15 deletions cosmic-agent/src/main/java/com/cloud/agent/AgentProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,28 @@
import static com.cloud.agent.AgentConstants.PROPERTY_KEY_ZONE;
import static com.cloud.utils.PropertiesUtil.parse;

import com.cloud.utils.PropertiesPojo;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

public class AgentProperties {
public class AgentProperties implements PropertiesPojo {
private String host = "";
private int workers = DEFAULT_NUMBER_OF_WORKERS;
private int port = DEFAULT_PORT;
private int consoleProxyHttpPort = DEFAULT_CONSOLE_PROXY_HTTP_PORT;
private String zone = DEFAULT_ZONE;
private String pod = "";
private String guid = "";
private String resource = "";
private String instance = "";
private int workers = DEFAULT_NUMBER_OF_WORKERS;
private int pingRetries = DEFAULT_NUMBER_OF_PING_RETRIES;
private boolean developer = false;
private String resource = "";
private boolean ipv6Disabled = DEFAULT_IPV6_DISABLED;
private boolean ipa6Preferred = DEFAULT_IPV6_PREFERRED;
private String instance = "";
private String pidDir = DEFAULT_PID_DIR;
private int consoleProxyHttpPort = DEFAULT_CONSOLE_PROXY_HTTP_PORT;
private String version = "";

public void load(final Properties properties) {
Expand All @@ -67,12 +69,6 @@ public void load(final Properties properties) {
validateValues();
}

public void load(final Map<String, Object> map) {
final Properties properties = new Properties();
properties.putAll(map);
load(properties);
}

private void validateValues() {
workers = workers <= 0 ? DEFAULT_NUMBER_OF_WORKERS : workers;
pingRetries = pingRetries <= 0 ? DEFAULT_NUMBER_OF_PING_RETRIES : pingRetries;
Expand Down Expand Up @@ -148,17 +144,17 @@ public Map<String, Object> buildPropertiesMap() {
final HashMap<String, Object> propertiesMap = new HashMap<>();
propertiesMap.put(PROPERTY_KEY_HOST, host);
propertiesMap.put(PROPERTY_KEY_PORT, port);
propertiesMap.put(PROPERTY_KEY_WORKERS, workers);
propertiesMap.put(PROPERTY_KEY_ZONE, zone);
propertiesMap.put(PROPERTY_KEY_POD, pod);
propertiesMap.put(PROPERTY_KEY_GUID, guid);
propertiesMap.put(PROPERTY_KEY_RESOURCE, resource);
propertiesMap.put(PROPERTY_KEY_INSTANCE, instance);
propertiesMap.put(PROPERTY_KEY_PID_DIR, pidDir);
propertiesMap.put(PROPERTY_KEY_WORKERS, workers);
propertiesMap.put(PROPERTY_KEY_PING_RETRIES, pingRetries);
propertiesMap.put(PROPERTY_KEY_DEVELOPER, developer);
propertiesMap.put(PROPERTY_KEY_RESOURCE, resource);
propertiesMap.put(PROPERTY_KEY_IPV6_DISABLED, ipv6Disabled);
propertiesMap.put(PROPERTY_KEY_IPV6_PREFERRED, ipa6Preferred);
propertiesMap.put(PROPERTY_KEY_INSTANCE, instance);
propertiesMap.put(PROPERTY_KEY_PID_DIR, pidDir);
propertiesMap.put(PROPERTY_KEY_CONSOLE_PROXY_HTTP_PORT, consoleProxyHttpPort);
return propertiesMap;
}
Expand Down
139 changes: 96 additions & 43 deletions cosmic-agent/src/main/java/com/cloud/agent/AgentShell.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.cloud.agent;

import static java.util.stream.Collectors.toMap;

import com.cloud.agent.Agent.ExitStatus;
import com.cloud.resource.ServerResource;
import com.cloud.utils.ProcessUtil;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.backoff.BackoffAlgorithm;
Expand All @@ -10,8 +13,11 @@
import javax.naming.ConfigurationException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.daemon.Daemon;
Expand All @@ -25,9 +31,40 @@ public class AgentShell implements IAgentShell, Daemon {
private static final String FILE_NAME_AGENT_PROPERTIES = "agent.properties";

private final AgentProperties agentProperties = new AgentProperties();
private final Map<String, Object> allProperties = new HashMap<>();
private Agent agent;
private BackoffAlgorithm backOff;

@Override
public String getHost() {
return agentProperties.getHost();
}

@Override
public int getPort() {
return agentProperties.getPort();
}

@Override
public int getWorkers() {
return agentProperties.getWorkers();
}

@Override
public String getGuid() {
return agentProperties.getGuid();
}

@Override
public String getZone() {
return agentProperties.getZone();
}

@Override
public String getPod() {
return agentProperties.getPod();
}

public static void main(final String[] args) {
try {
logger.info("Starting agent shell");
Expand Down Expand Up @@ -60,27 +97,16 @@ public void loadProperties() throws ConfigurationException {
}

logger.info("Found {} at {}", FILE_NAME_AGENT_PROPERTIES, file.getAbsolutePath());
agentProperties.load(loadPropertiesFromFile(file));
}

private Properties loadPropertiesFromFile(final File file) {
final Properties properties = new Properties();
try {
PropertiesUtil.loadFromFile(properties, file);
logPropertiesFound(properties);
} catch (final IOException e) {
throw new CloudRuntimeException("Can't load agent properties from " + file.getAbsolutePath(), e);
}
return properties;
}

private void logPropertiesFound(final Properties properties) {
properties.entrySet().forEach(entry -> logger.debug("Found property: {} = {}", entry.getKey(), entry.getValue()));
final Properties properties = loadPropertiesFromFile(file);
allProperties.putAll(convertPropertiesToStringObjectMap(properties));
agentProperties.load(properties);
}

protected boolean parseCommand(final String[] args) throws ConfigurationException {
final Properties commandLineProperties = PropertiesUtil.parse(Arrays.stream(args));
logPropertiesFound(commandLineProperties);
agentProperties.load(commandLineProperties);
allProperties.putAll(convertPropertiesToStringObjectMap(commandLineProperties));

final String guid = agentProperties.getGuid();
if (guid == null && !agentProperties.isDeveloper()) {
Expand All @@ -90,47 +116,72 @@ protected boolean parseCommand(final String[] args) throws ConfigurationExceptio
return true;
}

@Override
public String getHost() {
return agentProperties.getHost();
}

@Override
public int getPort() {
return agentProperties.getPort();
private Map<String, Object> convertPropertiesToStringObjectMap(final Properties properties) {
return properties.entrySet().stream().collect(toMap(entry -> entry.getKey().toString(), Map.Entry::getValue));
}

@Override
public int getWorkers() {
return agentProperties.getWorkers();
}

@Override
public String getGuid() {
return agentProperties.getGuid();
}

@Override
public String getZone() {
return agentProperties.getZone();
private Properties loadPropertiesFromFile(final File file) {
final Properties properties = new Properties();
try {
PropertiesUtil.loadFromFile(properties, file);
logPropertiesFound(properties);
} catch (final IOException e) {
throw new CloudRuntimeException("Can't load agent properties from " + file.getAbsolutePath(), e);
}
return properties;
}

@Override
public String getPod() {
return agentProperties.getPod();
private void logPropertiesFound(final Properties properties) {
properties.entrySet().forEach(entry -> logger.debug("Found property: {} = {}", entry.getKey(), entry.getValue()));
}

private void launchAgent() throws ConfigurationException {
final String resourceClassNames = agentProperties.getResource();
logger.debug("Launching agent with resource is {}", resourceClassNames);
logger.debug("Launching agent with resource {}", resourceClassNames);
if (resourceClassNames != null) {
agent = new Agent(agentProperties, backOff);
final ServerResource serverResource = loadServerResource(agentProperties.getResource());
configureServerResource(serverResource);
agent = new Agent(agentProperties, backOff, serverResource);
agent.start();
} else {
throw new ConfigurationException("Cannot launch agent without a agent resource class");
}
}

private void configureServerResource(final ServerResource serverResource) throws ConfigurationException {
final String serverResourceName = serverResource.getClass().getSimpleName();
logger.debug("Configuring agent resource {}", serverResourceName);

if (!serverResource.configure(serverResourceName, allProperties)) {
throw new ConfigurationException("Unable to configure " + serverResourceName);
} else {
logger.info("Agent resource {} configured", serverResourceName);
}
}

private ServerResource loadServerResource(final String resourceClassName) throws ConfigurationException {
logger.debug("Loading agent resource from class name {}", resourceClassName);
final String[] names = resourceClassName.split("\\|");
for (final String name : names) {
final Class<?> impl;
try {
impl = Class.forName(name);
final Constructor<?> constructor = impl.getDeclaredConstructor();
constructor.setAccessible(true);
return (ServerResource) constructor.newInstance();
} catch (final ClassNotFoundException
| SecurityException
| NoSuchMethodException
| IllegalArgumentException
| InstantiationException
| IllegalAccessException
| InvocationTargetException e) {
throw new ConfigurationException("Failed to launch agent due to " + e.getClass().getSimpleName() + ": " + e.getMessage());
}
}
throw new ConfigurationException("Could not find server resource class to load in: " + resourceClassName);
}

@Override
public void init(final DaemonContext dc) throws DaemonInitException {
logger.debug("Initializing AgentShell from JSVC");
Expand All @@ -148,7 +199,9 @@ public void start() {
configureIpStack();
checkPidFile();
launchAgent();
agent.wait();
synchronized (agent) {
agent.wait();
}
} catch (final ConfigurationException e) {
logger.error("Unable to start agent due to bad configuration", e);
System.exit(ExitStatus.Configuration.value());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void completeJoin(final long joinJobId, final JobInfo.Status joinStatus,
// String sql = "UPDATE async_job SET job_pending_signals=? WHERE id IN " +
// "(SELECT job_id FROM async_job_join_map WHERE next_wakeup < ? AND expiration > ?)";
// pstmt = txn.prepareStatement(sql);
// pstmt.setInt(1, AsyncJob.Constants.SIGNAL_MASK_WAKEUP);
// pstmt.setInt(1, AsyncJob.CloudConstants.SIGNAL_MASK_WAKEUP);
// pstmt.setString(2, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate));
// pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), cutDate));
// pstmt.executeUpdate();
Expand Down
Loading

0 comments on commit b78c036

Please # to comment.