public void parseURI(URI uri) throws URISyntaxException { String protocol = uri.getScheme(); if (!protocol.equalsIgnoreCase("hdfs2")) { throw new IllegalArgumentException( "Unrecognized Cache protocol: " + protocol + " for uri: " + uri); } hostName = uri.getHost(); if (hostName == null) { hostName = "localhost"; } port = uri.getPort() == -1 ? HdfsConstants.DEFAULT_PORT : uri.getPort(); path = uri.getPath(); Map<String, Object> hdfsSettings = URISupport.parseParameters(uri); overwrite = getBoolean(hdfsSettings, "overwrite", overwrite); append = getBoolean(hdfsSettings, "append", append); wantAppend = append; bufferSize = getInteger(hdfsSettings, "bufferSize", bufferSize); replication = getShort(hdfsSettings, "replication", replication); blockSize = getLong(hdfsSettings, "blockSize", blockSize); compressionType = getCompressionType(hdfsSettings, "compressionType", compressionType); compressionCodec = getCompressionCodec(hdfsSettings, "compressionCodec", compressionCodec); fileType = getFileType(hdfsSettings, "fileType", fileType); fileSystemType = getFileSystemType(hdfsSettings, "fileSystemType", fileSystemType); keyType = getWritableType(hdfsSettings, "keyType", keyType); valueType = getWritableType(hdfsSettings, "valueType", valueType); openedSuffix = getString(hdfsSettings, "openedSuffix", openedSuffix); readSuffix = getString(hdfsSettings, "readSuffix", readSuffix); initialDelay = getLong(hdfsSettings, "initialDelay", initialDelay); delay = getLong(hdfsSettings, "delay", delay); pattern = getString(hdfsSettings, "pattern", pattern); chunkSize = getInteger(hdfsSettings, "chunkSize", chunkSize); splitStrategies = getSplitStrategies(hdfsSettings); }
@Override public String toString() { if (ftpConsumerToString == null) { ftpConsumerToString = "FtpConsumer[" + URISupport.sanitizeUri(getEndpoint().getEndpointUri()) + "]"; } return ftpConsumerToString; }
@Override public String toString() { String value = null; try { value = getEndpointUri(); } catch (RuntimeException e) { // ignore any exception and use null for building the string value } return String.format("Endpoint[%s]", URISupport.sanitizeUri(value)); }
@Test public void testCreateCxfEndpointFromURI() throws Exception { CxfEndpoint endpoint1 = context.getEndpoint( "cxf:bean:routerEndpoint?address=http://localhost:9000/test1", CxfEndpoint.class); CxfEndpoint endpoint2 = context.getEndpoint( "cxf:bean:routerEndpoint?address=http://localhost:8000/test2", CxfEndpoint.class); assertEquals( "Get a wrong endpoint address.", "http://localhost:9000/test1", endpoint1.getAddress()); assertEquals( "Get a wrong endpoint address.", "http://localhost:8000/test2", endpoint2.getAddress()); // the uri will always be normalized String uri1 = URISupport.normalizeUri("cxf://bean:routerEndpoint?address=http://localhost:9000/test1"); String uri2 = URISupport.normalizeUri("cxf://bean:routerEndpoint?address=http://localhost:8000/test2"); assertEquals("Get a wrong endpoint key.", uri1, endpoint1.getEndpointKey()); assertEquals("Get a wrong endpoint key.", uri2, endpoint2.getEndpointKey()); }
public void testSanitizeUri() { assertNull(URISupport.sanitizeUri(null)); assertEquals("", URISupport.sanitizeUri("")); assertSanitizedUriUnchanged("http://camel.apache.org"); assertSanitizedUriUnchanged("irc://irc.codehaus.org/camel"); assertSanitizedUriUnchanged("direct:foo?bar=123&cheese=yes"); assertSanitizedUriUnchanged( "https://issues.apache.org/activemq/secure/AddComment!default.jspa?id=33239"); assertEquals( "ftp://host.mysite.com/records?passiveMode=true&user=someuser&password=xxxxxx", URISupport.sanitizeUri( "ftp://host.mysite.com/records?passiveMode=true&user=someuser&password=superSecret")); assertEquals( "sftp://host.mysite.com/records?user=someuser&privateKeyFile=key.file&privateKeyFilePassphrase=xxxxxx&knownHostsFile=hosts.list", URISupport.sanitizeUri( "sftp://host.mysite.com/records?user=someuser&privateKeyFile=key.file&privateKeyFilePassphrase=superSecret&knownHostsFile=hosts.list")); assertEquals( "aws-sqs://MyQueue?accessKey=1672t4rflhnhli3&secretKey=xxxxxx", URISupport.sanitizeUri( "aws-sqs://MyQueue?accessKey=1672t4rflhnhli3&secretKey=qi472qfberu33dqjncq")); }
/** * Creates the URI to invoke. * * @param exchange the exchange * @param url the url to invoke * @param endpoint the endpoint * @return the URI to invoke */ public static URI createURI(Exchange exchange, String url, NettyHttpEndpoint endpoint) throws URISyntaxException { URI uri = new URI(url); // is a query string provided in the endpoint URI or in a header (header overrules endpoint) String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class); if (queryString == null) { // use raw as we encode just below queryString = uri.getRawQuery(); } if (queryString != null) { // need to encode query string queryString = UnsafeUriCharactersEncoder.encodeHttpURI(queryString); uri = URISupport.createURIWithQuery(uri, queryString); } return uri; }
@Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { ObjectHelper.notNull(getCamelContext(), "Camel Context"); AbstractIgniteEndpoint answer = null; URI remainingUri = new URI(URISupport.normalizeUri(remaining)); String scheme = remainingUri.getScheme(); switch (scheme) { case "cache": answer = new IgniteCacheEndpoint(uri, remainingUri, parameters, this); break; case "compute": answer = new IgniteComputeEndpoint(uri, remainingUri, parameters, this); break; case "messaging": answer = new IgniteMessagingEndpoint(uri, remainingUri, parameters, this); break; case "events": answer = new IgniteEventsEndpoint(uri, remainingUri, parameters, this); break; case "set": answer = new IgniteSetEndpoint(uri, remainingUri, parameters, this); break; case "idgen": answer = new IgniteIdGenEndpoint(uri, remainingUri, parameters, this); break; case "queue": answer = new IgniteQueueEndpoint(uri, remainingUri, parameters, this); break; default: throw new MalformedURLException( "An invalid Ignite endpoint URI was provided. Please check that " + "it starts with:" + " ignite:[cache/compute/messaging/...]:..."); } setProperties(answer, parameters); return answer; }
@Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> params) throws Exception { int idx = remaining.indexOf(':'); if (idx > 0) { // we are registering a regular endpoint String name = remaining.substring(0, idx); String fabricPath = getFabricPath(name); // need to replace the "0.0.0.0" with the host and port String childUri = replaceAnyIpAddress(remaining.substring(idx + 1)); // we need to apply the params here if (params != null && params.size() > 0) { childUri = childUri + "?" + URISupport.createQueryString(params); } Group group = ZooKeeperGroupFactory.create(getCurator(), fabricPath); return new FabricPublisherEndpoint(uri, this, group, childUri); } else { String fabricPath = getFabricPath(remaining); Group group = ZooKeeperGroupFactory.create(getCurator(), fabricPath); return new FabricLocatorEndpoint(uri, this, group); } }
@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); } } } } }
@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(); } // just assume GET for now, we will later change that to the actual method to use HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri); 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"); } // append headers // 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(); // we should not add headers for the parameters in the uri if we bridge the endpoint // 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); } } } Object body = message.getBody(); if (body != null) { // support bodies as native Netty ChannelBuffer buffer; 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.getMandatoryBody(byte[].class); buffer = ChannelBuffers.copiedBuffer(data); } } if (buffer != null) { request.setContent(buffer); int len = buffer.readableBytes(); // set content-length request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, len); LOG.trace("Content-Length: {}", len); } else { // we do not support this kind of body throw new NoTypeConversionAvailableException(body, ChannelBuffer.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); // set the content type in the response. String contentType = MessageHelper.getContentType(message); if (contentType != null) { // set content-type request.headers().set(HttpHeaders.Names.CONTENT_TYPE, 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 host = u.getHost(); request.headers().set(HttpHeaders.Names.HOST, host); LOG.trace("Host: {}", host); // configure connection to accordingly to keep alive configuration // favor using the header from the message String connection = message.getHeader(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; } } request.headers().set(HttpHeaders.Names.CONNECTION, connection); LOG.trace("Connection: {}", connection); return request; }
@Override public String toString() { return "Consumer[" + URISupport.sanitizeUri(endpoint.getEndpointUri()) + "]"; }
@Override public String toString() { return "PublishEventNotifier[" + (endpoint != null ? endpoint : URISupport.sanitizeUri(endpointUri)) + "]"; }
@Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { String addressUri = createAddressUri(uri, remaining); // Do not set the HTTP URI because we still have all of the Camel internal // parameters in the URI at this point. AhcEndpoint endpoint = createAhcEndpoint(uri, this, null); setEndpointHeaderFilterStrategy(endpoint); endpoint.setClient(getClient()); endpoint.setClientConfig(getClientConfig()); endpoint.setBinding(getBinding()); endpoint.setSslContextParameters(getSslContextParameters()); setProperties(endpoint, parameters); if (IntrospectionSupport.hasProperties(parameters, CLIENT_CONFIG_PREFIX)) { AsyncHttpClientConfig.Builder builder = endpoint.getClientConfig() == null ? new AsyncHttpClientConfig.Builder() : AhcComponent.cloneConfig(endpoint.getClientConfig()); if (endpoint.getClient() != null) { LOG.warn( "The user explicitly set an AsyncHttpClient instance on the component or " + "endpoint, but this endpoint URI contains client configuration parameters. " + "Are you sure that this is what was intended? The AsyncHttpClient will be used" + " and the URI parameters will be ignored."); } else if (endpoint.getClientConfig() != null) { LOG.warn( "The user explicitly set an AsyncHttpClientConfig instance on the component or " + "endpoint, but this endpoint URI contains client configuration parameters. " + "Are you sure that this is what was intended? The URI parameters will be applied" + " to a clone of the supplied AsyncHttpClientConfig in order to prevent unintended modification" + " of the explicitly configured AsyncHttpClientConfig. That is, the URI parameters override the" + " settings on the explicitly configured AsyncHttpClientConfig for this endpoint."); } // special for realm builder Realm.RealmBuilder realmBuilder = null; if (IntrospectionSupport.hasProperties(parameters, CLIENT_REALM_CONFIG_PREFIX)) { realmBuilder = new Realm.RealmBuilder(); // set and validate additional parameters on client config Map<String, Object> realmParams = IntrospectionSupport.extractProperties(parameters, CLIENT_REALM_CONFIG_PREFIX); setProperties(realmBuilder, realmParams); validateParameters(uri, realmParams, null); } // set and validate additional parameters on client config Map<String, Object> clientParams = IntrospectionSupport.extractProperties(parameters, CLIENT_CONFIG_PREFIX); setProperties(builder, clientParams); validateParameters(uri, clientParams, null); if (realmBuilder != null) { builder.setRealm(realmBuilder.build()); } endpoint.setClientConfig(builder.build()); } // restructure uri to be based on the parameters left as we dont want to include the Camel // internal options addressUri = UnsafeUriCharactersEncoder.encodeHttpURI(addressUri); URI httpUri = URISupport.createRemainingURI(new URI(addressUri), parameters); endpoint.setHttpUri(httpUri); return endpoint; }
public void process(Exchange exchange) throws Exception { // 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 (getEndpoint().isBridgeEndpoint()) { exchange.setProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.TRUE); String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class); if (queryString != null) { skipRequestHeaders = URISupport.parseQuery(queryString); } // Need to remove the Host key as it should be not used exchange.getIn().getHeaders().remove("host"); } HttpMethod method = createMethod(exchange); Message in = exchange.getIn(); String httpProtocolVersion = in.getHeader(Exchange.HTTP_PROTOCOL_VERSION, String.class); if (httpProtocolVersion != null) { // set the HTTP protocol version HttpMethodParams params = method.getParams(); params.setVersion(HttpVersion.parse(httpProtocolVersion)); } HeaderFilterStrategy strategy = getEndpoint().getHeaderFilterStrategy(); // propagate headers as HTTP headers for (Map.Entry<String, Object> entry : in.getHeaders().entrySet()) { String key = entry.getKey(); Object headerValue = in.getHeader(key); if (headerValue != null) { // use an iterator as there can be multiple values. (must not use a delimiter, and allow // empty values) final Iterator<?> it = ObjectHelper.createIterator(headerValue, null, true); // the value to add as request header final List<String> values = new ArrayList<String>(); // if its a multi value then check each value if we can add it and for multi values they // should be combined into a single value while (it.hasNext()) { String value = exchange.getContext().getTypeConverter().convertTo(String.class, it.next()); // we should not add headers for the parameters in the uri if we bridge the endpoint // as then we would duplicate headers on both the endpoint uri, and in HTTP headers as // well if (skipRequestHeaders != null && skipRequestHeaders.containsKey(key)) { continue; } if (value != null && strategy != null && !strategy.applyFilterToCamelHeaders(key, value, exchange)) { values.add(value); } } // add the value(s) as a http request header if (values.size() > 0) { // use the default toString of a ArrayList to create in the form [xxx, yyy] // if multi valued, for a single value, then just output the value as is String s = values.size() > 1 ? values.toString() : values.get(0); method.addRequestHeader(key, s); } } } // lets store the result in the output message. try { if (LOG.isDebugEnabled()) { LOG.debug("Executing http {} method: {}", method.getName(), method.getURI().toString()); } int responseCode = executeMethod(method); LOG.debug("Http responseCode: {}", responseCode); if (!throwException) { // if we do not use failed exception then populate response for all response codes populateResponse(exchange, method, in, strategy, responseCode); } else { if (responseCode >= 100 && responseCode < 300) { // only populate response for OK response populateResponse(exchange, method, in, strategy, responseCode); } else { // operation failed so populate exception to throw throw populateHttpOperationFailedException(exchange, method, responseCode); } } } finally { method.releaseConnection(); } }
/** * Ensures that the Uri was not changed because no password was found. * * @param uri The uri to test. */ private void assertSanitizedUriUnchanged(String uri) { assertEquals(uri, URISupport.sanitizeUri(uri)); }
@Override public String toString() { return "SWFWorkflowConsumer[" + URISupport.sanitizeUri(getEndpoint().getEndpointUri()) + "]"; }
Consumer doCreateConsumer( CamelContext camelContext, Processor processor, String verb, String basePath, String uriTemplate, String consumes, String produces, RestConfiguration configuration, Map<String, Object> parameters, boolean api) throws Exception { String path = basePath; if (uriTemplate != null) { // make sure to avoid double slashes if (uriTemplate.startsWith("/")) { path = path + uriTemplate; } else { path = path + "/" + uriTemplate; } } path = FileUtil.stripLeadingSeparator(path); RestConfiguration config = configuration; if (config == null) { config = getCamelContext().getRestConfiguration("spark-rest", true); } Map<String, Object> map = new HashMap<String, Object>(); if (consumes != null) { map.put("accept", consumes); } // setup endpoint options if (config.getEndpointProperties() != null && !config.getEndpointProperties().isEmpty()) { map.putAll(config.getEndpointProperties()); } if (ObjectHelper.isNotEmpty(path)) { // spark-rest uses :name syntax instead of {name} so we need to replace those Matcher matcher = pattern.matcher(path); path = matcher.replaceAll(":$1"); } // prefix path with context-path if configured in rest-dsl configuration String contextPath = config.getContextPath(); if (ObjectHelper.isNotEmpty(contextPath)) { contextPath = FileUtil.stripTrailingSeparator(contextPath); contextPath = FileUtil.stripLeadingSeparator(contextPath); if (ObjectHelper.isNotEmpty(contextPath)) { path = contextPath + "/" + path; } } String url; if (api) { url = "spark-rest:%s:%s?matchOnUriPrefix=true"; } else { url = "spark-rest:%s:%s"; } url = String.format(url, verb, path); String query = URISupport.createQueryString(map); if (!query.isEmpty()) { url = url + "?" + query; } // get the endpoint SparkEndpoint endpoint = camelContext.getEndpoint(url, SparkEndpoint.class); setProperties(endpoint, parameters); // configure consumer properties Consumer consumer = endpoint.createConsumer(processor); if (config.getConsumerProperties() != null && !config.getConsumerProperties().isEmpty()) { setProperties(consumer, config.getConsumerProperties()); } return consumer; }