/**
* Abiquo community edition
* cloud management application for hybrid clouds
* Copyright (C) 2008-2010 - Abiquo Holdings S.L.
*
* This application is free software; you can redistribute it and/or
* modify it under the terms of the GNU LESSER GENERAL PUBLIC
* LICENSE as published by the Free Software Foundation under
* version 3 of the License
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* LESSER GENERAL PUBLIC LICENSE v.3 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package com.abiquo.appliancemanager.client;
import static java.lang.String.valueOf;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.Response.Status.Family;
import org.apache.wink.client.ClientConfig;
import org.apache.wink.client.ClientResponse;
import org.apache.wink.client.Resource;
import org.apache.wink.client.RestClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.abiquo.appliancemanager.util.URIResolver;
import com.abiquo.model.transport.error.ErrorDto;
public class AMClientResources
{
protected final static Logger LOGGER = LoggerFactory.getLogger(AMClient.class);
// public static final String GET_IDS_ACTION = "action/getstates";
protected String serviceUri;
private RestClient client;
private final static Integer CLIENT_TIMEOUT_MS = // 5 seconds
Integer.parseInt(System.getProperty("abiquo.appliancemanager.timeout", "5000"));
protected final static ClientConfig confTimeout;
static
{
// WARNING: this property is intended to be setup in the ''remote services'', but we will
// add a check in case of monolitic installs.
final Integer REPOSITORY_FILE_MARK_CHECK_TIMEOUT_MS = //
Integer.valueOf(System.getProperty("abiquo.repository.timeoutSeconds", "5")) * 1000;
// Use the higher timeout
final Integer EFFECTIVE_CLIENT_TIMEOUT =
REPOSITORY_FILE_MARK_CHECK_TIMEOUT_MS > CLIENT_TIMEOUT_MS
? REPOSITORY_FILE_MARK_CHECK_TIMEOUT_MS : CLIENT_TIMEOUT_MS;
confTimeout = new ClientConfig();
confTimeout.readTimeout(EFFECTIVE_CLIENT_TIMEOUT);
LOGGER.info("ApplianceManager client request timeout "
+ "for repository filesystem requests set to {}ms", EFFECTIVE_CLIENT_TIMEOUT);
}
/**
* @param configTimeout, only for am request that will require some repository filesystem action
*/
public void initializeClient(final String serviceUri, final boolean configTimeout)
{
this.serviceUri = serviceUri;
if (configTimeout)
{
this.client = new RestClient(confTimeout);
}
else
{
this.client = new RestClient();
}
}
public static String resolveTemplateUrl(final String serviceUri, final Integer idEnterprise,
String ovfid)
{
if (ovfid.startsWith("http://"))
{
ovfid = ovfid.substring("http://".length());
}
Map<String, String> params;
params = new HashMap<String, String>();
params.put("erepo", valueOf(idEnterprise));
// XXX calling from server encode the ''ovfid''
// params.put(TEMPLATE_PATH, ovfid);
return
// XXX calling from server encode the ''ovfid''
// URIResolver.resolveURI(serviceUri, "erepos/{erepo}/templates/{template}", params);
URIResolver.resolveURI(serviceUri, "erepos/{erepo}/templates", params) // + '/'
+ decodedUrl(ovfid);
}
Resource template(final Integer idEnterprise, final String ovfid)
{
String url = resolveTemplateUrl(serviceUri, idEnterprise, ovfid);
Resource resource = client.resource(url);
return resource;
}
Resource templates(final Integer idEnterprise)
{
final String url =
URIResolver.resolveURI(serviceUri, "erepos/{erepo}/templates",
Collections.singletonMap("erepo", valueOf(idEnterprise)));
return client.resource(url);
}
// Resource templates_GetIds(final Integer idEnterprise)
// {
// final String url =
// URIResolver.resolveURI(serviceUri, "erepos/{erepo}/templates/",
// Collections.singletonMap("erepo", valueOf(idEnterprise)));
//
// return client.resource(UriHelper.appendPathToBaseUri(url, GET_IDS_ACTION));
// }
Resource repository(final Integer idEnterprise)
{
final String url =
URIResolver.resolveURI(serviceUri, "erepos/{erepo}",
Collections.singletonMap("erepo", valueOf(idEnterprise)));
return client.resource(url);
}
Resource repositories()
{
final String url = String.format("%s/%s", serviceUri, "erepos");
Resource resource = client.resource(url);
return resource;
}
Resource check()
{
final String url = String.format("%s/%s", serviceUri, "check");
Resource resource = client.resource(url);
return resource;
}
/**
* Check each part of the url is properly encoded (uploading a template name with blanks)
*/
private static String decodedUrl(final String url)
{
try
{
String[] parts = url.split("/");
StringBuffer sb = new StringBuffer();
for (String part : parts)
{
sb.append("/").append(java.net.URLEncoder.encode(part, "UTF-8"));
}
return sb.toString();
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(url, e);
}
}
protected void checkResponseErrors(final ClientResponse response) throws AMClientException
{
if (response.getStatusType().getFamily() != Family.SUCCESSFUL)
{
Status status = Status.fromStatusCode(response.getStatusCode());
ErrorDto error = null;
try
{
error = response.getEntity(ErrorDto.class);
}
catch (Exception e)
{
error = new ErrorDto("AM-COMM-UNEXPECTED", response.getMessage());
}
if (error != null)
{
throw new AMClientException(status, error.getMessage());
}
throw new AMClientException(status, "Appliance Manager not properly configured");
}
}
}