예제 #1
0
 /**
  * Create a SolrClient based on the type of Solr specified.
  *
  * @param context The context
  * @return an HttpSolrClient or CloudSolrClient
  */
 protected SolrClient createSolrClient(final ProcessContext context) {
   if (SOLR_TYPE_STANDARD.equals(context.getProperty(SOLR_TYPE).getValue())) {
     return new HttpSolrClient(context.getProperty(SOLR_LOCATION).getValue());
   } else {
     CloudSolrClient cloudSolrClient =
         new CloudSolrClient(context.getProperty(SOLR_LOCATION).getValue());
     cloudSolrClient.setDefaultCollection(
         context.getProperty(COLLECTION).evaluateAttributeExpressions().getValue());
     return cloudSolrClient;
   }
 }
예제 #2
0
  @Override
  protected final Collection<ValidationResult> customValidate(ValidationContext context) {
    final List<ValidationResult> problems = new ArrayList<>();

    if (SOLR_TYPE_CLOUD.equals(context.getProperty(SOLR_TYPE).getValue())) {
      final String collection = context.getProperty(COLLECTION).getValue();
      if (collection == null || collection.trim().isEmpty()) {
        problems.add(
            new ValidationResult.Builder()
                .subject(COLLECTION.getName())
                .input(collection)
                .valid(false)
                .explanation("A collection must specified for Solr Type of Cloud")
                .build());
      }
    }

    Collection<ValidationResult> otherProblems = this.additionalCustomValidation(context);
    if (otherProblems != null) {
      problems.addAll(otherProblems);
    }

    return problems;
  }
예제 #3
0
  private synchronized void initializeServer(final ProcessContext context) throws Exception {
    if (initialized.get()) {
      return;
    }
    this.containerQueue =
        new LinkedBlockingQueue<>(context.getProperty(CONTAINER_QUEUE_SIZE).asInteger());
    final String host = context.getProperty(HOSTNAME).getValue();
    final int port = context.getProperty(PORT).asInteger();
    final SSLContextService sslService =
        context.getProperty(SSL_CONTEXT).asControllerService(SSLContextService.class);

    final String clientAuthValue = context.getProperty(CLIENT_AUTH).getValue();
    final boolean need;
    final boolean want;
    if (CLIENT_NEED.equals(clientAuthValue)) {
      need = true;
      want = false;
    } else if (CLIENT_WANT.equals(clientAuthValue)) {
      need = false;
      want = true;
    } else {
      need = false;
      want = false;
    }

    final SslContextFactory sslFactory =
        (sslService == null) ? null : createSslFactory(sslService, need, want);
    final Server server = new Server(port);

    // create the http configuration
    final HttpConfiguration httpConfiguration = new HttpConfiguration();
    if (sslFactory == null) {
      // create the connector
      final ServerConnector http =
          new ServerConnector(server, new HttpConnectionFactory(httpConfiguration));

      // set host and port
      if (StringUtils.isNotBlank(host)) {
        http.setHost(host);
      }
      http.setPort(port);

      // add this connector
      server.setConnectors(new Connector[] {http});
    } else {
      // add some secure config
      final HttpConfiguration httpsConfiguration = new HttpConfiguration(httpConfiguration);
      httpsConfiguration.setSecureScheme("https");
      httpsConfiguration.setSecurePort(port);
      httpsConfiguration.addCustomizer(new SecureRequestCustomizer());

      // build the connector
      final ServerConnector https =
          new ServerConnector(
              server,
              new SslConnectionFactory(sslFactory, "http/1.1"),
              new HttpConnectionFactory(httpsConfiguration));

      // set host and port
      if (StringUtils.isNotBlank(host)) {
        https.setHost(host);
      }
      https.setPort(port);

      // add this connector
      server.setConnectors(new Connector[] {https});
    }

    final Set<String> allowedMethods = new HashSet<>();
    if (context.getProperty(ALLOW_GET).asBoolean()) {
      allowedMethods.add("GET");
    }
    if (context.getProperty(ALLOW_POST).asBoolean()) {
      allowedMethods.add("POST");
    }
    if (context.getProperty(ALLOW_PUT).asBoolean()) {
      allowedMethods.add("PUT");
    }
    if (context.getProperty(ALLOW_DELETE).asBoolean()) {
      allowedMethods.add("DELETE");
    }
    if (context.getProperty(ALLOW_HEAD).asBoolean()) {
      allowedMethods.add("HEAD");
    }
    if (context.getProperty(ALLOW_OPTIONS).asBoolean()) {
      allowedMethods.add("OPTIONS");
    }

    final String additionalMethods = context.getProperty(ADDITIONAL_METHODS).getValue();
    if (additionalMethods != null) {
      for (final String additionalMethod : additionalMethods.split(",")) {
        final String trimmed = additionalMethod.trim();
        if (!trimmed.isEmpty()) {
          allowedMethods.add(trimmed.toUpperCase());
        }
      }
    }

    final String pathRegex = context.getProperty(PATH_REGEX).getValue();
    final Pattern pathPattern = (pathRegex == null) ? null : Pattern.compile(pathRegex);

    server.setHandler(
        new AbstractHandler() {
          @Override
          public void handle(
              final String target,
              final Request baseRequest,
              final HttpServletRequest request,
              final HttpServletResponse response)
              throws IOException, ServletException {

            final String requestUri = request.getRequestURI();
            if (!allowedMethods.contains(request.getMethod().toUpperCase())) {
              getLogger()
                  .info(
                      "Sending back METHOD_NOT_ALLOWED response to {}; method was {}; request URI was {}",
                      new Object[] {request.getRemoteAddr(), request.getMethod(), requestUri});
              response.sendError(Status.METHOD_NOT_ALLOWED.getStatusCode());
              return;
            }

            if (pathPattern != null) {
              final URI uri;
              try {
                uri = new URI(requestUri);
              } catch (final URISyntaxException e) {
                throw new ServletException(e);
              }

              if (!pathPattern.matcher(uri.getPath()).matches()) {
                response.sendError(Status.NOT_FOUND.getStatusCode());
                getLogger()
                    .info(
                        "Sending back NOT_FOUND response to {}; request was {} {}",
                        new Object[] {request.getRemoteAddr(), request.getMethod(), requestUri});
                return;
              }
            }

            // If destination queues full, send back a 503: Service Unavailable.
            if (context.getAvailableRelationships().isEmpty()) {
              response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
              return;
            }

            // Right now, that information, though, is only in the ProcessSession, not the
            // ProcessContext,
            // so it is not known to us. Should see if it can be added to the ProcessContext.
            final AsyncContext async = baseRequest.startAsync();
            async.setTimeout(Long.MAX_VALUE); // timeout is handled by HttpContextMap
            final boolean added =
                containerQueue.offer(new HttpRequestContainer(request, response, async));

            if (added) {
              getLogger()
                  .debug(
                      "Added Http Request to queue for {} {} from {}",
                      new Object[] {request.getMethod(), requestUri, request.getRemoteAddr()});
            } else {
              getLogger()
                  .info(
                      "Sending back a SERVICE_UNAVAILABLE response to {}; request was {} {}",
                      new Object[] {
                        request.getRemoteAddr(), request.getMethod(), request.getRemoteAddr()
                      });

              response.sendError(Status.SERVICE_UNAVAILABLE.getStatusCode());
              response.flushBuffer();
              async.complete();
            }
          }
        });

    this.server = server;
    server.start();

    getLogger().info("Server started and listening on port " + getPort());

    initialized.set(true);
  }