--- /dev/null
+package org.simantics.scl.rest;
+
+import java.util.concurrent.Future;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.InvocationCallback;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.tuple.Tuple0;
+
+public class HttpClientUtils {
+
+ public static Client buildClient(ClientBuilder clientBuilder) {
+ final ClientConfig clientConfig = new ClientConfig();
+ clientConfig.register(MultiPartFeature.class);
+ return ClientBuilder.newBuilder().withConfig((Configuration) clientConfig).build();
+ }
+
+ public static String statusMessageOf(Response response) {
+ return response.getStatusInfo().getReasonPhrase();
+ }
+
+ public static Future<Response> asyncInvoke(Invocation invocation, Function1<Response, Tuple0> responseCallback, Function1<Throwable, Tuple0> failureCallback) {
+ SCLContext context = SCLContext.createDerivedContext();
+
+ return invocation.submit(new InvocationCallback<Response>() {
+
+ @Override
+ public void completed(Response response) {
+ SCLContext.push(context);
+ try {
+ responseCallback.apply(response);
+ } finally {
+ SCLContext.pop();
+ }
+ }
+
+ @Override
+ public void failed(Throwable throwable) {
+ SCLContext.push(context);
+ try {
+ failureCallback.apply(throwable);
+ } finally {
+ SCLContext.pop();
+ }
+
+ }
+ });
+ }
+}