javamarklogicmarklogic-dhf

Can't get access to Data Hub Service using Java API


I'm trying to execute a search on my Data Hub Service using Java API. Unfortunately, the server returns the Unauthorized response. Here is the code:

  public Object doSearch() throws NoSuchAlgorithmException, KeyManagementException {
    String user = *****;
    String password = ******;
    String db = "data-hub-FINAL";
    String host = "***********.marklogicsvc.com";
    int port = 8011;
    SecurityContext auth = new DatabaseClientFactory.DigestAuthContext(user, password).withSSLContext(SSLContext.getDefault());
    DatabaseClient client = DatabaseClientFactory.newClient(host, port, db, auth);
    try {
      QueryManager qm = client.newQueryManager();
      StructuredQueryBuilder qb = qm.newStructuredQueryBuilder();
      qm.setPageLength(100);
      var query = qb.collection("listings");

      return qm.search(query, new SearchHandle());
    } finally {
      client.release();
    }
  }

I suspected that I've used wrong credentials but when I tried them in Visual Studio Code Marklogic Extension it worked fine, here are my VS Code settings and query:

    "marklogic.modulesDb": "data-hub-MODULES",
    "marklogic.host": "*******.marklogicsvc.com",
    "marklogic.password": *******,
    "marklogic.username": *******,
    "marklogic.ssl": true,
    "marklogic.port": 8011

query:

xquery version "3.0";

declare namespace cts = "http://marklogic.com/cts";

cts:search(fn:collection(("listings")), cts:and-query(()))

I would be very happy if you tell me what is wrong with my Java code that I can not connect to DHS.


Solution

  • The answer from @rjrudin is correct but here is a full code snippet that should work.

            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];                
                }
            };
            sslContext.init(null, new TrustManager[] { trustManager }, null);
    
            return DatabaseClientFactory.newClient(
                host, port,
                new DatabaseClientFactory.BasicAuthContext(user, password).withSSLContext(sslContext, trustManager),
                DatabaseClient.ConnectionType.GATEWAY
            );
    

    Note the DatabaseClient.ConnectionType.GATEWAY argument because you are connecting through a load balancer with DHS.

    Also note that this is not validating the certificate. For a production implementation, you would want to have logic in your trust manager that would meet your security requirements.