use of org.apache.camel.TypeConverter in project camel by apache.
the class UndertowProducer method process.
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
ClientConnection connection = null;
try {
final UndertowClient client = UndertowClient.getInstance();
IoFuture<ClientConnection> connect = client.connect(endpoint.getHttpURI(), worker, pool, options);
// creating the url to use takes 2-steps
final String exchangeUri = UndertowHelper.createURL(exchange, getEndpoint());
final URI uri = UndertowHelper.createURI(exchange, exchangeUri, getEndpoint());
final String pathAndQuery = URISupport.pathAndQueryOf(uri);
// what http method to use
HttpString method = UndertowHelper.createMethod(exchange, endpoint, exchange.getIn().getBody() != null);
ClientRequest request = new ClientRequest();
request.setProtocol(Protocols.HTTP_1_1);
request.setPath(pathAndQuery);
request.setMethod(method);
final HeaderMap requestHeaders = request.getRequestHeaders();
// Set the Host header
Message message = exchange.getIn();
final String host = message.getHeader("Host", String.class);
requestHeaders.put(Headers.HOST, Optional.ofNullable(host).orElseGet(() -> uri.getAuthority()));
Object body = getRequestBody(request, exchange);
TypeConverter tc = endpoint.getCamelContext().getTypeConverter();
ByteBuffer bodyAsByte = tc.tryConvertTo(ByteBuffer.class, body);
if (body != null) {
requestHeaders.put(Headers.CONTENT_LENGTH, bodyAsByte.array().length);
}
if (getEndpoint().getCookieHandler() != null) {
Map<String, List<String>> cookieHeaders = getEndpoint().getCookieHandler().loadCookies(exchange, uri);
for (Map.Entry<String, List<String>> entry : cookieHeaders.entrySet()) {
requestHeaders.putAll(new HttpString(entry.getKey()), entry.getValue());
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Executing http {} method: {}", method, pathAndQuery);
}
connection = connect.get();
connection.sendRequest(request, new UndertowProducerCallback(connection, bodyAsByte, exchange, callback));
} catch (Exception e) {
IOHelper.close(connection);
exchange.setException(e);
callback.done(true);
return true;
}
// use async routing engine
return false;
}
use of org.apache.camel.TypeConverter in project camel by apache.
the class MongoDbProducer method attemptConvertToList.
@SuppressWarnings("rawtypes")
private List<Document> attemptConvertToList(List insertList, Exchange exchange) throws CamelMongoDbException {
List<Document> documentList = new ArrayList<>(insertList.size());
TypeConverter converter = exchange.getContext().getTypeConverter();
for (Object item : insertList) {
try {
Document document = converter.mandatoryConvertTo(Document.class, item);
documentList.add(document);
} catch (Exception e) {
throw new CamelMongoDbException("MongoDB operation = insert, Assuming List variant of MongoDB insert operation, but List contains non-Document items", e);
}
}
return documentList;
}
use of org.apache.camel.TypeConverter in project camel by apache.
the class AbstractRestProcessor method processApproval.
final void processApproval(final Exchange exchange, final AsyncCallback callback) throws SalesforceException {
final TypeConverter converter = exchange.getContext().getTypeConverter();
final ApprovalRequest approvalRequestFromHeader = getParameter(SalesforceEndpointConfig.APPROVAL, exchange, IGNORE_BODY, IS_OPTIONAL, ApprovalRequest.class);
final boolean requestGivenInHeader = approvalRequestFromHeader != null;
// find if there is a ApprovalRequest as `approval` in the message header
final ApprovalRequest approvalHeader = Optional.ofNullable(approvalRequestFromHeader).orElse(new ApprovalRequest());
final Message incomingMessage = exchange.getIn();
final Map<String, Object> incomingHeaders = incomingMessage.getHeaders();
final boolean requestGivenInParametersInHeader = processApprovalHeaderValues(approvalHeader, incomingHeaders);
final boolean nothingInheader = !requestGivenInHeader && !requestGivenInParametersInHeader;
final Object approvalBody = incomingMessage.getBody();
final boolean bodyIsIterable = approvalBody instanceof Iterable;
final boolean bodyIsIterableButEmpty = bodyIsIterable && !((Iterable) approvalBody).iterator().hasNext();
// body contains nothing of interest if it's null, holds an empty iterable or cannot be converted to
// ApprovalRequest
final boolean nothingInBody = !(approvalBody != null && !bodyIsIterableButEmpty);
// we found nothing in the headers or the body
if (nothingInheader && nothingInBody) {
throw new SalesforceException("Missing " + SalesforceEndpointConfig.APPROVAL + " parameter in header or ApprovalRequest or List of ApprovalRequests body", 0);
}
// let's try to resolve the request body to send
final ApprovalRequests requestsBody;
if (nothingInBody) {
// nothing in body use the header values only
requestsBody = new ApprovalRequests(approvalHeader);
} else if (bodyIsIterable) {
// multiple ApprovalRequests are found
final Iterable<?> approvalRequests = (Iterable<?>) approvalBody;
// use header values as template and apply them to the body
final List<ApprovalRequest> requests = StreamSupport.stream(approvalRequests.spliterator(), false).map(value -> converter.convertTo(ApprovalRequest.class, value)).map(request -> request.applyTemplate(approvalHeader)).collect(Collectors.toList());
requestsBody = new ApprovalRequests(requests);
} else {
// we've looked at the body, and are expecting to see something resembling ApprovalRequest in there
// but lets see if that is so
final ApprovalRequest given = converter.tryConvertTo(ApprovalRequest.class, approvalBody);
final ApprovalRequest request = Optional.ofNullable(given).orElse(new ApprovalRequest()).applyTemplate(approvalHeader);
requestsBody = new ApprovalRequests(request);
}
final InputStream request = getRequestStream(requestsBody);
restClient.approval(request, (response, exception) -> processResponse(exchange, response, exception, callback));
}
use of org.apache.camel.TypeConverter in project camel by apache.
the class DefaultNettyHttpBinding method toNettyResponse.
@Override
public HttpResponse toNettyResponse(Message message, NettyHttpConfiguration configuration) throws Exception {
LOG.trace("toNettyResponse: {}", message);
// the message body may already be a Netty HTTP response
if (message.getBody() instanceof HttpResponse) {
return (HttpResponse) message.getBody();
}
// the response code is 200 for OK and 500 for failed
boolean failed = message.getExchange().isFailed();
int defaultCode = failed ? 500 : 200;
int code = message.getHeader(Exchange.HTTP_RESPONSE_CODE, defaultCode, int.class);
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(code));
LOG.trace("HTTP Status Code: {}", code);
TypeConverter tc = message.getExchange().getContext().getTypeConverter();
// must use entrySet to ensure case of keys is preserved
for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// use an iterator as there can be multiple values. (must not use a delimiter)
final Iterator<?> it = ObjectHelper.createIterator(value, null);
while (it.hasNext()) {
String headerValue = tc.convertTo(String.class, it.next());
if (headerValue != null && headerFilterStrategy != null && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, message.getExchange())) {
LOG.trace("HTTP-Header: {}={}", key, headerValue);
response.headers().add(key, headerValue);
}
}
}
Object body = message.getBody();
Exception cause = message.getExchange().getException();
// support bodies as native Netty
ChannelBuffer buffer;
// if there was an exception then use that as body
if (cause != null) {
if (configuration.isTransferException()) {
// we failed due an exception, and transfer it as java serialized object
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(cause);
oos.flush();
IOHelper.close(oos, bos);
// the body should be the serialized java object of the exception
body = ChannelBuffers.copiedBuffer(bos.toByteArray());
// force content type to be serialized java object
message.setHeader(Exchange.CONTENT_TYPE, NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT);
} else {
// we failed due an exception so print it as plain text
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
cause.printStackTrace(pw);
// the body should then be the stacktrace
body = ChannelBuffers.copiedBuffer(sw.toString().getBytes());
// force content type to be text/plain as that is what the stacktrace is
message.setHeader(Exchange.CONTENT_TYPE, "text/plain");
}
// and mark the exception as failure handled, as we handled it by returning it as the response
ExchangeHelper.setFailureHandled(message.getExchange());
}
if (body instanceof ChannelBuffer) {
buffer = (ChannelBuffer) body;
} else {
// try to convert to buffer first
buffer = message.getBody(ChannelBuffer.class);
if (buffer == null) {
// fallback to byte array as last resort
byte[] data = message.getBody(byte[].class);
if (data != null) {
buffer = ChannelBuffers.copiedBuffer(data);
} else {
// and if byte array fails then try String
String str;
if (body != null) {
str = message.getMandatoryBody(String.class);
} else {
str = "";
}
buffer = ChannelBuffers.copiedBuffer(str.getBytes());
}
}
}
if (buffer != null) {
response.setContent(buffer);
// We just need to reset the readerIndex this time
if (buffer.readerIndex() == buffer.writerIndex()) {
buffer.setIndex(0, buffer.writerIndex());
}
// TODO How to enable the chunk transport
int len = buffer.readableBytes();
// set content-length
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, len);
LOG.trace("Content-Length: {}", len);
}
// set the content type in the response.
String contentType = MessageHelper.getContentType(message);
if (contentType != null) {
// set content-type
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, contentType);
LOG.trace("Content-Type: {}", contentType);
}
// configure connection to accordingly to keep alive configuration
// favor using the header from the message
String connection = message.getHeader(HttpHeaders.Names.CONNECTION, String.class);
// Read the connection header from the exchange property
if (connection == null) {
connection = message.getExchange().getProperty(HttpHeaders.Names.CONNECTION, String.class);
}
if (connection == null) {
// fallback and use the keep alive from the configuration
if (configuration.isKeepAlive()) {
connection = HttpHeaders.Values.KEEP_ALIVE;
} else {
connection = HttpHeaders.Values.CLOSE;
}
}
response.headers().set(HttpHeaders.Names.CONNECTION, connection);
// Just make sure we close the channel when the connection value is close
if (connection.equalsIgnoreCase(HttpHeaders.Values.CLOSE)) {
message.setHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true);
}
LOG.trace("Connection: {}", connection);
return response;
}
use of org.apache.camel.TypeConverter in project camel by apache.
the class DefaultNettyHttpBinding method toNettyRequest.
@Override
public HttpRequest toNettyRequest(Message message, String uri, NettyHttpConfiguration configuration) throws Exception {
LOG.trace("toNettyRequest: {}", message);
// the message body may already be a Netty HTTP response
if (message.getBody() instanceof HttpRequest) {
return (HttpRequest) message.getBody();
}
String uriForRequest = uri;
if (configuration.isUseRelativePath()) {
int indexOfPath = uri.indexOf((new URI(uri)).getPath());
if (indexOfPath > 0) {
uriForRequest = uri.substring(indexOfPath);
}
}
// just assume GET for now, we will later change that to the actual method to use
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uriForRequest);
Object body = message.getBody();
if (body != null) {
// support bodies as native Netty
ByteBuf buffer;
if (body instanceof ByteBuf) {
buffer = (ByteBuf) body;
} else {
// try to convert to buffer first
buffer = message.getBody(ByteBuf.class);
if (buffer == null) {
// fallback to byte array as last resort
byte[] data = message.getMandatoryBody(byte[].class);
buffer = NettyConverter.toByteBuffer(data);
}
}
if (buffer != null) {
request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriForRequest, buffer);
int len = buffer.readableBytes();
// set content-length
request.headers().set(HttpHeaderNames.CONTENT_LENGTH.toString(), len);
LOG.trace("Content-Length: {}", len);
} else {
// we do not support this kind of body
throw new NoTypeConversionAvailableException(body, ByteBuf.class);
}
}
// update HTTP method accordingly as we know if we have a body or not
HttpMethod method = NettyHttpHelper.createMethod(message, body != null);
request.setMethod(method);
TypeConverter tc = message.getExchange().getContext().getTypeConverter();
// if we bridge endpoint then we need to skip matching headers with the HTTP_QUERY to avoid sending
// duplicated headers to the receiver, so use this skipRequestHeaders as the list of headers to skip
Map<String, Object> skipRequestHeaders = null;
if (configuration.isBridgeEndpoint()) {
String queryString = message.getHeader(Exchange.HTTP_QUERY, String.class);
if (queryString != null) {
skipRequestHeaders = URISupport.parseQuery(queryString, false, true);
}
// Need to remove the Host key as it should be not used
message.getHeaders().remove("host");
}
// must use entrySet to ensure case of keys is preserved
for (Map.Entry<String, Object> entry : message.getHeaders().entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// as then we would duplicate headers on both the endpoint uri, and in HTTP headers as well
if (skipRequestHeaders != null && skipRequestHeaders.containsKey(key)) {
continue;
}
// use an iterator as there can be multiple values. (must not use a delimiter)
final Iterator<?> it = ObjectHelper.createIterator(value, null, true);
while (it.hasNext()) {
String headerValue = tc.convertTo(String.class, it.next());
if (headerValue != null && headerFilterStrategy != null && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, message.getExchange())) {
LOG.trace("HTTP-Header: {}={}", key, headerValue);
request.headers().add(key, headerValue);
}
}
}
// set the content type in the response.
String contentType = MessageHelper.getContentType(message);
if (contentType != null) {
// set content-type
request.headers().set(HttpHeaderNames.CONTENT_TYPE.toString(), contentType);
LOG.trace("Content-Type: {}", contentType);
}
// must include HOST header as required by HTTP 1.1
// use URI as its faster than URL (no DNS lookup)
URI u = new URI(uri);
String hostHeader = u.getHost() + (u.getPort() == 80 ? "" : ":" + u.getPort());
request.headers().set(HttpHeaderNames.HOST.toString(), hostHeader);
LOG.trace("Host: {}", hostHeader);
// configure connection to accordingly to keep alive configuration
// favor using the header from the message
String connection = message.getHeader(HttpHeaderNames.CONNECTION.toString(), String.class);
if (connection == null) {
// fallback and use the keep alive from the configuration
if (configuration.isKeepAlive()) {
connection = HttpHeaderValues.KEEP_ALIVE.toString();
} else {
connection = HttpHeaderValues.CLOSE.toString();
}
}
request.headers().set(HttpHeaderNames.CONNECTION.toString(), connection);
LOG.trace("Connection: {}", connection);
return request;
}
Aggregations