#!/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); } } }""")