View Javadoc
1   package org.apache.commons.jcs3.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.nio.charset.Charset;
24  import java.nio.charset.StandardCharsets;
25  
26  import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheDispatcher;
27  import org.apache.commons.jcs3.auxiliary.remote.value.RemoteCacheRequest;
28  import org.apache.commons.jcs3.auxiliary.remote.value.RemoteCacheResponse;
29  import org.apache.commons.jcs3.log.Log;
30  import org.apache.commons.jcs3.log.LogManager;
31  import org.apache.commons.jcs3.utils.serialization.StandardSerializer;
32  import org.apache.http.HttpException;
33  import org.apache.http.HttpResponse;
34  import org.apache.http.client.methods.HttpUriRequest;
35  import org.apache.http.client.methods.RequestBuilder;
36  import org.apache.http.entity.ByteArrayEntity;
37  import org.apache.http.util.EntityUtils;
38  
39  /** Calls the service. */
40  public class RemoteHttpCacheDispatcher
41      extends AbstractHttpClient
42      implements IRemoteCacheDispatcher
43  {
44      /** Parameter encoding */
45      private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
46  
47      /** Named of the parameter */
48      private static final String PARAMETER_REQUEST_TYPE = "RequestType";
49  
50      /** Named of the parameter */
51      private static final String PARAMETER_KEY = "Key";
52  
53      /** Named of the parameter */
54      private static final String PARAMETER_CACHE_NAME = "CacheName";
55  
56      /** The Logger. */
57      private static final Log log = LogManager.getLog( RemoteHttpCacheDispatcher.class );
58  
59      /** This needs to be standard, since the other side is standard */
60      private final StandardSerializer serializer = new StandardSerializer();
61  
62      /**
63       * @param remoteHttpCacheAttributes
64       */
65      public RemoteHttpCacheDispatcher( final RemoteHttpCacheAttributes remoteHttpCacheAttributes )
66      {
67          super( remoteHttpCacheAttributes );
68      }
69  
70      /**
71       * All requests will go through this method.
72       * <p>
73       * TODO consider taking in a URL instead of using the one in the configuration.
74       * <p>
75       * @param remoteCacheRequest
76       * @return RemoteCacheResponse
77       * @throws IOException
78       */
79      @Override
80      public <K, V, T>
81          RemoteCacheResponse<T> dispatchRequest( final RemoteCacheRequest<K, V> remoteCacheRequest )
82          throws IOException
83      {
84          try
85          {
86              final byte[] requestAsByteArray = serializer.serialize( remoteCacheRequest );
87  
88              final byte[] responseAsByteArray = processRequest( requestAsByteArray,
89                      remoteCacheRequest,
90                      getRemoteHttpCacheAttributes().getUrl());
91  
92              RemoteCacheResponse<T> remoteCacheResponse = null;
93              try
94              {
95                  remoteCacheResponse = serializer.deSerialize( responseAsByteArray, null );
96              }
97              catch ( final ClassNotFoundException e )
98              {
99                  log.error( "Couldn't deserialize the response.", e );
100             }
101             return remoteCacheResponse;
102         }
103         catch ( final Exception e )
104         {
105             throw new IOException("Problem dispatching request.", e);
106         }
107     }
108 
109     /**
110      * Process single request
111      *
112      * @param requestAsByteArray request body
113      * @param remoteCacheRequest the cache request
114      * @param url target url
115      *
116      * @return byte[] - the response
117      *
118      * @throws IOException
119      * @throws HttpException
120      */
121     protected <K, V> byte[] processRequest( final byte[] requestAsByteArray,
122             final RemoteCacheRequest<K, V> remoteCacheRequest, final String url )
123         throws IOException, HttpException
124     {
125         final RequestBuilder builder = RequestBuilder.post( url ).setCharset( DEFAULT_ENCODING );
126 
127         if ( getRemoteHttpCacheAttributes().isIncludeCacheNameAsParameter()
128             && remoteCacheRequest.getCacheName() != null )
129         {
130             builder.addParameter( PARAMETER_CACHE_NAME, remoteCacheRequest.getCacheName() );
131         }
132         if ( getRemoteHttpCacheAttributes().isIncludeKeysAndPatternsAsParameter() )
133         {
134             String keyValue = "";
135             switch ( remoteCacheRequest.getRequestType() )
136             {
137                 case GET:
138                 case REMOVE:
139                 case GET_KEYSET:
140                     keyValue = remoteCacheRequest.getKey().toString();
141                     break;
142                 case GET_MATCHING:
143                     keyValue = remoteCacheRequest.getPattern();
144                     break;
145                 case GET_MULTIPLE:
146                     keyValue = remoteCacheRequest.getKeySet().toString();
147                     break;
148                 case UPDATE:
149                     keyValue = remoteCacheRequest.getCacheElement().getKey().toString();
150                     break;
151                 default:
152                     break;
153             }
154             builder.addParameter( PARAMETER_KEY, keyValue );
155         }
156         if ( getRemoteHttpCacheAttributes().isIncludeRequestTypeasAsParameter() )
157         {
158             builder.addParameter( PARAMETER_REQUEST_TYPE,
159                 remoteCacheRequest.getRequestType().toString() );
160         }
161 
162         builder.setEntity(new ByteArrayEntity( requestAsByteArray ));
163         final HttpResponse httpResponse = doWebserviceCall( builder );
164         return EntityUtils.toByteArray( httpResponse.getEntity() );
165     }
166 
167     /**
168      * Called before the execute call on the client.
169      * <p>
170      * @param requestBuilder http method request builder
171      *
172      * @throws IOException
173      */
174     @Override
175     protected void preProcessWebserviceCall( final RequestBuilder requestBuilder )
176         throws IOException
177     {
178         // do nothing. Child can override.
179     }
180 
181     /**
182      * Called after the execute call on the client.
183      * <p>
184      * @param request http request
185      * @param httpState result of execution
186      *
187      * @throws IOException
188      */
189     @Override
190     protected void postProcessWebserviceCall( final HttpUriRequest request, final HttpResponse httpState )
191         throws IOException
192     {
193         // do nothing. Child can override.
194     }
195 }