private TriggerKey createTriggerKey(String uri, String remaining, QuartzEndpoint endpoint)
      throws Exception {
    // Parse uri for trigger name and group
    URI u = new URI(uri);
    String path = ObjectHelper.after(u.getPath(), "/");
    String host = u.getHost();

    // host can be null if the uri did contain invalid host characters such as an underscore
    if (host == null) {
      host = ObjectHelper.before(remaining, "/");
    }

    // Trigger group can be optional, if so set it to this context's unique name
    String name;
    String group;
    if (ObjectHelper.isNotEmpty(path) && ObjectHelper.isNotEmpty(host)) {
      group = host;
      name = path;
    } else {
      String camelContextName = getCamelContext().getManagementName();
      group = camelContextName == null ? "Camel" : "Camel_" + camelContextName;
      name = host;
    }

    if (prefixJobNameWithEndpointId) {
      name = endpoint.getId() + "_" + name;
    }

    return new TriggerKey(name, group);
  }
Example #2
0
 public String getEndpointKey() {
   if (isLenientProperties()) {
     // only use the endpoint uri without parameters as the properties is
     // lenient
     String uri = getEndpointUri();
     if (uri.indexOf('?') != -1) {
       return ObjectHelper.before(uri, "?");
     } else {
       return uri;
     }
   } else {
     // use the full endpoint uri
     return getEndpointUri();
   }
 }
Example #3
0
 public static String getCharsetFromContentType(String contentType) {
   if (contentType != null) {
     // find the charset and set it to the Exchange
     int index = contentType.indexOf("charset=");
     if (index > 0) {
       String charset = contentType.substring(index + 8);
       // there may be another parameter after a semi colon, so skip that
       if (charset.contains(";")) {
         charset = ObjectHelper.before(charset, ";");
       }
       return IOHelper.normalizeCharset(charset);
     }
   }
   return null;
 }
Example #4
0
  /**
   * Gets the destination name which was configured from the endpoint uri.
   *
   * @return the destination name resolved from the endpoint uri
   */
  public String getEndpointConfiguredDestinationName() {
    String remainder = ObjectHelper.after(getEndpointKey(), "//");

    if (remainder != null && remainder.contains("@")) {
      remainder = remainder.substring(remainder.indexOf('@'));
    }

    if (remainder != null && remainder.contains("?")) {
      // remove parameters
      remainder = ObjectHelper.before(remainder, "?");
    }

    if (ObjectHelper.isEmpty(remainder)) {
      return remainder;
    }

    return remainder;
  }
Example #5
0
  @Override
  protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters)
      throws Exception {
    SparkConfiguration config = getSparkConfiguration().copy();
    setProperties(config, parameters);

    SparkEndpoint answer = new SparkEndpoint(uri, this);
    answer.setSparkConfiguration(config);
    answer.setSparkBinding(getSparkBinding());
    setProperties(answer, parameters);

    if (!remaining.contains(":")) {
      throw new IllegalArgumentException("Invalid syntax. Must be spark-rest:verb:path");
    }

    String verb = ObjectHelper.before(remaining, ":");
    String path = ObjectHelper.after(remaining, ":");

    answer.setVerb(verb);
    answer.setPath(path);

    return answer;
  }
Example #6
0
  /**
   * Get the operation(s) with the given name. We can have multiple when methods is overloaded.
   *
   * <p>Shorthand method names for getters is supported, so you can pass in eg 'name' and Camel will
   * can find the real 'getName' method instead.
   *
   * @param methodName the method name
   * @return the found method, or <tt>null</tt> if not found
   */
  private List<MethodInfo> getOperations(String methodName) {
    // do not use qualifier for name
    if (methodName.contains("(")) {
      methodName = ObjectHelper.before(methodName, "(");
    }

    List<MethodInfo> answer = operations.get(methodName);
    if (answer != null) {
      return answer;
    }

    // now try all getters to see if any of those matched the methodName
    for (Method method : methodMap.keySet()) {
      if (IntrospectionSupport.isGetter(method)) {
        String shorthandMethodName = IntrospectionSupport.getGetterShorthandName(method);
        // if the two names matches then see if we can find it using that name
        if (methodName != null && methodName.equals(shorthandMethodName)) {
          return operations.get(method.getName());
        }
      }
    }

    return null;
  }
Example #7
0
 /**
  * Checks whether the given http status code is within the ok range
  *
  * @param statusCode the status code
  * @param okStatusCodeRange the ok range (inclusive)
  * @return <tt>true</tt> if ok, <tt>false</tt> otherwise
  */
 public static boolean isStatusCodeOk(int statusCode, String okStatusCodeRange) {
   int from = Integer.valueOf(ObjectHelper.before(okStatusCodeRange, "-"));
   int to = Integer.valueOf(ObjectHelper.after(okStatusCodeRange, "-"));
   return statusCode >= from && statusCode <= to;
 }
  @Override
  public void populateCamelHeaders(
      HttpRequest request,
      Map<String, Object> headers,
      Exchange exchange,
      NettyHttpConfiguration configuration)
      throws Exception {
    LOG.trace("populateCamelHeaders: {}", request);

    // NOTE: these headers is applied using the same logic as camel-http/camel-jetty to be
    // consistent

    headers.put(Exchange.HTTP_METHOD, request.getMethod().getName());
    // strip query parameters from the uri
    String s = request.getUri();
    if (s.contains("?")) {
      s = ObjectHelper.before(s, "?");
    }

    // we want the full path for the url, as the client may provide the url in the HTTP headers as
    // absolute or relative, eg
    //   /foo
    //   http://servername/foo
    String http = configuration.isSsl() ? "https://" : "http://";
    if (!s.startsWith(http)) {
      if (configuration.getPort() != 80) {
        s = http + configuration.getHost() + ":" + configuration.getPort() + s;
      } else {
        s = http + configuration.getHost() + s;
      }
    }

    headers.put(Exchange.HTTP_URL, s);
    // uri is without the host and port
    URI uri = new URI(request.getUri());
    // uri is path and query parameters
    headers.put(Exchange.HTTP_URI, uri.getPath());
    headers.put(Exchange.HTTP_QUERY, uri.getQuery());
    headers.put(Exchange.HTTP_RAW_QUERY, uri.getRawQuery());

    // strip the starting endpoint path so the path is relative to the endpoint uri
    String path = uri.getPath();
    if (configuration.getPath() != null && path.startsWith(configuration.getPath())) {
      path = path.substring(configuration.getPath().length());
    }
    headers.put(Exchange.HTTP_PATH, path);

    if (LOG.isTraceEnabled()) {
      LOG.trace("HTTP-Method {}", request.getMethod().getName());
      LOG.trace("HTTP-Uri {}", request.getUri());
    }

    for (String name : request.headers().names()) {
      // mapping the content-type
      if (name.toLowerCase(Locale.US).equals("content-type")) {
        name = Exchange.CONTENT_TYPE;
      }

      if (name.toLowerCase(Locale.US).equals("authorization")) {
        String value = request.headers().get(name);
        // store a special header that this request was authenticated using HTTP Basic
        if (value != null && value.trim().startsWith("Basic")) {
          if (headerFilterStrategy != null
              && !headerFilterStrategy.applyFilterToExternalHeaders(
                  NettyHttpConstants.HTTP_AUTHENTICATION, "Basic", exchange)) {
            NettyHttpHelper.appendHeader(headers, NettyHttpConstants.HTTP_AUTHENTICATION, "Basic");
          }
        }
      }

      // add the headers one by one, and use the header filter strategy
      List<String> values = request.headers().getAll(name);
      Iterator<?> it = ObjectHelper.createIterator(values);
      while (it.hasNext()) {
        Object extracted = it.next();
        Object decoded = shouldUrlDecodeHeader(configuration, name, extracted, "UTF-8");
        LOG.trace("HTTP-header: {}", extracted);
        if (headerFilterStrategy != null
            && !headerFilterStrategy.applyFilterToExternalHeaders(name, decoded, exchange)) {
          NettyHttpHelper.appendHeader(headers, name, decoded);
        }
      }
    }

    // add uri parameters as headers to the Camel message
    if (request.getUri().contains("?")) {
      String query = ObjectHelper.after(request.getUri(), "?");
      Map<String, Object> uriParameters = URISupport.parseQuery(query, false, true);

      for (Map.Entry<String, Object> entry : uriParameters.entrySet()) {
        String name = entry.getKey();
        Object values = entry.getValue();
        Iterator<?> it = ObjectHelper.createIterator(values);
        while (it.hasNext()) {
          Object extracted = it.next();
          Object decoded = shouldUrlDecodeHeader(configuration, name, extracted, "UTF-8");
          LOG.trace("URI-Parameter: {}", extracted);
          if (headerFilterStrategy != null
              && !headerFilterStrategy.applyFilterToExternalHeaders(name, decoded, exchange)) {
            NettyHttpHelper.appendHeader(headers, name, decoded);
          }
        }
      }
    }

    // if body is application/x-www-form-urlencoded then extract the body as query string and append
    // as headers
    // if it is a bridgeEndpoint we need to skip this part of work
    if (request.getMethod().getName().equals("POST")
        && request.headers().get(Exchange.CONTENT_TYPE) != null
        && request
            .headers()
            .get(Exchange.CONTENT_TYPE)
            .startsWith(NettyHttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED)
        && !configuration.isBridgeEndpoint()) {

      String charset = "UTF-8";

      // Push POST form params into the headers to retain compatibility with DefaultHttpBinding
      String body = request.getContent().toString(Charset.forName(charset));
      if (ObjectHelper.isNotEmpty(body)) {
        for (String param : body.split("&")) {
          String[] pair = param.split("=", 2);
          if (pair.length == 2) {
            String name = shouldUrlDecodeHeader(configuration, "", pair[0], charset);
            String value = shouldUrlDecodeHeader(configuration, name, pair[1], charset);
            if (headerFilterStrategy != null
                && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, exchange)) {
              NettyHttpHelper.appendHeader(headers, name, value);
            }
          } else {
            throw new IllegalArgumentException(
                "Invalid parameter, expected to be a pair but was " + param);
          }
        }
      }
    }
  }
Example #9
0
  private MethodInvocation createInvocation(Object pojo, Exchange exchange, Method explicitMethod)
      throws AmbiguousMethodCallException, MethodNotFoundException {
    MethodInfo methodInfo = null;

    // find the explicit method to invoke
    if (explicitMethod != null) {
      for (List<MethodInfo> infos : operations.values()) {
        for (MethodInfo info : infos) {
          if (explicitMethod.equals(info.getMethod())) {
            return info.createMethodInvocation(pojo, exchange);
          }
        }
      }
      throw new MethodNotFoundException(exchange, pojo, explicitMethod.getName());
    }

    String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class);
    if (methodName != null) {

      // do not use qualifier for name
      String name = methodName;
      if (methodName.contains("(")) {
        name = ObjectHelper.before(methodName, "(");
        // the must be a ending parenthesis
        if (!methodName.endsWith(")")) {
          throw new IllegalArgumentException(
              "Method should end with parenthesis, was " + methodName);
        }
      }
      boolean emptyParameters = methodName.endsWith("()");

      // special for getClass, as we want the user to be able to invoke this method
      // for example to log the class type or the likes
      if ("class".equals(name) || "getClass".equals(name)) {
        try {
          Method method = pojo.getClass().getMethod("getClass");
          methodInfo =
              new MethodInfo(
                  exchange.getContext(),
                  pojo.getClass(),
                  method,
                  Collections.<ParameterInfo>emptyList(),
                  Collections.<ParameterInfo>emptyList(),
                  false,
                  false);
        } catch (NoSuchMethodException e) {
          throw new MethodNotFoundException(exchange, pojo, "getClass");
        }
        // special for length on an array type
      } else if ("length".equals(name) && pojo.getClass().isArray()) {
        try {
          // need to use arrayLength method from ObjectHelper as Camel's bean OGNL support is method
          // invocation based
          // and not for accessing fields. And hence we need to create a MethodInfo instance with a
          // method to call
          // and therefore use arrayLength from ObjectHelper to return the array length field.
          Method method = ObjectHelper.class.getMethod("arrayLength", Object[].class);
          ParameterInfo pi =
              new ParameterInfo(
                  0,
                  Object[].class,
                  null,
                  ExpressionBuilder.mandatoryBodyExpression(Object[].class, true));
          List<ParameterInfo> lpi = new ArrayList<ParameterInfo>(1);
          lpi.add(pi);
          methodInfo =
              new MethodInfo(
                  exchange.getContext(), pojo.getClass(), method, lpi, lpi, false, false);
          // Need to update the message body to be pojo for the invocation
          exchange.getIn().setBody(pojo);
        } catch (NoSuchMethodException e) {
          throw new MethodNotFoundException(exchange, pojo, "getClass");
        }
      } else {
        List<MethodInfo> methods = getOperations(name);
        if (methods != null && methods.size() == 1) {
          // only one method then choose it
          methodInfo = methods.get(0);

          // validate that if we want an explicit no-arg method, then that's what we get
          if (emptyParameters && methodInfo.hasParameters()) {
            throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)");
          }
        } else if (methods != null) {
          // there are more methods with that name so we cannot decide which to use

          // but first let's try to choose a method and see if that complies with the name
          // must use the method name which may have qualifiers
          methodInfo = chooseMethod(pojo, exchange, methodName);

          // validate that if we want an explicit no-arg method, then that's what we get
          if (emptyParameters) {
            if (methodInfo == null || methodInfo.hasParameters()) {
              // we could not find a no-arg method with that name
              throw new MethodNotFoundException(exchange, pojo, methodName, "(with no parameters)");
            }
          }

          if (methodInfo == null
              || (name != null && !name.equals(methodInfo.getMethod().getName()))) {
            throw new AmbiguousMethodCallException(exchange, methods);
          }
        } else {
          // a specific method was given to invoke but not found
          throw new MethodNotFoundException(exchange, pojo, methodName);
        }
      }
    }

    if (methodInfo == null) {
      // no name or type
      methodInfo = chooseMethod(pojo, exchange, null);
    }
    if (methodInfo == null) {
      methodInfo = defaultMethod;
    }
    if (methodInfo != null) {
      LOG.trace("Chosen method to invoke: {} on bean: {}", methodInfo, pojo);
      return methodInfo.createMethodInvocation(pojo, exchange);
    }

    LOG.debug("Cannot find suitable method to invoke on bean: {}", pojo);
    return null;
  }
Example #10
0
  private boolean matchMethod(Method method, String methodName) {
    if (methodName == null) {
      return true;
    }

    if (methodName.contains("(") && !methodName.endsWith(")")) {
      throw new IllegalArgumentException(
          "Name must have both starting and ending parenthesis, was: " + methodName);
    }

    // do not use qualifier for name matching
    String name = methodName;
    if (name.contains("(")) {
      name = ObjectHelper.before(name, "(");
    }

    // must match name
    if (name != null && !name.equals(method.getName())) {
      return false;
    }

    // is it a method with no parameters
    boolean noParameters = methodName.endsWith("()");
    if (noParameters) {
      return method.getParameterTypes().length == 0;
    }

    // match qualifier types which is used to select among overloaded methods
    String types = ObjectHelper.between(methodName, "(", ")");
    if (ObjectHelper.isNotEmpty(types)) {
      // we must qualify based on types to match method
      String[] parameters = StringQuoteHelper.splitSafeQuote(types, ',');
      Iterator<?> it = ObjectHelper.createIterator(parameters);
      for (int i = 0; i < method.getParameterTypes().length; i++) {
        if (it.hasNext()) {
          Class<?> parameterType = method.getParameterTypes()[i];

          String qualifyType = (String) it.next();
          if (ObjectHelper.isEmpty(qualifyType)) {
            continue;
          }
          // trim the type
          qualifyType = qualifyType.trim();

          if ("*".equals(qualifyType)) {
            // * is a wildcard so we accept and match that parameter type
            continue;
          }

          if (BeanHelper.isValidParameterValue(qualifyType)) {
            // its a parameter value, so continue to next parameter
            // as we should only check for FQN/type parameters
            continue;
          }

          // if qualify type indeed is a class, then it must be assignable with the parameter type
          Boolean assignable =
              BeanHelper.isAssignableToExpectedType(
                  getCamelContext().getClassResolver(), qualifyType, parameterType);
          // the method will return null if the qualifyType is not a class
          if (assignable != null && !assignable) {
            return false;
          }

        } else {
          // there method has more parameters than was specified in the method name qualifiers
          return false;
        }
      }

      // if the method has no more types then we can only regard it as matched
      // if there are no more qualifiers
      if (it.hasNext()) {
        return false;
      }
    }

    // the method matched
    return true;
  }