@Override
 protected Long compute() {
   try {
     final QueryResponse response = catalogFramework.query(queryRequest);
     return response.getHits();
   } catch (UnsupportedQueryException | FederationException | SourceUnavailableException e) {
     LOGGER.warn("Query error", e);
     return 0L;
   }
 }
Example #2
0
  @Override
  public QueryResponse processPostQuery(QueryResponse input) throws StopProcessingException {
    if (input.getRequest() == null || input.getRequest().getProperties() == null) {
      throw new StopProcessingException(
          "Unable to filter contents of current message, no user Subject available.");
    }
    Subject subject = getSubject(input);

    List<Result> results = input.getResults();
    List<Result> newResults = new ArrayList<>(results.size());
    Metacard metacard;
    KeyValueCollectionPermission securityPermission =
        new KeyValueCollectionPermission(CollectionPermission.READ_ACTION);
    int filteredMetacards = 0;
    for (Result result : results) {
      metacard = result.getMetacard();
      Attribute attr = metacard.getAttribute(Metacard.SECURITY);
      if (!checkPermissions(attr, securityPermission, subject, CollectionPermission.READ_ACTION)) {
        for (FilterStrategy filterStrategy : filterStrategies.values()) {
          FilterResult filterResult = filterStrategy.process(input, metacard);
          if (filterResult.processed()) {
            if (filterResult.metacard() != null) {
              newResults.add(new ResultImpl(filterResult.metacard()));
            }
            break;
            // returned responses are ignored for queries
          }
        }
        filteredMetacards++;
      } else {
        newResults.add(result);
      }
    }

    LOGGER.info("Filtered {} metacards, returned {}", filteredMetacards, newResults.size());
    SecurityLogger.logInfo(
        "Filtered " + filteredMetacards + " metacards, returned " + newResults.size());

    input.getResults().clear();
    input.getResults().addAll(newResults);
    newResults.clear();
    return input;
  }
Example #3
0
 /**
  * Replaces the site name(s) of {@link FederatedSource}s in the {@link QueryResponse} with the
  * fanout's site name to keep info about the {@link FederatedSource}s hidden from the external
  * client.
  *
  * @param queryResponse the original {@link QueryResponse} from the query request
  * @return the updated {@link QueryResponse} with all site names replaced with fanout's site name
  */
 public QueryResponse replaceSourceId(QueryResponse queryResponse) {
   LOGGER.trace("ENTERING: replaceSourceId()");
   List<Result> results = queryResponse.getResults();
   QueryResponseImpl newResponse =
       new QueryResponseImpl(queryResponse.getRequest(), queryResponse.getProperties());
   for (Result result : results) {
     MetacardImpl newMetacard = new MetacardImpl(result.getMetacard());
     newMetacard.setSourceId(this.getId());
     ResultImpl newResult = new ResultImpl(newMetacard);
     // Copy over scores
     newResult.setDistanceInMeters(result.getDistanceInMeters());
     newResult.setRelevanceScore(result.getRelevanceScore());
     newResponse.addResult(newResult, false);
   }
   newResponse.setHits(queryResponse.getHits());
   newResponse.closeResultQueue();
   LOGGER.trace("EXITING: replaceSourceId()");
   return newResponse;
 }
Example #4
0
  private QueryResponse injectAttributes(QueryResponse response) {
    List<Result> results =
        response
            .getResults()
            .stream()
            .map(
                result -> {
                  Metacard original = result.getMetacard();
                  Metacard metacard =
                      opsMetacardSupport.applyInjectors(
                          original, frameworkProperties.getAttributeInjectors());
                  ResultImpl newResult = new ResultImpl(metacard);
                  newResult.setDistanceInMeters(result.getDistanceInMeters());
                  newResult.setRelevanceScore(result.getRelevanceScore());
                  return newResult;
                })
            .collect(Collectors.toList());

    return new QueryResponseImpl(
        response.getRequest(), results, true, response.getHits(), response.getProperties());
  }
Example #5
0
  private QueryResponse populateQueryResponsePolicyMap(QueryResponse queryResponse)
      throws FederationException {
    HashMap<String, Set<String>> responsePolicyMap = new HashMap<>();
    Map<String, Serializable> unmodifiableProperties =
        Collections.unmodifiableMap(queryResponse.getProperties());
    for (Result result : queryResponse.getResults()) {
      HashMap<String, Set<String>> itemPolicyMap = new HashMap<>();
      for (PolicyPlugin plugin : frameworkProperties.getPolicyPlugins()) {
        try {
          PolicyResponse policyResponse = plugin.processPostQuery(result, unmodifiableProperties);
          opsSecuritySupport.buildPolicyMap(itemPolicyMap, policyResponse.itemPolicy().entrySet());
          opsSecuritySupport.buildPolicyMap(
              responsePolicyMap, policyResponse.operationPolicy().entrySet());
        } catch (StopProcessingException e) {
          throw new FederationException("Query could not be executed.", e);
        }
      }
      result.getMetacard().setAttribute(new AttributeImpl(Metacard.SECURITY, itemPolicyMap));
    }
    queryResponse.getProperties().put(PolicyPlugin.OPERATION_SECURITY, responsePolicyMap);

    return queryResponse;
  }
Example #6
0
  /**
   * Adds any exceptions to the query response's processing details.
   *
   * @param exceptions the set of exceptions to include in the response's {@link ProcessingDetails}.
   *     Can be empty, but cannot be null.
   * @param response the {@link QueryResponse} to add the exceptions to
   * @return the modified {@link QueryResponse}
   */
  private QueryResponse addProcessingDetails(
      Set<ProcessingDetails> exceptions, QueryResponse response) {

    if (!exceptions.isEmpty()) {
      // we have exceptions to merge in
      if (response == null) {
        LOGGER.debug(
            "Could not add Query exceptions to a QueryResponse because the list of ProcessingDetails was null -- according to the API this should not happen");
      } else {
        // need to merge them together.
        Set<ProcessingDetails> sourceDetails = response.getProcessingDetails();
        sourceDetails.addAll(exceptions);
      }
    }
    return response;
  }
Example #7
0
  /**
   * Validates that the {@link QueryResponse} has a non-null list of {@link Result}s in it, and that
   * the original {@link QueryRequest} is included in the response.
   *
   * @param queryResponse the original {@link QueryResponse} returned from the source
   * @param overrideFanoutRename
   * @param fanoutEnabled
   * @return the updated {@link QueryResponse}
   * @throws UnsupportedQueryException if the original {@link QueryResponse} is null or the results
   *     list is null
   */
  private QueryResponse validateFixQueryResponse(
      QueryResponse queryResponse, boolean overrideFanoutRename, boolean fanoutEnabled)
      throws UnsupportedQueryException {
    if (queryResponse == null) {
      throw new UnsupportedQueryException("CatalogProvider returned null QueryResponse Object.");
    }
    if (queryResponse.getResults() == null) {
      throw new UnsupportedQueryException(
          "CatalogProvider returned null list of results from query method.");
    }

    if (fanoutEnabled && !overrideFanoutRename) {
      queryResponse = replaceSourceId(queryResponse);
    }

    return queryResponse;
  }