
package info.freelibrary.jiiify.services.impl;

import static info.freelibrary.jiiify.Constants.JIIIFY_ARRAY;
import static info.freelibrary.jiiify.Constants.MESSAGES;

import info.freelibrary.jiiify.Configuration;
import info.freelibrary.jiiify.Metadata;
import info.freelibrary.jiiify.services.SolrService;
import info.freelibrary.util.Logger;
import info.freelibrary.util.LoggerFactory;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.json.JsonObject;

/**
 * Solr service implementation.
 */
public class SolrServiceImpl implements SolrService {

    private final Logger LOGGER = LoggerFactory.getLogger(SolrServiceImpl.class, MESSAGES);

    private final Configuration myConfig;

    private final Vertx myVertx;

    public SolrServiceImpl(final Configuration aConfig, final Vertx aVertx) {
        myConfig = aConfig;
        myVertx = aVertx;
    }

    @Override
    public void search(final JsonObject aJsonObject, final Handler<AsyncResult<JsonObject>> aHandler) {
        final String solr = myConfig.getSolrServer().toExternalForm() + "/query";
        final HttpClient client = myVertx.createHttpClient();
        final HttpClientRequest request;

        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("Sending Solr query to: {}", solr);
        }

        request = client.getAbs(solr, response -> {
            if (response.statusCode() == 200) {
                response.bodyHandler(body -> {
                    aHandler.handle(Future.succeededFuture(new JsonObject(body.toString())));
                });
            } else {
                aHandler.handle(Future.failedFuture(response.statusMessage()));
            }
        }).exceptionHandler(exceptionHandler -> {
            aHandler.handle(Future.failedFuture(exceptionHandler));
        });

        request.putHeader(Metadata.CONTENT_TYPE, Metadata.JSON_MIME_TYPE);
        request.end(aJsonObject.toString());
        client.close();
    }

    @Override
    public void index(final JsonObject aJsonObject, final Handler<AsyncResult<String>> aHandler) {
        final String solr = myConfig.getSolrServer().toExternalForm() + "/update/json?commit=true";
        final HttpClient client = myVertx.createHttpClient();
        final HttpClientRequest request;

        request = client.postAbs(solr, response -> {
            if (response.statusCode() == 200) {
                aHandler.handle(Future.succeededFuture());
            } else {
                aHandler.handle(Future.failedFuture(response.statusMessage()));
            }
        }).exceptionHandler(exceptionHandler -> {
            aHandler.handle(Future.failedFuture(exceptionHandler));
        });

        request.putHeader(Metadata.CONTENT_TYPE, Metadata.JSON_MIME_TYPE);

        if (aJsonObject.size() == 1 && aJsonObject.containsKey(JIIIFY_ARRAY)) {
            request.end(aJsonObject.getJsonArray(JIIIFY_ARRAY).toString());
        } else {
            request.end(aJsonObject.toString());
        }

        client.close();
    }

}

@@ -544,16 +544,61 @@
 Client;%0A
+import io.vertx.core.http.HttpClientOptions;%0A
 import i
@@ -857,24 +857,63 @@
 MESSAGES);%0A%0A
+    private final int MAX_TRIES = 10;%0A%0A
     private 
@@ -2402,16 +2402,124 @@
 =true%22;%0A
+        final HttpClientOptions options = new HttpClientOptions().setTcpKeepAlive(false).setMaxPoolSize(1);%0A
         
@@ -2565,35 +2565,43 @@
 eHttpClient(
+options
 );%0A
+%0A
         
 final HttpCl
@@ -2580,32 +2580,269 @@
 ions);%0A%0A        
+post(client, solr, aJsonObject, aHandler, 0);%0A    %7D%0A%0A    private void post(final HttpClient aClient, final String aURL, final JsonObject aJsonObject,%0A            final Handler%3CAsyncResult%3CString%3E%3E aHandler, final int aCounter) %7B%0A        
 final HttpClient
@@ -2848,34 +2848,16 @@
 tRequest
- request;%0A%0A       
  request
@@ -2855,25 +2855,26 @@
 t request = 
-c
+aC
 lient.postAb
@@ -2871,28 +2871,28 @@
 ent.postAbs(
-solr
+aURL
 , response -
@@ -2935,32 +2935,65 @@
 ode() == 200) %7B%0A
+                aClient.close();%0A
                 
@@ -3046,34 +3046,256 @@
          %7D else 
-%7B%0A
+if (response.statusCode() == 503) %7B%0A                if (aCounter %3C MAX_TRIES) %7B%0A                    post(aClient, aURL, aJsonObject, aHandler, aCounter + 1);%0A                %7D else %7B%0A                    aClient.close();%0A    
                 
@@ -3362,32 +3362,36 @@
 ));%0A            
+    
 %7D%0A        %7D).exc
@@ -3384,36 +3384,167 @@
         
-%7D).exceptionHandler(
+    %7D else %7B%0A                aClient.close();%0A                aHandler.handle(Future.failedFuture(response.statusMessage()));%0A            %7D%0A        %7D).
 exceptio
@@ -3543,38 +3543,138 @@
 exceptionHandler
+(exception
  -%3E %7B%0A
+            LOGGER.error(exception, exception.getMessage());%0A            aClient.close();%0A
             aHan
@@ -3706,39 +3706,32 @@
 Future(exception
-Handler
 ));%0A        %7D);%0A
@@ -4042,39 +4042,13 @@
    %7D
-%0A%0A        client.close();
 %0A    %7D%0A
-%0A
 %7D%0A

Add retry to Solr indexer