View Javadoc

1   package org.apache.jcs.auxiliary.remote.http.client;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.Serializable;
24  import java.io.UnsupportedEncodingException;
25  import java.net.URLEncoder;
26  
27  import org.apache.commons.httpclient.HttpException;
28  import org.apache.commons.httpclient.HttpMethod;
29  import org.apache.commons.httpclient.HttpState;
30  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
31  import org.apache.commons.httpclient.methods.PostMethod;
32  import org.apache.commons.httpclient.methods.RequestEntity;
33  import org.apache.commons.logging.Log;
34  import org.apache.commons.logging.LogFactory;
35  import org.apache.jcs.auxiliary.remote.behavior.IRemoteCacheDispatcher;
36  import org.apache.jcs.auxiliary.remote.value.RemoteCacheRequest;
37  import org.apache.jcs.auxiliary.remote.value.RemoteCacheResponse;
38  import org.apache.jcs.utils.serialization.StandardSerializer;
39  
40  /** Calls the service. */
41  public class RemoteHttpCacheDispatcher
42      extends AbstractHttpClient
43      implements IRemoteCacheDispatcher
44  {
45      /** Named of the parameter */
46      private static final String PARAMETER_REQUEST_TYPE = "RequestType";
47  
48      /** Named of the parameter */
49      private static final String PARAMETER_KEY = "Key";
50  
51      /** Named of the parameter */
52      private static final String PARAMETER_CACHE_NAME = "CacheName";
53  
54      /** The Logger. */
55      private final static Log log = LogFactory.getLog( RemoteHttpCacheDispatcher.class );
56  
57      /** This needs to be standard, since the other side is standard */
58      private StandardSerializer serializer = new StandardSerializer();
59  
60      /**
61       * @param remoteHttpCacheAttributes
62       */
63      public RemoteHttpCacheDispatcher( RemoteHttpCacheAttributes remoteHttpCacheAttributes )
64      {
65          super( remoteHttpCacheAttributes );
66      }
67  
68      /**
69       * All requests will go through this method.
70       * <p>
71       * TODO consider taking in a URL instead of using the one in the configuration.
72       * <p>
73       * @param remoteCacheRequest
74       * @return RemoteCacheResponse
75       * @throws IOException
76       */
77      public <K extends Serializable, V extends Serializable, T>
78          RemoteCacheResponse<T> dispatchRequest( RemoteCacheRequest<K, V> remoteCacheRequest )
79          throws IOException
80      {
81          try
82          {
83              byte[] requestAsByteArray = serializer.serialize( remoteCacheRequest );
84  
85              String url = addParameters( remoteCacheRequest, getRemoteHttpCacheAttributes().getUrl() );
86  
87              byte[] responseAsByteArray = processRequest( requestAsByteArray, url );
88  
89              RemoteCacheResponse<T> remoteCacheResponse = null;
90              try
91              {
92                  remoteCacheResponse = serializer.deSerialize( responseAsByteArray );
93              }
94              catch ( ClassNotFoundException e )
95              {
96                  log.error( "Couldn't deserialize the response.", e );
97              }
98              return remoteCacheResponse;
99          }
100         catch ( Exception e )
101         {
102             log.error( "Problem dispatching request.", e );
103             throw new IOException( e.getMessage() );
104         }
105     }
106 
107     /**
108      * @param requestAsByteArray
109      * @param url
110      * @return byte[] - the response
111      * @throws IOException
112      * @throws HttpException
113      */
114     protected byte[] processRequest( byte[] requestAsByteArray, String url )
115         throws IOException, HttpException
116     {
117         PostMethod post = new PostMethod( url );
118         RequestEntity requestEntity = new ByteArrayRequestEntity( requestAsByteArray );
119         post.setRequestEntity( requestEntity );
120         doWebserviceCall( post );
121         byte[] response = post.getResponseBody();
122         return response;
123     }
124 
125     /**
126      * @param remoteCacheRequest
127      * @param baseUrl
128      * @return String
129      */
130     protected <K extends Serializable, V extends Serializable> String addParameters( RemoteCacheRequest<K, V> remoteCacheRequest, String baseUrl )
131     {
132         StringBuffer url = new StringBuffer( baseUrl );
133 
134         try
135         {
136             if ( baseUrl != null && ( baseUrl.indexOf( "?" ) == -1 ) )
137             {
138                 url.append( "?" );
139             }
140             else
141             {
142                 url.append( "&" );
143             }
144 
145             if ( getRemoteHttpCacheAttributes().isIncludeCacheNameAsParameter() )
146             {
147                 if ( remoteCacheRequest.getCacheName() != null )
148                 {
149                     url.append( PARAMETER_CACHE_NAME + "="
150                         + URLEncoder.encode( remoteCacheRequest.getCacheName(), "UTF-8" ) );
151                 }
152             }
153             if ( getRemoteHttpCacheAttributes().isIncludeKeysAndPatternsAsParameter() )
154             {
155                 String keyValue = "";
156                 switch ( remoteCacheRequest.getRequestType() )
157                 {
158                     case GET:
159                         keyValue = remoteCacheRequest.getKey() + "";
160                         break;
161                     case REMOVE:
162                         keyValue = remoteCacheRequest.getKey() + "";
163                         break;
164                     case GET_MATCHING:
165                         keyValue = remoteCacheRequest.getPattern();
166                         break;
167                     case GET_MULTIPLE:
168                         keyValue = remoteCacheRequest.getKeySet() + "";
169                         break;
170                     case GET_GROUP_KEYS:
171                         keyValue = remoteCacheRequest.getKey() + "";
172                         break;
173                     case GET_GROUP_NAMES:
174                         keyValue = remoteCacheRequest.getKey() + "";
175                         break;
176                     case UPDATE:
177                         keyValue = remoteCacheRequest.getCacheElement().getKey() + "";
178                         break;
179                     default:
180                         break;
181                 }
182                 String encodedKeyValue = URLEncoder.encode( keyValue, "UTF-8" );
183                 url.append( "&" + PARAMETER_KEY + "=" + encodedKeyValue );
184             }
185             if ( getRemoteHttpCacheAttributes().isIncludeRequestTypeasAsParameter() )
186             {
187                 url.append( "&"
188                     + PARAMETER_REQUEST_TYPE
189                     + "="
190                     + URLEncoder.encode( remoteCacheRequest.getRequestType().toString(), "UTF-8" ) );
191             }
192         }
193         catch ( UnsupportedEncodingException e )
194         {
195             log.error( "Couldn't encode URL.", e );
196         }
197 
198         if ( log.isDebugEnabled() )
199         {
200             log.debug( "Url: " + url.toString() );
201         }
202 
203         return url.toString();
204     }
205 
206     /**
207      * Called before the executeMethod on the client.
208      * <p>
209      * @param post http method
210      * @return HttpState
211      * @throws IOException
212      */
213     @Override
214     public HttpState preProcessWebserviceCall( HttpMethod post )
215         throws IOException
216     {
217         // do nothing. Child can override.
218         return null;
219     }
220 
221     /**
222      * Called after the executeMethod on the client.
223      * <p>
224      * @param post http method
225      * @param httpState state
226      * @throws IOException
227      */
228     @Override
229     public void postProcessWebserviceCall( HttpMethod post, HttpState httpState )
230         throws IOException
231     {
232         // do nothing. Child can override.
233     }
234 }