#!/usr/bin/env python
# This script generates source files for testing primitive types in SOAP.
# To run it, simply invoke it without any arguments. It will generate several
# files in the Scala and Java client directory.
#
# e.g.
# $ python generate-primitives.py
import os
def gen(f, text):
f.write(text)
def genForPrimitives(f, text):
primitives = [
('boolean', 'java.lang.Boolean', 'true', 'true'),
('byte', 'java.lang.Byte', '1.toByte', '(byte) 1'),
('double', 'java.lang.Double', '1.0d', '1.0d'),
('float', 'java.lang.Float', '1.0f', '1.0f'),
('int', 'java.lang.Integer', '1', '1'),
('long', 'java.lang.Long', '1L', '1L'),
('short', 'java.lang.Short', '1.toShort', '(short) 1')
]
# p = primitive, b = box, s = Scala value, j = Java value
for p, b, s, j in primitives:
gen(f, text.format(p=p, b=b, s=s, j=j))
scriptDir = os.path.dirname(os.path.abspath(__file__))
pluginTestDir = os.path.abspath(os.path.join(scriptDir, '..', 'sbt-plugin', 'src', 'sbt-test', 'play-soap'))
print('Generating files in {}'.format(pluginTestDir))
for project in ['simple-client-scala-future', 'simple-client-play-java-future']:
#### primitives.wsdl ####
with open(os.path.join(pluginTestDir, project, 'conf', 'wsdls', 'primitives.wsdl'), 'w') as f:
gen(f,
"""
""")
genForPrimitives(f, """
""")
gen(f, """
""")
genForPrimitives(f, """
""")
genForPrimitives(f, """
""")
gen(f, """
""")
genForPrimitives(f, """
""")
gen(f, """
""")
genForPrimitives(f, """
""")
gen(f, """
""")
### Primitives.java ###
with open(os.path.join(pluginTestDir, project, 'app', 'play', 'soap', 'testservice', 'Primitives.java'), 'w') as f:
gen(f, """/*
* Copyright (C) 2015-2017 Lightbend Inc.
*/
package play.soap.testservice;
import javax.jws.WebParam;
import javax.jws.WebService;
import java.util.List;
/*
* THIS FILE IS AUTO GENERATED. DO NOT EDIT THIS FILE MANUALLY.
*
* Run 'generate-primitives.py' to regenerate it.
*/
@WebService(targetNamespace = "http://testservice.soap.play/primitives")
public interface Primitives {""")
genForPrimitives(f, """
public {p} {p}Op(@WebParam(name = "x") {p} x);
public java.util.List<{b}> {p}Sequence(@WebParam(name = "xs") {p} xs);
""")
gen(f, """
}""")
### PrimitivesImpl.java ###
with open(os.path.join(pluginTestDir, project, 'app', 'play', 'soap', 'testservice', 'PrimitivesImpl.java'), 'w') as f:
gen(f, """/*
* Copyright (C) 2015-2017 Lightbend Inc.
*/
package play.soap.testservice;
import javax.jws.WebParam;
import javax.jws.WebService;
import java.util.ArrayList;
import java.util.List;
/*
* THIS FILE IS AUTO GENERATED. DO NOT EDIT THIS FILE MANUALLY.
*
* Run 'generate-primitives.py' to regenerate it.
*/
@WebService(
targetNamespace = "http://testservice.soap.play/primitives",
endpointInterface = "play.soap.testservice.Primitives",
serviceName = "PrimitivesService", portName = "Primitives")
public class PrimitivesImpl implements Primitives {""")
genForPrimitives(f, """
@Override
public {p} {p}Op(@WebParam(name = "x") {p} x) {{
return x;
}}
@Override
public java.util.List<{b}> {p}Sequence(@WebParam(name = "xs") {p} xs) {{
return java.util.Arrays.<{b}>asList({j}, {j}, {j});
}}
""")
gen(f, """
}""")
### PrimitivesSpec.scala (Scala project only) ###
with open(os.path.join(pluginTestDir, "simple-client-scala-future", "tests", "play", "soap", "sbtplugin", "tester", "PrimitivesSpec.scala"), 'w') as f:
gen(f, """/*
* Copyright (C) 2015-2017 Lightbend Inc.
*/
package play.soap.sbtplugin.tester
import java.net.ServerSocket
import java.util.Arrays
import java.util.concurrent.atomic.AtomicBoolean
import javax.xml.ws.Endpoint
import javax.xml.ws.handler.soap._
import javax.xml.ws.handler.MessageContext
import org.apache.cxf.jaxws.EndpointImpl
import play.soap.testservice.client._
import scala.collection.JavaConverters._
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scala.reflect.ClassTag
import play.api.test._
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder
import play.soap.testservice.PrimitivesImpl
/*
* THIS FILE IS AUTO GENERATED. DO NOT EDIT THIS FILE MANUALLY.
*
* Run 'generate-primitives.py' to regenerate it.
*/
object PrimitivesSpec extends ServiceSpec {
sequential
"Primitives" should {
""")
genForPrimitives(f, """
"handle {p} ops" in withClient {{ client =>
await(client.{p}Op({s})) must_== {s}
}}
"handle {p} sequences" in withClient {{ client =>
await(client.{p}Sequence(Arrays.asList({s}, {s}))).toList must_== List({s}, {s}, {s})
}}""")
gen(f, """
}
override type ServiceClient = PrimitivesService
override type Service = Primitives
override implicit val serviceClientClass: ClassTag[PrimitivesService] = ClassTag(classOf[PrimitivesService])
override def getServiceFromClient(c: ServiceClient): Service = c.primitives
override def createServiceImpl(): Any = new PrimitivesImpl
val servicePath: String = "primitives"
}""")
### HelloWorldTest.java (Java project only) ###
with open(os.path.join(pluginTestDir, "simple-client-play-java-future", "tests", "play", "soap", "sbtplugin", "tester", "PrimitivesTest.java"), 'w') as f:
gen(f, """/*
* Copyright (C) 2015-2017 Lightbend Inc.
*/
package play.soap.sbtplugin.tester;
import java.lang.RuntimeException;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.function.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.namespace.QName;
import javax.xml.ws.Endpoint;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.*;
import org.apache.cxf.jaxws.EndpointImpl;
import org.junit.*;
import play.soap.testservice.client.*;
import play.Application;
import play.inject.guice.GuiceApplicationBuilder;
import java.util.concurrent.CompletionStage;
import static org.junit.Assert.*;
import static play.test.Helpers.*;
/*
* THIS FILE IS AUTO GENERATED. DO NOT EDIT THIS FILE MANUALLY.
*
* Run 'generate-primitives.py' to regenerate it.
*/
public class PrimitivesTest {
""")
genForPrimitives(f, """
@Test
public void {p}Op() {{
withClient(client ->
assertEquals(({b}) {j}, await(client.{p}Op({j})))
);
}}
@Test
public void {p}Sequence() {{
withClient(client ->
assertEquals(Arrays.asList({j}, {j}, {j}), await(client.{p}Sequence(Arrays.asList({j}, {j}))))
);
}}""")
gen(f, """
private static T await(CompletionStage promise) {
try {
return promise.toCompletableFuture().get(10, TimeUnit.SECONDS);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
private static void withClient(Consumer block) {
withApp(app -> {
Primitives client = app.injector().instanceOf(PrimitivesService.class).getPrimitives();
block.accept(client);
});
}
private static void withApp(Consumer block) {
withService(port -> {
GuiceApplicationBuilder builder = new GuiceApplicationBuilder()
.configure("play.soap.address", "http://localhost:"+port+"/primitives")
.configure("play.soap.debugLog", true);
Application app = builder.build();
running(app, () -> block.accept(app));
});
}
private static void withService(Consumer block) {
final int port = findAvailablePort();
final Endpoint endpoint = Endpoint.publish(
"http://localhost:"+port+"/primitives",
new play.soap.testservice.PrimitivesImpl());
try {
block.accept(port);
} finally {
endpoint.stop();
// Need to shutdown whole engine. Note, Jetty's shutdown doesn't seem to happen synchronously, have to wait
// a few seconds for the port to be released. This is why we use a different port each time.
((EndpointImpl) endpoint).getBus().shutdown(true);
}
}
private static int findAvailablePort() {
try {
final ServerSocket socket = new ServerSocket(0);
try {
return socket.getLocalPort();
} finally {
socket.close();
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}""")