From: Mathieu Baudier Date: Sun, 7 Jun 2009 16:26:44 +0000 (+0000) Subject: @update:79; Wait for one agent X-Git-Tag: argeo-slc-2.1.7~1816 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=4f2c9778c7f5559bec3d9480de011181962ad105;hp=8536d871354d83c032dfd85f763c7fdf965c02b7;p=gpl%2Fargeo-slc.git @update:79; Wait for one agent git-svn-id: https://svn.argeo.org/slc/trunk@2511 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/integration-tests/org.argeo.slc.it.webapp/.classpath b/integration-tests/org.argeo.slc.it.webapp/.classpath index 04257bbcb..9bedaab94 100644 --- a/integration-tests/org.argeo.slc.it.webapp/.classpath +++ b/integration-tests/org.argeo.slc.it.webapp/.classpath @@ -1,8 +1,11 @@ - - - - - + + + + + diff --git a/integration-tests/org.argeo.slc.it.webapp/pom.xml b/integration-tests/org.argeo.slc.it.webapp/pom.xml index b9879ddab..ef2287379 100644 --- a/integration-tests/org.argeo.slc.it.webapp/pom.xml +++ b/integration-tests/org.argeo.slc.it.webapp/pom.xml @@ -2,12 +2,11 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 - + org.argeo.slc integration-tests 0.11.4-SNAPSHOT @@ -22,6 +21,31 @@ org.argeo.slc.maven maven-argeo-osgi-plugin ${version.maven-argeo-osgi} + + + -clean + + + + ${basedir}/../../demo/site;in=*;ex=target, + ${basedir}/../../server/org.argeo.slc.siteserver/bundles;in=* + + + org.argeo.dep.osgi.catalina.start, + org.springframework.osgi.extender, + org.springframework.osgi.web.extender, + org.springframework.osgi.samples.simplewebapp, + org.argeo.slc.server.activemq, + org.argeo.slc.server.hsqldb, + org.argeo.slc.server.hibernate, + org.argeo.slc.server.services, + org.argeo.slc.server.jms, + org.argeo.slc.webapp, + org.argeo.slc.ria, + org.argeo.slc.agent + + + equinox-start @@ -31,28 +55,6 @@ false - - -clean - - - - ${basedir}/../../demo/site;in=*;ex=target, - ${basedir}/../../server/org.argeo.slc.siteserver/bundles;in=* - - - org.argeo.dep.osgi.catalina.start, - org.springframework.osgi.extender, - org.springframework.osgi.web.extender, - org.springframework.osgi.samples.simplewebapp, - org.argeo.slc.server.activemq, - org.argeo.slc.server.hsqldb, - org.argeo.slc.server.hibernate, - org.argeo.slc.server.services, - org.argeo.slc.server.jms, - org.argeo.slc.webapp, - org.argeo.slc.ria - - diff --git a/integration-tests/org.argeo.slc.it.webapp/src/test/java/org/argeo/slc/it/webapp/AgentTest.java b/integration-tests/org.argeo.slc.it.webapp/src/test/java/org/argeo/slc/it/webapp/AgentTest.java index e4515d275..a66eca480 100644 --- a/integration-tests/org.argeo.slc.it.webapp/src/test/java/org/argeo/slc/it/webapp/AgentTest.java +++ b/integration-tests/org.argeo.slc.it.webapp/src/test/java/org/argeo/slc/it/webapp/AgentTest.java @@ -1,20 +1,16 @@ package org.argeo.slc.it.webapp; -import org.argeo.slc.msg.ObjectList; -import org.argeo.slc.server.client.SlcServerHttpClient; +import java.net.InetAddress; + +import org.argeo.slc.runtime.SlcAgentDescriptor; import org.argeo.slc.server.unit.AbstractHttpClientTestCase; -public class AgentTest extends AbstractHttpClientTestCase{ +public class AgentTest extends AbstractHttpClientTestCase { public void testListAgents() throws Exception { - waitForServerToBeReady(); - SlcServerHttpClient httpClient = getBean(SlcServerHttpClient.class); - ObjectList objectList = httpClient.callService("listAgents.service", - null); - assertEquals(0, objectList.getObjects().size()); -// SlcAgentDescriptor slcAgentDescriptor = (SlcAgentDescriptor) objectList -// .getObjects().get(0); -// assertEquals(InetAddress.getLocalHost().getHostName(), -// slcAgentDescriptor.getHost()); + SlcAgentDescriptor slcAgentDescriptor = getHttpClient() + .waitForOneAgent(); + assertEquals(InetAddress.getLocalHost().getHostName(), + slcAgentDescriptor.getHost()); } } diff --git a/integration-tests/org.argeo.slc.it.webapp/src/test/resources/log4j.properties b/integration-tests/org.argeo.slc.it.webapp/src/test/resources/log4j.properties new file mode 100644 index 000000000..bd20b8e12 --- /dev/null +++ b/integration-tests/org.argeo.slc.it.webapp/src/test/resources/log4j.properties @@ -0,0 +1,14 @@ +log4j.rootLogger=WARN, console + +## Levels +# SLC +log4j.logger.org.argeo=DEBUG + +## Appenders +# A1 is set to be a ConsoleAppender. +log4j.appender.console=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern= %-5p %d{ISO8601} %m - %c%n + diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/HttpServicesClient.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/HttpServicesClient.java new file mode 100644 index 000000000..9bdcd5fb5 --- /dev/null +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/HttpServicesClient.java @@ -0,0 +1,27 @@ +package org.argeo.slc.server.client; + +import java.util.Map; + +import org.argeo.slc.Condition; + +/** Abstraction of the access to HTTP services . */ +public interface HttpServicesClient { + /** Call service, failing if it is not available. */ + public T callService(String path, Map parameters); + + /** + * Call service, waiting and retrying until the timeout is reached if it is + * not immediately available. + * + * @param path + * service path + * @param condition + * if not null, a condition to be applied on received object, + * keep trying if it returns false. + * @param timeout + * timeout after which an exception is thrown + */ + public T callServiceSafe(String path, Map parameters, + Condition condition, Long timeout); + +} diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/SlcServerHttpClient.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/SlcServerHttpClient.java index 7102a749c..2113438f8 100644 --- a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/SlcServerHttpClient.java +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/SlcServerHttpClient.java @@ -1,121 +1,9 @@ package org.argeo.slc.server.client; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Map; - -import javax.xml.transform.stream.StreamSource; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.slc.SlcException; -import org.springframework.oxm.Unmarshaller; -import org.springframework.util.Assert; - -public class SlcServerHttpClient { - private final static Log log = LogFactory.getLog(SlcServerHttpClient.class); - - private Unmarshaller unmarshaller; - private String baseUrl; - - private Long retryPeriod = 1000l; - - @SuppressWarnings(value = { "unchecked" }) - public T callService(String path, Map parameters) { - try { - return (T) callServiceLowLevel(path, parameters); - } catch (Exception e) { - throw new SlcException("Cannot call service " + path + " on " - + baseUrl, e); - } - } - - @SuppressWarnings(value = { "unchecked" }) - public T callServiceSafe(String path, Map parameters, - long timeout) { - long begin = System.currentTimeMillis(); - try { - Object obj = null; - long duration = System.currentTimeMillis() - begin; - while (duration < timeout) { - try { - obj = callServiceLowLevel(path, parameters); - } catch (IOException e) { - if (log.isTraceEnabled()) - log.trace("Exception when calling service " + path - + " on " + baseUrl, e); - } - - if (obj != null) - break; - - // wait a bit - try { - Thread.sleep(retryPeriod); - } catch (InterruptedException e) { - // silent - } - } - - if (obj == null) - throw new SlcException( - "Service " - + path - + " on " - + baseUrl - + " did not return an answer after calling it safely for " - + duration + " ms."); - return (T) obj; - } catch (Exception e) { - throw new SlcException( - "Unexpected exception when safely calling service " + path - + " on " + baseUrl, e); - } - } - - protected Object callServiceLowLevel(String path, - Map parameters) throws IOException { - Assert.notNull(baseUrl, "base url"); - InputStream in = null; - try { - URL url = new URL(baseUrl + path); - HttpURLConnection connection = (HttpURLConnection) url - .openConnection(); - if (parameters != null) { - for (String key : parameters.keySet()) { - connection.addRequestProperty(key, parameters.get(key)); - } - } - - connection.connect(); - - in = connection.getInputStream(); - StreamSource source = new StreamSource(in); - Object obj = unmarshaller.unmarshal(source); - return obj; - } finally { - IOUtils.closeQuietly(in); - } - } - - public void setUnmarshaller(Unmarshaller unmarshaller) { - this.unmarshaller = unmarshaller; - } - - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; - } - - public Long getRetryPeriod() { - return retryPeriod; - } - - /** Retry period in ms when accessing service safely. Default is 1000 ms. */ - public void setRetryPeriod(Long retryPeriod) { - this.retryPeriod = retryPeriod; - } +import org.argeo.slc.runtime.SlcAgentDescriptor; +/** Abstraction of the access to HTTP services of an SLC Server. */ +public interface SlcServerHttpClient extends HttpServicesClient { + /** Wait for one agent to be available. */ + public SlcAgentDescriptor waitForOneAgent(); } diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/AbstractHttpServicesClient.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/AbstractHttpServicesClient.java new file mode 100644 index 000000000..ba4e584ef --- /dev/null +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/AbstractHttpServicesClient.java @@ -0,0 +1,126 @@ +package org.argeo.slc.server.client.impl; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Map; + +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.Condition; +import org.argeo.slc.SlcException; +import org.argeo.slc.server.client.HttpServicesClient; +import org.springframework.oxm.Unmarshaller; +import org.springframework.util.Assert; + +public abstract class AbstractHttpServicesClient implements HttpServicesClient { + private final static Log log = LogFactory + .getLog(AbstractHttpServicesClient.class); + private Unmarshaller unmarshaller; + private String baseUrl; + + private Long retryPeriod = 1000l; + @SuppressWarnings(value = { "unchecked" }) + public T callService(String path, Map parameters) { + try { + return (T) callServiceLowLevel(path, parameters); + } catch (Exception e) { + throw new SlcException("Cannot call service " + path + " on " + + baseUrl, e); + } + } + + @SuppressWarnings(value = { "unchecked" }) + public T callServiceSafe(String path, Map parameters, + Condition condition, Long timeout) { + long begin = System.currentTimeMillis(); + try { + Object obj = null; + long duration = System.currentTimeMillis() - begin; + while (duration < timeout) { + try { + obj = callServiceLowLevel(path, parameters); + } catch (IOException e) { + if (log.isTraceEnabled()) + log.trace("Exception when calling service " + path + + " on " + baseUrl, e); + } + + if (obj != null) { + if (condition == null) + break; + else { + if (condition.check((T) obj)) + break; + } + } + // wait a bit + try { + Thread.sleep(retryPeriod); + } catch (InterruptedException e) { + // silent + } + } + + if (obj == null) + throw new SlcException( + "Service " + + path + + " on " + + baseUrl + + " did not return an answer after calling it safely for " + + duration + " ms."); + return (T) obj; + } catch (Exception e) { + throw new SlcException( + "Unexpected exception when safely calling service " + path + + " on " + baseUrl, e); + } + } + + protected Object callServiceLowLevel(String path, + Map parameters) throws IOException { + Assert.notNull(baseUrl, "base url"); + InputStream in = null; + try { + URL url = new URL(baseUrl + path); + HttpURLConnection connection = (HttpURLConnection) url + .openConnection(); + if (parameters != null) { + for (String key : parameters.keySet()) { + connection.addRequestProperty(key, parameters.get(key)); + } + } + + connection.connect(); + + in = connection.getInputStream(); + StreamSource source = new StreamSource(in); + Object obj = unmarshaller.unmarshal(source); + return obj; + } finally { + IOUtils.closeQuietly(in); + } + } + + public void setUnmarshaller(Unmarshaller unmarshaller) { + this.unmarshaller = unmarshaller; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public Long getRetryPeriod() { + return retryPeriod; + } + + /** Retry period in ms when accessing service safely. Default is 1000 ms. */ + public void setRetryPeriod(Long retryPeriod) { + this.retryPeriod = retryPeriod; + } +} diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/SlcServerHttpClientImpl.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/SlcServerHttpClientImpl.java new file mode 100644 index 000000000..75e4e8ea0 --- /dev/null +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/client/impl/SlcServerHttpClientImpl.java @@ -0,0 +1,37 @@ +package org.argeo.slc.server.client.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.slc.Condition; +import org.argeo.slc.msg.ObjectList; +import org.argeo.slc.runtime.SlcAgentDescriptor; +import org.argeo.slc.server.client.SlcServerHttpClient; + +public class SlcServerHttpClientImpl extends AbstractHttpServicesClient + implements SlcServerHttpClient { + public final static String LIST_AGENTS = "listAgents.service"; + + private final static Log log = LogFactory + .getLog(SlcServerHttpClientImpl.class); + + private Long retryTimeout = 60 * 1000l; + + public SlcAgentDescriptor waitForOneAgent() { + ObjectList objectList = callServiceSafe(LIST_AGENTS, null, + new Condition() { + public Boolean check(ObjectList obj) { + int size = obj.getObjects().size(); + if (log.isTraceEnabled()) + log.trace("Object list size: " + size); + return size == 1; + } + }, retryTimeout); + return (SlcAgentDescriptor) objectList.getObjects().get(0); + } + + /** Timeout in ms after which a safe call will throw an exception. */ + public void setRetryTimeout(Long retryTimeout) { + this.retryTimeout = retryTimeout; + } + +} diff --git a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/unit/AbstractHttpClientTestCase.java b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/unit/AbstractHttpClientTestCase.java index 5d5dcea5e..f0142ba50 100644 --- a/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/unit/AbstractHttpClientTestCase.java +++ b/runtime/org.argeo.slc.server/src/main/java/org/argeo/slc/server/unit/AbstractHttpClientTestCase.java @@ -13,11 +13,12 @@ public abstract class AbstractHttpClientTestCase extends AbstractSpringTestCase protected void setUp() throws Exception { super.setUp(); httpClient = createHttpClient(); + waitForServerToBeReady(); } protected void waitForServerToBeReady() { ExecutionAnswer answer = httpClient.callServiceSafe( - isServerReadyService, null, getServerReadyTimeout()); + isServerReadyService, null, null, getServerReadyTimeout()); if (!answer.isOk()) throw new SlcException("Server is not ready: " + answer); } diff --git a/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/client/spring.xml b/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/client/spring.xml index e67633eec..8f63be9b1 100644 --- a/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/client/spring.xml +++ b/runtime/org.argeo.slc.server/src/main/resources/org/argeo/slc/server/client/spring.xml @@ -10,7 +10,7 @@ - diff --git a/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/Condition.java b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/Condition.java new file mode 100644 index 000000000..f476961f0 --- /dev/null +++ b/runtime/org.argeo.slc.specs/src/main/java/org/argeo/slc/Condition.java @@ -0,0 +1,11 @@ +package org.argeo.slc; + +/** Binary check on an arbitrary object. */ +public interface Condition { + /** + * Checks the condition. + * + * @return true, if the condition is verified, false if not. + */ + public Boolean check(T obj); +}