| 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. |
| } |
| } |