예제 #1
0
  public void process(Exchange exchange) throws Exception {
    if (executor == null) {
      executor =
          exchange
              .getContext()
              .getExecutorServiceManager()
              .newFixedThreadPool(this, "CLAIM-CHECK", 4);
    }

    String id = tag.evaluate(exchange, String.class);
    exchange.setProperty(ClaimCheck.CLAIMCHECK_TAG_HEADER, id);

    final Producer conveyor = findDestination(exchange).createProducer();
    final Exchange baggage = ExchangeHelper.createCorrelatedCopy(exchange, false);

    LOG.info("Checking in 'baggage'");
    executor.submit(
        new Callable<Exchange>() {
          public Exchange call() throws Exception {
            try {
              LOG.debug("[claimcheck] {} {}", conveyor, baggage);
              conveyor.process(baggage);
            } catch (Throwable e) {
              LOG.warn(
                  "Error occurred during processing " + baggage + " checked in at " + conveyor, e);
            }
            return baggage;
          };
        });

    LOG.info("Continue normal flow without 'baggage'");
    Message out = exchange.getOut();
    out.setBody(value.evaluate(exchange, Object.class));
  }
예제 #2
0
    /** Evaluate using classic parameter binding using the pre compute expression */
    private Object evaluateParameterBinding(
        Exchange exchange, Expression expression, int index, Class<?> parameterType) {
      Object answer = null;

      // use object first to avoid type conversion so we know if there is a value or not
      Object result = expression.evaluate(exchange, Object.class);
      if (result != null) {
        try {
          if (parameterType.isInstance(result)) {
            // optimize if the value is already the same type
            answer = result;
          } else {
            // we got a value now try to convert it to the expected type
            answer =
                exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, result);
          }
          if (LOG.isTraceEnabled()) {
            LOG.trace(
                "Parameter #{} evaluated as: {} type: ",
                new Object[] {index, answer, ObjectHelper.type(answer)});
          }
        } catch (NoTypeConversionAvailableException e) {
          if (LOG.isDebugEnabled()) {
            LOG.debug(
                "Cannot convert from type: {} to type: {} for parameter #{}",
                new Object[] {ObjectHelper.type(result), parameterType, index});
          }
          throw new ParameterBindingException(e, method, index, parameterType, result);
        }
      } else {
        LOG.trace("Parameter #{} evaluated as null", index);
      }

      return answer;
    }
예제 #3
0
  @Override
  public Object convert(
      Object existingDestinationFieldValue,
      Object sourceFieldValue,
      Class<?> destinationClass,
      Class<?> sourceClass) {
    try {
      if (currentExchange.get() == null) {
        throw new IllegalStateException("Current exchange has not been set for ExpressionMapper");
      }

      Expression exp;

      // Resolve the language being used for this expression and evaluate
      Exchange exchange = currentExchange.get();
      Language expLang = exchange.getContext().resolveLanguage(getLanguagePart());
      String scheme = getSchemePart();
      if (scheme != null
          && (scheme.equalsIgnoreCase("classpath")
              || scheme.equalsIgnoreCase("file")
              || scheme.equalsIgnoreCase("http"))) {
        String path = getPathPart();
        try {
          exp = expLang.createExpression(resolveScript(scheme + ":" + path));
        } catch (IOException e) {
          throw new IllegalStateException("Expression script specified but not found", e);
        }
      } else {
        exp = expLang.createExpression(getExpressionPart());
      }
      return exp.evaluate(exchange, destinationClass);
    } finally {
      done();
    }
  }
예제 #4
0
  @Override
  public boolean process(Exchange exchange, AsyncCallback callback) {
    // use atomic integer to be able to pass reference and keep track on the values
    AtomicInteger index = new AtomicInteger();
    AtomicInteger count = new AtomicInteger();

    // Intermediate conversion to String is needed when direct conversion to Integer is not
    // available
    // but evaluation result is a textual representation of a numeric value.
    String text = expression.evaluate(exchange, String.class);
    try {
      int num = ExchangeHelper.convertToMandatoryType(exchange, Integer.class, text);
      count.set(num);
    } catch (NoTypeConversionAvailableException e) {
      exchange.setException(e);
      callback.done(true);
      return true;
    }

    // we hold on to the original Exchange in case it's needed for copies
    final Exchange original = exchange;

    // per-iteration exchange
    Exchange target = exchange;

    // set the size before we start
    exchange.setProperty(Exchange.LOOP_SIZE, count);

    // loop synchronously
    while (index.get() < count.get()) {

      // and prepare for next iteration
      // if (!copy) target = exchange; else copy of original
      target = prepareExchange(exchange, index.get(), original);
      boolean sync = process(target, callback, index, count, original);

      if (!sync) {
        LOG.trace(
            "Processing exchangeId: {} is continued being processed asynchronously",
            target.getExchangeId());
        // the remainder of the routing slip will be completed async
        // so we break out now, then the callback will be invoked which then continue routing from
        // where we left here
        return false;
      }

      LOG.trace(
          "Processing exchangeId: {} is continued being processed synchronously",
          target.getExchangeId());

      // increment counter before next loop
      index.getAndIncrement();
    }

    // we are done so prepare the result
    ExchangeHelper.copyResults(exchange, target);
    LOG.trace("Processing complete for exchangeId: {} >>> {}", exchange.getExchangeId(), exchange);
    callback.done(true);
    return true;
  }
 public void testCamelContextPropertiesExpression() throws Exception {
   camelContext.getProperties().put("CamelTestKey", "CamelTestValue");
   Expression expression = camelContextPropertyExpression("CamelTestKey");
   assertExpression(expression, exchange, "CamelTestValue");
   expression = camelContextPropertiesExpression();
   Map<?, ?> properties = expression.evaluate(exchange, Map.class);
   assertEquals("Get a wrong properties size", properties.size(), 1);
 }
예제 #6
0
  @Override
  public boolean process(Exchange exchange, AsyncCallback callback) {
    try {
      Object newBody = expression.evaluate(exchange, Object.class);

      if (exchange.getException() != null) {
        // the expression threw an exception so we should break-out
        callback.done(true);
        return true;
      }

      boolean out = exchange.hasOut();
      Message old = out ? exchange.getOut() : exchange.getIn();

      // create a new message container so we do not drag specialized message objects along
      // but that is only needed if the old message is a specialized message
      boolean copyNeeded = !(old.getClass().equals(DefaultMessage.class));

      if (copyNeeded) {
        Message msg = new DefaultMessage();
        msg.copyFrom(old);
        msg.setBody(newBody);

        // replace message on exchange
        ExchangeHelper.replaceMessage(exchange, msg, false);
      } else {
        // no copy needed so set replace value directly
        old.setBody(newBody);
      }

    } catch (Throwable e) {
      exchange.setException(e);
    }

    callback.done(true);
    return true;
  }
  public String createFileName(Exchange exchange) {
    String answer;

    // overrule takes precedence
    Object value;

    Object overrule = exchange.getIn().getHeader(Exchange.OVERRULE_FILE_NAME);
    if (overrule != null) {
      if (overrule instanceof Expression) {
        value = overrule;
      } else {
        value =
            exchange.getContext().getTypeConverter().convertTo(String.class, exchange, overrule);
      }
    } else {
      value = exchange.getIn().getHeader(Exchange.FILE_NAME);
    }

    // if we have an overrule then override the existing header to use the overrule computed name
    // from this point forward
    if (overrule != null) {
      exchange.getIn().setHeader(Exchange.FILE_NAME, value);
    }

    if (value != null
        && value instanceof String
        && StringHelper.hasStartToken((String) value, "simple")) {
      log.warn(
          "Simple expression: {} detected in header: {} of type String. This feature has been removed (see CAMEL-6748).",
          value,
          Exchange.FILE_NAME);
    }

    // expression support
    Expression expression = endpoint.getFileName();
    if (value != null && value instanceof Expression) {
      expression = (Expression) value;
    }

    // evaluate the name as a String from the value
    String name;
    if (expression != null) {
      log.trace("Filename evaluated as expression: {}", expression);
      name = expression.evaluate(exchange, String.class);
    } else {
      name = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, value);
    }

    // flatten name
    if (name != null && endpoint.isFlatten()) {
      // check for both windows and unix separators
      int pos = Math.max(name.lastIndexOf("/"), name.lastIndexOf("\\"));
      if (pos != -1) {
        name = name.substring(pos + 1);
      }
    }

    // compute path by adding endpoint starting directory
    String endpointPath = endpoint.getConfiguration().getDirectory();
    String baseDir = "";
    if (endpointPath.length() > 0) {
      // Its a directory so we should use it as a base path for the filename
      // If the path isn't empty, we need to add a trailing / if it isn't already there
      baseDir = endpointPath;
      boolean trailingSlash = endpointPath.endsWith("/") || endpointPath.endsWith("\\");
      if (!trailingSlash) {
        baseDir += getFileSeparator();
      }
    }
    if (name != null) {
      answer = baseDir + name;
    } else {
      // use a generated filename if no name provided
      answer = baseDir + endpoint.getGeneratedFileName(exchange.getIn());
    }

    if (endpoint.getConfiguration().needToNormalize()) {
      // must normalize path to cater for Windows and other OS
      answer = normalizePath(answer);
    }

    return answer;
  }
예제 #8
0
    /**
     * Evaluate using parameter values where the values can be provided in the method name syntax.
     *
     * <p>This methods returns accordingly:
     *
     * <ul>
     *   <li><tt>null</tt> - if not a parameter value
     *   <li><tt>Void.TYPE</tt> - if an explicit null, forcing Camel to pass in <tt>null</tt> for
     *       that given parameter
     *   <li>a non <tt>null</tt> value - if the parameter was a parameter value, and to be used
     * </ul>
     *
     * @since 2.9
     */
    private Object evaluateParameterValue(
        Exchange exchange, int index, Object parameterValue, Class<?> parameterType) {
      Object answer = null;

      // convert the parameter value to a String
      String exp =
          exchange
              .getContext()
              .getTypeConverter()
              .convertTo(String.class, exchange, parameterValue);
      if (exp != null) {
        // check if its a valid parameter value
        boolean valid = BeanHelper.isValidParameterValue(exp);

        if (!valid) {
          // it may be a parameter type instead, and if so, then we should return null,
          // as this method is only for evaluating parameter values
          Boolean isClass =
              BeanHelper.isAssignableToExpectedType(
                  exchange.getContext().getClassResolver(), exp, parameterType);
          // the method will return a non null value if exp is a class
          if (isClass != null) {
            return null;
          }
        }

        // use simple language to evaluate the expression, as it may use the simple language to
        // refer to message body, headers etc.
        Expression expression = null;
        try {
          expression = exchange.getContext().resolveLanguage("simple").createExpression(exp);
          parameterValue = expression.evaluate(exchange, Object.class);
          // use "null" to indicate the expression returned a null value which is a valid response
          // we need to honor
          if (parameterValue == null) {
            parameterValue = "null";
          }
        } catch (Exception e) {
          throw new ExpressionEvaluationException(
              expression,
              "Cannot create/evaluate simple expression: "
                  + exp
                  + " to be bound to parameter at index: "
                  + index
                  + " on method: "
                  + getMethod(),
              exchange,
              e);
        }

        // special for explicit null parameter values (as end users can explicit indicate they want
        // null as parameter)
        // see method javadoc for details
        if ("null".equals(parameterValue)) {
          return Void.TYPE;
        }

        // the parameter value may match the expected type, then we use it as-is
        if (parameterType.isAssignableFrom(parameterValue.getClass())) {
          valid = true;
        } else {
          // the parameter value was not already valid, but since the simple language have evaluated
          // the expression
          // which may change the parameterValue, so we have to check it again to see if its now
          // valid
          exp = exchange.getContext().getTypeConverter().tryConvertTo(String.class, parameterValue);
          // String values from the simple language is always valid
          if (!valid) {
            // re validate if the parameter was not valid the first time (String values should be
            // accepted)
            valid = parameterValue instanceof String || BeanHelper.isValidParameterValue(exp);
          }
        }

        if (valid) {
          // we need to unquote String parameters, as the enclosing quotes is there to denote a
          // parameter value
          if (parameterValue instanceof String) {
            parameterValue = StringHelper.removeLeadingAndEndingQuotes((String) parameterValue);
          }
          if (parameterValue != null) {
            try {
              // its a valid parameter value, so convert it to the expected type of the parameter
              answer =
                  exchange
                      .getContext()
                      .getTypeConverter()
                      .mandatoryConvertTo(parameterType, exchange, parameterValue);
              if (LOG.isTraceEnabled()) {
                LOG.trace(
                    "Parameter #{} evaluated as: {} type: ",
                    new Object[] {index, answer, ObjectHelper.type(answer)});
              }
            } catch (Exception e) {
              if (LOG.isDebugEnabled()) {
                LOG.debug(
                    "Cannot convert from type: {} to type: {} for parameter #{}",
                    new Object[] {ObjectHelper.type(parameterValue), parameterType, index});
              }
              throw new ParameterBindingException(e, method, index, parameterType, parameterValue);
            }
          }
        }
      }

      return answer;
    }
예제 #9
0
  public MethodInvocation createMethodInvocation(final Object pojo, final Exchange exchange) {
    final Object[] arguments = parametersExpression.evaluate(exchange, Object[].class);
    return new MethodInvocation() {
      public Method getMethod() {
        return method;
      }

      public Object[] getArguments() {
        return arguments;
      }

      public boolean proceed(AsyncCallback callback) {
        Object body = exchange.getIn().getBody();
        if (body != null && body instanceof StreamCache) {
          // ensure the stream cache is reset before calling the method
          ((StreamCache) body).reset();
        }
        try {
          return doProceed(callback);
        } catch (InvocationTargetException e) {
          exchange.setException(e.getTargetException());
          callback.done(true);
          return true;
        } catch (Throwable e) {
          exchange.setException(e);
          callback.done(true);
          return true;
        }
      }

      private boolean doProceed(AsyncCallback callback) throws Exception {
        // dynamic router should be invoked beforehand
        if (dynamicRouter != null) {
          if (!dynamicRouter.isStarted()) {
            ServiceHelper.startService(dynamicRouter);
          }
          // use a expression which invokes the method to be used by dynamic router
          Expression expression = new DynamicRouterExpression(pojo);
          return dynamicRouter.doRoutingSlip(exchange, expression, callback);
        }

        // invoke pojo
        if (LOG.isTraceEnabled()) {
          LOG.trace(
              ">>>> invoking: {} on bean: {} with arguments: {} for exchange: {}",
              new Object[] {method, pojo, asString(arguments), exchange});
        }
        Object result = invoke(method, pojo, arguments, exchange);

        if (recipientList != null) {
          // ensure its started
          if (!recipientList.isStarted()) {
            ServiceHelper.startService(recipientList);
          }
          return recipientList.sendToRecipientList(exchange, result, callback);
        }
        if (routingSlip != null) {
          if (!routingSlip.isStarted()) {
            ServiceHelper.startService(routingSlip);
          }
          return routingSlip.doRoutingSlip(exchange, result, callback);
        }

        // If it's Java 8 async result
        if (CompletionStage.class.isAssignableFrom(getMethod().getReturnType())) {
          CompletionStage<?> completionStage = (CompletionStage<?>) result;

          completionStage.whenComplete(
              (resultObject, e) -> {
                if (e != null) {
                  exchange.setException(e);
                } else if (resultObject != null) {
                  fillResult(exchange, resultObject);
                }
                callback.done(false);
              });
          return false;
        }

        // if the method returns something then set the value returned on the Exchange
        if (!getMethod().getReturnType().equals(Void.TYPE) && result != Void.TYPE) {
          fillResult(exchange, result);
        }

        // we did not use any of the eips, but just invoked the bean
        // so notify the callback we are done synchronously
        callback.done(true);
        return true;
      }

      public Object getThis() {
        return pojo;
      }

      public AccessibleObject getStaticPart() {
        return method;
      }
    };
  }
예제 #10
0
 public <T> T evaluate(Exchange exchange, Class<T> type) {
   if (expression == null) {
     expression = createExpression(exchange);
   }
   return expression.evaluate(exchange, type);
 }
예제 #11
0
  /**
   * Enriches the input data (<code>exchange</code>) by first obtaining additional data from an
   * endpoint represented by an endpoint <code>producer</code> and second by aggregating input data
   * and additional data. Aggregation of input data and additional data is delegated to an {@link
   * org.apache.camel.processor.aggregate.AggregationStrategy} object set at construction time. If
   * the message exchange with the resource endpoint fails then no aggregation will be done and the
   * failed exchange content is copied over to the original message exchange.
   *
   * @param exchange input data.
   */
  @Override
  public boolean process(Exchange exchange, AsyncCallback callback) {
    try {
      preCheckPoll(exchange);
    } catch (Exception e) {
      exchange.setException(new CamelExchangeException("Error during pre poll check", exchange, e));
      callback.done(true);
      return true;
    }

    // which consumer to use
    PollingConsumer consumer;
    Endpoint endpoint;

    // use dynamic endpoint so calculate the endpoint to use
    Object recipient = null;
    try {
      recipient = expression.evaluate(exchange, Object.class);
      endpoint = resolveEndpoint(exchange, recipient);
      // acquire the consumer from the cache
      consumer = consumerCache.acquirePollingConsumer(endpoint);
    } catch (Throwable e) {
      if (isIgnoreInvalidEndpoint()) {
        if (LOG.isDebugEnabled()) {
          LOG.debug(
              "Endpoint uri is invalid: " + recipient + ". This exception will be ignored.", e);
        }
      } else {
        exchange.setException(e);
      }
      callback.done(true);
      return true;
    }

    Exchange resourceExchange;
    try {
      if (timeout < 0) {
        LOG.debug("Consumer receive: {}", consumer);
        resourceExchange = consumer.receive();
      } else if (timeout == 0) {
        LOG.debug("Consumer receiveNoWait: {}", consumer);
        resourceExchange = consumer.receiveNoWait();
      } else {
        LOG.debug("Consumer receive with timeout: {} ms. {}", timeout, consumer);
        resourceExchange = consumer.receive(timeout);
      }

      if (resourceExchange == null) {
        LOG.debug("Consumer received no exchange");
      } else {
        LOG.debug("Consumer received: {}", resourceExchange);
      }
    } catch (Exception e) {
      exchange.setException(new CamelExchangeException("Error during poll", exchange, e));
      callback.done(true);
      return true;
    } finally {
      // return the consumer back to the cache
      consumerCache.releasePollingConsumer(endpoint, consumer);
    }

    try {
      if (!isAggregateOnException() && (resourceExchange != null && resourceExchange.isFailed())) {
        // copy resource exchange onto original exchange (preserving pattern)
        copyResultsPreservePattern(exchange, resourceExchange);
      } else {
        prepareResult(exchange);

        // prepare the exchanges for aggregation
        ExchangeHelper.prepareAggregation(exchange, resourceExchange);
        // must catch any exception from aggregation
        Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange);
        if (aggregatedExchange != null) {
          // copy aggregation result onto original exchange (preserving pattern)
          copyResultsPreservePattern(exchange, aggregatedExchange);
          // handover any synchronization
          if (resourceExchange != null) {
            resourceExchange.handoverCompletions(exchange);
          }
        }
      }

      // set header with the uri of the endpoint enriched so we can use that for tracing etc
      if (exchange.hasOut()) {
        exchange.getOut().setHeader(Exchange.TO_ENDPOINT, consumer.getEndpoint().getEndpointUri());
      } else {
        exchange.getIn().setHeader(Exchange.TO_ENDPOINT, consumer.getEndpoint().getEndpointUri());
      }
    } catch (Throwable e) {
      exchange.setException(
          new CamelExchangeException("Error occurred during aggregation", exchange, e));
      callback.done(true);
      return true;
    }

    callback.done(true);
    return true;
  }