1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.cache.browser.rest.client;
35
36 import info.magnolia.cache.browser.rest.endpoint.CacheEndpoint;
37 import info.magnolia.rest.client.ConfiguredRestCallDefinition;
38 import info.magnolia.rest.client.ConfiguredRestClientDefinition;
39 import info.magnolia.rest.client.RestCallDefinition;
40 import info.magnolia.rest.client.RestClient;
41 import info.magnolia.rest.client.RestClientDefinition;
42 import info.magnolia.rest.client.authentication.definition.BasicSecuritySchemeDefinition;
43 import info.magnolia.rest.client.authentication.definition.SecuritySchemeDefinition;
44 import info.magnolia.rest.client.factory.RestClientFactory;
45
46 import java.io.UnsupportedEncodingException;
47 import java.net.URLEncoder;
48 import java.nio.charset.StandardCharsets;
49 import java.util.Collections;
50 import java.util.HashMap;
51 import java.util.Map;
52
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 import com.fasterxml.jackson.databind.JsonNode;
57
58
59
60
61 public class RestClientCacheService implements CacheService {
62
63 private static final String SECURITY_SCHEME_NAME = "security-cache";
64 private static final Logger log = LoggerFactory.getLogger(RestClientCacheService.class);
65
66 private final static String PING = "ping";
67 private final static String GET_ALL = "getAll";
68 private final static String GET = "get";
69 private final static String SIZE = "size";
70 private final static String DOWNLOAD = "download";
71 private final static String DELETE = "delete";
72
73 private final RestClient restClient;
74 private final String name;
75
76 public static RestClientCacheService create(String name, String baseUrl, String[] credentials, RestClientFactory restClientFactory) {
77 ConfiguredRestClientDefinition restClientDefinition = new ConfiguredRestClientDefinition();
78 restClientDefinition.setName(name);
79 if (credentials != null && credentials.length == 2) {
80 BasicSecuritySchemeDefinition securitySchemeDefinition = new BasicSecuritySchemeDefinition();
81 securitySchemeDefinition.setUsername(credentials[0]);
82 securitySchemeDefinition.setPassword(credentials[1]);
83 restClientDefinition.setSecuritySchemes(Collections.singletonMap(SECURITY_SCHEME_NAME, securitySchemeDefinition));
84 }
85 restClientDefinition.setBaseUrl(baseUrl + CacheEndpoint.DEFAULT_REST_URL);
86
87 return new RestClientCacheService(name, restClientFactory, restClientDefinition);
88 }
89
90 private RestClientCacheService(String name, RestClientFactory restClientFactory, ConfiguredRestClientDefinition restClientDefinition) {
91 this.restClient = restClientFactory.createClient(withRestCalls(restClientDefinition));
92 this.name = name;
93 }
94
95 @Override
96 public String ping() throws CacheServiceException {
97 try {
98 return (String)restClient.invoke(PING).getEntity();
99 } catch (Throwable t) {
100 log.debug("Error ping cache {}", name, t);
101 throw new CacheServiceException(t);
102 }
103 }
104
105 @Override
106 public String getAllKeys(String cacheName) throws CacheServiceException {
107 try {
108 return (String)restClient.invoke(GET_ALL, Collections.singletonMap("cacheName", cacheName)).getEntity();
109 } catch (Throwable t) {
110 log.debug("Error getting all cache {}", name, t);
111 throw new CacheServiceException(t);
112 }
113 }
114
115 @Override
116 public String getKeys(String cacheName, int offset, int pageLength, String sortOrder, String sortProperty) throws CacheServiceException {
117 try {
118 Map<String, Object> properties = new HashMap<>();
119 properties.put("cacheName", cacheName);
120 properties.put("offset", offset);
121 properties.put("pageLength", pageLength);
122 if (sortOrder != null) {
123 properties.put("sortOrder", sortOrder);
124 }
125 if (sortProperty != null) {
126 properties.put("sortProperty", sortProperty);
127 }
128 return (String)restClient.invoke(GET, properties).getEntity();
129 } catch (Throwable t) {
130 log.debug("Error getting keys cache {}", name, t);
131 throw new CacheServiceException(t);
132 }
133 }
134
135 @Override
136 public JsonNode getCacheSize(String cacheName) throws CacheServiceException {
137 try {
138 return (JsonNode)restClient.invoke(SIZE, Collections.singletonMap("cacheName", cacheName)).getEntity();
139 } catch (Throwable t) {
140 log.debug("Error getting size cache {}", name, t);
141 throw new CacheServiceException(t);
142 }
143 }
144
145 @Override
146 public JsonNode getCacheContent(String cacheName, String cacheKey) throws CacheServiceException {
147 try {
148 Map<String, Object> properties = new HashMap<>();
149 properties.put("cacheName", cacheName);
150 properties.put("cacheKey", encodeKey(cacheKey));
151 return (JsonNode)restClient.invoke(DOWNLOAD, properties).getEntity();
152 } catch (Throwable t) {
153 log.debug("Error getting content cache {}", name, t);
154 throw new CacheServiceException(t);
155 }
156 }
157
158 @Override
159 public void delete(String cacheName, String cacheKey) throws CacheServiceException {
160 try {
161 Map<String, Object> properties = new HashMap<>();
162 properties.put("cacheName", cacheName);
163 properties.put("cacheKey", encodeKey(cacheKey));
164 restClient.invoke(DELETE, properties);
165 } catch (Throwable t) {
166 log.debug("Error deleting cache {}", name, t);
167 throw new CacheServiceException(t);
168 }
169 }
170
171 private String encodeKey(String key) throws UnsupportedEncodingException {
172 return URLEncoder.encode(key, StandardCharsets.UTF_8.toString());
173 }
174
175 private RestClientDefinition withRestCalls(ConfiguredRestClientDefinition restClientDefinition) {
176 Map<String, RestCallDefinition> restCalls = new HashMap<>();
177 restCalls.put(PING, withSecurityIfNeeded(pingCall(), restClientDefinition));
178 restCalls.put(SIZE, withSecurityIfNeeded(sizeCall(), restClientDefinition));
179 restCalls.put(GET, withSecurityIfNeeded(getCall(), restClientDefinition));
180 restCalls.put(GET_ALL, withSecurityIfNeeded(getAllCall(), restClientDefinition));
181 restCalls.put(DOWNLOAD, withSecurityIfNeeded(downloadCall(), restClientDefinition));
182 restCalls.put(DELETE, withSecurityIfNeeded(deleteCall(), restClientDefinition));
183 restClientDefinition.setRestCalls(restCalls);
184 return restClientDefinition;
185 }
186
187 private RestCallDefinition withSecurityIfNeeded(ConfiguredRestCallDefinition restCallDefinition, ConfiguredRestClientDefinition restClientDefinition) {
188 Map<String, SecuritySchemeDefinition> securitySchemes = restClientDefinition.getSecuritySchemes();
189 if (securitySchemes != null && securitySchemes.size() > 0) {
190 restCallDefinition.setSecurityScheme(SECURITY_SCHEME_NAME);
191 }
192 return restCallDefinition;
193 }
194
195 private ConfiguredRestCallDefinition pingCall() {
196 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
197 restCallDefinition.setMethod("GET");
198 restCallDefinition.setPath("/ping");
199 restCallDefinition.setEntityClass(String.class);
200 return restCallDefinition;
201 }
202
203 private ConfiguredRestCallDefinition sizeCall() {
204 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
205 restCallDefinition.setMethod("GET");
206 restCallDefinition.setPath("/{cacheName}/size");
207 restCallDefinition.setEntityClass(JsonNode.class);
208 return restCallDefinition;
209 }
210
211 private ConfiguredRestCallDefinition getAllCall() {
212 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
213 restCallDefinition.setMethod("GET");
214 restCallDefinition.setPath("/{cacheName}/getAll");
215 restCallDefinition.setEntityClass(String.class);
216 return restCallDefinition;
217 }
218
219 private ConfiguredRestCallDefinition downloadCall() {
220 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
221 restCallDefinition.setMethod("GET");
222 restCallDefinition.setPath("/{cacheName}/download");
223 restCallDefinition.setQueryParameters(Collections.singletonMap("cacheKey", "{cacheKey}"));
224 restCallDefinition.setEntityClass(JsonNode.class);
225 return restCallDefinition;
226 }
227
228 private ConfiguredRestCallDefinition deleteCall() {
229 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
230 restCallDefinition.setMethod("DELETE");
231 restCallDefinition.setPath("/{cacheName}/delete");
232 restCallDefinition.setQueryParameters(Collections.singletonMap("cacheKey", "{cacheKey}"));
233 restCallDefinition.setEntityClass(String.class);
234 return restCallDefinition;
235 }
236
237 private ConfiguredRestCallDefinition getCall() {
238 ConfiguredRestCallDefinition restCallDefinition = new ConfiguredRestCallDefinition();
239 restCallDefinition.setMethod("GET");
240 restCallDefinition.setPath("/{cacheName}/get");
241 restCallDefinition.setEntityClass(String.class);
242 Map<String, String> queryParameters = new HashMap<>();
243 queryParameters.put("offset", "{offset}");
244 queryParameters.put("pageLength", "{pageLength}");
245 queryParameters.put("sortOrder", "{sortOrder}");
246 queryParameters.put("sortProperty", "{sortProperty}");
247 restCallDefinition.setQueryParameters(queryParameters);
248 Map<String, Object> defaultValues = new HashMap<>();
249 defaultValues.put("sortOrder", "");
250 defaultValues.put("sortProperty", "");
251 restCallDefinition.setDefaultValues(defaultValues);
252 return restCallDefinition;
253 }
254 }