/**
* Copyright (C) 2008 Progress Software, Inc. All rights reserved.
* http://fusesource.com
*
* The software in this package is published under the terms of the AGPL license
* a copy of which has been included with this distribution in the license.txt file.
*/
package org.fusesource.cloudmix.agent;
import java.net.URI;
import java.net.URLEncoder;
import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.fusesource.cloudmix.agent.security.PasswordProvider;
import org.fusesource.cloudmix.agent.security.SecurityUtils;
import org.fusesource.cloudmix.common.CloudmixHelper;
import org.fusesource.cloudmix.common.RuntimeURISyntaxException;
import org.fusesource.cloudmix.common.URIs;
import org.fusesource.cloudmix.common.jaxrs.JAXBContextResolver;
import org.fusesource.cloudmix.common.jaxrs.PropertiesProvider;
/**
* A useful base class for any RESTful client facacde.
*
* @version $Revision: 1.1 $
*/
public class RestClientSupport {
private static final transient Log LOG = LogFactory.getLog(RestClientSupport.class);
public static final String PROPERTY_REQUEST_READ_TIMEOUT = "cloudmix.rest.read.timeout";
public static final Integer DEFAULT_READ_TIMEOUT = Integer.getInteger(PROPERTY_REQUEST_READ_TIMEOUT, 0);
private Client client;
private URI rootUri;
private RestTemplate template = new RestTemplate();
private String username;
private PasswordProvider passwordProvider;
private String credentials;
private int readTimeout = DEFAULT_READ_TIMEOUT;
private boolean loggedNoPassword;
public RestClientSupport() {
}
@Override
public String toString() {
return "RestClient[rootUri: " + rootUri + "]";
}
public Client getClient(String credential) {
//TODO: find a way around the classloader magic to get this working in Karaf
ClassLoader old = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(HeaderDelegate.class.getClassLoader());
if (client == null) {
DefaultClientConfig config = new DefaultClientConfig();
config.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, Boolean.FALSE);
config.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, readTimeout);
config.getClasses().add(JAXBContextResolver.class);
config.getClasses().add(PropertiesProvider.class);
client = Client.create(config);
if (credential != null) {
client.addFilter(new AuthClientFilter(credential));
}
}
} finally {
Thread.currentThread().setContextClassLoader(old);
}
return client;
}
public void setClient(Client client) {
this.client = client;
}
public RestTemplate getTemplate() {
return template;
}
public void setTemplate(RestTemplate template) {
this.template = template;
}
public URI getRootUri() {
if (rootUri == null) {
setRootUri(URIs.createURI(CloudmixHelper.getDefaultRootUrl()));
}
return rootUri;
}
public void setRootUri(URI rootUri) {
setRootUri(rootUri, true);
}
public void setRootUri(URI rooturi, boolean appendSlash) {
if ("http://localhost:8181/".equals(rooturi.toString())) {
rooturi = URIs.createURI(CloudmixHelper.getDefaultRootUrl());
}
if (appendSlash && !rooturi.toString().endsWith("/")) {
rooturi = URIs.createURI(rooturi.toString() + "/");
}
this.rootUri = rooturi;
}
protected URI append(URI uri, String... s) {
StringBuffer buffer = new StringBuffer(uri.toString());
for (String s1 : s) {
if (s1.contains("/")) {
buffer.append(s1);
} else {
try {
String urlEnString = URLEncoder.encode(s1, "UTF-8");
buffer.append(urlEnString);
} catch (Exception e) {
throw new RuntimeURISyntaxException(s1, e);
}
}
}
return URIs.createURI(buffer.toString());
}
public void setUsername(String u) {
username = u;
}
public String getUsername() {
return username;
}
public void setPasswordProvider(PasswordProvider pp) {
passwordProvider = pp;
}
public PasswordProvider getPasswordProvider() {
return passwordProvider;
}
public void setCredentials(String c) {
credentials = c;
}
public String getCredentials() {
if (credentials == null) {
// Determine credentials from username/password
if (username == null) {
return null;
}
LOG.debug("Getting credentials for user " + username);
if (passwordProvider == null) {
if (!loggedNoPassword) {
loggedNoPassword = true;
LOG.warn("cannot provide credentials for user \"" + username
+ "\", no password provider");
}
return null;
}
char[] password = passwordProvider.getPassword();
if (password == null) {
if (!loggedNoPassword) {
loggedNoPassword = true;
LOG.warn("cannot provide credentials for user \"" + username
+ "\", no password provided");
}
return null;
}
credentials = SecurityUtils.toBasicAuth(username, password);
}
return credentials;
}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
protected WebResource resource(URI uri) {
if (LOG.isDebugEnabled()) {
LOG.debug("about to use URI: " + uri);
}
return getClient(getCredentials()).resource(uri);
}
}