001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.gae.http;
018
019 import java.lang.reflect.Proxy;
020 import java.net.URI;
021 import java.net.URISyntaxException;
022 import java.net.URL;
023 import java.util.Map;
024
025 import javax.servlet.http.HttpServletRequest;
026 import javax.servlet.http.HttpServletResponse;
027
028 import com.google.appengine.api.urlfetch.HTTPRequest;
029 import com.google.appengine.api.urlfetch.HTTPResponse;
030 import com.google.appengine.api.urlfetch.URLFetchService;
031
032 import org.apache.camel.Exchange;
033 import org.apache.camel.Producer;
034 import org.apache.camel.component.gae.bind.HttpBindingInvocationHandler;
035 import org.apache.camel.component.gae.bind.InboundBinding;
036 import org.apache.camel.component.gae.bind.OutboundBinding;
037 import org.apache.camel.component.gae.bind.OutboundBindingSupport;
038 import org.apache.camel.component.http.HttpBinding;
039 import org.apache.camel.component.http.HttpClientConfigurer;
040 import org.apache.camel.component.servlet.ServletComponent;
041 import org.apache.camel.component.servlet.ServletEndpoint;
042 import org.apache.camel.util.URISupport;
043 import org.apache.camel.util.UnsafeUriCharactersEncoder;
044 import org.apache.commons.httpclient.HttpConnectionManager;
045 import org.apache.commons.httpclient.params.HttpClientParams;
046
047 /**
048 * Represents a <a href="http://camel.apache.org/todo.html">Google App Engine
049 * HTTP endpoint</a>.
050 */
051 public class GHttpEndpoint extends ServletEndpoint implements OutboundBindingSupport<GHttpEndpoint, HTTPRequest, HTTPResponse> {
052
053 public static final String GHTTP_SCHEME = "ghttp";
054 public static final String GHTTPS_SCHEME = "ghttps";
055
056 public static final String HTTP_SCHEME = "http";
057 public static final String HTTPS_SCHEME = "https";
058
059 private URLFetchService urlFetchService;
060
061 private OutboundBinding<GHttpEndpoint, HTTPRequest, HTTPResponse> outboundBinding;
062 private InboundBinding<GHttpEndpoint, HttpServletRequest, HttpServletResponse> inboundBinding;
063
064 public GHttpEndpoint(String endpointUri, ServletComponent component,
065 URI httpUri, HttpClientParams params,
066 HttpConnectionManager httpConnectionManager,
067 HttpClientConfigurer clientConfigurer) throws URISyntaxException {
068 super(endpointUri, component, httpUri, params, httpConnectionManager, clientConfigurer);
069 }
070
071 /**
072 * Constructs a {@link URL} from an <code>uri</code> and an optional
073 * <code>query</code> string. The encoding strategy follow those of the
074 * Camel HTTP component.
075 *
076 * @param uri
077 * must be encoded with
078 * {@link UnsafeUriCharactersEncoder#encode(String)}.
079 * @param query
080 * decoded query string. Replaces the query part of
081 * <code>uri</code> if not <code>null</code>.
082 */
083 @SuppressWarnings("unchecked")
084 static URL getEndpointUrl(String uri, String query) throws Exception {
085 Map<String, Object> parameters = null;
086 URI uriObj = new URI(uri);
087 if (query == null) {
088 parameters = URISupport.parseParameters(uriObj);
089 } else {
090 parameters = URISupport.parseQuery(query);
091 }
092 if (uriObj.getScheme().equals(GHTTPS_SCHEME)) {
093 uriObj = new URI(HTTPS_SCHEME + ":" + uriObj.getRawSchemeSpecificPart());
094 } else { // ghttp or anything else
095 uriObj = new URI(HTTP_SCHEME + ":" + uriObj.getRawSchemeSpecificPart());
096 }
097 return URISupport.createRemainingURI(uriObj, (Map)parameters).toURL();
098 }
099
100 public URL getEndpointUrl() throws Exception {
101 return getEndpointUrl(getEndpointUri(), null);
102 }
103
104 public URLFetchService getUrlFetchService() {
105 return urlFetchService;
106 }
107
108 public void setUrlFetchService(URLFetchService urlFetchService) {
109 this.urlFetchService = urlFetchService;
110 }
111
112 public OutboundBinding<GHttpEndpoint, HTTPRequest, HTTPResponse> getOutboundBinding() {
113 return outboundBinding;
114 }
115
116 public void setOutboundBinding(OutboundBinding<GHttpEndpoint, HTTPRequest, HTTPResponse> outboundBinding) {
117 this.outboundBinding = outboundBinding;
118 }
119
120 public InboundBinding<GHttpEndpoint, HttpServletRequest, HttpServletResponse> getInboundBinding() {
121 return inboundBinding;
122 }
123
124 public void setInboundBinding(
125 InboundBinding<GHttpEndpoint, HttpServletRequest, HttpServletResponse> inboundBinding) {
126 this.inboundBinding = inboundBinding;
127 }
128
129 /**
130 * Proxies the {@link HttpBinding} returned by {@link super#getBinding()}
131 * with a dynamic proxy. The proxy's invocation handler further delegates to
132 * {@link InboundBinding#readRequest(org.apache.camel.Endpoint, Exchange, Object)}
133 * .
134 *
135 * @return proxied {@link HttpBinding}.
136 */
137 @Override
138 public HttpBinding getBinding() {
139 return (HttpBinding)Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {HttpBinding.class},
140 new HttpBindingInvocationHandler<GHttpEndpoint, HttpServletRequest, HttpServletResponse>(
141 this, super.getBinding(), getInboundBinding()));
142 }
143
144 public Producer createProducer() throws Exception {
145 return new GHttpProducer(this);
146 }
147
148 }