blob: a19ef5133ba3e9eb258d0b43471c7dfa5c356ef0 [file] [log] [blame]
package org.apache.commons.jcs.auxiliary.remote.http.client;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.jcs.auxiliary.remote.behavior.IRemoteCacheDispatcher;
import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheRequest;
import org.apache.commons.jcs.auxiliary.remote.value.RemoteCacheResponse;
import org.apache.commons.jcs.utils.serialization.StandardSerializer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** Calls the service. */
public class RemoteHttpCacheDispatcher
extends AbstractHttpClient
implements IRemoteCacheDispatcher
{
/** Parameter encoding */
private static final String DEFAULT_ENCODING = "UTF-8";
/** Named of the parameter */
private static final String PARAMETER_REQUEST_TYPE = "RequestType";
/** Named of the parameter */
private static final String PARAMETER_KEY = "Key";
/** Named of the parameter */
private static final String PARAMETER_CACHE_NAME = "CacheName";
/** The Logger. */
private static final Log log = LogFactory.getLog( RemoteHttpCacheDispatcher.class );
/** This needs to be standard, since the other side is standard */
private StandardSerializer serializer = new StandardSerializer();
/**
* @param remoteHttpCacheAttributes
*/
public RemoteHttpCacheDispatcher( RemoteHttpCacheAttributes remoteHttpCacheAttributes )
{
super( remoteHttpCacheAttributes );
}
/**
* All requests will go through this method.
* <p>
* TODO consider taking in a URL instead of using the one in the configuration.
* <p>
* @param remoteCacheRequest
* @return RemoteCacheResponse
* @throws IOException
*/
@Override
public <K, V, T>
RemoteCacheResponse<T> dispatchRequest( RemoteCacheRequest<K, V> remoteCacheRequest )
throws IOException
{
try
{
byte[] requestAsByteArray = serializer.serialize( remoteCacheRequest );
String url = addParameters( remoteCacheRequest, getRemoteHttpCacheAttributes().getUrl() );
byte[] responseAsByteArray = processRequest( requestAsByteArray, url );
RemoteCacheResponse<T> remoteCacheResponse = null;
try
{
remoteCacheResponse = serializer.deSerialize( responseAsByteArray, null );
}
catch ( ClassNotFoundException e )
{
log.error( "Couldn't deserialize the response.", e );
}
return remoteCacheResponse;
}
catch ( Exception e )
{
throw new IOException("Problem dispatching request.", e);
}
}
/**
* @param requestAsByteArray
* @param url
* @return byte[] - the response
* @throws IOException
* @throws HttpException
*/
protected byte[] processRequest( byte[] requestAsByteArray, String url )
throws IOException, HttpException
{
PostMethod post = new PostMethod( url );
RequestEntity requestEntity = new ByteArrayRequestEntity( requestAsByteArray );
post.setRequestEntity( requestEntity );
doWebserviceCall( post );
byte[] response = post.getResponseBody();
return response;
}
/**
* @param remoteCacheRequest
* @param baseUrl
* @return String
*/
protected <K, V> String addParameters( RemoteCacheRequest<K, V> remoteCacheRequest, String baseUrl )
{
StringBuilder url = new StringBuilder( baseUrl == null ? "" : baseUrl );
try
{
if ( baseUrl != null && baseUrl.indexOf( "?" ) == -1 )
{
url.append( "?" );
}
else
{
url.append( "&" );
}
if ( getRemoteHttpCacheAttributes().isIncludeCacheNameAsParameter() )
{
if ( remoteCacheRequest.getCacheName() != null )
{
url.append( PARAMETER_CACHE_NAME + "="
+ URLEncoder.encode( remoteCacheRequest.getCacheName(), DEFAULT_ENCODING ) );
}
}
if ( getRemoteHttpCacheAttributes().isIncludeKeysAndPatternsAsParameter() )
{
String keyValue = "";
switch ( remoteCacheRequest.getRequestType() )
{
case GET:
case REMOVE:
case GET_KEYSET:
keyValue = remoteCacheRequest.getKey() + "";
break;
case GET_MATCHING:
keyValue = remoteCacheRequest.getPattern();
break;
case GET_MULTIPLE:
keyValue = remoteCacheRequest.getKeySet() + "";
break;
case UPDATE:
keyValue = remoteCacheRequest.getCacheElement().getKey() + "";
break;
default:
break;
}
String encodedKeyValue = URLEncoder.encode( keyValue, DEFAULT_ENCODING );
url.append( "&" + PARAMETER_KEY + "=" + encodedKeyValue );
}
if ( getRemoteHttpCacheAttributes().isIncludeRequestTypeasAsParameter() )
{
url.append( "&"
+ PARAMETER_REQUEST_TYPE
+ "="
+ URLEncoder.encode( remoteCacheRequest.getRequestType().toString(), DEFAULT_ENCODING ) );
}
}
catch ( UnsupportedEncodingException e )
{
log.error( "Couldn't encode URL.", e );
}
if ( log.isDebugEnabled() )
{
log.debug( "Url: " + url.toString() );
}
return url.toString();
}
/**
* Called before the executeMethod on the client.
* <p>
* @param post http method
* @return HttpState
* @throws IOException
*/
@Override
protected HttpState preProcessWebserviceCall( HttpMethod post )
throws IOException
{
// do nothing. Child can override.
return null;
}
/**
* Called after the executeMethod on the client.
* <p>
* @param post http method
* @param httpState state
* @throws IOException
*/
@Override
protected void postProcessWebserviceCall( HttpMethod post, HttpState httpState )
throws IOException
{
// do nothing. Child can override.
}
}