View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.shiro.testing.web;
20  
21  import org.apache.shiro.codec.Base64;
22  
23  import com.gargoylesoftware.htmlunit.WebClient;
24  import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
25  import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
26  import org.eclipse.jetty.annotations.AnnotationConfiguration;
27  import org.eclipse.jetty.server.Server;
28  import org.eclipse.jetty.util.resource.FileResource;
29  import org.eclipse.jetty.webapp.Configuration;
30  import org.eclipse.jetty.webapp.FragmentConfiguration;
31  import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
32  import org.eclipse.jetty.webapp.MetaInfConfiguration;
33  import org.eclipse.jetty.webapp.WebAppContext;
34  import org.eclipse.jetty.webapp.WebInfConfiguration;
35  import org.eclipse.jetty.webapp.WebXmlConfiguration;
36  import org.junit.AfterClass;
37  import org.junit.Before;
38  import org.junit.BeforeClass;
39  
40  import java.io.File;
41  import java.io.FilenameFilter;
42  import java.io.UnsupportedEncodingException;
43  
44  import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
45  import static org.eclipse.jetty.util.resource.Resource.newResource;
46  import static org.junit.Assert.assertEquals;
47  import static org.junit.Assert.assertTrue;
48  
49  public abstract class AbstractContainerIT {
50  
51      protected static EmbeddedJetty jetty;
52  
53      protected final WebClient webClient = new WebClient();
54  
55      @BeforeClass
56      public static void startContainer() throws Exception {
57  
58          EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
59                  .withWebapp(getWarDir())
60                  .build();
61  
62          jetty = new EmbeddedJetty(config) {
63  
64              /**
65               * Overriding with contents of this pull request, to make fragment scanning work.
66               * https://github.com/mjeanroy/junit-servers/pull/3
67               */
68              protected WebAppContext createdWebAppContext() throws Exception {
69                  final String path = configuration.getPath();
70                  final String webapp = configuration.getWebapp();
71                  final String classpath = configuration.getClasspath();
72  
73                  WebAppContext ctx = new WebAppContext();
74                  ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
75                  ctx.setContextPath(path);
76  
77                  // Useful for WebXmlConfiguration
78                  ctx.setBaseResource(newResource(webapp));
79  
80                  ctx.setConfigurations(new Configuration[]{
81                          new WebInfConfiguration(),
82                          new WebXmlConfiguration(),
83                          new AnnotationConfiguration(),
84                          new JettyWebXmlConfiguration(),
85                          new MetaInfConfiguration(),
86                          new FragmentConfiguration(),
87                  });
88  
89                  if (isNotBlank(classpath)) {
90                      // Fix to scan Spring WebApplicationInitializer
91                      // This will add compiled classes to jetty classpath
92                      // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
93                      // And more precisely: http://stackoverflow.com/a/18449506/1215828
94                      File classes = new File(classpath);
95                      FileResource containerResources = new FileResource(classes.toURI());
96                      ctx.getMetaData().addContainerResource(containerResources);
97                  }
98  
99                  Server server = getDelegate();
100 
101                 ctx.setParentLoaderPriority(true);
102                 ctx.setWar(webapp);
103                 ctx.setServer(server);
104 
105                 // Add server context
106                 server.setHandler(ctx);
107 
108                 return ctx;
109             }
110         };
111 
112         jetty.start();
113 
114         assertTrue(jetty.isStarted());
115     }
116 
117     protected static String getBaseUri() {
118         return "http://localhost:" + jetty.getPort() + "/";
119     }
120 
121     protected static String getWarDir() {
122         File[] warFiles = new File("target").listFiles(new FilenameFilter() {
123             @Override
124             public boolean accept(File dir, String name) {
125                 return name.endsWith(".war");
126             }
127         });
128 
129         assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
130 
131         return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
132     }
133 
134     protected static String getBasicAuthorizationHeaderValue(String username, String password) throws UnsupportedEncodingException {
135         String authorizationHeader = username + ":" + password;
136         byte[] valueBytes;
137         valueBytes = authorizationHeader.getBytes("UTF-8");
138         authorizationHeader = new String(Base64.encode(valueBytes));
139         return "Basic " + authorizationHeader;
140     }
141 
142     @Before
143     public void beforeTest() {
144         webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
145     }
146 
147     @AfterClass
148     public static void stopContainer() {
149         if (jetty != null) {
150             jetty.stop();
151         }
152     }
153 }