Skip to content

Commit be7fd2e

Browse files
committed
feat: Add client dereferencer
1 parent c5c5534 commit be7fd2e

2 files changed

Lines changed: 174 additions & 2 deletions

File tree

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package uniresolver.client;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import org.apache.http.HttpEntity;
5+
import org.apache.http.client.HttpClient;
6+
import org.apache.http.client.methods.CloseableHttpResponse;
7+
import org.apache.http.client.methods.HttpGet;
8+
import org.apache.http.entity.ContentType;
9+
import org.apache.http.impl.client.HttpClients;
10+
import org.apache.http.protocol.HTTP;
11+
import org.apache.http.util.EntityUtils;
12+
import org.slf4j.Logger;
13+
import org.slf4j.LoggerFactory;
14+
import uniresolver.DereferencingException;
15+
import uniresolver.ResolutionException;
16+
import uniresolver.UniDereferencer;
17+
import uniresolver.result.DereferenceResult;
18+
import uniresolver.util.HttpBindingClientUtil;
19+
20+
import java.net.URI;
21+
import java.nio.charset.Charset;
22+
import java.util.Arrays;
23+
import java.util.HashMap;
24+
import java.util.List;
25+
import java.util.Map;
26+
27+
public class ClientUniDereferencer implements UniDereferencer {
28+
29+
private static final Logger log = LoggerFactory.getLogger(ClientUniDereferencer.class);
30+
31+
private static final ObjectMapper objectMapper = new ObjectMapper();
32+
33+
public static final HttpClient DEFAULT_HTTP_CLIENT = HttpClients.createDefault();
34+
public static final URI DEFAULT_DEREFERENCE_URI = URI.create("http://localhost:8080/1.0/identifiers");
35+
36+
private HttpClient httpClient = DEFAULT_HTTP_CLIENT;
37+
private URI dereferenceUri = DEFAULT_DEREFERENCE_URI;
38+
39+
public ClientUniDereferencer() {
40+
41+
}
42+
43+
public static ClientUniDereferencer create(URI baseUri) {
44+
45+
if (! baseUri.toString().endsWith("/")) baseUri = URI.create(baseUri + "/");
46+
47+
ClientUniDereferencer clientUniDereferencer = new ClientUniDereferencer();
48+
clientUniDereferencer.setDereferenceUri(URI.create(baseUri + "identifiers"));
49+
50+
return clientUniDereferencer;
51+
}
52+
53+
@Override
54+
public DereferenceResult dereference(String didUrlString, Map<String, Object> dereferenceOptions) throws DereferencingException, ResolutionException {
55+
56+
if (log.isDebugEnabled()) log.debug("dereference(" + didUrlString + ") with options: " + dereferenceOptions);
57+
58+
if (didUrlString == null) throw new NullPointerException();
59+
if (dereferenceOptions == null) dereferenceOptions = new HashMap<>();
60+
61+
// set HTTP URI
62+
63+
String uriString = this.getDereferenceUri().toString();
64+
65+
if (! uriString.endsWith("/")) uriString += "/";
66+
uriString += didUrlString;
67+
68+
// set Accept header
69+
70+
String accept = (String) dereferenceOptions.get("accept");
71+
if (accept == null) throw new DereferencingException("No 'accept' provided in 'dereferenceOptions' for dereference().");
72+
73+
List<String> acceptMediaTypes = Arrays.asList(DereferenceResult.MEDIA_TYPE, accept);
74+
String acceptMediaTypesString = String.join(",", acceptMediaTypes);
75+
76+
if (log.isDebugEnabled()) log.debug("Setting Accept: header to " + acceptMediaTypesString);
77+
78+
// prepare HTTP request
79+
80+
HttpGet httpGet = new HttpGet(URI.create(uriString));
81+
httpGet.addHeader("Accept", acceptMediaTypesString);
82+
83+
// execute HTTP request and read response
84+
85+
DereferenceResult dereferenceResult = null;
86+
87+
if (log.isDebugEnabled()) log.debug("Request for DID " + didUrlString + " to " + uriString + " with Accept: header " + acceptMediaTypesString);
88+
89+
try (CloseableHttpResponse httpResponse = (CloseableHttpResponse) this.getHttpClient().execute(httpGet)) {
90+
91+
// execute HTTP request
92+
93+
HttpEntity httpEntity = httpResponse.getEntity();
94+
int httpStatusCode = httpResponse.getStatusLine().getStatusCode();
95+
String httpStatusMessage = httpResponse.getStatusLine().getReasonPhrase();
96+
ContentType httpContentType = ContentType.get(httpResponse.getEntity());
97+
Charset httpCharset = (httpContentType != null && httpContentType.getCharset() != null) ? httpContentType.getCharset() : HTTP.DEF_CONTENT_CHARSET;
98+
99+
if (log.isDebugEnabled()) log.debug("Response HTTP status from " + uriString + ": " + httpStatusCode + " " + httpStatusMessage);
100+
if (log.isDebugEnabled()) log.debug("Response HTTP content type from " + uriString + ": " + httpContentType + " / " + httpCharset);
101+
102+
// read result
103+
104+
byte[] httpBodyBytes = EntityUtils.toByteArray(httpEntity);
105+
String httpBodyString = new String(httpBodyBytes, httpCharset);
106+
EntityUtils.consume(httpEntity);
107+
108+
if (log.isDebugEnabled()) log.debug("Response HTTP body from " + uriString + ": " + httpBodyString);
109+
110+
if (httpContentType != null && (DereferenceResult.isMediaType(httpContentType) || HttpBindingClientUtil.isDereferenceResultHttpContent(httpBodyString))) {
111+
dereferenceResult = HttpBindingClientUtil.fromHttpBodyDereferenceResult(httpBodyString);
112+
}
113+
114+
if (httpStatusCode == 404 && dereferenceResult == null) {
115+
throw new DereferencingException(DereferencingException.ERROR_NOTFOUND, httpStatusCode + " " + httpStatusMessage + " (" + httpBodyString + ")");
116+
}
117+
118+
if (httpStatusCode == 406 && dereferenceResult == null) {
119+
throw new DereferencingException(DereferencingException.ERROR_CONTENTTYPENOTSUPPORTED, httpStatusCode + " " + httpStatusMessage + " (" + httpBodyString + ")");
120+
}
121+
122+
if (httpStatusCode != 200 && dereferenceResult == null) {
123+
throw new DereferencingException(DereferencingException.ERROR_INTERNALERROR, "Cannot retrieve DEREFERENCE result for " + didUrlString + ": " + httpStatusCode + " " + httpStatusMessage + " (" + httpBodyString + ")");
124+
}
125+
126+
if (dereferenceResult != null && dereferenceResult.isErrorResult()) {
127+
if (log.isWarnEnabled()) log.warn("Received DEREFERENCE result: " + dereferenceResult.getError() + " -> " + dereferenceResult.getErrorMessage());
128+
throw DereferencingException.fromDereferenceResult(dereferenceResult);
129+
}
130+
131+
if (dereferenceResult == null) {
132+
dereferenceResult = HttpBindingClientUtil.fromHttpBodyContent(httpBodyBytes, httpContentType);
133+
}
134+
} catch (DereferencingException ex) {
135+
136+
throw ex;
137+
} catch (Exception ex) {
138+
139+
throw new DereferencingException("Cannot retrieve DEREFERENCE result for " + didUrlString + " from " + uriString + ": " + ex.getMessage(), ex);
140+
}
141+
142+
if (log.isDebugEnabled()) log.debug("Retrieved DEREFERENCE result for " + didUrlString + " (" + uriString + "): " + dereferenceResult);
143+
144+
// done
145+
146+
return dereferenceResult;
147+
}
148+
149+
/*
150+
* Getters and setters
151+
*/
152+
153+
public HttpClient getHttpClient() {
154+
return this.httpClient;
155+
}
156+
157+
public void setHttpClient(HttpClient httpClient) {
158+
this.httpClient = httpClient;
159+
}
160+
161+
public URI getDereferenceUri() {
162+
return this.dereferenceUri;
163+
}
164+
165+
public void setDereferenceUri(URI dereferenceUri) {
166+
this.dereferenceUri = dereferenceUri;
167+
}
168+
169+
public void setDereferenceUri(String dereferenceUri) {
170+
this.dereferenceUri = URI.create(dereferenceUri);
171+
}
172+
}

uni-resolver-client/src/main/java/uniresolver/client/ClientUniResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static ClientUniResolver create(URI baseUri) {
6262
@Override
6363
public ResolveResult resolve(String didString, Map<String, Object> resolutionOptions) throws ResolutionException {
6464

65-
if (log.isDebugEnabled()) log.debug("resolveRepresentation(" + didString + ") with options: " + resolutionOptions);
65+
if (log.isDebugEnabled()) log.debug("resolve(" + didString + ") with options: " + resolutionOptions);
6666

6767
if (didString == null) throw new NullPointerException();
6868
if (resolutionOptions == null) resolutionOptions = new HashMap<>();
@@ -77,7 +77,7 @@ public ResolveResult resolve(String didString, Map<String, Object> resolutionOpt
7777
// set Accept header
7878

7979
String accept = (String) resolutionOptions.get("accept");
80-
if (accept == null) throw new ResolutionException("No 'accept' provided in 'resolutionOptions' for resolveRepresentation().");
80+
if (accept == null) throw new ResolutionException("No 'accept' provided in 'resolutionOptions' for resolve().");
8181

8282
List<String> acceptMediaTypes = Arrays.asList(ResolveResult.MEDIA_TYPE, accept);
8383
String acceptMediaTypesString = String.join(",", acceptMediaTypes);

0 commit comments

Comments
 (0)