001 002package io.vrap.rmf.base.client; 003 004import java.net.URI; 005import java.util.HashMap; 006import java.util.Map; 007import java.util.Optional; 008import java.util.concurrent.CompletableFuture; 009import java.util.function.Consumer; 010 011import com.fasterxml.jackson.core.type.TypeReference; 012import com.fasterxml.jackson.databind.JavaType; 013 014public class ContextApiHttpClientImpl extends AutoCloseableService implements ContextApiHttpClient { 015 private final ApiHttpClient client; 016 017 private Map<Object, Object> contextMap; 018 019 private final Consumer<ContextAware<ContextApiHttpClient>> consumer; 020 021 public ContextApiHttpClientImpl(ApiHttpClient client) { 022 this(client, new HashMap<>(), null); 023 } 024 025 public ContextApiHttpClientImpl(ApiHttpClient client, Map<Object, Object> contextMap) { 026 this(client, contextMap, null); 027 } 028 029 public ContextApiHttpClientImpl(ApiHttpClient client, Map<Object, Object> contextMap, 030 Consumer<ContextAware<ContextApiHttpClient>> consumer) { 031 this.client = client; 032 this.contextMap = contextMap; 033 this.consumer = consumer; 034 } 035 036 public ContextApiHttpClientImpl(final ContextApiHttpClientImpl c) { 037 this.client = c.client; 038 this.contextMap = c.contextMap; 039 this.consumer = c.consumer; 040 } 041 042 public Map<Object, Object> getContextMap() { 043 return contextMap; 044 } 045 046 public ContextApiHttpClient withContextMap(final Map<Object, Object> contextMap) { 047 final ContextApiHttpClientImpl client = copy(); 048 client.contextMap = new HashMap<>(contextMap); 049 050 return client; 051 } 052 053 @SuppressWarnings("unchecked") 054 public <T> T getContext(Class<T> key) { 055 return (T) contextMap.get(key); 056 } 057 058 public <T> ContextApiHttpClient addContext(T value) { 059 final ContextApiHttpClientImpl client = copy(); 060 final Map<Object, Object> contextMap = new HashMap<>(client.contextMap); 061 contextMap.put(value.getClass(), value); 062 client.contextMap = contextMap; 063 064 return client; 065 } 066 067 public Object getContext(Object key) { 068 return contextMap.get(key); 069 } 070 071 public ContextApiHttpClient addContext(Object key, Object value) { 072 final ContextApiHttpClientImpl client = copy(); 073 final Map<Object, Object> contextMap = new HashMap<>(client.contextMap); 074 contextMap.put(key, value); 075 client.contextMap = contextMap; 076 077 return client; 078 } 079 080 private ContextApiHttpClientImpl copy() { 081 return new ContextApiHttpClientImpl(this); 082 } 083 084 private void restoreContext() { 085 Optional.ofNullable(consumer).ifPresent(c -> c.accept(this)); 086 } 087 088 @Override 089 public <O> CompletableFuture<ApiHttpResponse<O>> execute(ApiHttpRequest request, Class<O> outputType) { 090 restoreContext(); 091 return client.execute(request.withContextMap(contextMap), outputType); 092 } 093 094 @Override 095 public <O> CompletableFuture<ApiHttpResponse<O>> execute(ApiHttpRequest request, TypeReference<O> outputType) { 096 restoreContext(); 097 return client.execute(request.withContextMap(contextMap), outputType); 098 } 099 100 @Override 101 public <O> CompletableFuture<ApiHttpResponse<O>> execute(ApiHttpRequest request, JavaType outputType) { 102 restoreContext(); 103 return client.execute(request.withContextMap(contextMap), outputType); 104 } 105 106 @Override 107 public <O> CompletableFuture<ApiHttpResponse<O>> execute(ClientRequestCommand<O> method) { 108 restoreContext(); 109 return method.execute(this); 110 } 111 112 @Override 113 public ResponseSerializer getSerializerService() { 114 return client.getSerializerService(); 115 } 116 117 @Override 118 public URI getBaseUri() { 119 return client.getBaseUri(); 120 } 121 122 @Override 123 public CompletableFuture<ApiHttpResponse<byte[]>> execute(ApiHttpRequest request) { 124 restoreContext(); 125 return client.execute(request.withContextMap(contextMap)); 126 } 127 128 @Override 129 protected void internalClose() { 130 closeQuietly(client); 131 } 132}