CRMConnection.java [src/java/rv/utils] Revision: default  Date:
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API, and application suite.
 *
 * 2012-2022, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package rv.utils;

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
import csip.utils.Client;
import csip.SessionLogger;
import csip.utils.Parallel;
import csip.utils.TTLCache;
import java.util.logging.Level;
import m.rv.ApplicationResources;

/**
 *
 * @author od
 */
public class CRMConnection implements ApplicationResources {

  static final TTLCache<String, String> cache = new TTLCache<>()
      .withSize(CRM_CACHE_SIZE);

  SessionLogger log;

  static final int retry = CRM_CON_RETRY;

  static final Configuration CONF = Configuration.defaultConfiguration()
      .addOptions(Option.SUPPRESS_EXCEPTIONS);


  public CRMConnection(SessionLogger log) {
    this.log = log;
  }


  String callCRM(String url, String req) throws Exception {
    int r = 0;
    String res;
    synchronized (cache) {
      res = cache.get(req);   // change to 'url + req' if url is variant.
    }
    if (res != null) {
      if (log != null && log.isLoggable(Level.INFO))
        log.info("From Cache: " + url + ": " + res);

      return res;
    }

    while (r < retry) {
      try (Client c = new Client(CRM_TIMEOUT)) {
        res = c.doPOST(url, req);
        if (res == null || res.isEmpty())
          throw new Exception("Empty response, calling " + url);

        int err_idx;
        if ((err_idx = res.indexOf("error")) > 0) {
//          throw new Exception("Error calling '" + url + "' wih: " + req
//              + ", Error: '" + res.substring(err_idx + 7));
          res = "[ { \"error\": \"" + res.substring(err_idx + 7) + "\"} ]";
          log.severe("Retry # " + r + " because of: " + res);
          r++;
          continue;
        }

        synchronized (cache) {
          long untilEoD = TTLCache.untilEndOfDay();
          cache.put(req, res, CRM_CACHE_TTL, untilEoD);
        }

        if (log != null && log.isLoggable(Level.INFO))
          log.info("From CRM: " + url + ": " + res);
        
        // all good, break out.
        r = retry;
      } catch (Exception E) {
        r++;
        log.severe("Error for " + req + " :" + E.getMessage());
        res = "[ { \"error\": \"" + E.getMessage() + "\"} ]";
      }
    }

    return res;
  }


  String[] callCRM(String req[], SessionLogger log) throws Exception {
    String[] res = new String[req.length];

    Parallel.run(CRM_PARALLEL_CALLS, req.length, (Integer i) -> () -> {
      res[i] = getProductList(req[i]);
      log.info("Result: " + i + ": " + res[i]);
    });
    return res;
  }


  public String getProductList(String sym) throws Exception {
    return callCRM(CRM_URL + CRM_PRODUCTS, "{\"plantsymbol\":\"" + sym + "\"}");
  }


  public String[] getProductsList(String syms[], SessionLogger log) throws Exception {
    return callCRM(syms, log);
  }

}