diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 85416382fd..ee8f684717 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -45,30 +45,6 @@ ${jersey.version} - - sonia.net.ahc - jersey-ahc-client - 1.0.2.1 - - - jaxb-api - javax.xml.bind - - - jaxb-impl - com.sun.xml.bind - - - stax-api - stax - - - jersey-json - com.sun.jersey - - - - diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java index 8c38f83eb1..48111de0d8 100644 --- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java +++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java @@ -38,9 +38,6 @@ package sonia.scm.client; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonatype.spice.jersey.client.ahc.AhcHttpClient; -import org.sonatype.spice.jersey.client.ahc.config.DefaultAhcConfig; - import sonia.scm.ScmState; import sonia.scm.url.UrlProvider; import sonia.scm.url.UrlProviderFactory; @@ -49,11 +46,20 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.ClientRequest; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.ClientFilter; import com.sun.jersey.core.util.MultivaluedMapImpl; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.NewCookie; /** * @@ -100,7 +106,7 @@ public class JerseyClientProvider implements ScmClientProvider */ @Override public JerseyClientSession createSession(String url, String username, - String password) + String password) { AssertUtil.assertIsNotEmpty(url); @@ -111,59 +117,24 @@ public class JerseyClientProvider implements ScmClientProvider user = username; } - if (logger.isInfoEnabled()) - { - logger.info("create new session for {} with username {}", url, user); - } + logger.info("create new session for {} with username {}", url, user); UrlProvider urlProvider = UrlProviderFactory.createUrlProvider(url, UrlProviderFactory.TYPE_RESTAPI_XML); - DefaultAhcConfig config = new DefaultAhcConfig(); - AhcHttpClient client = AhcHttpClient.create(config); - ClientResponse response = null; + + Client client = Client.create(); + + client.addFilter(new CookieClientFilter()); + + ClientResponse response; if (Util.isNotEmpty(username) && Util.isNotEmpty(password)) { - String authUrl = urlProvider.getAuthenticationUrl(); - - if (logger.isDebugEnabled()) - { - logger.debug("try login at {}", authUrl); - } - - WebResource resource = ClientUtil.createResource(client, authUrl, - enableLogging); - - if (logger.isDebugEnabled()) - { - logger.debug("try login for {}", username); - } - - MultivaluedMap formData = new MultivaluedMapImpl(); - - formData.add("username", username); - formData.add("password", password); - response = resource.type("application/x-www-form-urlencoded").post( - ClientResponse.class, formData); + response = login(urlProvider, client, username, password); } else { - String stateUrl = urlProvider.getStateUrl(); - - if (logger.isDebugEnabled()) - { - logger.debug("retrive state from {}", stateUrl); - } - - WebResource resource = ClientUtil.createResource(client, stateUrl, - enableLogging); - - if (logger.isDebugEnabled()) - { - logger.debug("try anonymous login"); - } - - response = resource.get(ClientResponse.class); + response = state(urlProvider, client); } ClientUtil.checkResponse(response); @@ -172,10 +143,7 @@ public class JerseyClientProvider implements ScmClientProvider if (!state.isSuccess()) { - if (logger.isWarnEnabled()) - { - logger.warn("server returned state failed"); - } + logger.warn("server returned state failed"); throw new ScmClientException("create ScmClientSession failed"); } @@ -187,6 +155,122 @@ public class JerseyClientProvider implements ScmClientProvider return new JerseyClientSession(client, urlProvider, state); } + /** + * Method description + * + * + * @param urlProvider + * @param client + * @param username + * @param password + * + * @return + */ + private ClientResponse login(UrlProvider urlProvider, Client client, + String username, String password) + { + String authUrl = urlProvider.getAuthenticationUrl(); + + if (logger.isDebugEnabled()) + { + logger.debug("try login at {}", authUrl); + } + + WebResource resource = ClientUtil.createResource(client, authUrl, + enableLogging); + + if (logger.isDebugEnabled()) + { + logger.debug("try login for {}", username); + } + + MultivaluedMap formData = new MultivaluedMapImpl(); + + formData.add("username", username); + formData.add("password", password); + + return resource.type("application/x-www-form-urlencoded").post( + ClientResponse.class, formData); + } + + /** + * Method description + * + * + * @param urlProvider + * @param client + * + * @return + */ + private ClientResponse state(UrlProvider urlProvider, Client client) + { + String stateUrl = urlProvider.getStateUrl(); + + if (logger.isDebugEnabled()) + { + logger.debug("retrive state from {}", stateUrl); + } + + WebResource resource = ClientUtil.createResource(client, stateUrl, + enableLogging); + + if (logger.isDebugEnabled()) + { + logger.debug("try anonymous login"); + } + + return resource.get(ClientResponse.class); + } + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 14/07/05 + * @author Enter your name here... + */ + private class CookieClientFilter extends ClientFilter + { + + /** + * Method description + * + * + * @param request + * + * @return + * + * @throws ClientHandlerException + */ + @Override + public ClientResponse handle(ClientRequest request) + throws ClientHandlerException + { + for (NewCookie c : cookies) + { + request.getHeaders().putSingle("Cookie", c); + } + + ClientResponse response = getNext().handle(request); + + if (response.getCookies() != null) + { + cookies.addAll(response.getCookies()); + } + + return response; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private final List cookies = + Collections.synchronizedList(new ArrayList()); + } + + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 0f7fbbf822..1a11d56e6e 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -55,6 +55,7 @@ import sonia.scm.event.ScmEventBus; import sonia.scm.filter.AdminSecurityFilter; import sonia.scm.filter.BaseUrlFilter; import sonia.scm.filter.GZipFilter; +import sonia.scm.filter.MDCFilter; import sonia.scm.filter.SecurityFilter; import sonia.scm.group.DefaultGroupManager; import sonia.scm.group.GroupDAO; @@ -360,6 +361,9 @@ public class ScmServletModule extends ServletModule filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(SecurityFilter.class); filter(PATTERN_CONFIG, PATTERN_ADMIN).through(AdminSecurityFilter.class); + // added mdcs for logging + filter(PATTERN_ALL).through(MDCFilter.class); + // debug servlet serve(PATTERN_DEBUG).with(DebugServlet.class); diff --git a/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java new file mode 100644 index 0000000000..6630543bc3 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/filter/MDCFilter.java @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.filter; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Singleton; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +import org.slf4j.MDC; + +import sonia.scm.SCMContext; +import sonia.scm.web.filter.HttpFilter; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Sebastian Sdorra + */ +@Singleton +public class MDCFilter extends HttpFilter +{ + + /** Field description */ + private static final String MDC_CLIEN_HOST = "client_host"; + + /** Field description */ + private static final String MDC_CLIEN_IP = "client_ip"; + + /** Field description */ + private static final String MDC_USERNAME = "username"; + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param response + * @param chain + * + * @throws IOException + * @throws ServletException + */ + @Override + protected void doFilter(HttpServletRequest request, + HttpServletResponse response, FilterChain chain) + throws IOException, ServletException + { + MDC.put(MDC_USERNAME, getUsername()); + MDC.put(MDC_CLIEN_IP, request.getRemoteAddr()); + MDC.put(MDC_CLIEN_HOST, request.getRemoteHost()); + + try + { + chain.doFilter(request, response); + } + finally + { + MDC.remove(MDC_USERNAME); + MDC.remove(MDC_CLIEN_IP); + MDC.remove(MDC_CLIEN_HOST); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + private String getUsername() + { + Subject subject = SecurityUtils.getSubject(); + String username; + Object principal = subject.getPrincipal(); + + if (principal == null) + { + username = SCMContext.USER_ANONYMOUS; + } + else + { + username = principal.toString(); + } + + return username; + } +}