Skip to Content.
Sympa Menu

perfsonar-dev - [pS-dev] [GEANT/SA2/ps-java-services] r6107 - in trunk/psBase3: perfsonar-base/src/main/java/net/geant/perfsonar perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response perfsonar-base/src/main/java/net/geant/perfsonar/xpath perfsonar-base/src/test/java/net/geant/perfsonar perfsonar-base/src/test/java/net/geant/perfsonar/helpers perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet perfsonar-base/src/test/java/net/geant/perfsonar/xpath perfsonar-base/src/test/resources perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet psbase3-apt psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice psbase3-apt/src/main/java/net/geant/perfsonar/annotations psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath psbase3-apt/src/main/resources/META-INF/services psbase3-apt/src/test/java/net/geant/perfsonar/annotations psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler

Subject: perfsonar development work

List archive

[pS-dev] [GEANT/SA2/ps-java-services] r6107 - in trunk/psBase3: perfsonar-base/src/main/java/net/geant/perfsonar perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response perfsonar-base/src/main/java/net/geant/perfsonar/xpath perfsonar-base/src/test/java/net/geant/perfsonar perfsonar-base/src/test/java/net/geant/perfsonar/helpers perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet perfsonar-base/src/test/java/net/geant/perfsonar/xpath perfsonar-base/src/test/resources perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet psbase3-apt psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice psbase3-apt/src/main/java/net/geant/perfsonar/annotations psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath psbase3-apt/src/main/resources/META-INF/services psbase3-apt/src/test/java/net/geant/perfsonar/annotations psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler


Chronological Thread 
  • From:
  • To:
  • Subject: [pS-dev] [GEANT/SA2/ps-java-services] r6107 - in trunk/psBase3: perfsonar-base/src/main/java/net/geant/perfsonar perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response perfsonar-base/src/main/java/net/geant/perfsonar/xpath perfsonar-base/src/test/java/net/geant/perfsonar perfsonar-base/src/test/java/net/geant/perfsonar/helpers perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet perfsonar-base/src/test/java/net/geant/perfsonar/xpath perfsonar-base/src/test/resources perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet psbase3-apt psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice psbase3-apt/src/main/java/net/geant/perfsonar/annotations psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath psbase3-apt/src/main/resources/META-INF/services psbase3-apt/src/test/java/net/geant/perfsonar/annotations psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler
  • Date: Wed, 16 Jan 2013 12:28:06 +0000 (GMT)

Author: psnc.pietrzak
Date: 2013-01-16 12:28:06 +0000 (Wed, 16 Jan 2013)
New Revision: 6107

Added:

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SSHTelnetMPWebServiceTest.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SchedulerTest.java
trunk/psBase3/perfsonar-base/src/test/resources/configuration.xml

trunk/psBase3/perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet/LSRegister.template
trunk/psBase3/psbase3-apt/annotated/

trunk/psBase3/psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice/ServiceController.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/LookupServiceRegister.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/Namespace.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/XPath.java
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/LookupServiceRegisterProcessor.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/TemplateEngine.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/RequestProcessor.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/TemplateEngine.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/TemplateEngine.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathCollector.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathProcessor.java

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/LookupServiceRegisterProcessorTest.java

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/RequestProcessorTest.java

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/XPathProcessorTest.java
Removed:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/annotations/
trunk/psBase3/psbase3-apt/net/
Modified:

trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/Configuration.java

trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/NMWGMessage.java

trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/PerfSONAR.java

trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response/TemplateEngine.java

trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/xpath/XPathDeserializer.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/PerfSONARTest.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/NMWG.groovy

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARClient.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARServiceClient.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/SSHTelnetMPService.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/ServiceController.java

trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/xpath/XPathDeserializerTest.java
trunk/psBase3/psbase3-apt/pom.xml

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessor.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListener.java

trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListenerImpl.java

trunk/psBase3/psbase3-apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorTest.java

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/CompilerHelper.java

trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/Diagnostics.java
Log:
Added two sections to PsBase3 developer guide.
Provided a work around for running PsBase3 framework inside Apache CXF.
Apache CXF has a bug when the provider implements Provider<SAXSource>
although it is stressed in the documentation that it's correct. The changes
included to use Provider<StreamSource> instead.
Code cleanup.

Modified:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/Configuration.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/Configuration.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/Configuration.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -1,26 +1,80 @@
package net.geant.perfsonar;

import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.Map;

+import net.geant.perfsonar.xpath.Helper;
+
+/**
+ * Represents configuration necessary for handling requests and registering
to
+ * Lookup Service.
+ *
+ * It consists of a set of static methods to improve the readability of the
code.
+ * Please static import all the methods from the class.
+ *
+ * In order to configure the handler for the given type of request the
following
+ * code snippet must be used:
+ *
<code>configure(when("SetupData").then(ServiceController.class).createUser(any(String.class)))</code>
+ *
+ * Configuration records the method invocation and assigns it to the given
request type.
+ * This way of configuring is developer friendly. It ensures that when the
code
+ * will be refactored, configuration will refactor with code too.
+ * Furthermore, it checks at compile time whether controller methods are not
void.
+ * They must provide some results that are serialized as responses to
clients.
+ * Method configure ensures on compilation phase that the controller method
will return type.
+ * Method when describes the type of the request. In this example the type
is SetupDataRequest.
+ * Method then starts recording method invocation. In order to compile the
code correctly
+ * one must specify class of the controller method. Then the appropriate
method is invoked.
+ * In this example it is createUser(String). Please note that no real
invocation takes place.
+ * Controller methods may contain zero or one parameters. If they contain a
parameter then
+ * in order to compile an argument must be passed. Method any provide
compiler friendly
+ * implementation. As an argument one provide type of the argument.
+ *
+ * In order to configure the handler for the Lookup Service registration the
following
+ * code snippet must be used:
+ *
<code>configure(registerToLookupService(ServiceController.class).details())</code>
+ *
+ * @author <a
href="mailto:">Blazej
Pietrzak</a>
+ */
public class Configuration {
private static Method method;
private static String type;
private static Map<String, Method> handlers = new Hashtable<String,
Method>();
+ private static int lsInterval = 60 * 60;
+ private static List<String> lsAddresses = new ArrayList<String>();

+ /**
+ * Method used for configuration of handlers. It ensures on the
compile time phase
+ * that handlers return types that are later on serialized as
responses.
+ * Please note that the handler cannot be of type void.
+ *
+ * @param executeMethod
+ */
public static <T> void configure(T executeMethod) {
handlers.put(type, method);
}
-
+
+ /**
+ *
+ * @param messageType
+ * @return
+ */
public static HandlerConfiguration when(String messageType) {
return new HandlerConfiguration(messageType);
}
-
+
public static <T> T any(Class<T> type) {
return null;
}

+ /**
+ *
+ * @param type request type
+ * @return controller method that handles the request
+ */
public static Method getHandler(String type) {
return handlers.get(type);
}
@@ -35,4 +89,32 @@
method = null;
handlers.clear();
}
+
+ /**
+ * Sets timeout between subsequent registrations/keepalives to Lookup
Service.
+ */
+ public void setLookupServiceInterval(String interval) {
+ Configuration.lsInterval = Integer.parseInt(interval);
+ }
+
+ /**
+ * Returns timeout between subsequent registrations/keepalives to
Lookup Service.
+ */
+ public static int getLSInterval() {
+ return Configuration.lsInterval;
+ }
+
+ public static <T> T registerToLookupService(Class<T> controller) {
+ return Helper.createMock(controller, new HandlerConfiguration(
+ "LSRegister"));
+ }
+
+ public static List<String> getLSAddresses() {
+ return lsAddresses;
+ }
+
+ public static void addLSAddress(String address) {
+ if (!lsAddresses.contains(address))
+ lsAddresses.add(address);
+ }
}

Modified:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/NMWGMessage.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/NMWGMessage.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/NMWGMessage.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -1,10 +1,22 @@
package net.geant.perfsonar;

+/**
+ * Represents NMWG message. It is used internally by PerfSONAR class.
+ *
+ * @author <a
href="">Blazej
Pietrzak</a>
+ */
public class NMWGMessage {
private String type;
private String eventType;
private String id;
+ private String key;

+ public NMWGMessage() {
+ }
+ public NMWGMessage(String requestId, String type) {
+ this.id = requestId;
+ this.type = type;
+ }
public String getType() {
return type;
}
@@ -32,4 +44,41 @@
public void setEventType(String eventType) {
this.eventType = eventType;
}
+ public String getKey() {
+ return this.key;
+ }
+ public void setKey(String key) {
+ this.key = key;
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((type == null) ? 0 :
type.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ NMWGMessage other = (NMWGMessage) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (type == null) {
+ if (other.type != null)
+ return false;
+ } else if (!type.equals(other.type))
+ return false;
+ return true;
+ }
+
+
}

Modified:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/PerfSONAR.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/PerfSONAR.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/PerfSONAR.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -5,16 +5,29 @@
import static net.geant.perfsonar.xpath.XPathDeserializer.whenXPath;

import java.io.IOException;
-import java.io.Reader;
+import java.io.OutputStreamWriter;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.io.StringReader;
import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;

-import javax.xml.transform.sax.SAXSource;
+import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Dispatch;
import javax.xml.ws.Provider;
+import javax.xml.ws.Service;
+import javax.xml.ws.soap.SOAPBinding;

import net.geant.perfsonar.base.Scheduler;
import net.geant.perfsonar.nmwg.response.EchoResponse;
@@ -25,18 +38,16 @@

import org.xml.sax.InputSource;

-//@WebServiceProvider(targetNamespace = "http://base3.perfsonar.geant.net/";,
-// portName = "PerfSONARPort", serviceName = "PerfSONARService")
/**
- * Base class for all web service classes.
+ * Base class for all NMWG web service classes.
*
* @author <a
href="mailto:">Blazej
Pietrzak</a>
*/
-// @WebServiceProvider(portName="SSHTelnetPort",
serviceName="PerfSONARService",
-// targetNamespace = "http://base3.perfsonar.geant.net/";)
-public abstract class PerfSONAR implements Provider<SAXSource> {
+public abstract class PerfSONAR implements Provider<StreamSource> {
public static final Object ANY = null;

+ private static int defaultThreadPoolSize = 10;
+
static {
try {
declarePrefix("nmwg",
"http://ggf.org/ns/nmwg/base/2.0/";);
@@ -45,44 +56,96 @@

whenXPath("nmwg:message/@type").then(NMWGMessage.class).setType(any(String.class));

whenXPath("nmwg:message/@id").then(NMWGMessage.class).setId(any(String.class));

whenXPath("nmwg:message/nmwg:metadata[@id='meta']/nmwg:eventType/text()").then(NMWGMessage.class).setEventType(any(String.class));
+
whenXPath("nmwg:message/nmwg:metadata/nmwg:key/text()").then(NMWGMessage.class).setKey(any(String.class));
} catch (Exception ex) { }
}

private static SelfTestResponse response;

- private Scheduler scheduler = new Scheduler() {
+ private Scheduler scheduler = createThreadPool();
+ private Map<String, String> keys = new Hashtable<String, String>();

- public void runInParallel(Runnable task) {
- task.run();
- }
+ public PerfSONAR() {
+ loadConfiguration();
+ getScheduler().runEvery(Configuration.getLSInterval(),
registerToLSServices());
+ }

- };
-
+ private Runnable registerToLSServices() {
+ return new Runnable() {
+ public void run() {
+ for (String address :
Configuration.getLSAddresses()) {
+ try {
+
registerToLookupService(address);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * It creates an instance of net.geant.perfsonar.SelfTestRunnerImpl.
+ * If you would like to use a different implementation of
SelfTestRunner you must override this method.
+ *
+ */
protected SelfTestRunner newSelfTestRunner() throws
InstantiationException,
IllegalAccessException, ClassNotFoundException {
return (SelfTestRunner) Class.forName(

"net.geant.perfsonar.SelfTestRunnerImpl").newInstance();
}
+
+ private void loadConfiguration() {
+ try {
+
Class.forName("net.geant.perfsonar.XPaths").newInstance();
+
Class.forName("net.geant.perfsonar.Handlers").newInstance();
+
Class.forName("net.geant.perfsonar.LookupServiceRegister").newInstance();
+ } catch (Exception ex) { }
+ }

- protected abstract ServiceType getServiceType();
+ private static Scheduler createThreadPool() {
+ return new Scheduler() {
+ private ExecutorService pool =
Executors.newFixedThreadPool(defaultThreadPoolSize);
+ private Timer timer = new Timer();
+
+ public void runInParallel(Runnable task) {
+ pool.execute(task);
+ }

- protected abstract String getServiceName();
+ public void runEvery(int seconds, final Runnable
task) {
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ task.run();
+ }
+ }, 0, seconds * 1000);
+ }

+ };
+ }
+
+ public abstract ServiceType getServiceType();
+
+ public abstract String getServiceName();
+
/**
* Processes the incoming xml message.
*
* @see javax.xml.ws.Provider#invoke(java.lang.Object)
*/
@SuppressWarnings("unchecked")
- public SAXSource invoke(SAXSource request) {
+ public StreamSource invoke(StreamSource request) {
final XPathDeserializer deserializer = new
XPathDeserializer();
final List<Object> objects;
try {
- objects = (List<Object>)
deserializer.deserialize(request.getInputSource().getCharacterStream());
+ objects = (List<Object>)
deserializer.deserialize(toInputSource(request));//.getCharacterStream());
} catch (Exception e1) {
return null;
}

+ if (getObjects(NMWGMessage.class, objects).size() <= 0)
+ throw new RuntimeException("NMWG message was not
found in the payload.");
+
final NMWGMessage msg = getObjects(NMWGMessage.class,
objects).get(0);

final StringWriter writer = new StringWriter();
@@ -113,15 +176,22 @@
e.printStackTrace();
}
} catch (Exception ex) {
+ ex.printStackTrace();
return null;
}

- return new SAXSource(toInputSource(new StringReader(
- writer.toString())));
+ return new StreamSource(new
StringReader(writer.toString()));
}
}

- private SAXSource handleSelfTest(final NMWGMessage msg,
+ private InputSource toInputSource(StreamSource request) {
+ if (request.getInputStream() != null)
+ return new InputSource(request.getInputStream());
+ else
+ return new InputSource(request.getReader());
+ }
+
+ private StreamSource handleSelfTest(final NMWGMessage msg,
final StringWriter writer) {
try {
response = new SelfTestResponse(getServiceType(),
@@ -140,19 +210,16 @@
}
}

- return new SAXSource(toInputSource(new StringReader(
- writer.toString())));
+ return new StreamSource(new StringReader(writer.toString()));
}

- private SAXSource handleEcho(final NMWGMessage msg, final
StringWriter writer) {
+ private StreamSource handleEcho(final NMWGMessage msg, final
StringWriter writer) {
try {
EchoResponse.writeEcho(writer, msg.getId());
} catch (IOException e) {
- return new SAXSource(toInputSource(new StringReader(
- e.toString())));
+ return new StreamSource(new
StringReader(e.toString()));
}
- return new SAXSource(toInputSource(new StringReader(
- writer.toString())));
+ return new StreamSource(new StringReader(writer.toString()));
}

@SuppressWarnings("unchecked")
@@ -166,7 +233,81 @@
return result;
}

- private InputSource toInputSource(Reader reader) {
- return SAXSource.sourceToInputSource(new
StreamSource(reader));
+ /**
+ * @return scheduler that uses thread pool.
+ */
+ protected Scheduler getScheduler() {
+ return scheduler;
}
+
+ /**
+ * Sets thread pool size used by scheduler.
+ * @param size
+ */
+ public void setThreadPoolSize(int size) {
+ PerfSONAR.defaultThreadPoolSize = size;
+ scheduler = createThreadPool();
+ }
+
+ /**
+ * Registers a service to Lookup Service.
+ * If the service is already registered (key was returned from LS
successfully) it sends keepalive messages.
+ * It uses LSRegister.template template found in the directory where
the controller method that provides data for registration is defined.
+ *
+ */
+ @SuppressWarnings("unchecked")
+ protected void registerToLookupService(final String address) throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException,
InstantiationException, IOException {
+ final Method m = Configuration.getHandler("LSRegister");
+ if (m == null)
+ return;
+
+ TemplateEngine.put("requestId", "request1");
+ TemplateEngine.put("result",
m.invoke(m.getDeclaringClass().newInstance()));
+ TemplateEngine.put("service", this);
+
+ final String NAMESPACE = "http://base3.perfsonar.geant.net/";;
+ final QName PORT = new QName(NAMESPACE, "PerfSONARPort");
+ final Service service = Service.create(new QName(NAMESPACE,
"PerfSONARService"));
+ service.addPort(PORT, SOAPBinding.SOAP11HTTP_BINDING,
address);
+ Dispatch<StreamSource> client = service.createDispatch(PORT,
StreamSource.class, Service.Mode.PAYLOAD);
+ final PipedInputStream in = new PipedInputStream();
+ final PipedOutputStream out = new PipedOutputStream(in);
+ final Writer writer = new OutputStreamWriter(out);
+ getScheduler().runInParallel(new Runnable() {
+
+ public void run() {
+ try {
+ if (keys.get(address) == null)
+
TemplateEngine.evaluate(writer, m.getDeclaringClass(), "LSRegister.template");
+ else
+
writer.write(getKeepAliveMessage(keys.get(address)));
+ writer.flush();
+ out.close();
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ private String getKeepAliveMessage(String key) {
+ return "<?xml version='1.0'
encoding='UTF-8'?>"
+ + "<nmwg:message id='request1'
type='LSKeepaliveRequest' xmlns:nmwg='http://ggf.org/ns/nmwg/base/2.0/'>"
+ + "<nmwg:metadata
id='key_to_keepalive'><nmwg:key>" + key + "</nmwg:key></nmwg:metadata>"
+ + "<nmwg:data id='d1'
metadataIdRef='key_to_keepalive' />"
+ + "</nmwg:message>\n";
+ }
+ });
+
+ if (keys.get(address) == null) {
+ final XPathDeserializer deserializer = new
XPathDeserializer();
+ final NMWGMessage msg;
+ try {
+ msg = getObjects(NMWGMessage.class,
(List<Object>) deserializer.deserialize(new InputSource(client.invoke(new
StreamSource(in)).getInputStream()))).get(0);
+ if (msg.getKey() != null)
+ keys.put(address, msg.getKey());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else
+ client.invoke(new StreamSource(in));
+ }
}

Modified:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response/TemplateEngine.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response/TemplateEngine.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response/TemplateEngine.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -8,10 +8,21 @@
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

+/**
+ * Provides facade to the underlying template engine. This implementation
uses
+ * Velocity engine.
+ *
+ * @author <a
href="mailto:">Blazej
Pietrzak</a>
+ *
+ */
+/**
+ * @author <a
href="">Blazej
Pietrzak</a>
+ *
+ */
public class TemplateEngine {
private final static VelocityEngine templateEngine = new
VelocityEngine();
private final static VelocityContext context = new VelocityContext();
-
+
static {
try {
templateEngine.init();
@@ -20,27 +31,44 @@
ex.printStackTrace();
}
}
-
- private static InputStream getTemplate(Class<?> homeDir, String name)
throws IOException {
+
+ private static InputStream getTemplate(Class<?> homeDir, String name)
+ throws IOException {
final InputStream in =
homeDir.getClassLoader().getResourceAsStream(
getFullPath(homeDir, name));
-
+
if (in == null)
throw new IOException("Template " + name + " cannot
be found.");
return in;
}
-
+
private static String getFullPath(Class<?> homeDir, String name) {
String result = homeDir.getPackage().getName();
- for (; result.indexOf(".") != -1; result =
result.replace(".", File.separator));
+ for (; result.indexOf(".") != -1; result = result.replace(".",
+ File.separator))
+ ;
return result + File.separator + name;
}
-
- public static void evaluate(Writer writer, Class<?> homeDir, String
name) throws IOException {
- //TODO change to not deprecated
- templateEngine.evaluate(context, writer, "successMessage",
getTemplate(homeDir, name));
+
+ /**
+ * Writes to the stream provided by writer argument, the template
found in
+ * the directory where the given class is stored using the template
provided
+ * by name.
+ *
+ */
+ public static void evaluate(Writer writer, Class<?> homeDir, String
name)
+ throws IOException {
+ // TODO change to not deprecated
+ templateEngine.evaluate(context, writer, "successMessage",
+ getTemplate(homeDir, name));
}
+

+ /**
+ * Put data to the context. Data can be used in templates with a
macro ${identifier}
+ * where identifier is the name put in the context.
+ * More on template engine can be found at Apache Velocity website.
+ */
public static void put(String name, Object value) {
context.put(name, value);
}

Modified:
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/xpath/XPathDeserializer.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/xpath/XPathDeserializer.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/main/java/net/geant/perfsonar/xpath/XPathDeserializer.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -1,6 +1,5 @@
package net.geant.perfsonar.xpath;

-import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -22,6 +21,45 @@
import org.jaxen.saxpath.SAXPathException;
import org.xml.sax.InputSource;

+/**
+ * Deserializes data from XML stream.
+ *
+ * This class provides API for configuring XPath expressions that trigger
+ * method invocation with values of the expression evaluation.
+ * Please note that it uses streaming XPaths, so only a subset of
expressions can
+ * be used. Those that require creation of DOM tree are not allowed.
+ *
+ * There are two approaches to configure deserializer: via API or via
annotations.
+ * By invoking:
+ * <code>declarePrefix("nmwg", uri)</code>
+ * one informs the deserializer about prefixes for various namespaces.
+ * By invoking:
+ *
<code>whenXPath("/nmwg:message/@id").then(NMWGMessage.class).setId(any(String.class))</code>
+ * deserializer will fire setId method from instance of NMWGMesssage class
and provide
+ * as an argument the result of XPath expression provided in whenXPath
method.
+ * During configuration no real method is executed.
+ * The following configuration is developer friendly. It statically checks
whether
+ * the method exists and in case of refactoring it will be reconfigured
automatically.
+ *
+ * By invoking:
+ * <code>whenXPath(
+ *
"nmwg:message/nmwg:data[starts-with(@metadataIdRef,
'metadata')]/@metadataIdRef")
+ * .then(Command.class).setCurrentRouter(
+ * getReference(Router.class,
identifier(Router.class).getId()));</code>
+ *
+ * deserializer will invoke setCurrentRouter method and will provide a real
instance (not string)
+ * of Router class identified by getId method in defined in Router class.
+ *
+ * Configuring deserializer via annotations requires psbase3-apt tool to be
present on the classpath during compilation.
+ * By invoking:
+ *
<code>@XPath(xpath="nmwg:message/nmwg:metadata[@id='meta']/nmwg:eventType/text()",
+ *
namespaces=@Namespace(prefix="nmwg",
uri=NMWG_URI)) public void setEventType(String type)</code>
+ *
+ * setEventType method will be invoked when the xpath will be evaluated.
+ *
+ * @author <a
href="mailto:">Blazej
Pietrzak</a>
+ *
+ */
public class XPathDeserializer {

private final static DefaultNamespaceContext context = new
DefaultNamespaceContext();
@@ -61,7 +99,7 @@
private static Set<String> getXPaths() {
return xpaths.keySet();
}
-
+
private static Method getXPathMethod(String xpath) {
return xpaths.get(xpath);
}
@@ -69,14 +107,17 @@
public XPathDeserializer() {
}

- public List<?> deserialize(Reader reader) throws SAXPathException,
XPathException, IllegalArgumentException, IllegalAccessException,
InvocationTargetException, InstantiationException {
+ /**
+ * Deserializes objects from xml stream using streaming XPath
expressions.
+ */
+ public List<?> deserialize(InputSource reader) throws
SAXPathException, XPathException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException, InstantiationException {

final XMLDog dog = new XMLDog(context);
final List<Expression> expressions = new
ArrayList<Expression>();
for (String xpath : XPathDeserializer.getXPaths()) {
expressions.add(dog.addXPath(xpath));
}

- final XPathResults results = dog.sniff(new
InputSource(reader));
+ final XPathResults results = dog.sniff(reader);

for (Expression expr : sort(expressions)) {
@SuppressWarnings("unchecked")
@@ -108,6 +149,9 @@
final List<Expression> result = new ArrayList<Expression>();
final Iterator<Expression> iter = expressions.iterator();

+ if (expressions.size() <= 0)
+ return result;
+
for (Expression expr = iter.next(); iter.hasNext(); expr =
iter.next()) {
Method method =
XPathDeserializer.getXPathMethod(expr.getXPath());
if (method == null)

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/PerfSONARTest.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/PerfSONARTest.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/PerfSONARTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -6,16 +6,26 @@

import java.io.IOException;
import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;

+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Provider;
+import javax.xml.ws.WebServiceProvider;
+
import net.geant.perfsonar.helpers.NMWG;
import net.geant.perfsonar.helpers.PerfSONARClient;
import net.geant.perfsonar.helpers.SelfTestResult;
import net.geant.perfsonar.mp.sshtelnet.Command;
import net.geant.perfsonar.mp.sshtelnet.SSHTelnetMPService;
+import net.geant.perfsonar.mp.sshtelnet.ServiceController;
+import net.geant.perfsonar.xpath.XPathDeserializer;

+import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class PerfSONARTest {
@@ -24,11 +34,50 @@

private PerfSONARClient client;

+ private SSHTelnetMPService service = new SSHTelnetMPService();
+ private Endpoint ls;
+
+ private int lsKeepAliveCount;
+
+ private int lsRegisterCount;
+
@Before
public void givenPerfSONARClient() {
- client = new PerfSONARClient(new SSHTelnetMPService());
+ client = new PerfSONARClient(service);
+ ls = Endpoint.publish("http://localhost:9000/perfsonar-ls";,
+ new LSService());
}

+ @After
+ public void destroy() {
+ ls.stop();
+ }
+
+ @WebServiceProvider
+ class LSService implements Provider<StreamSource> {
+
+ @SuppressWarnings("unchecked")
+ public StreamSource invoke(StreamSource input) {
+ final XPathDeserializer deserializer = new
XPathDeserializer();
+ NMWGMessage msg;
+ try {
+ msg = getObjects(
+ NMWGMessage.class,
+ (List<Object>) deserializer
+
.deserialize(new InputSource(input
+
.getInputStream()))).get(0);
+ if
(msg.getType().equals("LSKeepaliveRequest"))
+ lsKeepAliveCount++;
+ else if
(msg.getType().equals("LSRegisterRequest"))
+ lsRegisterCount++;
+ return new
StreamSource(NMWG.toLSResponse(msg.getId()));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+ }
+
@Test
public void checkEcho() throws SAXException {
assertEquals(NMWG.toEchoResponse(REQUEST_ID),
client.echo(REQUEST_ID));
@@ -45,22 +94,50 @@
client.selfTest(REQUEST_ID));
}

- @Ignore @Test
+ @Test
public void checkMetadataKey() throws SAXException, IOException {
- print(client.listAvailableCommands(REQUEST_ID).getReader());

+ print(client.listAvailableCommands(REQUEST_ID).getReader());
}
-
+
@Test
public void checkSetupDataRequest() throws Exception {
- final Command command1 = (Command)
Command.SHOW_ENVIRONMENT.newInstance();
+ final Command command1 = (Command) Command.SHOW_ENVIRONMENT
+ .newInstance();
command1.setRouterName("host1");
final Command command2 = (Command)
Command.PING_IPV6.newInstance();
command2.setRouterName("host2");
- print(client.executeCommands(REQUEST_ID, command1,
command2).getReader());
+ print(client.executeCommands(REQUEST_ID, command1, command2)
+ .getReader());
}

private void print(Reader reader) throws IOException {
for (int i = reader.read(); i != -1; i = reader.read())
System.out.print((char) i);
}
+
+ @Test
+ public void registerToLookupService() throws Exception {
+ Configuration.configure(Configuration.registerToLookupService(
+
ServiceController.class).listAvailableRoutersAndCommands());
+
+
service.registerToLookupService("http://localhost:9000/perfsonar-ls";);
+
service.registerToLookupService("http://localhost:9000/perfsonar-ls";);
+
service.registerToLookupService("http://localhost:9000/perfsonar-ls";);
+
+ Thread.sleep(5 * 1000);
+
+ assertEquals(2, lsKeepAliveCount);
+ assertEquals(1, lsRegisterCount);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> getObjects(Class<T> type, List<Object> objects) {
+ final List<T> result = new ArrayList<T>();
+ for (Object obj : objects) {
+ if (obj.getClass().equals(type)) {
+ result.add((T) obj);
+ }
+ }
+ return result;
+ }
}

Added:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SSHTelnetMPWebServiceTest.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SSHTelnetMPWebServiceTest.java
(rev 0)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SSHTelnetMPWebServiceTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,45 @@
+package net.geant.perfsonar;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import javax.xml.ws.Endpoint;
+
+import net.geant.perfsonar.helpers.NMWG;
+import net.geant.perfsonar.helpers.PerfSONARServiceClient;
+import net.geant.perfsonar.mp.sshtelnet.SSHTelnetMPService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class SSHTelnetMPWebServiceTest {
+ private static final String SERVICE_URL =
"http://localhost:9000/perfsonar-java-sshtelnet-mp";;
+ private static final String REQUEST_ID = "request1";
+
+ private Endpoint endpoint;
+
+ @Before
+ public void givenSSHTelnetMPWebService() throws InterruptedException,
IOException {
+ endpoint = Endpoint.publish(SERVICE_URL, new
SSHTelnetMPService());
+ }
+
+ @After
+ public void destroy() {
+ endpoint.stop();
+ }
+
+ @Test
+ public void shouldSayEcho() throws SAXException, InterruptedException
{
+ final PerfSONARServiceClient client = new
PerfSONARServiceClient(SERVICE_URL);
+ assertEquals(NMWG.toEchoResponse(REQUEST_ID),
client.echo(REQUEST_ID));
+ }
+
+ @Test
+ public void shouldSetLSInterval() {
+ assertEquals(600, Configuration.getLSInterval());
+ }
+
+}

Added:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SchedulerTest.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SchedulerTest.java
(rev 0)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/SchedulerTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,67 @@
+package net.geant.perfsonar;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import net.geant.perfsonar.base.Scheduler;
+import net.geant.perfsonar.mp.sshtelnet.SSHTelnetMPService;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class SchedulerTest {
+ private PerfSONAR service = new SSHTelnetMPService();
+ private boolean executed1 = false;
+ private boolean executed2 = false;
+ private Scheduler scheduler;
+
+ @Before
+ public void givenScheduler() {
+ scheduler = service.getScheduler();
+ }
+
+ @Test
+ public void shouldRunTwoTasksInParallel() throws InterruptedException
{
+ scheduler.runInParallel(new Runnable() {
+ public void run() {
+ int i = 0;
+ while (!executed1 || (i > 10)) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) { }
+ i++;
+ }
+ executed2 = executed1;
+ }
+ });
+
+ scheduler.runInParallel(new Runnable() {
+ public void run() {
+ executed1 = true;
+ }
+ });
+ Thread.sleep(1000);
+ assertTrue(executed1);
+ assertTrue(executed2);
+ }
+
+ @Test
+ public void shouldRunEveryOneSecond() throws InterruptedException {
+ final CounterTask task = new CounterTask();
+ scheduler.runEvery(1, task);
+ Thread.sleep(3 * 1000);
+ assertEquals(3, task.getCounter());
+ }
+
+ class CounterTask implements Runnable {
+ private int counter = 0;
+
+ public void run() {
+ if (counter == 3) return;
+ counter++;
+ }
+
+ public int getCounter() {
+ return counter;
+ }
+ }
+}

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/NMWG.groovy
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/NMWG.groovy
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/NMWG.groovy
2013-01-16 12:28:06 UTC (rev 6107)
@@ -4,6 +4,7 @@
import net.geant.perfsonar.mp.sshtelnet.Router;


+import java.io.InputStream;
import java.io.Reader;

import groovy.xml.MarkupBuilder
@@ -12,6 +13,7 @@
private static Reader createRequest(id, eventType, version) {
def writer = new StringWriter()
MarkupBuilder xml = new MarkupBuilder(writer)
+ xml.mkp.xmlDeclaration(version:"1.0", encoding:"UTF-8")

xml.'nmwg:message'('xmlns:nmwg':'http://ggf.org/ns/nmwg/base/2.0/', id:id,
type:"EchoRequest") {
'nmwg:metadata'(id:"meta") {
'nmwg:eventType'
"http://schemas.perfsonar.net/tools/admin/${eventType}/${version}";
@@ -19,6 +21,7 @@
'nmwg:data'(id:"data", metadataIdRef:"meta")
}

+ writer.write("\n");
new StringReader(writer.toString())
}

@@ -195,5 +198,19 @@
}
}
new Response(new StringReader(writer.toString()))
+ }
+
+ public static Reader toLSResponse(String id) {
+ def writer = new StringWriter()
+ MarkupBuilder xml = new MarkupBuilder(writer)
+
xml.'nmwg:message'('xmlns:nmwg':'http://ggf.org/ns/nmwg/base/2.0/',
id:"${id}_resp", messageIdRef:id, type:"LSRegisterResponse") {
+ 'nmwg:metadata'(id:"meta") {
+ 'nmwg:eventType' "success"
+ 'nmwg:key' "${id}"
+ }
+ 'nmwg:data'(id:"data", metadataIdRef:"meta")
+ }
+
+ new StringReader(writer.toString())
}
}

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARClient.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARClient.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARClient.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -2,14 +2,12 @@

import java.io.Reader;

-import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;

import net.geant.perfsonar.PerfSONAR;
import net.geant.perfsonar.mp.sshtelnet.Command;

-import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import org.xml.sax.helpers.XMLReaderFactory;


public class PerfSONARClient {
@@ -28,7 +26,8 @@
}

private Reader invoke(Reader request) throws SAXException {
- return service.invoke(new
SAXSource(XMLReaderFactory.createXMLReader(), new
InputSource(request))).getInputSource().getCharacterStream();
+ final StreamSource source = service.invoke(new
StreamSource(request));
+ return source.getReader();
}

public Response listAvailableCommands(String id) throws SAXException {

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARServiceClient.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARServiceClient.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/helpers/PerfSONARServiceClient.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -33,6 +33,7 @@
}

private InputStream invoke(Reader request) throws SAXException {
- return client.invoke(new
StreamSource(request)).getInputStream();
+ final StreamSource source = client.invoke(new
StreamSource(request));
+ return source.getInputStream();
}
}

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/SSHTelnetMPService.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/SSHTelnetMPService.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/SSHTelnetMPService.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -3,47 +3,83 @@
import static net.geant.perfsonar.Configuration.configure;
import static net.geant.perfsonar.Configuration.when;
import static net.geant.perfsonar.xpath.XPathDeserializer.any;
+import static net.geant.perfsonar.xpath.XPathDeserializer.declarePrefix;
import static net.geant.perfsonar.xpath.XPathDeserializer.whenXPath;

+import java.io.File;
+import java.io.FileInputStream;
+
import javax.xml.ws.WebServiceProvider;

+import net.geant.perfsonar.Configuration;
import net.geant.perfsonar.PerfSONAR;
import net.geant.perfsonar.ServiceType;
+import net.geant.perfsonar.xpath.XPathDeserializer;

-@WebServiceProvider(targetNamespace
= "http://base3.perfsonar.geant.net/";,
-portName = "PerfSONARPort", serviceName = "PerfSONARService")
+import org.xml.sax.InputSource;
+
+@WebServiceProvider
public class SSHTelnetMPService extends PerfSONAR {

+ private static final int SECOND = 1;
+
+ public SSHTelnetMPService() {
+ super();
+ getScheduler().runEvery(SECOND,
checkWhetherConfigurationFileChanged());
+ }
+
@Override
- protected ServiceType getServiceType() {
+ public ServiceType getServiceType() {
return ServiceType.MP;
}

@Override
- protected String getServiceName() {
+ public String getServiceName() {
return "SSHTELNET";
}

+ private Runnable checkWhetherConfigurationFileChanged() {
+ return new Runnable() {
+ private File file = new
File("src/test/resources/configuration.xml");
+ private long lastModified = 0;
+
+ public void run() {
+ if (!file.exists()) {
+ System.err.println("Configuration
file: " + file.getAbsolutePath() + " is missing");
+ return;
+ }
+
+ if (file.lastModified() > lastModified) {
+ lastModified = file.lastModified();
+ XPathDeserializer deserializer = new
XPathDeserializer();
+ try {
+ deserializer.deserialize(new
InputSource(new FileInputStream(file)));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }};
+ }
+
static {
try {
- configure(
-
when("MetadataKeyRequest").then(ServiceController.class).listAvailableRoutersAndCommands());
+
configure(when("MetadataKeyRequest").then(ServiceController.class)
+ .listAvailableRoutersAndCommands());

- configure(
-
when("SetupDataRequest").then(ServiceController.class).execute(any(Command.class)));
+
configure(when("SetupDataRequest").then(ServiceController.class)
+ .execute(any(Command.class)));

whenXPath(
-
"nmwg:message/nmwg:metadata/nmwg:subject/nmwgtopo:endPoint/text()")
+
"nmwg:message/nmwg:metadata/nmwg:subject/nmwgtopo:endPoint/text()")

.then(Command.class).setRouterName(any(String.class));
-
- whenXPath(
-
"nmwg:message/nmwg:metadata/nmwg:eventType/text()")
-
.then(Command.class).setEventType(any(String.class));

+
whenXPath("nmwg:message/nmwg:metadata/nmwg:eventType/text()").then(
+
Command.class).setEventType(any(String.class));
+
whenXPath(

"nmwg:message/nmwg:metadata/nmwg:parameters/nmwg:parameter[@name='command']/@value")

.then(Command.class).setName(any(String.class));
-
+
whenXPath(

"nmwg:message/nmwg:metadata/nmwg:parameters/nmwg:parameter[@name='description']/@value")

.then(Command.class).setDescription(any(String.class));
@@ -51,6 +87,12 @@
whenXPath(

"nmwg:message/nmwg:metadata/nmwg:parameters/nmwg:parameter[@name='syntax']/@value")

.then(Command.class).setSyntax(any(String.class));
+
+ declarePrefix("ns",
"http://service.perfsonar.org/ns/config/base/0.9/";);
+
+ whenXPath(
+
"ns:configuration/ns:service/ns:auxiliaryComponents/ns:component[@name='scheduling']/ns:actions/ns:action[@name='registration']/ns:option[@name='interval']/@value")
+
.then(Configuration.class).setLookupServiceInterval(any(String.class));
} catch (Exception ex) {
}
}

Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/ServiceController.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/ServiceController.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet/ServiceController.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -13,7 +13,7 @@
return Arrays.asList(
new Router("metadata0", "Cisco",
InetAddress.getAllByName("10.10.14.4")[0],
Command.SHOW_ENVIRONMENT, Command.PING),
- new Router("metadata1", "JuniperGeantAmsterdam",
InetAddress.getAllByName("rt1.ams.nl.geant2.net")[0],
+ new Router("metadata1", "JuniperGeantAmsterdam",
InetAddress.getByName("10.10.14.5"),
Command.SHOW_INTERFACES_FILTERS));
}


Modified:
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/xpath/XPathDeserializerTest.java
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/xpath/XPathDeserializerTest.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/perfsonar-base/src/test/java/net/geant/perfsonar/xpath/XPathDeserializerTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -9,7 +9,9 @@

import java.io.Reader;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;

import net.geant.perfsonar.helpers.NMWG;
import net.geant.perfsonar.mp.sshtelnet.Command;
@@ -17,8 +19,8 @@

import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
+import org.xml.sax.InputSource;

public class XPathDeserializerTest {
private static final String REQUEST_ID = "1";
@@ -79,16 +81,23 @@
XPathDeserializer.clearConfiguration();
}

- @Test @Ignore
+ @Test
public void shouldReturnRouters() throws Exception {
-
- assertEquals(Arrays.asList(
- Command.PING_IPV6,
- Command.SHOW_ENVIRONMENT,
- new Router("metadata0", "test1", InetAddress
-
.getAllByName("192.168.1.1")[0]),
- new Router("metadata1", "test2", InetAddress
-
.getAllByName("192.168.1.2")[0])),
- deserializer.deserialize(reader));
+ final List<Object> actual = (List<Object>)
deserializer.deserialize(new InputSource(reader));
+
+ assertEquals(Arrays.asList(Command.PING_IPV6,
Command.SHOW_ENVIRONMENT), getObjects(Command.class, actual));
+ assertEquals(Arrays.asList(new Router("metadata0", "test1",
InetAddress.getAllByName("192.168.1.1")[0]),
+ new Router("metadata1", "test2",
InetAddress.getAllByName("192.168.1.2")[0])), getObjects(Router.class,
actual));
}
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> getObjects(Class<T> type, List<Object> objects) {
+ final List<T> result = new ArrayList<T>();
+ for (Object obj : objects) {
+ if (obj.getClass().equals(type)) {
+ result.add((T) obj);
+ }
+ }
+ return result;
+ }
}

Added: trunk/psBase3/perfsonar-base/src/test/resources/configuration.xml
===================================================================
--- trunk/psBase3/perfsonar-base/src/test/resources/configuration.xml
(rev 0)
+++ trunk/psBase3/perfsonar-base/src/test/resources/configuration.xml
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,133 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<configuration xmlns="http://service.perfsonar.org/ns/config/base/0.9/";>
+ <service name="sshtelnet-mp">
+ <lookupInformation>
+ <option name="accessPoint"
value="http://localhost:${tomcat.port}/${project.artifactId}/services/SSHTelnet"/>
+ <option name="serviceName" value="Geant3 JAVA - SSHTelnet MP"/>
+ <option name="serviceType" value="MP"/>
+ </lookupInformation>
+
+ <!-- Message Handlers - message types and service engines -->
+
+ <messageHandler>
+
+ <message type="EchoRequest"
+
handler="org.perfsonar.base2.service.messages.GenericMessageHandler">
+ <option name="ServiceEngine"
+
value="org.perfsonar.service.measurementPoint.EchoServiceEngine" />
+ <option name="authN" value="no" />
+ </message>
+
+ <message type="MetadataKeyRequest"
+
handler="org.perfsonar.base2.service.messages.GenericMessageHandler">
+ <option name="ServiceEngine"
+
value="org.perfsonar.service.measurementPoint.ServiceCapabilitiesEngine" />
+ <option name="authN" value="no" />
+ </message>
+
+ <message type="SetupDataRequest"
+
handler="org.perfsonar.base2.service.messages.GenericMessageHandler">
+ <option name="ServiceEngine"
+
value="org.perfsonar.service.measurementPoint.SetupDataServiceEngine" />
+ <option name="authN" value="no" />
+ </message>
+
+ </messageHandler>
+
+ <!-- Additional auxiliary components -->
+
+ <auxiliaryComponents>
+ <component name="migrator"
className="org.perfsonar.base2.service.configuration.migration.MigratorComponent">
+ <option name="config-directory" value="${old-config-directory}" />
+ </component>
+ <component name="XMLDB"
className="org.perfsonar.base2.service.storage.xml.XMLDBComponent">
+ <option name="dataStorageClassName"
value="org.perfsonar.base2.service.storage.xml.exist.ExistHTTPDataStorage" />
+ <option name="uri"
value="http://localhost:${tomcat.port}/exist/rest/db"/>
+ <option name="username" value="sshtelnet"/>
+ <option name="password" value="sshtelnet"/>
+ </component>
+
+ <component name="Configuration"
className="org.perfsonar.service.measurementPoint.Configuration">
+ <option name="metadata-file"
value="${config.path}/sshtelnetmetadata.xml" />
+ <option name="token-path" value="${token.path}" />
+ </component>
+
+ <!-- auth configuration -->
+ <component name="auth"
className="org.perfsonar.base2.service.authn.component.wssec.WSSecAuthNComponent">
+ <option name="as_endpoint"
value="http://homer.rediris.es:8080/geant2-java-as-1.2/services/SimpleService"/>
+ <option name="comp_id" value="urn:compId"/>
+ </component>
+
+ <!-- Scheduler -->
+ <component name="scheduling"
className="org.perfsonar.base2.service.scheduler.SchedulingComponent">
+ <option name="schedulerClassName"
value="org.perfsonar.base2.service.scheduler.SimpleScheduler"/>
+ <option name="interval" value="60"/>
+
+ <actions>
+ <action name="registration"
className="org.perfsonar.base2.service.registration.LSRegistrationAction">
+ <option name="status" value="on" />
+ <option name="interval" value="600" />
+ <option name="registerDataSource"
value="org.perfsonar.base2.service.registration.MetadataExistDBRegisterDataSource"/>

+ <option name="registerEventType"
value="http://ogf.org/ns/nmwg/tools/org/perfsonar/service/lookup/registration/summary/2.0"/>
+ <option name="registrator"
value="org.perfsonar.base2.service.registration.GenericLSRegistrator"/>
+ <option name="lsAddress-1"
value="http://localhost:8080/geant2-java-xml-ls/services/LookupService"/>
+ <option name="lsAddress-2"
value="http://localhost:8380/perfsonar-java-xml-ls/services/LookupService"/>
+ </action>
+
+ <!-- Checks whether a given metadata file has changed and updates
it in the database.
+ If the given metadata file is not stored in the database it
is added. -->
+ <action name="metadata-updater"
className="org.perfsonar.service.measurementPoint.MetadataUpdater">
+ <!-- Should the user configured in the "Configuration" section
be created if it does not exist -->
+ <option name="create-user" value="yes" />
+
+ <!-- login and password for the user that has rights to create
user accounts. Obligatory only when "create-user" option is set to "yes" -->
+ <option name="username" value="admin" />
+ <option name="password" value="" />
+ </action>
+ </actions>
+ </component>
+ </auxiliaryComponents>
+
+ <extension name="registerExtension-registerDataSource">
+ <option name="exist-config" value="XMLDB" />
+ </extension>
+
+ <!--
....................................................................................
-->
+
+ <!-- Protocol mappings, XML elements and their bingings -->
+
+ <protocolMappings>
+
+
+ <!-- default mapping -->
+
+
+ <!-- general mappings -->
+ <element name="{*}message"
+ mapping="org.perfsonar.base2.xml.nmwg.Message"/>
+ <element name="{*}metadata"
+ mapping="org.perfsonar.base2.xml.nmwg.Metadata"/>
+ <element name="{*}eventType"
+ mapping="org.perfsonar.base2.xml.nmwg.EventType"/>
+ <element name="{*}data"
+ mapping="org.perfsonar.base2.xml.nmwg.Data"/>
+ <element name="{*}subject"
+ mapping="org.perfsonar.base2.xml.nmwg.Subject"/>
+ <element name="{*}parameters"
+ mapping="org.perfsonar.base2.xml.nmwg.Parameters"/>
+ <element name="{*}parameter"
+ mapping="org.perfsonar.base2.xml.nmwg.Parameter"/>
+ <element name="*"
+ mapping="org.perfsonar.base2.xml.Element"/>
+ <element
name="{http://ggf.org/ns/nmwg/tools/org/perfsonar/service/lookup/xquery/1.0/}subject";

+ mapping="org.perfsonar.base2.xml.TextElement"/>
+
+
+ </protocolMappings>
+
+
+ </service>
+
+
+</configuration>

Added:
trunk/psBase3/perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet/LSRegister.template
===================================================================
---
trunk/psBase3/perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet/LSRegister.template
(rev 0)
+++
trunk/psBase3/perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet/LSRegister.template
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nmwg:message id="${requestId}" type="LSRegisterRequest"
xmlns:nmwg="http://ggf.org/ns/nmwg/base/2.0/";>
+ <nmwg:metadata id="serviceLookupInfo">
+
<nmwg:eventType>http://ogf.org/ns/nmwg/tools/org/perfsonar/service/lookup/registration/service/2.0</nmwg:eventType>
+ <nmwg:subject id="commonParameters" name="perfsonar">
+ <psservice:service id="serviceParameters"
xmlns:psservice="http://ggf.org/ns/nmwg/tools/org/perfsonar/service/1.0/";>
+
<psservice:accessPoint>http://localhost:9000/perfsonar-sshtelnet-mp</psservice:accessPoint>
+
<psservice:serviceName>${service.serviceName}</psservice:serviceName>
+
<psservice:serviceType>${service.serviceType}</psservice:serviceType>
+ </psservice:service>
+ </nmwg:subject>
+ </nmwg:metadata>
+ <nmwg:data metadataIdRef="serviceLookupInfo">
+ <nmwg:metadata id="metadata0">
+ <nmwg:subject
id="subject0">DummyCiscoRouter</nmwg:subject>
+ <nmwg:parameters id="metaParams0">
+ <nmwg:parameter name="class_name"
value="org.perfsonar.service.measurementPoint.lookingGlassType.engine.adapters.CiscoAdapter"
/>
+ <nmwg:parameter name="url" value="0.0.0.0" />
+ <nmwg:parameter name="port" value="0" />
+ <nmwg:parameter name="prompt"
value="DummyRouter&gt;" />
+ <nmwg:parameter name="rate" value="500" />
+ <nmwg:parameter name="username"
value="dummyUser" />
+ <nmwg:parameter name="password"
value="ab05D8Z22537EdEzaWmlmA==" />
+ <nmwg:parameter name="timeout" value="10000"
/>
+ <nmwg:parameter name="numberOfUsers"
value="0" />
+ <nmwg:parameter name="cache" value="0" />
+ </nmwg:parameters>
+ </nmwg:metadata>
+ </nmwg:data>
+</nmwg:message>

Added:
trunk/psBase3/psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice/ServiceController.java
===================================================================
---
trunk/psBase3/psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice/ServiceController.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice/ServiceController.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,23 @@
+package net.geant.perfsonar.dummyservice;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+
+import net.geant.perfsonar.annotations.LookupServiceRegister;
+import net.geant.perfsonar.annotations.request.*;
+
+public class ServiceController {
+ @MetadataKey
+ @LookupServiceRegister
+ public List<String> listAvailableRouters() throws
UnknownHostException {
+ return Arrays.asList("router1", "router2");
+ }
+
+ @SetupData
+ public String execute(String command) throws IOException {
+ return "Executed: " + command;
+ }
+}

Modified: trunk/psBase3/psbase3-apt/pom.xml
===================================================================
--- trunk/psBase3/psbase3-apt/pom.xml 2013-01-16 12:10:58 UTC (rev 6106)
+++ trunk/psBase3/psbase3-apt/pom.xml 2013-01-16 12:28:06 UTC (rev 6107)
@@ -45,6 +45,12 @@
<version>3.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>net.geant.perfsonar</groupId>
+ <artifactId>perfsonar-base</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>

</project>
\ No newline at end of file

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/LookupServiceRegister.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/LookupServiceRegister.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/LookupServiceRegister.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,18 @@
+package net.geant.perfsonar.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes the method that provides data to Lookup Service registration.
+ *
+ * @author <a
href="mailto:">Blazej
Pietrzak</a>
+ *
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface LookupServiceRegister {
+
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/Namespace.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/Namespace.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/Namespace.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,7 @@
+package net.geant.perfsonar.annotations;
+
+
+public @interface Namespace {
+ String prefix();
+ String uri();
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/XPath.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/XPath.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/XPath.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,7 @@
+package net.geant.perfsonar.annotations;
+
+
+public @interface XPath {
+ String xpath();
+ Namespace[] namespaces();
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/LookupServiceRegisterProcessor.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/LookupServiceRegisterProcessor.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/LookupServiceRegisterProcessor.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,113 @@
+package net.geant.perfsonar.annotations.ls;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.tools.FileObject;
+
+import net.geant.perfsonar.annotations.LookupServiceRegister;
+import net.geant.perfsonar.annotations.selftest.SelfTestProcessorListener;
+import
net.geant.perfsonar.annotations.selftest.SelfTestProcessorListenerImpl;
+
+@SupportedAnnotationTypes("net.geant.perfsonar.annotations.LookupServiceRegister")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class LookupServiceRegisterProcessor extends AbstractProcessor {
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+
+ if (annotations.size() <= 0)
+ return false;
+
+ final SelfTestProcessorListener reporter = new
SelfTestProcessorListenerImpl(processingEnv.getMessager());
+ ExecutableElement handler = null;
+
+ for (Element method :
roundEnv.getElementsAnnotatedWith(LookupServiceRegister.class)) {
+ if (isDeclarationViolated((ExecutableElement) method,
reporter))
+ continue;
+
+ if (handler != null) {
+ reporter.error("Only one handler for Lookup
Service registration is allowed.", method);
+ continue;
+ }
+
+ handler = (ExecutableElement) method;
+ }
+
+ Writer writer = null;
+ try {
+ writer = openWriter(roundEnv.getRootElements());
+ new TemplateEngine().writeHandler(writer, handler);
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ } finally {
+ if (writer != null)
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ }
+ }
+
+ return false;
+ }
+
+ protected boolean isDeclarationViolated(ExecutableElement elem,
+ SelfTestProcessorListener listener) {
+ int errorsCount = 0;
+
+ if (elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ listener.error("The method cannot be abstract", elem);
+ errorsCount++;
+ }
+
+ if (!elem.getModifiers().contains(Modifier.PUBLIC)) {
+ listener.error("The method must be public.", elem);
+ errorsCount++;
+ }
+
+ if (elem.getModifiers().contains(Modifier.STATIC)) {
+ listener.error("The method cannot be static.", elem);
+ errorsCount++;
+ }
+
+ if (elem.getReturnType().getKind() == TypeKind.VOID) {
+ listener.error("Type of the method cannot be void.",
elem);
+ errorsCount++;
+ }
+
+ if (elem.getModifiers().contains(Modifier.FINAL)) {
+ listener.error("The method cannot be final.", elem);
+ errorsCount++;
+ }
+
+ if (elem.isVarArgs() || (elem.getParameters().size() > 0)) {
+ listener.error("The method cannot have any
parameters.", elem);
+ errorsCount++;
+ }
+
+ return (errorsCount > 0);
+ }
+
+ private Writer openWriter(Set<? extends Element> elements)
+ throws IOException {
+ final Filer filer = processingEnv.getFiler();
+ final FileObject out = filer.createSourceFile(
+ "net.geant.perfsonar.LookupServiceRegister",
+ elements.toArray(new Element[0]));
+ return out.openWriter();
+ }
+
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/TemplateEngine.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/TemplateEngine.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls/TemplateEngine.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,42 @@
+package net.geant.perfsonar.annotations.ls;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.lang.model.element.ExecutableElement;
+
+public class TemplateEngine {
+ private Writer writer;
+
+ private void write(String text) throws IOException {
+ writer.write(text);
+ }
+
+ public void writeHandler(Writer writer, ExecutableElement handler)
throws IOException {
+ this.writer = writer;
+
+ write("package net.geant.perfsonar;\n\n");
+
+ write("import static net.geant.perfsonar.Configuration.*;\n");
+ write("import javax.annotation.Generated;\n");
+ write("\n");
+ write("@Generated(\"" + getClass().getName() + "\")\n");
+ write("public class LookupServiceRegister {\n");
+ write("\n");
+ write(" static {\n");
+ write(" try {\n");
+ writeHandlerInvocation(handler);
+ write(" } catch (Exception ex) { }\n");
+ write(" }\n");
+ write("}\n");
+ }
+
+ private void writeHandlerInvocation(ExecutableElement method) throws
IOException {
+ write(" ");
+ write("configure(registerToLookupService(");
+ write(method.getEnclosingElement().asType().toString());
+ write(".class).");
+ write(method.getSimpleName().toString());
+ write("());\n");
+ }
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/RequestProcessor.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/RequestProcessor.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/RequestProcessor.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,128 @@
+package net.geant.perfsonar.annotations.request;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.tools.FileObject;
+
+import net.geant.perfsonar.annotations.selftest.SelfTestProcessorListener;
+import
net.geant.perfsonar.annotations.selftest.SelfTestProcessorListenerImpl;
+
+@SupportedAnnotationTypes(RequestProcessor.ANNOTATION_PREFIX
+ ".*")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class RequestProcessor extends AbstractProcessor {
+ static final String ANNOTATION_PREFIX =
"net.geant.perfsonar.annotations.request";
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+
+ if (annotations.size() <= 0)
+ return false;
+
+ final SelfTestProcessorListener reporter = new
SelfTestProcessorListenerImpl(
+ processingEnv.getMessager());
+ final Map<String, ExecutableElement> handlers = new
Hashtable<String, ExecutableElement>();
+
+ for (Element root : roundEnv.getRootElements()) {
+ for (Element method : root.getEnclosedElements()) {
+ for (AnnotationMirror annotation : method
+ .getAnnotationMirrors())
+ if (getName(annotation).startsWith(
+
RequestProcessor.ANNOTATION_PREFIX)) {
+ if
(isDeclarationViolated((ExecutableElement) method,
+ reporter))
+ continue;
+ handlers.put(
+
getName(annotation).substring(
+
RequestProcessor.ANNOTATION_PREFIX
+
.length() + 1)
+
+ "Request", (ExecutableElement) method);
+ }
+ }
+ }
+
+ Writer writer = null;
+ try {
+ writer = openWriter(roundEnv.getRootElements());
+ new TemplateEngine().writeHandlers(writer, handlers);
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ } finally {
+ if (writer != null)
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ }
+ }
+
+ return false;
+ }
+
+ private String getName(AnnotationMirror annotation) {
+ return annotation.getAnnotationType().toString();
+ }
+
+ protected boolean isDeclarationViolated(ExecutableElement elem,
+ SelfTestProcessorListener listener) {
+ int errorsCount = 0;
+
+ if (elem.getModifiers().contains(Modifier.ABSTRACT)) {
+ listener.error("The method cannot be abstract", elem);
+ errorsCount++;
+ }
+
+ if (!elem.getModifiers().contains(Modifier.PUBLIC)) {
+ listener.error("The method must be public.", elem);
+ errorsCount++;
+ }
+
+ if (elem.getModifiers().contains(Modifier.STATIC)) {
+ listener.error("The method cannot be static.", elem);
+ errorsCount++;
+ }
+
+ if (elem.getReturnType().getKind() == TypeKind.VOID) {
+ listener.error("Type of the method cannot be void.",
elem);
+ errorsCount++;
+ }
+
+ if (elem.getModifiers().contains(Modifier.FINAL)) {
+ listener.error("The method cannot be final.", elem);
+ errorsCount++;
+ }
+
+ if (elem.isVarArgs() || (elem.getParameters().size() > 1)) {
+ listener.error("The method cannot have more than one
parameter.",
+ elem);
+ errorsCount++;
+ }
+
+ return (errorsCount > 0);
+ }
+
+ private Writer openWriter(Set<? extends Element> elements)
+ throws IOException {
+ final Filer filer = processingEnv.getFiler();
+ final FileObject out = filer.createSourceFile(
+ "net.geant.perfsonar.Handlers",
+ elements.toArray(new Element[0]));
+ return out.openWriter();
+ }
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/TemplateEngine.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/TemplateEngine.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request/TemplateEngine.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,55 @@
+package net.geant.perfsonar.annotations.request;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import javax.lang.model.element.ExecutableElement;
+
+public class TemplateEngine {
+ private Writer writer;
+
+ private void write(String text) throws IOException {
+ writer.write(text);
+ }
+
+ public void writeHandlers(Writer writer, Map<String,
ExecutableElement> handlers) throws IOException {
+ this.writer = writer;
+
+ write("package net.geant.perfsonar;\n\n");
+
+ write("import static net.geant.perfsonar.Configuration.*;\n");
+ write("import javax.annotation.Generated;\n");
+ write("\n");
+ write("@Generated(\"" + getClass().getName() + "\")\n");
+ write("public class Handlers {\n");
+ write("\n");
+ write(" static {\n");
+ write(" try {\n");
+ writeHandlerInvocations(handlers);
+ write(" } catch (Exception ex) { }\n");
+ write(" }\n");
+ write("}\n");
+ }
+
+ private void writeHandlerInvocations(Map<String, ExecutableElement>
handlers) throws IOException {
+ for (String request : handlers.keySet()) {
+ final ExecutableElement method =
handlers.get(request);
+
+ write(" ");
+ write("configure(when(\"");
+ write(request);
+ write("\").then(");
+
write(method.getEnclosingElement().asType().toString());
+ write(".class).");
+ write(method.getSimpleName().toString());
+ if (method.getParameters().size() <= 0)
+ write("());\n");
+ else {
+ write("(any(");
+
write(method.getParameters().get(0).asType().toString());
+ write(".class)));\n");
+ }
+ }
+ }
+}

Modified:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessor.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessor.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessor.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -85,7 +85,7 @@
if (!checker.isEnclosingClassAbstract(method))
result.put(name, method);
else
- reporter.error("The class containing self
test cannot be abstract.", checker.getEnclosingType(method));
+ reporter.error("The class cannot be
abstract.", checker.getEnclosingType(method));
}

return result;

Modified:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListener.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListener.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListener.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -2,7 +2,7 @@

import javax.lang.model.element.Element;

-interface SelfTestProcessorListener {
+public interface SelfTestProcessorListener {
void error(String message);
void error(String message, Element element);
}

Modified:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListenerImpl.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListenerImpl.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorListenerImpl.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -8,7 +8,7 @@

private Messager messager;

- protected SelfTestProcessorListenerImpl(Messager messager) {
+ public SelfTestProcessorListenerImpl(Messager messager) {
this.messager = messager;
}


Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/TemplateEngine.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/TemplateEngine.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/TemplateEngine.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,62 @@
+package net.geant.perfsonar.annotations.xpath;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import javax.lang.model.element.ExecutableElement;
+
+import net.geant.perfsonar.annotations.XPath;
+import net.geant.perfsonar.annotations.Namespace;
+
+public class TemplateEngine {
+ private Writer writer;
+
+ private void write(String text) throws IOException {
+ writer.write(text);
+ }
+
+ public void writeXPaths(Writer writer, Map<String, ExecutableElement>
xpaths) throws IOException {
+ this.writer = writer;
+
+ write("package net.geant.perfsonar;\n\n");
+ write("import static
net.geant.perfsonar.xpath.XPathDeserializer.any;\n");
+ write("import static
net.geant.perfsonar.xpath.XPathDeserializer.declarePrefix;\n");
+ write("import static
net.geant.perfsonar.xpath.XPathDeserializer.whenXPath;\n");
+ write("import javax.annotation.Generated;\n");
+ write("\n");
+ write("@Generated(\"" + getClass().getName() + "\")\n");
+ write("public class XPaths {\n");
+ write("\n");
+ write(" static {\n");
+ write(" try {\n");
+ writeXPathInvocations(xpaths);
+ write(" } catch (Exception ex) { }\n");
+ write(" }\n");
+ write("}\n");
+ }
+
+ private void writeXPathInvocations(Map<String, ExecutableElement>
xpaths) throws IOException {
+ for (String xpath : xpaths.keySet()) {
+ final ExecutableElement method = xpaths.get(xpath);
+
+ for (Namespace namespace :
method.getAnnotation(XPath.class).namespaces()) {
+ write(" ");
+ write("declarePrefix(\"");
+ write(namespace.prefix());
+ write("\", \"");
+ write(namespace.uri());
+ write("\");\n");
+ }
+
+ write(" ");
+ write("whenXPath(\"");
+ write(xpath);
+ write("\").then(");
+
write(method.getEnclosingElement().asType().toString());
+ write(".class).");
+ write(method.getSimpleName().toString());
+ write("(any(String.class));\n");
+ }
+ }
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathCollector.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathCollector.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathCollector.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,63 @@
+package net.geant.perfsonar.annotations.xpath;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.type.TypeKind;
+
+import net.geant.perfsonar.annotations.XPath;
+import net.geant.perfsonar.annotations.selftest.BaseMethodElementVisitor;
+import net.geant.perfsonar.annotations.selftest.SelfTestProcessorListener;
+
+public class XPathCollector extends BaseMethodElementVisitor<Map<String,
ExecutableElement>, SelfTestProcessorListener> {
+
+ private final Map<String, ExecutableElement> xpaths
+ = new Hashtable<String, ExecutableElement>();
+
+ protected XPathCollector(Map<String, ExecutableElement> xpaths) {
+
+ this.xpaths.putAll(xpaths);
+ }
+
+ @Override
+ public Map<String, ExecutableElement>
visitExecutable(ExecutableElement elem, SelfTestProcessorListener listener) {
+ if(isDeclarationViolated(elem, listener))
+ return xpaths;
+
+ xpaths.put(elem.getAnnotation(XPath.class).xpath(), elem);
+
+ return xpaths;
+ }
+
+ protected boolean isDeclarationViolated(ExecutableElement elem,
+ SelfTestProcessorListener listener) {
+ int errorsCount = 0;
+
+ if (super.isDeclarationViolated(elem, listener))
+ errorsCount++;
+
+ if (elem.getReturnType().getKind() != TypeKind.VOID) {
+ listener.error("Type of the method must be void.",
elem);
+ errorsCount++;
+ }
+
+ if (elem.getModifiers().contains(Modifier.FINAL)) {
+ listener.error("The method cannot be final.", elem);
+ errorsCount++;
+ }
+
+ if (elem.isVarArgs() || (elem.getParameters().size() > 1)) {
+ listener.error("The method cannot have more than one
parameter.", elem);
+ errorsCount++;
+ }
+
+ if ((elem.getParameters().size() < 1) ||
(!elem.getParameters().get(0).asType().toString().equals("java.lang.String")))
{
+ listener.error("The method must have exactly one
parameter of type java.lang.String", elem);
+ errorsCount++;
+ }
+
+ return (errorsCount > 0);
+ }
+}

Added:
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathProcessor.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathProcessor.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath/XPathProcessor.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,83 @@
+package net.geant.perfsonar.annotations.xpath;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.FileObject;
+
+import net.geant.perfsonar.annotations.XPath;
+import net.geant.perfsonar.annotations.selftest.AbstractClassChecker;
+import net.geant.perfsonar.annotations.selftest.SelfTestProcessorListener;
+import
net.geant.perfsonar.annotations.selftest.SelfTestProcessorListenerImpl;
+
+@SupportedAnnotationTypes("net.geant.perfsonar.annotations.XPath")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class XPathProcessor extends AbstractProcessor {
+ private Map<String, ExecutableElement> filter(Map<String,
ExecutableElement> xpaths, SelfTestProcessorListener reporter) {
+ final Map<String, ExecutableElement> result = new
Hashtable<String, ExecutableElement>();
+ final AbstractClassChecker checker = new
AbstractClassChecker();
+ for (String name : xpaths.keySet()) {
+ final ExecutableElement method = xpaths.get(name);
+ if (!checker.isEnclosingClassAbstract(method))
+ result.put(name, method);
+ else
+ reporter.error("The class cannot be
abstract.", checker.getEnclosingType(method));
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations,
+ RoundEnvironment roundEnv) {
+
+ if (annotations.size() <= 0)
+ return false;
+
+ final SelfTestProcessorListener reporter = new
SelfTestProcessorListenerImpl(processingEnv.getMessager());
+ final Map<String, ExecutableElement> xpaths = new
Hashtable<String, ExecutableElement>();
+
+ for (Element method : getXPaths(roundEnv)) {
+ xpaths.putAll(method.accept(new
XPathCollector(xpaths), reporter));
+ }
+
+ Writer writer = null;
+ try {
+ writer = openWriter(getXPaths(roundEnv));
+ new TemplateEngine().writeXPaths(writer,
filter(xpaths, reporter));
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ } finally {
+ if (writer != null)
+ try {
+ writer.close();
+ } catch (IOException ex) {
+ reporter.error(ex.toString());
+ }
+ }
+
+ return false;
+ }
+
+ private Writer openWriter(Set<? extends Element> elements) throws
IOException {
+ final Filer filer = processingEnv.getFiler();
+ final FileObject out =
filer.createSourceFile("net.geant.perfsonar.XPaths", elements.toArray(new
Element[0]));
+ return out.openWriter();
+ }
+
+ private Set<? extends Element> getXPaths(RoundEnvironment roundEnv) {
+ return roundEnv.getElementsAnnotatedWith(XPath.class);
+ }
+}

Modified:
trunk/psBase3/psbase3-apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
===================================================================
---
trunk/psBase3/psbase3-apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
2013-01-16 12:28:06 UTC (rev 6107)
@@ -1 +1,4 @@
net.geant.perfsonar.annotations.selftest.SelfTestProcessor
+net.geant.perfsonar.annotations.xpath.XPathProcessor
+net.geant.perfsonar.annotations.request.RequestProcessor
+net.geant.perfsonar.annotations.ls.LookupServiceRegisterProcessor

Added:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/LookupServiceRegisterProcessorTest.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/LookupServiceRegisterProcessorTest.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/LookupServiceRegisterProcessorTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,61 @@
+package net.geant.perfsonar.annotations;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.geant.perfsonar.Configuration;
+import net.geant.perfsonar.annotations.ls.LookupServiceRegisterProcessor;
+import net.geant.perfsonar.annotations.selftest.compiler.BinaryClassLoader;
+import net.geant.perfsonar.annotations.selftest.compiler.CompilerHelper;
+import net.geant.perfsonar.annotations.selftest.compiler.Diagnostics;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LookupServiceRegisterProcessorTest {
+ private static final String SAMPLES_PATH = "dummyservice";
+ final BinaryClassLoader classLoader = new
BinaryClassLoader(getClassPath());
+ private CompilerHelper compiler;
+
+ private static String[] getClassPath() {
+ final List<String> result = new ArrayList<String>();
+ for (String path :
System.getProperty("java.class.path").split(File.pathSeparator)) {
+ result.add(path);
+ }
+
+ result.add(CompilerHelper.ANNOTATED_SOURCE_OUTPUT);
+ result.add(SAMPLES_PATH);
+
+ return result.toArray(new String[0]);
+ }
+
+ @Before
+ public void givenCompiler() throws Exception {
+ compiler = new CompilerHelper(SAMPLES_PATH, new
LookupServiceRegisterProcessor());
+ }
+
+ @After
+ public void finalizeCompiler() throws IOException {
+ compiler.close();
+ compiler = null;
+ }
+
+ @Test
+ public void shouldCompileController() {
+ assertEquals(Diagnostics.EMPTY,
+
compiler.compile("/net/geant/perfsonar/dummyservice/ServiceController.java"));
+ }
+
+ @Test
+ public void shouldConfigureLookupServiceHandler() throws Exception {
+
compiler.compile("/net/geant/perfsonar/dummyservice/ServiceController.java");
+
classLoader.loadClass("net.geant.perfsonar.LookupServiceRegister").newInstance();
+ assertNotNull(Configuration.getHandler("LSRegister"));
+ }
+}

Added:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/RequestProcessorTest.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/RequestProcessorTest.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/RequestProcessorTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,69 @@
+package net.geant.perfsonar.annotations;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.geant.perfsonar.Configuration;
+import net.geant.perfsonar.annotations.request.RequestProcessor;
+import net.geant.perfsonar.annotations.selftest.compiler.BinaryClassLoader;
+import net.geant.perfsonar.annotations.selftest.compiler.CompilerHelper;
+import net.geant.perfsonar.annotations.selftest.compiler.Diagnostics;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RequestProcessorTest {
+ private static final String SAMPLES_PATH = "dummyservice";
+ final BinaryClassLoader classLoader = new
BinaryClassLoader(getClassPath());
+ private CompilerHelper compiler;
+
+ private static String[] getClassPath() {
+ final List<String> result = new ArrayList<String>();
+ for (String path :
System.getProperty("java.class.path").split(File.pathSeparator)) {
+ result.add(path);
+ }
+
+ result.add(CompilerHelper.ANNOTATED_SOURCE_OUTPUT);
+ result.add(SAMPLES_PATH);
+
+ return result.toArray(new String[0]);
+ }
+
+ @Before
+ public void givenCompiler() throws Exception {
+ compiler = new CompilerHelper(SAMPLES_PATH, new
RequestProcessor());
+ }
+
+ @After
+ public void finalizeCompiler() throws IOException {
+ compiler.close();
+ compiler = null;
+ }
+
+ @Test
+ public void shouldCompileController() {
+ assertEquals(Diagnostics.EMPTY,
+
compiler.compile("/net/geant/perfsonar/dummyservice/ServiceController.java"));
+ }
+
+ @Test
+ public void shouldConfigureSetupData() throws Exception {
+
compiler.compile("/net/geant/perfsonar/dummyservice/ServiceController.java");
+
classLoader.loadClass("net.geant.perfsonar.Handlers").newInstance();
+ assertNotNull(Configuration.getHandler("SetupDataRequest"));
+ }
+
+ @Test
+ public void shouldConfigureMetadataKey() throws Exception {
+
compiler.compile("/net/geant/perfsonar/dummyservice/ServiceController.java");
+
classLoader.loadClass("net.geant.perfsonar.Handlers").newInstance();
+ assertNotNull(Configuration.getHandler("MetadataKeyRequest"));
+ }
+
+}

Added:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/XPathProcessorTest.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/XPathProcessorTest.java
(rev 0)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/XPathProcessorTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -0,0 +1,130 @@
+package net.geant.perfsonar.annotations;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import net.geant.perfsonar.annotations.selftest.SelfTestLoggerHelper;
+import net.geant.perfsonar.annotations.selftest.compiler.BinaryClassLoader;
+import net.geant.perfsonar.annotations.selftest.compiler.CompilerHelper;
+import net.geant.perfsonar.annotations.selftest.compiler.Diagnostics;
+import net.geant.perfsonar.annotations.xpath.XPathProcessor;
+import net.geant.perfsonar.xpath.XPathDeserializer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+
+public class XPathProcessorTest {
+ private static final String SAMPLES_PATH = "dummyservice";
+ final BinaryClassLoader classLoader = new
BinaryClassLoader(getClassPath());
+ private CompilerHelper compiler;
+
+ final SelfTestLoggerHelper logger = new SelfTestLoggerHelper();
+
+ private static String[] getClassPath() {
+ final List<String> result = new ArrayList<String>();
+ for (String path :
System.getProperty("java.class.path").split(File.pathSeparator)) {
+ result.add(path);
+ }
+
+ result.add(CompilerHelper.ANNOTATED_SOURCE_OUTPUT);
+ result.add(SAMPLES_PATH);
+
+ return result.toArray(new String[0]);
+ }
+
+ @Before
+ public void givenCompiler() throws Exception {
+ compiler = new CompilerHelper(SAMPLES_PATH, new
XPathProcessor());
+ }
+
+ @After
+ public void finalizeCompiler() throws IOException {
+ compiler.close();
+ compiler = null;
+ }
+
+ @Test
+ public void shouldCompileValidXPaths() {
+ assertEquals(Diagnostics.EMPTY,
+
compiler.compile("/net/geant/perfsonar/dummyservice/xpath/NMWGMessage.java"));
+ }
+
+ @Test
+ public void shouldNotCompileAbstractClass() {
+ assertEquals(
+ new Diagnostics()
+ .addAbstractClassViolationAtLine(6),
+
+
compiler.compile("/net/geant/perfsonar/dummyservice/xpath/InvalidXPathsAbstractClass.java"));
+ }
+
+ @Test
+ public void shouldNotCompileInvalidXPaths() {
+ assertEquals(
+ new Diagnostics()
+ .addAbstractMethodViolationAtLine(14)
+ .addNumberOfParametersViolationAtLine(18)
+ .addStaticMethodViolationAtLine(23)
+ .addRangeViolationAtLine(23)
+ .addSetterArgumentTypeViolationAtLine(28)
+ .addSetterReturnTypeViolationAtLine(33),
+
+
compiler.compile("/net/geant/perfsonar/dummyservice/xpath/InvalidXPaths.java"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void shouldDeserializeNMWGMessage() throws Exception {
+ compiler.compile(
+
"/net/geant/perfsonar/dummyservice/xpath/NMWGMessage.java",
+
"/net/geant/perfsonar/dummyservice/xpath/EchoMessage.java");
+
+
classLoader.loadClass("net.geant.perfsonar.XPaths").newInstance();
+
+ final Class<?> nmwgClass =
classLoader.loadClass("net.geant.perfsonar.dummyservice.xpath.NMWGMessage");
+ final Class<?> echoClass =
classLoader.loadClass("net.geant.perfsonar.dummyservice.xpath.EchoMessage");
+
+ final XPathDeserializer deserializer = new
XPathDeserializer();
+ final List<Object> objects = (List<Object>)
deserializer.deserialize(new InputSource(toEchoRequest("request1")));
+ Object msg = getObjects(nmwgClass, objects).get(0);
+ Object echo = getObjects(echoClass, objects).get(0);
+
+ assertEquals("request1",
msg.getClass().getMethod("getId").invoke(msg));
+ assertEquals("EchoRequest",
msg.getClass().getMethod("getType").invoke(msg));
+
assertEquals("http://schemas.perfsonar.net/tools/admin/echo/2.0";,
echo.getClass().getMethod("getEventType").invoke(echo));
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> List<T> getObjects(Class<T> type, List<Object> objects) {
+ final List<T> result = new ArrayList<T>();
+ for (Object obj : objects) {
+ if (obj.getClass().equals(type)) {
+ result.add((T) obj);
+ }
+ }
+ return result;
+ }
+
+ private Reader toEchoRequest(String id) {
+ final StringWriter writer = new StringWriter();
+ writer.write("<?xml version='1.0' encoding='UTF-8'?>");
+ writer.write("<nmwg:message
xmlns:nmwg='http://ggf.org/ns/nmwg/base/2.0/' id='");
+ writer.write(id);
+ writer.write("' type='EchoRequest'>");
+ writer.write("<nmwg:metadata id='meta'>");
+
writer.write("<nmwg:eventType>http://schemas.perfsonar.net/tools/admin/echo/2.0</nmwg:eventType>");
+ writer.write("</nmwg:metadata>");
+ writer.write("<nmwg:data id='data' metadataIdRef='meta' />");
+ writer.write("</nmwg:message>");
+ return new StringReader(writer.toString());
+ }
+}

Modified:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorTest.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorTest.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/SelfTestProcessorTest.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -27,6 +27,10 @@
public void runInParallel(Runnable runnable) {
runnable.run();
}
+
+ @Override
+ public void runEvery(int seconds, Runnable task) {
+ }
};
final SelfTestLoggerHelper logger = new SelfTestLoggerHelper();


Modified:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/CompilerHelper.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/CompilerHelper.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/CompilerHelper.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -38,9 +38,14 @@
// return compile(clazz.getSimpleName() + ".java");
//}

- public List<Diagnostic<? extends JavaFileObject>> compile(String
fileName) {
+ public List<Diagnostic<? extends JavaFileObject>> compile(String...
fileNames) {
+ final List<String> absoluteNames = new ArrayList<String>();
+
+ for (String fileName : fileNames)
+ absoluteNames.add(path + fileName);
+
final Iterable<? extends JavaFileObject> compilationUnits =
- fileManager.getJavaFileObjectsFromStrings(Arrays.asList(path
+ fileName));
+ fileManager.getJavaFileObjectsFromStrings(absoluteNames);

CompilationTask task =
compiler.getTask(null, fileManager, diagnostics, null, null,
compilationUnits);

Modified:
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/Diagnostics.java
===================================================================
---
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/Diagnostics.java
2013-01-16 12:10:58 UTC (rev 6106)
+++
trunk/psBase3/psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler/Diagnostics.java
2013-01-16 12:28:06 UTC (rev 6107)
@@ -29,7 +29,7 @@
}

public Diagnostics addAbstractClassViolationAtLine(int lineNumber) {
- return add(lineNumber, "The class containing self test cannot
be abstract.");
+ return add(lineNumber, "The class cannot be abstract.");
}

// public Diagnostics addSelfTestReturnTypeViolation(int lineNumber) {
@@ -43,6 +43,10 @@
public Diagnostics addRangeViolationAtLine(int lineNumber) {
return add(lineNumber, "The method must be public.");
}
+
+ public Diagnostics addSetterViolationAtLine(int lineNumber) {
+ return add(lineNumber, "The method must have one parameter.");
+ }

public Diagnostics addNumberOfParametersViolationAtLine(int
lineNumber) {
return add(lineNumber, "The method cannot have more than one
parameter.");
@@ -60,7 +64,15 @@
return add(lineNumber, "There are no self test data provided.
Add a public method annotatated with @SelfTestData of return type
java.util.List<java.lang.Integer>");
}

- public Object addSelfTestDataReturnTypeViolationAtLine(int
lineNumber) {
+ public Diagnostics addSelfTestDataReturnTypeViolationAtLine(int
lineNumber) {
return add(lineNumber, "The return type of the method must be
of type java.util.List<E>");
}
+
+ public Diagnostics addSetterReturnTypeViolationAtLine(int lineNumber)
{
+ return add(lineNumber, "Type of the method must be void.");
+ }
+
+ public Diagnostics addSetterArgumentTypeViolationAtLine(int
lineNumber) {
+ return add(lineNumber, "The method must have exactly one
parameter of type java.lang.String");
+ }
}



  • [pS-dev] [GEANT/SA2/ps-java-services] r6107 - in trunk/psBase3: perfsonar-base/src/main/java/net/geant/perfsonar perfsonar-base/src/main/java/net/geant/perfsonar/nmwg/response perfsonar-base/src/main/java/net/geant/perfsonar/xpath perfsonar-base/src/test/java/net/geant/perfsonar perfsonar-base/src/test/java/net/geant/perfsonar/helpers perfsonar-base/src/test/java/net/geant/perfsonar/mp/sshtelnet perfsonar-base/src/test/java/net/geant/perfsonar/xpath perfsonar-base/src/test/resources perfsonar-base/src/test/resources/net/geant/perfsonar/mp/sshtelnet psbase3-apt psbase3-apt/dummyservice/net/geant/perfsonar/dummyservice psbase3-apt/src/main/java/net/geant/perfsonar/annotations psbase3-apt/src/main/java/net/geant/perfsonar/annotations/ls psbase3-apt/src/main/java/net/geant/perfsonar/annotations/request psbase3-apt/src/main/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/main/java/net/geant/perfsonar/annotations/xpath psbase3-apt/src/main/resources/META-INF/services psbase3-apt/src/test/java/net/geant/perfsonar/annotations psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest psbase3-apt/src/test/java/net/geant/perfsonar/annotations/selftest/compiler, svn-noreply, 01/16/2013

Archive powered by MHonArc 2.6.16.

Top of Page