org.aarboard.nextcloud.api.utils.ConnectorCommon Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nextcloud-api Show documentation
Show all versions of nextcloud-api Show documentation
Java api library to access nextcloud features from java applications
package org.aarboard.nextcloud.api.utils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import javax.net.ssl.SSLContext;
import org.aarboard.nextcloud.api.ServerConfig;
import org.aarboard.nextcloud.api.exception.NextcloudApiException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
public class ConnectorCommon
{
private final ServerConfig serverConfig;
public ConnectorCommon(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
}
public CompletableFuture executeGet(String part, ResponseParser parser) {
return executeGet(part, null, parser);
}
public CompletableFuture executeGet(String part, List queryParams, ResponseParser parser) {
try {
URI url= buildUrl(part, queryParams, parser instanceof JsonAnswerParser);
HttpRequestBase request = new HttpGet(url.toString());
return executeRequest(parser, request);
} catch (IOException e) {
throw new NextcloudApiException(e);
}
}
public CompletableFuture executePost(String part, ResponseParser parser) {
return executePost(part, null, parser);
}
public CompletableFuture executePost(String part, List postParams, ResponseParser parser) {
try {
URI url= buildUrl(part, postParams, parser instanceof JsonAnswerParser);
HttpRequestBase request = new HttpPost(url.toString());
return executeRequest(parser, request);
} catch (IOException e) {
throw new NextcloudApiException(e);
}
}
public CompletableFuture executePut(String part1, String part2, ResponseParser parser) {
return executePut(part1, part2, null, parser);
}
public CompletableFuture executePut(String part1, String part2, List putParams, ResponseParser parser) {
try {
URI url= buildUrl(part1 + "/" + part2, putParams, parser instanceof JsonAnswerParser);
HttpRequestBase request = new HttpPut(url.toString());
return executeRequest(parser, request);
} catch (IOException e) {
throw new NextcloudApiException(e);
}
}
public CompletableFuture executeDelete(String part1, String part2, ResponseParser parser) {
return executeDelete(part1, part2, null, parser);
}
public CompletableFuture executeDelete(String part1, String part2, List deleteParams, ResponseParser parser) {
try {
URI url= buildUrl(part1 + "/" + part2, deleteParams, parser instanceof JsonAnswerParser);
HttpRequestBase request = new HttpDelete(url.toString());
return executeRequest(parser, request);
} catch (IOException e) {
throw new NextcloudApiException(e);
}
}
private URI buildUrl(String subPath, List queryParams, boolean useJson) {
if(serverConfig.getSubPathPrefix()!=null) {
subPath = serverConfig.getSubPathPrefix()+"/"+subPath;
}
if (useJson) {
if (queryParams == null || queryParams.isEmpty()) {
queryParams = new ArrayList<>();
}
queryParams.add(new BasicNameValuePair("format", "json"));
}
URIBuilder uB= new URIBuilder()
.setScheme(serverConfig.isUseHTTPS() ? "https" : "http")
.setHost(serverConfig.getServerName())
.setPort(serverConfig.getPort())
.setPath(subPath);
if (serverConfig.getAuthenticationConfig().usesBasicAuthentication()) {
uB.setUserInfo(serverConfig.getAuthenticationConfig().getLoginName(),
serverConfig.getAuthenticationConfig().getPassword());
}
if (queryParams != null) {
uB.addParameters(queryParams);
}
try {
return uB.build();
} catch (URISyntaxException e) {
throw new NextcloudApiException(e);
}
}
private CompletableFuture executeRequest(final ResponseParser parser, HttpRequestBase request) throws IOException, ClientProtocolException {
// https://docs.nextcloud.com/server/14/developer_manual/core/ocs-share-api.html
request.addHeader("OCS-APIRequest", "true");
request.addHeader("Content-Type", "application/x-www-form-urlencoded");
request.setProtocolVersion(HttpVersion.HTTP_1_1);
HttpClientContext context = prepareContext();
CompletableFuture futureResponse = new CompletableFuture<>();
HttpAsyncClientSingleton.getInstance(serverConfig).execute(request, context, new ResponseCallback<>(parser, futureResponse));
return futureResponse;
}
private HttpClientContext prepareContext() {
if (serverConfig.getAuthenticationConfig().usesBasicAuthentication()) {
HttpHost targetHost = new HttpHost(serverConfig.getServerName(), serverConfig.getPort(), serverConfig.isUseHTTPS() ? "https" : "http");
AuthCache authCache = new BasicAuthCache();
authCache.put(targetHost, new BasicScheme());
CredentialsProvider credsProvider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials(serverConfig.getAuthenticationConfig().getLoginName(), serverConfig.getAuthenticationConfig().getPassword());
credsProvider.setCredentials(AuthScope.ANY, credentials);
// Add AuthCache to the execution context
HttpClientContext context = HttpClientContext.create();
context.setCredentialsProvider(credsProvider);
context.setAuthCache(authCache);
return context;
}
return HttpClientContext.create();
}
private final class ResponseCallback implements FutureCallback {
private final ResponseParser parser;
private final CompletableFuture futureResponse;
private ResponseCallback(ResponseParser parser, CompletableFuture futureResponse) {
this.parser = parser;
this.futureResponse = futureResponse;
}
@Override
public void completed(HttpResponse response) {
try {
R result = handleResponse(parser, response);
futureResponse.complete(result);
} catch(Exception ex) {
futureResponse.completeExceptionally(ex);
}
}
private R handleResponse(ResponseParser parser, HttpResponse response) throws IOException {
StatusLine statusLine= response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
if (entity != null) {
Charset charset = ContentType.getOrDefault(entity).getCharset();
Reader reader = new InputStreamReader(entity.getContent(), charset);
return parser.parseResponse(reader);
}
throw new NextcloudApiException("Empty response received");
}
throw new NextcloudApiException(String.format("Request failed with %d %s", statusLine.getStatusCode(), statusLine.getReasonPhrase()));
}
@Override
public void failed(Exception ex) {
futureResponse.completeExceptionally(ex);
}
@Override
public void cancelled() {
futureResponse.cancel(true);
}
}
private static class HttpAsyncClientSingleton {
private static CloseableHttpAsyncClient HTTPC_CLIENT;
private HttpAsyncClientSingleton(){}
public static CloseableHttpAsyncClient getInstance(ServerConfig serverConfig)
throws IOException{
if (HTTPC_CLIENT == null) {
if (serverConfig.isTrustAllCertificates()) {
try {
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build();
HTTPC_CLIENT = HttpAsyncClients.custom()
.setSSLHostnameVerifier((NoopHostnameVerifier.INSTANCE))
.setSSLContext(sslContext)
.build();
} catch (KeyManagementException | NoSuchAlgorithmException
| KeyStoreException e) {
throw new IOException(e);
}
} else {
HTTPC_CLIENT = HttpAsyncClients.createDefault();
}
HTTPC_CLIENT.start();
}
return HTTPC_CLIENT;
}
}
public interface ResponseParser {
R parseResponse(Reader reader);
}
/**
* Close the http client. Required for clean shutdown.
* @throws IOException error on shutdown
*/
public static void shutdown() throws IOException {
if(HttpAsyncClientSingleton.HTTPC_CLIENT != null) {
HttpAsyncClientSingleton.getInstance(null).close();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy