Search in sources :

Example 1 with BindingException

use of org.apache.camel.processor.binding.BindingException in project camel by apache.

the class RestBindingAdvice method unmarshal.

private void unmarshal(Exchange exchange, Map<String, Object> state) throws Exception {
    boolean isXml = false;
    boolean isJson = false;
    String contentType = ExchangeHelper.getContentType(exchange);
    if (contentType != null) {
        isXml = contentType.toLowerCase(Locale.ENGLISH).contains("xml");
        isJson = contentType.toLowerCase(Locale.ENGLISH).contains("json");
    }
    // that information in the consumes
    if (!isXml && !isJson) {
        isXml = consumes != null && consumes.toLowerCase(Locale.ENGLISH).contains("xml");
        isJson = consumes != null && consumes.toLowerCase(Locale.ENGLISH).contains("json");
    }
    if (exchange.getIn() instanceof DataTypeAware && (isJson || isXml)) {
        ((DataTypeAware) exchange.getIn()).setDataType(new DataType(isJson ? "json" : "xml"));
    }
    // only allow xml/json if the binding mode allows that
    isXml &= bindingMode.equals("auto") || bindingMode.contains("xml");
    isJson &= bindingMode.equals("auto") || bindingMode.contains("json");
    // if we do not yet know if its xml or json, then use the binding mode to know the mode
    if (!isJson && !isXml) {
        isXml = bindingMode.equals("auto") || bindingMode.contains("xml");
        isJson = bindingMode.equals("auto") || bindingMode.contains("json");
    }
    state.put(STATE_KEY_ACCEPT, exchange.getIn().getHeader("Accept", String.class));
    String body = null;
    if (exchange.getIn().getBody() != null) {
        // as they assume a non-empty body
        if (isXml || isJson) {
            // we have binding enabled, so we need to know if there body is empty or not
            // so force reading the body as a String which we can work with
            body = MessageHelper.extractBodyAsString(exchange.getIn());
            if (body != null) {
                if (exchange.getIn() instanceof DataTypeAware) {
                    ((DataTypeAware) exchange.getIn()).setBody(body, new DataType(isJson ? "json" : "xml"));
                } else {
                    exchange.getIn().setBody(body);
                }
                if (isXml && isJson) {
                    // we have still not determined between xml or json, so check the body if its xml based or not
                    isXml = body.startsWith("<");
                    isJson = !isXml;
                }
            }
        }
    }
    // add missing default values which are mapped as headers
    if (queryDefaultValues != null) {
        for (Map.Entry<String, String> entry : queryDefaultValues.entrySet()) {
            if (exchange.getIn().getHeader(entry.getKey()) == null) {
                exchange.getIn().setHeader(entry.getKey(), entry.getValue());
            }
        }
    }
    // favor json over xml
    if (isJson && jsonUnmarshal != null) {
        // add reverse operation
        state.put(STATE_KEY_DO_MARSHAL, STATE_JSON);
        if (ObjectHelper.isNotEmpty(body)) {
            jsonUnmarshal.process(exchange);
            ExchangeHelper.prepareOutToIn(exchange);
        }
        return;
    } else if (isXml && xmlUnmarshal != null) {
        // add reverse operation
        state.put(STATE_KEY_DO_MARSHAL, STATE_XML);
        if (ObjectHelper.isNotEmpty(body)) {
            xmlUnmarshal.process(exchange);
            ExchangeHelper.prepareOutToIn(exchange);
        }
        return;
    }
    // we could not bind
    if ("off".equals(bindingMode) || bindingMode.equals("auto")) {
        // okay for auto we do not mind if we could not bind
        state.put(STATE_KEY_DO_MARSHAL, STATE_JSON);
    } else {
        if (bindingMode.contains("xml")) {
            exchange.setException(new BindingException("Cannot bind to xml as message body is not xml compatible", exchange));
        } else {
            exchange.setException(new BindingException("Cannot bind to json as message body is not json compatible", exchange));
        }
    }
}
Also used : DataTypeAware(org.apache.camel.spi.DataTypeAware) DataType(org.apache.camel.spi.DataType) HashMap(java.util.HashMap) Map(java.util.Map) BindingException(org.apache.camel.processor.binding.BindingException)

Example 2 with BindingException

use of org.apache.camel.processor.binding.BindingException in project camel by apache.

the class RestProducerBindingProcessor method process.

@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
    boolean isXml = false;
    boolean isJson = false;
    // skip before binding for empty/null body
    Object body = exchange.getIn().getBody();
    if (ObjectHelper.isEmpty(body)) {
        if (outType != null) {
            // wrap callback to add reverse operation if we know the output type from the REST service
            callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, false);
        }
        // okay now we can continue routing to the producer
        return getProcessor().process(exchange, callback);
    }
    // we only need to perform before binding if the message body is POJO based
    if (body instanceof String || body instanceof byte[]) {
        // the body is text based and thus not POJO so no binding needed
        if (outType != null) {
            // wrap callback to add reverse operation if we know the output type from the REST service
            callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, false);
        }
        // okay now we can continue routing to the producer
        return getProcessor().process(exchange, callback);
    } else {
        // if its convertable to stream based then its not POJO based
        InputStream is = camelContext.getTypeConverter().tryConvertTo(InputStream.class, exchange, body);
        if (is != null) {
            exchange.getIn().setBody(is);
            if (outType != null) {
                // wrap callback to add reverse operation if we know the output type from the REST service
                callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, false);
            }
            // okay now we can continue routing to the producer
            return getProcessor().process(exchange, callback);
        }
    }
    // assume body is POJO based and binding needed
    String contentType = ExchangeHelper.getContentType(exchange);
    if (contentType != null) {
        isXml = contentType.toLowerCase(Locale.ENGLISH).contains("xml");
        isJson = contentType.toLowerCase(Locale.ENGLISH).contains("json");
    }
    // only allow xml/json if the binding mode allows that
    isXml &= bindingMode.equals("auto") || bindingMode.contains("xml");
    isJson &= bindingMode.equals("auto") || bindingMode.contains("json");
    // if we do not yet know if its xml or json, then use the binding mode to know the mode
    if (!isJson && !isXml) {
        isXml = bindingMode.equals("auto") || bindingMode.contains("xml");
        isJson = bindingMode.equals("auto") || bindingMode.contains("json");
    }
    // favor json over xml
    if (isJson && jsonMarshal != null) {
        try {
            jsonMarshal.process(exchange);
        } catch (Exception e) {
            // we failed so cannot call producer
            exchange.setException(e);
            callback.done(true);
            return true;
        }
        // need to prepare exchange first
        ExchangeHelper.prepareOutToIn(exchange);
        if (outType != null) {
            // wrap callback to add reverse operation if we know the output type from the REST service
            callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, false);
        }
        // okay now we can continue routing to the producer
        return getProcessor().process(exchange, callback);
    } else if (isXml && xmlMarshal != null) {
        try {
            xmlMarshal.process(exchange);
        } catch (Exception e) {
            // we failed so cannot call producer
            exchange.setException(e);
            callback.done(true);
            return true;
        }
        // need to prepare exchange first
        ExchangeHelper.prepareOutToIn(exchange);
        if (outType != null) {
            // wrap callback to add reverse operation if we know the output type from the REST service
            callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, true);
        }
        // okay now we can continue routing to the producer
        return getProcessor().process(exchange, callback);
    }
    // we could not bind
    if ("off".equals(bindingMode) || bindingMode.equals("auto")) {
        if (outType != null) {
            // wrap callback to add reverse operation if we know the output type from the REST service
            callback = new RestProducerBindingUnmarshalCallback(exchange, callback, jsonMarshal, xmlMarshal, false);
        }
        // okay now we can continue routing to the producer
        return getProcessor().process(exchange, callback);
    } else {
        if (bindingMode.contains("xml")) {
            exchange.setException(new BindingException("Cannot bind to xml as message body is not xml compatible", exchange));
        } else {
            exchange.setException(new BindingException("Cannot bind to json as message body is not json compatible", exchange));
        }
        // we failed so cannot call producer
        callback.done(true);
        return true;
    }
}
Also used : InputStream(java.io.InputStream) BindingException(org.apache.camel.processor.binding.BindingException) BindingException(org.apache.camel.processor.binding.BindingException)

Example 3 with BindingException

use of org.apache.camel.processor.binding.BindingException in project camel by apache.

the class RestBindingAdvice method marshal.

private void marshal(Exchange exchange, Map<String, Object> state) {
    // only marshal if there was no exception
    if (exchange.getException() != null) {
        return;
    }
    if (skipBindingOnErrorCode) {
        Integer code = exchange.hasOut() ? exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class) : exchange.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
        // if there is a custom http error code then skip binding
        if (code != null && code >= 300) {
            return;
        }
    }
    boolean isXml = false;
    boolean isJson = false;
    // accept takes precedence
    String accept = (String) state.get(STATE_KEY_ACCEPT);
    if (accept != null) {
        isXml = accept.toLowerCase(Locale.ENGLISH).contains("xml");
        isJson = accept.toLowerCase(Locale.ENGLISH).contains("json");
    }
    // fallback to content type if still undecided
    if (!isXml && !isJson) {
        String contentType = ExchangeHelper.getContentType(exchange);
        if (contentType != null) {
            isXml = contentType.toLowerCase(Locale.ENGLISH).contains("xml");
            isJson = contentType.toLowerCase(Locale.ENGLISH).contains("json");
        }
    }
    // that information in the consumes
    if (!isXml && !isJson) {
        isXml = produces != null && produces.toLowerCase(Locale.ENGLISH).contains("xml");
        isJson = produces != null && produces.toLowerCase(Locale.ENGLISH).contains("json");
    }
    // only allow xml/json if the binding mode allows that (when off we still want to know if its xml or json)
    if (bindingMode != null) {
        isXml &= bindingMode.equals("off") || bindingMode.equals("auto") || bindingMode.contains("xml");
        isJson &= bindingMode.equals("off") || bindingMode.equals("auto") || bindingMode.contains("json");
        // if we do not yet know if its xml or json, then use the binding mode to know the mode
        if (!isJson && !isXml) {
            isXml = bindingMode.equals("auto") || bindingMode.contains("xml");
            isJson = bindingMode.equals("auto") || bindingMode.contains("json");
        }
    }
    // in case we have not yet been able to determine if xml or json, then use the same as in the unmarshaller
    if (isXml && isJson) {
        isXml = state.get(STATE_KEY_DO_MARSHAL).equals(STATE_XML);
        isJson = !isXml;
    }
    // need to prepare exchange first
    ExchangeHelper.prepareOutToIn(exchange);
    // ensure there is a content type header (even if binding is off)
    ensureHeaderContentType(produces, isXml, isJson, exchange);
    if (bindingMode == null || "off".equals(bindingMode)) {
        // binding is off, so no message body binding
        return;
    }
    // is there any marshaller at all
    if (jsonMarshal == null && xmlMarshal == null) {
        return;
    }
    // is the body empty
    if ((exchange.hasOut() && exchange.getOut().getBody() == null) || (!exchange.hasOut() && exchange.getIn().getBody() == null)) {
        return;
    }
    String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
    // need to lower-case so the contains check below can match if using upper case
    contentType = contentType.toLowerCase(Locale.US);
    try {
        // favor json over xml
        if (isJson && jsonMarshal != null) {
            // only marshal if its json content type
            if (contentType.contains("json")) {
                jsonMarshal.process(exchange);
                setOutputDataType(exchange, new DataType("json"));
            }
        } else if (isXml && xmlMarshal != null) {
            // only marshal if its xml content type
            if (contentType.contains("xml")) {
                xmlMarshal.process(exchange);
                setOutputDataType(exchange, new DataType("xml"));
            }
        } else {
            // we could not bind
            if (bindingMode.equals("auto")) {
            // okay for auto we do not mind if we could not bind
            } else {
                if (bindingMode.contains("xml")) {
                    exchange.setException(new BindingException("Cannot bind to xml as message body is not xml compatible", exchange));
                } else {
                    exchange.setException(new BindingException("Cannot bind to json as message body is not json compatible", exchange));
                }
            }
        }
    } catch (Throwable e) {
        exchange.setException(e);
    }
}
Also used : DataType(org.apache.camel.spi.DataType) BindingException(org.apache.camel.processor.binding.BindingException)

Aggregations

BindingException (org.apache.camel.processor.binding.BindingException)3 DataType (org.apache.camel.spi.DataType)2 InputStream (java.io.InputStream)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 DataTypeAware (org.apache.camel.spi.DataTypeAware)1