Java tutorial
/* * Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.switchyard.component.http; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.jboss.logging.Logger; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.ChallengeState; import org.apache.http.auth.Credentials; import org.apache.http.auth.NTCredentials; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.params.AuthPNames; import org.apache.http.client.AuthCache; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpOptions; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.params.AuthPolicy; import org.apache.http.client.protocol.ClientContext; import org.apache.http.client.utils.HttpClientUtils; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HTTP; import org.switchyard.Exchange; import org.switchyard.HandlerException; import org.switchyard.Message; import org.switchyard.Scope; import org.switchyard.ServiceDomain; import org.switchyard.component.common.composer.MessageComposer; import org.switchyard.component.http.composer.HttpComposition; import org.switchyard.component.http.composer.HttpBindingData; import org.switchyard.component.http.composer.HttpRequestBindingData; import org.switchyard.component.http.composer.HttpResponseBindingData; import org.switchyard.component.http.config.model.HttpBindingModel; import org.switchyard.deploy.BaseServiceHandler; import org.switchyard.label.BehaviorLabel; import org.switchyard.runtime.event.ExchangeCompletionEvent; /** * Handles invoking external HTTP services. * * @author Magesh Kumar B <mageshbk@jboss.com> (C) 2012 Red Hat Inc. */ public class OutboundHandler extends BaseServiceHandler { private static final Logger LOGGER = Logger.getLogger(OutboundHandler.class); private static final String HTTP_GET = "GET"; private static final String HTTP_POST = "POST"; private static final String HTTP_DELETE = "DELETE"; private static final String HTTP_HEAD = "HEAD"; private static final String HTTP_PUT = "PUT"; private static final String HTTP_OPTIONS = "OPTIONS"; private static final Set<String> REQUEST_HEADER_BLACKLIST = new HashSet<String>( Arrays.asList(HTTP.CONTENT_LEN, HTTP.TRANSFER_ENCODING)); private final HttpBindingModel _config; private final String _bindingName; private final String _referenceName; private MessageComposer<HttpBindingData> _messageComposer; private String _baseAddress = "http://localhost:8080"; private String _httpMethod = HTTP_GET; private String _contentType; private AuthScope _authScope; private AuthCache _authCache; private Credentials _credentials; private HttpHost _proxyHost; private Integer _timeout; /** * Constructor. * @param config the configuration settings * @param domain the service domain */ public OutboundHandler(final HttpBindingModel config, final ServiceDomain domain) { super(domain); _config = config; _bindingName = config.getName(); _referenceName = config.getReference().getName(); } /** * Start lifecycle. * * @throws HttpConsumeException If unable to load or access a HTTP uri */ @Override protected void doStart() throws HttpConsumeException { String address = _config.getAddress(); if (address != null) { _baseAddress = address; } String method = _config.getMethod(); if (method != null) { _httpMethod = method; } String contentType = _config.getContentType(); if (contentType != null) { _contentType = contentType; } // Create and configure the HTTP message composer _messageComposer = HttpComposition.getMessageComposer(_config); if (_config.hasAuthentication()) { // Set authentication if (_config.isBasicAuth()) { _authScope = createAuthScope(_config.getBasicAuthConfig().getHost(), _config.getBasicAuthConfig().getPort(), _config.getBasicAuthConfig().getRealm()); _credentials = new UsernamePasswordCredentials(_config.getBasicAuthConfig().getUser(), _config.getBasicAuthConfig().getPassword()); // Create AuthCache instance _authCache = new BasicAuthCache(); _authCache.put(new HttpHost(_authScope.getHost(), _authScope.getPort()), new BasicScheme(ChallengeState.TARGET)); } else { _authScope = createAuthScope(_config.getNtlmAuthConfig().getHost(), _config.getNtlmAuthConfig().getPort(), _config.getNtlmAuthConfig().getRealm()); _credentials = new NTCredentials(_config.getNtlmAuthConfig().getUser(), _config.getNtlmAuthConfig().getPassword(), "", _config.getNtlmAuthConfig().getDomain()); } } if (_config.getProxyConfig() != null) { if (_config.getProxyConfig().getPort() != null) { _proxyHost = new HttpHost(_config.getProxyConfig().getHost(), Integer.valueOf(_config.getProxyConfig().getPort()).intValue()); } else { _proxyHost = new HttpHost(_config.getProxyConfig().getHost(), -1); } if (_config.getProxyConfig().getUser() != null) { _authScope = createAuthScope(_config.getProxyConfig().getHost(), _config.getProxyConfig().getPort(), null); _credentials = new UsernamePasswordCredentials(_config.getProxyConfig().getUser(), _config.getProxyConfig().getPassword()); if (_authCache == null) { _authCache = new BasicAuthCache(); } _authCache.put(_proxyHost, new BasicScheme(ChallengeState.PROXY)); } } _timeout = _config.getTimeout(); } private AuthScope createAuthScope(String host, String portStr, String realm) throws HttpConsumeException { URL url = null; try { url = new URL(_baseAddress); } catch (MalformedURLException mue) { final String m = HttpMessages.MESSAGES.invalidHttpURL(); LOGGER.error(m, mue); throw new HttpConsumeException(m, mue); } if (realm == null) { realm = AuthScope.ANY_REALM; } int port = url.getPort(); if (host == null) { host = url.getHost(); } if (portStr != null) { port = Integer.valueOf(portStr).intValue(); } return new AuthScope(host, port, realm); } /** * The handler method that invokes the actual HTTP service when the * component is used as a HTTP consumer. * @param exchange the Exchange * @throws HandlerException handler exception */ @Override public void handleMessage(final Exchange exchange) throws HandlerException { // identify ourselves exchange.getContext().setProperty(ExchangeCompletionEvent.GATEWAY_NAME, _bindingName, Scope.EXCHANGE) .addLabels(BehaviorLabel.TRANSIENT.label()); if (getState() != State.STARTED) { final String m = HttpMessages.MESSAGES.bindingNotStarted(_referenceName, _bindingName); LOGGER.error(m); throw new HandlerException(m); } HttpClient httpclient = new DefaultHttpClient(); if (_timeout != null) { HttpParams httpParams = httpclient.getParams(); HttpConnectionParams.setConnectionTimeout(httpParams, _timeout); HttpConnectionParams.setSoTimeout(httpParams, _timeout); } try { if (_credentials != null) { ((DefaultHttpClient) httpclient).getCredentialsProvider().setCredentials(_authScope, _credentials); List<String> authpref = new ArrayList<String>(); authpref.add(AuthPolicy.NTLM); authpref.add(AuthPolicy.BASIC); httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref); } if (_proxyHost != null) { httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, _proxyHost); } HttpBindingData httpRequest = _messageComposer.decompose(exchange, new HttpRequestBindingData()); HttpRequestBase request = null; if (_httpMethod.equals(HTTP_GET)) { request = new HttpGet(_baseAddress); } else if (_httpMethod.equals(HTTP_POST)) { request = new HttpPost(_baseAddress); ((HttpPost) request).setEntity(new BufferedHttpEntity( new InputStreamEntity(httpRequest.getBodyBytes(), httpRequest.getBodyBytes().available()))); } else if (_httpMethod.equals(HTTP_DELETE)) { request = new HttpDelete(_baseAddress); } else if (_httpMethod.equals(HTTP_HEAD)) { request = new HttpHead(_baseAddress); } else if (_httpMethod.equals(HTTP_PUT)) { request = new HttpPut(_baseAddress); ((HttpPut) request).setEntity(new BufferedHttpEntity( new InputStreamEntity(httpRequest.getBodyBytes(), httpRequest.getBodyBytes().available()))); } else if (_httpMethod.equals(HTTP_OPTIONS)) { request = new HttpOptions(_baseAddress); } Iterator<Map.Entry<String, List<String>>> entries = httpRequest.getHeaders().entrySet().iterator(); while (entries.hasNext()) { Map.Entry<String, List<String>> entry = entries.next(); String name = entry.getKey(); if (REQUEST_HEADER_BLACKLIST.contains(name)) { HttpLogger.ROOT_LOGGER.removingProhibitedRequestHeader(name); continue; } List<String> values = entry.getValue(); for (String value : values) { request.addHeader(name, value); } } if (_contentType != null) { request.addHeader("Content-Type", _contentType); } HttpResponse response = null; if ((_credentials != null) && (_credentials instanceof NTCredentials)) { // Send a request for the Negotiation response = httpclient.execute(new HttpGet(_baseAddress)); HttpClientUtils.closeQuietly(response); } if (_authCache != null) { BasicHttpContext context = new BasicHttpContext(); context.setAttribute(ClientContext.AUTH_CACHE, _authCache); response = httpclient.execute(request, context); } else { response = httpclient.execute(request); } int status = response.getStatusLine().getStatusCode(); HttpEntity entity = response.getEntity(); HttpResponseBindingData httpResponse = new HttpResponseBindingData(); Header[] headers = response.getAllHeaders(); for (Header header : headers) { httpResponse.addHeader(header.getName(), header.getValue()); } if (entity != null) { if (entity.getContentType() != null) { httpResponse.setContentType(new ContentType(entity.getContentType().getValue())); } else { httpResponse.setContentType(new ContentType()); } httpResponse.setBodyFromStream(entity.getContent()); } httpResponse.setStatus(status); Message out = _messageComposer.compose(httpResponse, exchange); if (httpResponse.getStatus() < 400) { exchange.send(out); } else { exchange.sendFault(out); } } catch (Exception e) { final String m = HttpMessages.MESSAGES.unexpectedExceptionHandlingHTTPMessage(); LOGGER.error(m, e); throw new HandlerException(m, e); } finally { // When HttpClient instance is no longer needed, // shut down the connection manager to ensure // immediate deallocation of all system resources httpclient.getConnectionManager().shutdown(); } } }