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.endpoint; import java.io.IOException; import java.net.InetSocketAddress; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.jboss.logging.Logger; import org.jboss.com.sun.net.httpserver.BasicAuthenticator; import org.jboss.com.sun.net.httpserver.HttpContext; import org.jboss.com.sun.net.httpserver.HttpExchange; import org.jboss.com.sun.net.httpserver.HttpHandler; import org.jboss.com.sun.net.httpserver.HttpServer; import org.switchyard.ServiceDomain; import org.switchyard.component.common.Endpoint; import org.switchyard.component.http.ContentType; import org.switchyard.component.http.HttpLogger; import org.switchyard.component.http.InboundHandler; import org.switchyard.component.http.composer.HttpRequestBindingData; import org.switchyard.component.http.composer.HttpRequestInfo; import org.switchyard.component.http.composer.HttpResponseBindingData; import org.switchyard.security.jboss.credential.extractor.HttpExchangeCredentialExtractor; /** * Publishes standalone HTTP endpoint. * <p> * By default it will be published in port {@value #DEFAULT_PORT}. This can be configured making use of * <i>{@value #DEFAULT_PORT_PROPERTY}</i> system property. * </p> * * @author Magesh Kumar B <mageshbk@jboss.com> (C) 2012 Red Hat Inc. */ public class StandaloneEndpointPublisher implements EndpointPublisher { /** * Default port in which the standalone publisher is started. */ public static final int DEFAULT_PORT = 8080; /** * System property to adjust the port in which the standalone publisher is started. */ public static final String DEFAULT_PORT_PROPERTY = "org.switchyard.component.http.standalone.port"; private static final Logger LOGGER = Logger.getLogger(StandaloneEndpointPublisher.class); private static final String CONTENT_TYPE = "Content-Type"; // The global standalone HttpServer private static HttpServer _httpServer; static { try { _httpServer = HttpServer.create(new InetSocketAddress(getPort()), 10); _httpServer.setExecutor(null); // creates a default executor _httpServer.start(); } catch (IOException ioe) { HttpLogger.ROOT_LOGGER.unableToLaunchStandaloneHttpServer(ioe); } } /** * {@inheritDoc} */ public Endpoint publish(ServiceDomain domain, String context, InboundHandler handler) throws Exception { HttpContext httpContext = null; if (!context.startsWith("/")) { context = "/" + context; } if (_httpServer != null) { httpContext = _httpServer.createContext(context, new StandaloneHandler(handler)); } return new StandaloneEndpoint(httpContext); } private static class StandaloneHandler implements HttpHandler { private InboundHandler _handler; public StandaloneHandler(InboundHandler handler) { _handler = handler; } public void handle(HttpExchange exchange) { try { HttpRequestBindingData httpRequest = new HttpRequestBindingData(); byte[] responseBody = null; try { String contentTypeStr = exchange.getRequestHeaders().getFirst(CONTENT_TYPE); ContentType contentType = new ContentType(contentTypeStr); httpRequest.setContentType(contentType); httpRequest.setBodyFromStream(exchange.getRequestBody()); httpRequest.setHeaders(exchange.getRequestHeaders()); httpRequest.setRequestInfo(getRequestInfo(exchange, contentType)); } catch (IOException e) { HttpLogger.ROOT_LOGGER.unexpectedExceptionWhileReadingRequest(e); } HttpResponseBindingData httpResponse = _handler.invoke(httpRequest); try { if (httpResponse != null) { exchange.getResponseHeaders().putAll(httpResponse.getHeaders()); if (httpResponse.getBodyBytes() != null) { exchange.sendResponseHeaders(httpResponse.getStatus(), httpResponse.getBodyBytes().available()); httpResponse.writeBodyToStream(exchange.getResponseBody()); } else { if (httpResponse.getStatus() != null) { exchange.sendResponseHeaders(httpResponse.getStatus(), 0); } else { exchange.sendResponseHeaders(HttpServletResponse.SC_ACCEPTED, 0); } } } else { exchange.sendResponseHeaders(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 0); } } catch (IOException e) { HttpLogger.ROOT_LOGGER.unexpectedExceptionWhileWritingResponse(e); } } catch (Exception e) { HttpLogger.ROOT_LOGGER.unexpectedExceptionWhileHandlingHttpRequest(e); } } } /** * Method for get request information from a http exchange. * * @param request HttpExchange * @param type ContentType * @return Request information from a http exchange * @throws IOException when the request information could not be read */ public static HttpRequestInfo getRequestInfo(HttpExchange request, ContentType type) throws IOException { HttpRequestInfo requestInfo = new HttpRequestInfo(); if (request.getHttpContext().getAuthenticator() instanceof BasicAuthenticator) { requestInfo.setAuthType(HttpServletRequest.BASIC_AUTH); } URI u = request.getRequestURI(); URI requestURI = null; try { requestURI = new URI(u.getScheme(), u.getUserInfo(), u.getHost(), u.getPort(), u.getPath(), null, null); } catch (URISyntaxException e) { // Strange that this could happen when copying from another URI. LOGGER.debug(e); } requestInfo.setCharacterEncoding(type.getCharset()); requestInfo.setContentType(type.toString()); requestInfo.setContextPath(request.getHttpContext().getPath()); requestInfo.setLocalAddr(request.getLocalAddress().getAddress().getHostAddress()); requestInfo.setLocalName(request.getLocalAddress().getAddress().getHostName()); requestInfo.setMethod(request.getRequestMethod()); requestInfo.setProtocol(request.getProtocol()); requestInfo.setQueryString(u.getQuery()); requestInfo.setRemoteAddr(request.getRemoteAddress().getAddress().getHostAddress()); requestInfo.setRemoteHost(request.getRemoteAddress().getAddress().getHostName()); if (request.getHttpContext().getAuthenticator() instanceof BasicAuthenticator) { requestInfo.setRemoteUser(request.getPrincipal().getUsername()); } requestInfo.setContentLength(request.getRequestBody().available()); // requestInfo.setRequestSessionId(request.getRequestedSessionId()); if (requestURI != null) { requestInfo.setRequestURI(requestURI.toString()); } requestInfo.setScheme(u.getScheme()); requestInfo.setServerName(u.getHost()); requestInfo.setRequestPath(u.getPath()); // Http Query params... if (requestInfo.getQueryString() != null) { Charset charset = null; if (type.getCharset() != null) { try { charset = Charset.forName(type.getCharset()); } catch (Exception exception) { LOGGER.debug(exception); } } for (NameValuePair nameValuePair : URLEncodedUtils.parse(requestInfo.getQueryString(), charset)) { requestInfo.addQueryParam(nameValuePair.getName(), nameValuePair.getValue()); } } // Credentials... requestInfo.getCredentials().addAll(new HttpExchangeCredentialExtractor().extract(request)); if (LOGGER.isTraceEnabled()) { LOGGER.trace(requestInfo); } return requestInfo; } /** * Returns the port where the standalone publisher will be started * @return the port */ static int getPort() { int port = DEFAULT_PORT; final String portAsStr = System.getProperty(DEFAULT_PORT_PROPERTY); if (portAsStr != null) { port = Integer.parseInt(portAsStr); } return port; } }