4 Replies Latest reply on Oct 24, 2016 9:02 PM by rjwalker

    Deploying a helper WAR and finding its URL

    rjwalker

      Hi, I've been using Arquillian to test part of the functionality of my web application, and it has worked well for me so far. I'm using an embedded Tomcat server as my container.

       

      Now I want to test another part of the functionality, that relies on access to a running instance of OpenRDF Sesame, now known as RDF4J Server. What that is doesn't matter; think of it as another web application for which I have a WAR file that needs to be deployed in advance to a servlet container.

       

      So before deploying my own test archive, I want to deploy this "helper" WAR file to the embedded Tomcat server I'm already using, and I want to configure my own web app to point to the URL of the deployed RDF4J Server.

       

      What is "best practice" for this? (Or, I guess in the first instance I'd be helpful for any way of doing this.)

       

      The documentation seemed to point in the direction of defining another @Deployment, thus:

       

          /** Create deployment for OpenRDF Sesame.
            * @return The OpenRDF Sesame WebArchive to be deployed prior to testing.
            */
           @Deployment(name = "Sesame", order = 1)
           public static WebArchive getSesameWAR() {
               return ShrinkWrap.create(ZipImporter.class,
                       "openrdf-sesame.war").
                       importFrom(new File(
                               "openrdf-sesame.war")).
                       as(WebArchive.class);
           }

       

      ... and then to set "order = 2" on my existing deployment:

       

          /** Create deployment for testing.
            * @return The WebArchive to be deployed for testing.
            */
           @Deployment(order = 2)
           public static WebArchive createTestArchive() {
               WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
                       .addPackages(true, .... etc. ...

       

       

      So far so good, but ... inside the method createTestArchive(), how do I get the URL of the already-deployed Sesame web application? I need it in order to customize a configuration file that gets deployed as part of my test archive.

       

      I can't see how to use injection to do this. This doesn't help:

       

          /** URL to the deployed Sesame server. */
           @ArquillianResource @OperateOnDeployment("Sesame")
           private URL sesameDeploymentURL;

       

      because @Deployment methods are static, so createTestArchive() can't refer to non-static field sesameDeploymentURL. And injected parameters are not allowed for @Deployment methods either.

        • 1. Re: Deploying a helper WAR and finding its URL
          bmajsak

          Try to make your Sesame deployment as `testable=false`. It worked for me with 3 or more deployments and URL injections. But I'm surprised it's not working in a shape you posted... Makes me wonder if it's a bug... Can you see the successful deployment of this new app in your embedded tomcat?

           

          You can also simplify your Sesame deployment method to:

           

          ShrinkWrap.createFromZipFile(WebArchive.class, new File("openrdf-sesame.war"));

          • 2. Re: Deploying a helper WAR and finding its URL
            rjwalker

            Bartosz Majsak wrote:

             

            Can you see the successful deployment of this new app in your embedded tomcat?

            Yes, hence why I wrote "So far so good". There was no problem per se with getting the two Deployments deployed to Tomcat.

             

            My question was, and still is: "inside the method createTestArchive(), how do I get the URL of the already-deployed Sesame web application?".

             

            You can also simplify your Sesame deployment method to:

             

            ShrinkWrap.createFromZipFile(WebArchive.class, new File("openrdf-sesame.war"));

             

            Thank you for that tip.

            • 3. Re: Deploying a helper WAR and finding its URL
              mjobanek

              Hi,

              by default, there is no feature that could ensure it - injection between two deployment. The reason is that all managed deployments are deployed in the same phase and injection is performed afterwards (before each test method).

               

              There is a way to do a similar thing, but doesn't solve your problem - getting the urlSesame in the createTestArchive method:

              let the first deployment being deployed automatically. The second one mark as manual and somehow name the deployment (name="test", managed=false), which means that this deployment with name "test" will be managed by you. Then inject a Deployer which is a helper class for managing manual deployments. Then, in the first test, the URL of the first deployment is already known, so you can deploy the second deployment. Then perform all tests and don't forget to undeploy  the second deployment in the last test.

               

              An example:

               

                   @Deployment(name = "Sesame")
                   public static WebArchive getSesameWAR() {
                       return ShrinkWrap.create(WebArchive.class);
                   }
              
                   @Deployment(name = "test", managed = false)
                   public static WebArchive createTestArchive() {
                       return ShrinkWrap.create(WebArchive.class);
                   }
              
                   @ArquillianResource
                   @OperateOnDeployment("Sesame")
                   private URL urlSesame;
              
                   @ArquillianResource
                   private Deployer deployer;
              
                   @Test
                   @InSequence(1)
                   public void testDeploy() {
                       assertNotNull(urlSesame);
                       deployer.deploy("test");
                   } 
              
                   @Test
                   @InSequence(2)
                   public void runTest(@ArquillianResource @OperateOnDeployment("test") URL urlSecond) {
                       assertNotNull(urlSesame);
                       assertNotNull(urlSecond);
                   } 
              
                   @Test
                   @InSequence(3)
                   public void testUndeploy() { 
                      deployer.undeploy("test");
                   }
              
              
              1 of 1 people found this helpful
              • 4. Re: Deploying a helper WAR and finding its URL
                rjwalker

                OK, I see, thank you.

                 

                One can't access urlSesame directly within createTestArchive(), so I guess one also has to add another static field, and then, within testDeploy(), copy the value of urlSesame into it before the call to deployer.deploy().

                 

                In the mean time, I worked around my problem by starting another embedded Tomcat instance within my @BeforeSuite (TestNG) method, and deploying Sesame to that instance. This is terrible, but (before your answer) it seemed to be the only way I could "inject" the URL of the deployed Sesame web app into the configuration of my own web app. (Of course, it does not use injection at all, just some settings in a configuration file read by both the @BeforeSuite method and my web app.)

                 

                But I'm not sure I want to change my code to add all those additional annotations to my test methods, so although my workaround is not so good, I think I will leave it until there's a better way (but recognizing that that may be a long wait).