/* * JBoss, Home of Professional Open Source * Copyright 2006, JBoss Inc., and others contributors as indicated * by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * (C) 2005-2006, JBoss Inc. */ package cl.mas.siniestros.esb.action.ejemplo; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.HttpStatus; import org.apache.log4j.Logger; import org.jboss.internal.soa.esb.publish.Publish; import org.jboss.internal.soa.esb.util.StreamUtils; import org.jboss.soa.esb.ConfigurationException; import org.jboss.soa.esb.actions.ActionLifecycleException; import org.jboss.soa.esb.actions.ActionProcessingException; import org.jboss.soa.esb.actions.annotation.Process; import org.jboss.soa.esb.actions.routing.AbstractRouter; import org.jboss.soa.esb.actions.routing.http.HttpMethodFactory; import org.jboss.soa.esb.actions.routing.http.ResponseType; import org.jboss.soa.esb.helpers.ConfigTree; import org.jboss.soa.esb.http.HttpClientFactory; import org.jboss.soa.esb.http.HttpHeader; import org.jboss.soa.esb.http.HttpRequest; import org.jboss.soa.esb.http.HttpResponse; import org.jboss.soa.esb.listeners.ListenerTagNames; import org.jboss.soa.esb.listeners.message.MessageDeliverException; import org.jboss.soa.esb.message.Message; import org.jboss.soa.esb.message.Properties; import org.jboss.soa.esb.message.ResponseHeader; import org.jboss.soa.esb.message.ResponseStatus; import org.jboss.soa.esb.message.format.MessageFactory; import org.jboss.soa.esb.util.FileUtil; public class HttpRestRouter extends AbstractRouter { private static Logger logger = Logger.getLogger(HttpRestRouter.class); private ConfigTree config; private java.util.Properties httpClientProps = new java.util.Properties(); private HttpClient httpclient; private URL endpointUrl; private String method; private HttpMethodFactory methodFactory; private ResponseType responseType; private String contentType; private ConfigTree[] requestHeaders; private boolean httpResponseStatusEnabled; private String rsPath = ""; private String rsUrl; private final String[] mappedHeaderList ; private static Set<String> coreProperties; static { coreProperties = new HashSet<String>(); coreProperties.add("endpointUrl"); coreProperties.add("method"); coreProperties.add("responseType"); coreProperties.add("Content-Type"); coreProperties.add("method"); } public HttpRestRouter(ConfigTree config) throws ConfigurationException { super(config); this.config = config; rsUrl = config.getRequiredAttribute("endpointUrl"); this.method = config.getRequiredAttribute("method"); this.rsPath = config.getRequiredAttribute("path"); String substring = this.rsPath.substring(0, 1); if("/".equals(substring)) this.rsPath = this.rsPath.replaceFirst("/", ""); extractHttpClientProps(config); mappedHeaderList = extractMappedHeaderListConfig(); } public void init(String url, String contentType)throws ConfigurationException { this.httpclient = HttpClientFactory.createHttpClient(httpClientProps); try { this.endpointUrl = new URL(url); } catch (MalformedURLException e) { throw new ConfigurationException("Invalid endpoint URL '" + config.getRequiredAttribute("endpointUrl") + "'.", e); } this.responseType = ResponseType.valueOf(config.getAttribute("responseType", ResponseType.STRING.toString())); this.methodFactory = HttpMethodFactory.Factory.getInstance(method.toUpperCase(), config, endpointUrl); this.contentType = config.getAttribute("Content-Type"); this.requestHeaders = config.getChildren("header"); this.httpResponseStatusEnabled = ResponseStatus.isHttpEnabled(config); } private String formURL(HttpRequest request) throws ActionProcessingException{ String auxPath = ""; String requestURI = request.getRequestURI(); String esbUrl = request.getContextPath()+ request.getRequestPath(); String restURI = requestURI.replace(esbUrl, ""); String subString = ""; if(restURI != null && restURI.length() > 0) subString = restURI.substring(0, 1); if("/".equals(subString)) restURI = restURI.replaceFirst("/", ""); String[] listRsPath = this.rsPath.split("/"); String[] listRsURI = restURI.split("/"); if(listRsPath == null) throw new ActionProcessingException("listRSPath can not be null"); if(listRsURI == null) throw new ActionProcessingException("listRsURI can not be null"); if(listRsURI.length != listRsPath.length) throw new ActionProcessingException("listRSPath not equal listRsURI"); if(listRsPath.length != 0){ String[] token = new String[listRsPath.length]; for (int i = 0; i < listRsPath.length; i++) { if(listRsPath[i].startsWith("{")){ token[i] = listRsURI[i]; }else{ if(!listRsPath[i].equals(listRsURI[i])) throw new ActionProcessingException("listRSPath not equal listRsURI"); token[i] = listRsPath[i]; } } auxPath = this.implode(token, "/"); } auxPath = this.rsUrl +"/"+ auxPath; return auxPath; } public static String implode(String[] ary, String delim) { String out = ""; for(int i=0; i<ary.length; i++) { if(i!=0) { out += delim; } out += ary[i]; } } @Process public Message process(Message message) throws ActionProcessingException { HttpMethodBase httpMethod = null; HttpRequest request = HttpRequest.getRequest(message); String path = this.formURL(request); try { this.init(path, request.getContentType()); } catch (ConfigurationException e1) { e1.printStackTrace(); throw new ActionProcessingException(e1); } try { httpMethod = methodFactory.getInstance(message); httpMethod.setQueryString(request.getQueryString()); try { setRequestHeaders(httpMethod, message); int responseCode = httpclient.executeMethod(httpMethod); if(responseCode != HttpStatus.SC_OK) { logger.warn("Received status code '" + responseCode + "' on HTTP " + httpMethod + " request to '" + endpointUrl + "'."); } attachResponseDetails(message, httpMethod, responseCode); InputStream resultStream = httpMethod.getResponseBodyAsStream(); try { byte[] bytes = readStream(resultStream); if(responseType == ResponseType.STRING) { getPayloadProxy().setPayload(message, new String(bytes, httpMethod.getResponseCharSet())); } else { getPayloadProxy().setPayload(message, bytes); } } catch (MessageDeliverException e) { throw new ActionProcessingException("problem setting message payload: " + e.getMessage(), e); } finally { closeStream(resultStream); } } finally { httpMethod.releaseConnection(); } } catch (IOException e) { throw new ActionProcessingException("problem processing HTTP I/O: " + e.getMessage(), e); } return message; } static byte[] readStream(final InputStream stream) throws IOException { if (stream != null) { return StreamUtils.readStream(stream); } else return new byte[0]; } static void closeStream(final Closeable c) throws IOException { if (c != null) { c.close(); } } private String[] extractMappedHeaderListConfig() throws ConfigurationException { final String mappedHeaders = config.getAttribute("MappedHeaderList"); if (mappedHeaders != null) { final String[] headerList = mappedHeaders.split(","); final int numHeaders = headerList.length ; final ArrayList<String> headers = new ArrayList<String>(numHeaders) ; for(int count = 0 ; count < numHeaders ; count++) { final String header = headerList[count].trim() ; if (header.length() > 0) { headers.add(header) ; } } return (String[])headers.toArray(new String[headers.size()]) ; } else { return new String[0] ; } } private void attachResponseDetails(Message message, HttpMethodBase method, int responseCode) { HttpResponse response = new HttpResponse(responseCode); Properties properties = message.getProperties(); response.setEncoding(method.getResponseCharSet()); response.setLength(method.getResponseContentLength()); Header[] responseHeaders = method.getResponseHeaders(); for(Header responseHeader : responseHeaders) { String name = responseHeader.getName(); String value = responseHeader.getValue(); response.addHeader(new org.jboss.soa.esb.http.HttpHeader(name, value)); // JBESB-2511 new ResponseHeader(name, value).setPropertyNameThis(properties); } // JBESB-2761 if (httpResponseStatusEnabled) { ResponseStatus.setHttpProperties(properties, responseCode, method.getStatusLine().getReasonPhrase()); } response.setResponse(message); } private void setRequestHeaders(HttpMethodBase method, Message message) { setMappedHttpHeaders(method, message); for (int i = 0; i < requestHeaders.length; i++) { ConfigTree header = requestHeaders[i]; String name = header.getAttribute("name"); String value = header.getAttribute("value"); if(name != null && value != null) { method.setRequestHeader(name, value); } else { logger.error("null Http request header name/value: '" + name + "':'" + value + "'."); } } if (contentType != null) { method.setRequestHeader("Content-Type", contentType); } else if (method.getRequestHeader("Content-Type") == null) { method.setRequestHeader("Content-Type", "text/xml;charset=UTF-8") ; } } private void setMappedHttpHeaders(HttpMethodBase method, Message message) { HttpRequest request = HttpRequest.getRequest(message); Properties properties = message.getProperties(); for (String headerName : mappedHeaderList) { String headerValue = null; if (request != null) { headerValue = getHttpHeaderValue(request, headerName); } if (headerValue == null) { headerValue = getHttpHeaderValue(properties, headerName); } if (headerValue != null) { method.setRequestHeader(headerName, headerValue); } } } private String getHttpHeaderValue(HttpRequest request, String headerName) { String headerValue = null; for (HttpHeader header : request.getHeaders()) { String name = header.getName(); if (name.equalsIgnoreCase(headerName)) { headerValue = header.getValue(); break; } } return headerValue; } private String getHttpHeaderValue(Properties properties, String headerName) { String headerValue = null; for (String name : properties.getNames()) { if (name.equalsIgnoreCase(headerName)) { Object property = properties.getProperty(name); if (property != null) { headerValue = property.toString(); if (headerValue.length() == 0) { headerValue = null; } } break; } } return headerValue; } public String[] getMappedHeaderList() { return mappedHeaderList; } public void destroy() throws ActionLifecycleException { if (httpclient != null) { HttpClientFactory.shutdown(httpclient); } super.destroy(); } private void extractHttpClientProps(ConfigTree config) { ConfigTree[] httpClientConfigTrees = config.getChildren("http-client-property"); httpClientProps.setProperty(HttpClientFactory.TARGET_HOST_URL, this.rsUrl); final ConfigTree parent = config.getParent() ; if (parent != null) { final String maxThreads = config.getParent().getAttribute(ListenerTagNames.MAX_THREADS_TAG) ; if (maxThreads != null) { httpClientProps.setProperty("3", maxThreads) ; } } for(ConfigTree httpClientProp : httpClientConfigTrees) { String propName = httpClientProp.getAttribute("name"); String propValue = httpClientProp.getAttribute("value"); if(propName != null && propValue != null) { httpClientProps.setProperty(propName, propValue); } } } public static void main(String[] args) throws ConfigurationException, ActionProcessingException { ConfigTree configTree = new ConfigTree("config"); for(String arg : args) { int equalsIdx = arg.indexOf('='); if(equalsIdx == -1) { throw new IllegalArgumentException("Arguments must be in 'name=value' format."); } String name = arg.substring(0, equalsIdx); String value = arg.substring(equalsIdx + 1); if(!coreProperties.contains(name) && !name.equals("payload")) { ConfigTree httpClientProperty = new ConfigTree("http-client-property", configTree); httpClientProperty.setAttribute("name", name); httpClientProperty.setAttribute("value", value); } else { configTree.setAttribute(name, value); } } HttpRestRouter router = new HttpRestRouter(configTree); Message message = MessageFactory.getInstance().getMessage(); String payload = configTree.getAttribute("payload"); if(payload != null) { try { File file = new File(payload); if(file.exists()) { payload = FileUtil.readTextFile(file); } } catch (Exception e) { e.printStackTrace(); } System.out.println("Request payload:\n" + payload); System.out.println("--------------------------\n"); message.getBody().add(payload); } message = router.process(message); HttpResponse responseInfo = HttpResponse.getResponse(message); System.out.println(); System.out.println("Response Status Code: " + responseInfo.getResponseCode()); System.out.println("Response payload:\n" + message.getBody().get()); System.out.println("--------------------------\n"); } @Override public void route(Object arg0) throws ActionProcessingException { // TODO Auto-generated method stub } }
Comments