public Promise<ResourceResponse, ResourceException> handleUpdate(
     Context context, UpdateRequest request) {
   EventEntry measure =
       Publisher.start(
           Name.get(
               "openidm/internal/script/" + this.getScriptEntry().getName().getName() + "/update"),
           null,
           null);
   try {
     final ScriptEntry _scriptEntry = getScriptEntry();
     if (!_scriptEntry.isActive()) {
       throw new ServiceUnavailableException("Inactive script: " + _scriptEntry.getName());
     }
     final Script script = _scriptEntry.getScript(context);
     script.setBindings(script.createBindings());
     customizer.handleUpdate(context, request, script.getBindings());
     return evaluate(request, script);
   } catch (ScriptException e) {
     return convertScriptException(e).asPromise();
   } catch (ResourceException e) {
     return e.asPromise();
   } catch (Exception e) {
     return new InternalServerErrorException(e.getMessage(), e).asPromise();
   } finally {
     measure.end();
   }
 }
 public Promise<ActionResponse, ResourceException> handleAction(
     final Context context, final ActionRequest request) {
   EventEntry measure =
       Publisher.start(
           Name.get(
               "openidm/internal/script/" + this.getScriptEntry().getName().getName() + "/action"),
           null,
           null);
   try {
     final ScriptEntry _scriptEntry = getScriptEntry();
     if (!_scriptEntry.isActive()) {
       throw new ServiceUnavailableException("Inactive script: " + _scriptEntry.getName());
     }
     final Script script = _scriptEntry.getScript(context);
     script.setBindings(script.createBindings());
     customizer.handleAction(context, request, script.getBindings());
     Object result = script.eval();
     if (null == result) {
       return newActionResponse(new JsonValue(null)).asPromise();
     } else if (result instanceof JsonValue) {
       return newActionResponse((JsonValue) result).asPromise();
     } else if (result instanceof Map) {
       return newActionResponse(new JsonValue(result)).asPromise();
     } else {
       JsonValue resource = new JsonValue(new HashMap<String, Object>(1));
       resource.put("result", result);
       return newActionResponse(new JsonValue(result)).asPromise();
     }
   } catch (ScriptException e) {
     return convertScriptException(e).asPromise();
   } catch (ResourceException e) {
     return e.asPromise();
   } catch (Exception e) {
     return new InternalServerErrorException(e.getMessage(), e).asPromise();
   } finally {
     measure.end();
   }
 }
  /**
   * TODO Implement this method
   *
   * <p>{@inheritDoc}
   */
  public Promise<QueryResponse, ResourceException> handleQuery(
      final Context context, final QueryRequest request, final QueryResourceHandler handler) {
    EventEntry measure =
        Publisher.start(
            Name.get(
                "openidm/internal/script/" + this.getScriptEntry().getName().getName() + "/query"),
            null,
            null);
    try {
      final ScriptEntry _scriptEntry = getScriptEntry();
      if (!_scriptEntry.isActive()) {
        throw new ServiceUnavailableException("Inactive script: " + _scriptEntry.getName());
      }
      final Script script = _scriptEntry.getScript(context);
      script.setBindings(script.createBindings());
      customizer.handleQuery(context, request, script.getBindings());

      final Function<Void> queryCallback =
          new Function<Void>() {
            @Override
            public Void call(Parameter scope, Function<?> callback, Object... arguments)
                throws ResourceException, NoSuchMethodException {
              if (arguments.length == 3 && null != arguments[2]) {
                if (arguments[2] instanceof Map) {}

                if (arguments[2] instanceof JsonValue) {

                } else {
                  throw new NoSuchMethodException(
                      FunctionFactory.getNoSuchMethodMessage("callback", arguments));
                }
              } else if (arguments.length >= 2 && null != arguments[1]) {
                if (arguments[1] instanceof Map) {}

                if (arguments[1] instanceof JsonValue) {

                } else {
                  throw new NoSuchMethodException(
                      FunctionFactory.getNoSuchMethodMessage("callback", arguments));
                }
              } else if (arguments.length >= 1 && null != arguments[0]) {
                if (arguments[0] instanceof Map) {}

                if (arguments[0] instanceof JsonValue) {

                } else {
                  throw new NoSuchMethodException(
                      FunctionFactory.getNoSuchMethodMessage("callback", arguments));
                }
              } else {
                throw new NoSuchMethodException(
                    FunctionFactory.getNoSuchMethodMessage("callback", arguments));
              }
              return null;
            }
          };
      script.putSafe("callback", queryCallback);
      Object rawResult = script.eval();
      JsonValue result = null;
      if (rawResult instanceof JsonValue) {
        result = (JsonValue) rawResult;
      } else {
        result = new JsonValue(rawResult);
      }
      QueryResponse queryResponse = newQueryResponse();
      // Script can either
      // - return null and instead use callback hook to call
      //   handleResource, handleResult, handleError
      //   careful! script MUST call handleResult or handleError itself
      // or
      // - return a result list of resources
      // or
      // - return a full query result structure
      if (!result.isNull()) {
        if (result.isList()) {
          // Script may return just the result elements as a list
          handleQueryResultList(result, handler);
        } else {
          // Or script may return a full query response structure,
          // with meta-data and results field
          if (result.isDefined(QueryResponse.FIELD_RESULT)) {
            handleQueryResultList(result.get(QueryResponse.FIELD_RESULT), handler);
            queryResponse =
                newQueryResponse(
                    result.get(QueryResponse.FIELD_PAGED_RESULTS_COOKIE).asString(),
                    result
                        .get(QueryResponse.FIELD_TOTAL_PAGED_RESULTS_POLICY)
                        .asEnum(CountPolicy.class),
                    result.get(QueryResponse.FIELD_TOTAL_PAGED_RESULTS).asInteger());
          } else {
            logger.debug("Script returned unexpected query result structure: ", result.getObject());
            return new InternalServerErrorException(
                    "Script returned unexpected query result structure of type "
                        + result.getObject().getClass())
                .asPromise();
          }
        }
      }
      return queryResponse.asPromise();
    } catch (ScriptException e) {
      return convertScriptException(e).asPromise();
    } catch (ResourceException e) {
      return e.asPromise();
    } catch (Exception e) {
      return new InternalServerErrorException(e.getMessage(), e).asPromise();
    } finally {
      measure.end();
    }
  }
Example #4
0
  public Integer command(final String type, Map<String, Object> params, Connection con)
      throws ResourceException {

    Integer result = null;
    params.put(ServerConstants.RESOURCE_NAME, type);

    String queryExpression = (String) params.get("commandExpression");
    String queryId = (String) params.get("commandId");
    if (queryId == null && queryExpression == null) {
      throw new BadRequestException(
          "Either "
              + "commandId"
              + " or "
              + "commandExpression"
              + " to identify/define a query must be passed in the parameters. "
              + params);
    }
    final PreparedStatement foundQuery;
    try {
      if (queryExpression != null) {
        foundQuery = resolveInlineQuery(con, queryExpression, params);
      } else if (commands.queryIdExists(queryId)) {
        foundQuery = commands.getQuery(con, queryId, type, params);
      } else {
        throw new BadRequestException(
            "The passed command identifier "
                + queryId
                + " does not match any configured commands on the JDBC repository service.");
      }
    } catch (SQLException ex) {
      throw new InternalServerErrorException(
          "DB reported failure preparing command: "
              + (queryExpression != null
                  ? queryExpression
                  : commands.getQueryInfo(queryId).getQueryString())
              + " with params: "
              + params
              + " error code: "
              + ex.getErrorCode()
              + " sqlstate: "
              + ex.getSQLState()
              + " message: "
              + ex.getMessage(),
          ex);
    }

    Name eventName = getEventName(queryId);
    EventEntry measure = Publisher.start(eventName, foundQuery, null);
    ResultSet rs = null;
    try {
      result = foundQuery.executeUpdate();
      measure.setResult(result);
    } catch (SQLException ex) {
      throw new InternalServerErrorException(
          "DB reported failure executing query "
              + foundQuery.toString()
              + " with params: "
              + params
              + " error code: "
              + ex.getErrorCode()
              + " sqlstate: "
              + ex.getSQLState()
              + " message: "
              + ex.getMessage(),
          ex);
    } finally {
      CleanupHelper.loggedClose(rs);
      CleanupHelper.loggedClose(foundQuery);
      measure.end();
    }
    return result;
  }
Example #5
0
  /**
   * Execute a query, either a pre-configured query by using the query ID, or a query expression
   * passed as part of the params.
   *
   * <p>The keys for the input parameters as well as the return map entries are in QueryConstants.
   *
   * @param type the resource component name targeted by the URI
   * @param params the parameters which include the query id, or the query expression, as well as
   *     the token key/value pairs to replace in the query
   * @param con a handle to a database connection newBuilder for exclusive use by the query method
   *     whilst it is executing.
   * @return The query result, which includes meta-data about the query, and the result set itself.
   * @throws BadRequestException if the passed request parameters are invalid, e.g. missing query id
   *     or query expression or tokens.
   * @throws InternalServerErrorException if the preparing or executing the query fails because of
   *     configuration or DB issues
   */
  public List<Map<String, Object>> query(
      final String type, Map<String, Object> params, Connection con) throws ResourceException {

    List<Map<String, Object>> result = null;
    params.put(ServerConstants.RESOURCE_NAME, type);

    // If paged results are requested then decode the cookie in order to determine
    // the index of the first result to be returned.
    final int requestPageSize = (Integer) params.get(PAGE_SIZE);

    final String offsetParam;
    final String pageSizeParam;

    if (requestPageSize > 0) {
      offsetParam = String.valueOf((Integer) params.get(PAGED_RESULTS_OFFSET));
      pageSizeParam = String.valueOf(requestPageSize);
    } else {
      offsetParam = "0";
      pageSizeParam = String.valueOf(Integer.MAX_VALUE);
    }

    params.put(PAGED_RESULTS_OFFSET, offsetParam);
    params.put(PAGE_SIZE, pageSizeParam);
    QueryFilter queryFilter = (QueryFilter) params.get(QUERY_FILTER);
    String queryExpression = (String) params.get(QUERY_EXPRESSION);
    String queryId = (String) params.get(QUERY_ID);
    if (queryId == null && queryExpression == null && queryFilter == null) {
      throw new BadRequestException(
          "Either "
              + QUERY_ID
              + ", "
              + QUERY_EXPRESSION
              + ", or "
              + QUERY_FILTER
              + " to identify/define a query must be passed in the parameters. "
              + params);
    }
    logger.debug("Querying " + params);
    final PreparedStatement foundQuery;
    try {
      if (queryFilter != null) {
        foundQuery = parseQueryFilter(con, queryFilter, params);
      } else if (queryExpression != null) {
        foundQuery = resolveInlineQuery(con, queryExpression, params);
      } else if (queries.queryIdExists(queryId)) {
        foundQuery = queries.getQuery(con, queryId, type, params);
      } else {
        throw new BadRequestException(
            "The passed query identifier "
                + queryId
                + " does not match any configured queries on the JDBC repository service.");
      }
    } catch (SQLException ex) {
      final String queryDescription;
      if (queryFilter != null) {
        queryDescription = queryFilter.toString();
      } else if (queryExpression != null) {
        queryDescription = queryExpression;
      } else {
        queryDescription = queries.getQueryInfo(queryId).getQueryString();
      }
      throw new InternalServerErrorException(
          "DB reported failure preparing query: "
              + queryDescription
              + " with params: "
              + params
              + " error code: "
              + ex.getErrorCode()
              + " sqlstate: "
              + ex.getSQLState()
              + " message: "
              + ex.getMessage(),
          ex);
    }

    Name eventName = getEventName(queryId);
    EventEntry measure = Publisher.start(eventName, foundQuery, null);
    ResultSet rs = null;
    try {
      rs = foundQuery.executeQuery();
      result = resultMapper.mapQueryToObject(rs, queryId, type, params, this);
      measure.setResult(result);
    } catch (SQLException ex) {
      throw new InternalServerErrorException(
          "DB reported failure executing query "
              + foundQuery.toString()
              + " with params: "
              + params
              + " error code: "
              + ex.getErrorCode()
              + " sqlstate: "
              + ex.getSQLState()
              + " message: "
              + ex.getMessage(),
          ex);
    } catch (IOException ex) {
      throw new InternalServerErrorException(
          "Failed to convert result objects for query "
              + foundQuery.toString()
              + " with params: "
              + params
              + " message: "
              + ex.getMessage(),
          ex);
    } finally {
      CleanupHelper.loggedClose(rs);
      CleanupHelper.loggedClose(foundQuery);
      measure.end();
    }
    return result;
  }