001package org.apache.commons.jcs3.auxiliary.remote.http.client; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.IOException; 023import java.nio.charset.Charset; 024import java.nio.charset.StandardCharsets; 025 026import org.apache.commons.jcs3.auxiliary.remote.behavior.IRemoteCacheDispatcher; 027import org.apache.commons.jcs3.auxiliary.remote.value.RemoteCacheRequest; 028import org.apache.commons.jcs3.auxiliary.remote.value.RemoteCacheResponse; 029import org.apache.commons.jcs3.log.Log; 030import org.apache.commons.jcs3.log.LogManager; 031import org.apache.commons.jcs3.utils.serialization.StandardSerializer; 032import org.apache.http.HttpException; 033import org.apache.http.HttpResponse; 034import org.apache.http.client.methods.HttpUriRequest; 035import org.apache.http.client.methods.RequestBuilder; 036import org.apache.http.entity.ByteArrayEntity; 037import org.apache.http.util.EntityUtils; 038 039/** Calls the service. */ 040public class RemoteHttpCacheDispatcher 041 extends AbstractHttpClient 042 implements IRemoteCacheDispatcher 043{ 044 /** Parameter encoding */ 045 private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8; 046 047 /** Named of the parameter */ 048 private static final String PARAMETER_REQUEST_TYPE = "RequestType"; 049 050 /** Named of the parameter */ 051 private static final String PARAMETER_KEY = "Key"; 052 053 /** Named of the parameter */ 054 private static final String PARAMETER_CACHE_NAME = "CacheName"; 055 056 /** The Logger. */ 057 private static final Log log = LogManager.getLog( RemoteHttpCacheDispatcher.class ); 058 059 /** This needs to be standard, since the other side is standard */ 060 private final StandardSerializer serializer = new StandardSerializer(); 061 062 /** 063 * @param remoteHttpCacheAttributes 064 */ 065 public RemoteHttpCacheDispatcher( final RemoteHttpCacheAttributes remoteHttpCacheAttributes ) 066 { 067 super( remoteHttpCacheAttributes ); 068 } 069 070 /** 071 * All requests will go through this method. 072 * <p> 073 * TODO consider taking in a URL instead of using the one in the configuration. 074 * <p> 075 * @param remoteCacheRequest 076 * @return RemoteCacheResponse 077 * @throws IOException 078 */ 079 @Override 080 public <K, V, T> 081 RemoteCacheResponse<T> dispatchRequest( final RemoteCacheRequest<K, V> remoteCacheRequest ) 082 throws IOException 083 { 084 try 085 { 086 final byte[] requestAsByteArray = serializer.serialize( remoteCacheRequest ); 087 088 final byte[] responseAsByteArray = processRequest( requestAsByteArray, 089 remoteCacheRequest, 090 getRemoteHttpCacheAttributes().getUrl()); 091 092 RemoteCacheResponse<T> remoteCacheResponse = null; 093 try 094 { 095 remoteCacheResponse = serializer.deSerialize( responseAsByteArray, null ); 096 } 097 catch ( final ClassNotFoundException e ) 098 { 099 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}