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 011public class ContextApiHttpClientImpl extends AutoCloseableService implements ContextApiHttpClient { 012 private final ApiHttpClient client; 013 014 private final boolean closeHttpClient; 015 016 private Map<Object, Object> contextMap; 017 018 private final Consumer<ContextAware<ContextApiHttpClient>> consumer; 019 020 public ContextApiHttpClientImpl(final ApiHttpClient client) { 021 this(client, new HashMap<>(), null); 022 } 023 024 public ContextApiHttpClientImpl(final ApiHttpClient client, final Map<Object, Object> contextMap) { 025 this(client, contextMap, null); 026 } 027 028 public ContextApiHttpClientImpl(final ApiHttpClient client, final Map<Object, Object> contextMap, 029 final Consumer<ContextAware<ContextApiHttpClient>> consumer) { 030 this(client, contextMap, consumer, true); 031 } 032 033 public ContextApiHttpClientImpl(final ApiHttpClient client, final boolean closeHttpClient) { 034 this(client, new HashMap<>(), null, closeHttpClient); 035 } 036 037 public ContextApiHttpClientImpl(final ApiHttpClient client, final Map<Object, Object> contextMap, 038 final boolean closeHttpClient) { 039 this(client, contextMap, null, closeHttpClient); 040 } 041 042 public ContextApiHttpClientImpl(final ApiHttpClient client, final Map<Object, Object> contextMap, 043 final Consumer<ContextAware<ContextApiHttpClient>> consumer, final boolean closeHttpClient) { 044 this.client = client; 045 this.contextMap = contextMap; 046 this.consumer = consumer; 047 this.closeHttpClient = closeHttpClient; 048 } 049 050 public ContextApiHttpClientImpl(final ContextApiHttpClientImpl c) { 051 this.client = c.client; 052 this.contextMap = c.contextMap; 053 this.consumer = c.consumer; 054 this.closeHttpClient = c.closeHttpClient; 055 } 056 057 public Map<Object, Object> getContextMap() { 058 return contextMap; 059 } 060 061 public ContextApiHttpClient withContextMap(final Map<Object, Object> contextMap) { 062 final ContextApiHttpClientImpl client = copy(); 063 client.contextMap = new HashMap<>(contextMap); 064 065 return client; 066 } 067 068 @SuppressWarnings("unchecked") 069 public <T> T getContext(Class<T> key) { 070 return (T) contextMap.get(key); 071 } 072 073 public <T> ContextApiHttpClient addContext(final T value) { 074 final ContextApiHttpClientImpl client = copy(); 075 final Map<Object, Object> contextMap = new HashMap<>(client.contextMap); 076 contextMap.put(value.getClass(), value); 077 if (value instanceof ClassReferenceContext) { 078 contextMap.put(((ClassReferenceContext) value).classReference(), value); 079 } 080 client.contextMap = contextMap; 081 082 return client; 083 } 084 085 public Object getContext(final Object key) { 086 return contextMap.get(key); 087 } 088 089 public ContextApiHttpClient addContext(final Object key, final Object value) { 090 final ContextApiHttpClientImpl client = copy(); 091 final Map<Object, Object> contextMap = new HashMap<>(client.contextMap); 092 contextMap.put(key, value); 093 client.contextMap = contextMap; 094 095 return client; 096 } 097 098 private ContextApiHttpClientImpl copy() { 099 return new ContextApiHttpClientImpl(this); 100 } 101 102 private void restoreContext() { 103 Optional.ofNullable(consumer).ifPresent(c -> c.accept(this)); 104 } 105 106 @Override 107 public ResponseSerializer getSerializerService() { 108 return client.getSerializerService(); 109 } 110 111 @Override 112 public URI getBaseUri() { 113 return client.getBaseUri(); 114 } 115 116 @Override 117 public CompletableFuture<ApiHttpResponse<byte[]>> execute(final ApiHttpRequest request) { 118 restoreContext(); 119 return client.execute(request.withContextMap(contextMap)); 120 } 121 122 @Override 123 protected void internalClose() { 124 if (closeHttpClient) { 125 closeQuietly(client); 126 } 127 contextMap.values().forEach(o -> { 128 if (o instanceof AutoCloseable) { 129 closeQuietly((AutoCloseable) o); 130 } 131 }); 132 } 133}