001package org.conqat.engine.service.shared.client; 002 003import java.io.IOException; 004 005import org.apache.http.HttpHeaders; 006import org.apache.http.client.HttpClient; 007import org.apache.http.client.methods.HttpDelete; 008import org.apache.http.client.methods.HttpGet; 009import org.apache.http.client.methods.HttpPost; 010import org.apache.http.client.methods.HttpPut; 011import org.apache.http.impl.client.CloseableHttpClient; 012 013/** 014 * Interface to enable testing service calls with provided responses. For an 015 * example see IdeServiceClientTest. 016 */ 017@FunctionalInterface 018public interface ServiceClientCallable<T> { 019 020 /** Overridden by implementors, actually starts the service call */ 021 T call(HttpClient client) throws ServiceCallException; 022 023 /** 024 * Helper method for starting a service call using a given 025 * {@link CloseableHttpClient}. 026 */ 027 static <T> T withHttpClient(CloseableHttpClient client, ServiceClientCallable<T> callable) 028 throws ServiceCallException { 029 try (CloseableHttpClient c = client) { 030 return callable.call(c); 031 } catch (IOException e) { 032 throw new ServiceCallException("Problem closing HTTP client: " + e.getMessage(), e); 033 } 034 } 035 036 /** 037 * Helper method for starting a service call with the given 038 * {@link ServerDetails}. 039 */ 040 static <T> T with(ServerDetails serverDetails, ServiceClientCallable<T> callable) throws ServiceCallException { 041 return withHttpClient(ServiceClientUtils.getHttpClient(serverDetails), callable); 042 } 043 044 /** 045 * @return a {@link ServiceClientCallable} for a HTTP GET on the given URI. 046 */ 047 static <R> ServiceClientCallable<R> get(IDeserializationFormat<R> deserializationFormat, String uri) { 048 return client -> { 049 HttpGet httpGet = new HttpGet(uri); 050 return ServiceClientUtils.executeRequest(client, httpGet, deserializationFormat.getMimeType().orElse(null), 051 deserializationFormat::deserialize); 052 }; 053 } 054 055 /** 056 * @return a {@link ServiceClientCallable} for a HTTP POST on the given URI. 057 */ 058 static <S, T extends S, R> ServiceClientCallable<R> post(ISerializationFormat<S> serializationFormat, T data, 059 IDeserializationFormat<R> deserializationFormat, String uri) { 060 return client -> { 061 HttpPost httpPost = new HttpPost(uri); 062 serializationFormat.getMimeType() 063 .ifPresent(mimeType -> httpPost.setHeader(HttpHeaders.CONTENT_TYPE, mimeType.getType())); 064 httpPost.setEntity(serializationFormat.toHttpEntity(data)); 065 return ServiceClientUtils.executeRequest(client, httpPost, deserializationFormat.getMimeType().orElse(null), 066 deserializationFormat::deserialize); 067 }; 068 } 069 070 /** 071 * @return a {@link ServiceClientCallable} for a HTTP POST on the given URI. 072 */ 073 static <R> ServiceClientCallable<R> post(IDeserializationFormat<R> deserializationFormat, String uri) { 074 return client -> { 075 HttpPost httpPost = new HttpPost(uri); 076 return ServiceClientUtils.executeRequest(client, httpPost, deserializationFormat.getMimeType().orElse(null), 077 deserializationFormat::deserialize); 078 }; 079 } 080 081 /** 082 * @return a {@link ServiceClientCallable} for a HTTP PUT on the given URI. 083 */ 084 static <S, T extends S, R> ServiceClientCallable<R> put(ISerializationFormat<S> serializationFormat, T data, 085 IDeserializationFormat<R> deserializationFormat, String uri) { 086 return client -> { 087 HttpPut httpPut = new HttpPut(uri); 088 serializationFormat.getMimeType() 089 .ifPresent(mimeType -> httpPut.setHeader(HttpHeaders.CONTENT_TYPE, mimeType.getType())); 090 httpPut.setEntity(serializationFormat.toHttpEntity(data)); 091 return ServiceClientUtils.executeRequest(client, httpPut, deserializationFormat.getMimeType().orElse(null), 092 deserializationFormat::deserialize); 093 }; 094 } 095 096 /** 097 * @return a {@link ServiceClientCallable} for a HTTP PUT on the given URI 098 * without any payload. 099 * @deprecated PUT requests should always have a body 100 */ 101 @Deprecated 102 static <R> ServiceClientCallable<R> put(IDeserializationFormat<R> deserializationFormat, String uri) { 103 return client -> { 104 HttpPut httpPut = new HttpPut(uri); 105 return ServiceClientUtils.executeRequest(client, httpPut, deserializationFormat.getMimeType().orElse(null), 106 deserializationFormat::deserialize); 107 }; 108 } 109 110 /** 111 * @return a {@link ServiceClientCallable} for a HTTP DELETE on the given URI. 112 */ 113 static <R> ServiceClientCallable<R> delete(IDeserializationFormat<R> deserializationFormat, String uri) { 114 return client -> { 115 HttpDelete httpDelete = new HttpDelete(uri); 116 return ServiceClientUtils.executeRequest(client, httpDelete, 117 deserializationFormat.getMimeType().orElse(null), deserializationFormat::deserialize); 118 }; 119 } 120}