You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mi...@apache.org on 2008/10/01 02:39:57 UTC
svn commit: r700646 - in /ode/branches/APACHE_ODE_1.X:
axis2-war/src/test/java/org/apache/ode/axis2/
axis2-war/src/test/resources/TestEndpointProperties/
axis2/src/main/java/org/apache/ode/axis2/httpbinding/
Author: midon
Date: Tue Sep 30 17:39:57 2008
New Revision: 700646
URL: http://svn.apache.org/viewvc?rev=700646&view=rev
Log:
Support Basic/Digest auth for external services
Added:
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointConfigurationTest.java
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/jetty-realm.properties
Removed:
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointPropertiesTest.java
Modified:
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/JettyWrapper.java
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/Echo.wsdl
ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/test-endpoint-properties.bpel
ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointConfigurationTest.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointConfigurationTest.java?rev=700646&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointConfigurationTest.java (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/EndpointConfigurationTest.java Tue Sep 30 17:39:57 2008
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.ode.axis2;
+
+import junit.framework.TestCase;
+import org.apache.ode.axis2.JettyWrapper;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.handler.HandlerList;
+import org.mortbay.jetty.security.Constraint;
+import org.mortbay.jetty.security.ConstraintMapping;
+import org.mortbay.jetty.security.SecurityHandler;
+import org.mortbay.jetty.security.HashUserRealm;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ *
+ *
+ */
+public class EndpointConfigurationTest extends Axis2TestBase {
+
+
+ public void testEndpointProperties() throws Exception {
+ executeProcess();
+ }
+
+ protected void executeProcess() throws Exception {
+ executeProcess(null);
+ }
+
+ protected void executeProcess(ContextHandler handler) throws Exception {
+ JettyWrapper jettyWrapper = new JettyWrapper(handler);
+ jettyWrapper.start();
+
+ try {
+ String bundleName = "TestEndpointProperties";
+ if (server.isDeployed(bundleName)) server.undeployProcess(bundleName);
+ server.deployProcess(bundleName);
+ try {
+ String response = server.sendRequestFile("http://localhost:8080/processes/helloWorld",
+ bundleName, "testRequest.soap");
+ assertTrue(response.contains("helloResponse") && response.contains("OK!!!"));
+ } finally {
+ server.undeployProcess(bundleName);
+ }
+ } finally {
+ jettyWrapper.stop();
+ }
+ }
+
+ /**
+ * Redo the exact same test but with Basic Authentication activated on the external service
+ * @throws Exception
+ */
+ public void testHttpAuthentication() throws Exception {
+ ContextHandler securedEchoContext;
+ {
+ Constraint constraint = new Constraint();
+ constraint.setName(Constraint.__BASIC_AUTH);
+ constraint.setRoles(new String[]{"user"});
+ constraint.setAuthenticate(true);
+
+ ConstraintMapping cm = new ConstraintMapping();
+ cm.setConstraint(constraint);
+ cm.setPathSpec("/*");
+
+ SecurityHandler sh = new SecurityHandler();
+ sh.setUserRealm(new HashUserRealm("MyRealm", getClass().getResource("/TestEndpointProperties/jetty-realm.properties").toURI().toString()));
+ sh.setConstraintMappings(new ConstraintMapping[]{cm});
+
+ securedEchoContext = new ContextHandler();
+ securedEchoContext.setContextPath("/EchoService");
+
+ HandlerList hc = new HandlerList();
+ hc.addHandler(sh);
+ hc.addHandler(new JettyWrapper.EchoServiceHandler());
+ securedEchoContext.addHandler(hc);
+ }
+ executeProcess(securedEchoContext);
+ }
+
+
+}
Modified: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/JettyWrapper.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/JettyWrapper.java?rev=700646&r1=700645&r2=700646&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/JettyWrapper.java (original)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/java/org/apache/ode/axis2/JettyWrapper.java Tue Sep 30 17:39:57 2008
@@ -22,9 +22,14 @@
import org.mortbay.jetty.handler.AbstractHandler;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.handler.ContextHandlerCollection;
+import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Request;
+import org.mortbay.jetty.security.ConstraintMapping;
+import org.mortbay.jetty.security.Constraint;
+import org.mortbay.jetty.security.SecurityHandler;
+import org.mortbay.jetty.security.HashUserRealm;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.StreamUtils;
import org.apache.commons.lang.StringUtils;
@@ -41,20 +46,14 @@
import java.util.Enumeration;
import java.util.List;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
/**
* @author <a href="mailto:midon@intalio.com">Alexis Midon</a>
*/
public class JettyWrapper {
- static List REQUEST_HEADERS = new ArrayList();
-
- static {
- REQUEST_HEADERS.add("");
- }
-
protected Server server;
- private ContextHandlerCollection handlerColl;
public JettyWrapper() throws Exception {
this(7070);
@@ -62,6 +61,18 @@
public JettyWrapper(int port) throws Exception {
server = new Server(port);
+ addDefaultHandlers();
+ }
+
+
+ public JettyWrapper(ContextHandler handler) {
+ server = new Server(7070);
+ if(handler!=null) server.addHandler(handler);
+ else addDefaultHandlers();
+ }
+
+
+ private void addDefaultHandlers() {
ContextHandler arithmeticsContext = new ContextHandler();
arithmeticsContext.setContextPath("/HttpBindingTest/ArithmeticsService");
arithmeticsContext.setHandler(new ArithmeticsServiceHandler());
@@ -74,7 +85,7 @@
echoContext.setContextPath("/EchoService");
echoContext.setHandler(new EchoServiceHandler());
- handlerColl = new ContextHandlerCollection();
+ ContextHandlerCollection handlerColl = new ContextHandlerCollection();
Handler[] handlers = {arithmeticsContext, blogContext, echoContext};
handlerColl.setHandlers(handlers);
@@ -82,20 +93,18 @@
}
public void start() throws Exception {
- if (!server.isStarted())
- server.start();
+ server.start();
}
public void stop() throws Exception {
server.stop();
}
- private class EchoServiceHandler extends AbstractHandler {
-
+ static public class EchoServiceHandler extends AbstractHandler {
public void handle(String s, HttpServletRequest request, HttpServletResponse response, int i) throws IOException, ServletException {
String method = request.getMethod();
- if (StringUtils.isNotEmpty(request.getParameter("ping"))) {
+ if (request.getParameter("ping")!=null) {
response.setStatus(200);
response.getOutputStream().println("Yep, I'm here!");
} else {
Modified: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/Echo.wsdl
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/Echo.wsdl?rev=700646&r1=700645&r2=700646&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/Echo.wsdl (original)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/Echo.wsdl Tue Sep 30 17:39:57 2008
@@ -9,7 +9,19 @@
xmlns:odex="http://www.apache.org/ode/type/extension/http"
targetNamespace="http://ode/bpel/test/properties">
-
+ <wsdl:types>
+ <xsd:schema xmlns:ns="http://ode/bpel/test/properties" attributeFormDefault="qualified"
+ elementFormDefault="unqualified" targetNamespace="http://ode/bpel/test/properties">
+
+ <xsd:element name="credentials">
+ <xsd:complexType>
+ <xsd:attribute name="scheme" type="xsd:string" default="server-decide"/>
+ <xsd:attribute name="username" type="xsd:string"/>
+ <xsd:attribute name="password" type="xsd:string"/>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ </wsdl:types>
<!--
The goal of this test is to make sure endpoint properties are properly passed around.
Endpoint properties might be set with property files matching *.endpoint.
@@ -33,6 +45,7 @@
<wsdl:part name="header_BC" type="xsd:string"/>
<wsdl:part name="header_AA" type="xsd:string"/>
<wsdl:part name="header_BB" type="xsd:string"/>
+ <wsdl:part name="WWW-Authenticate" element="credentials"/>
</wsdl:message>
@@ -49,9 +62,9 @@
<odex:binding verb="GET"/>
<wsdl:input>
<http:urlReplacement/>
- <odex:header name="header_A" part="header_A" />
- <odex:header name="header_B" part="header_B" />
- <odex:header name="header_C" part="header_C" />
+ <odex:header name="header_A" part="header_A"/>
+ <odex:header name="header_B" part="header_B"/>
+ <odex:header name="header_C" part="header_C"/>
<odex:header name="header_ABC" part="header_ABC"/>
<odex:header name="header_AB" part="header_AB"/>
<odex:header name="header_AC" part="header_AC"/>
@@ -60,9 +73,9 @@
<odex:header name="header_BB" part="header_BB"/>
</wsdl:input>
<wsdl:output>
- <odex:header name="header_A" part="header_A" />
- <odex:header name="header_B" part="header_B" />
- <odex:header name="header_C" part="header_C" />
+ <odex:header name="header_A" part="header_A"/>
+ <odex:header name="header_B" part="header_B"/>
+ <odex:header name="header_C" part="header_C"/>
<odex:header name="header_ABC" part="header_ABC"/>
<odex:header name="header_AB" part="header_AB"/>
<odex:header name="header_AC" part="header_AC"/>
Added: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/jetty-realm.properties
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/jetty-realm.properties?rev=700646&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/jetty-realm.properties (added)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/jetty-realm.properties Tue Sep 30 17:39:57 2008
@@ -0,0 +1,3 @@
+
+#username=password, role, role, ...
+superuser=topsecret, user
Modified: ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/test-endpoint-properties.bpel
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/test-endpoint-properties.bpel?rev=700646&r1=700645&r2=700646&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/test-endpoint-properties.bpel (original)
+++ ode/branches/APACHE_ODE_1.X/axis2-war/src/test/resources/TestEndpointProperties/test-endpoint-properties.bpel Tue Sep 30 17:39:57 2008
@@ -68,6 +68,11 @@
<!-- Assign all header parts -->
<assign>
+
+ <copy>
+ <from><literal><credentials username="superuser" password="topsecret"/></literal></from>
+ <to>$reqMsg.WWW-Authenticate</to>
+ </copy>
<!-- header_A will be set through a property file in the global config dir -->
<!-- header_B will be set through a property file in the deployment unit dir -->
Modified: ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java?rev=700646&r1=700645&r2=700646&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java (original)
+++ ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java Tue Sep 30 17:39:57 2008
@@ -149,8 +149,10 @@
// create a client
HttpClient client = new HttpClient(connections);
+
// configure the client (proxy, security, etc)
- HttpHelper.configure(client, method.getURI(), params);
+ Element authenticatePart = DOMUtils.findChildByName(odeMex.getRequest().getMessage(), new QName(null, "WWW-Authenticate"));
+ HttpHelper.configure(client, method.getURI(), authenticatePart, params);
// this callable encapsulates the http method execution and the process of the response
final Callable executionCallable;
Modified: ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java?rev=700646&r1=700645&r2=700646&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java (original)
+++ ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java Tue Sep 30 17:39:57 2008
@@ -29,6 +29,8 @@
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpParams;
@@ -40,9 +42,11 @@
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.http.HttpUtils;
import static org.apache.ode.utils.http.StatusCode.*;
+import org.apache.ode.bpel.iapi.Message;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
+import javax.xml.namespace.QName;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -52,9 +56,9 @@
private static final Log log = LogFactory.getLog(HttpHelper.class);
- public static void configure(HttpClient client, URI targetURI, HttpParams params) throws URIException {
- if (log.isDebugEnabled()) log.debug("Configuring http client...");
+ public static void configure(HttpClient client, URI targetURI, Element authPart, HttpParams params) throws URIException {
+ if (log.isDebugEnabled()) log.debug("Configuring http client...");
/* Do not forget to wire params so that endpoint properties are passed around
Down the road, when the request will be executed, the hierarchy of parameters will be the following:
@@ -68,7 +72,6 @@
// Actually HttpClient *appends* default headers while we want them to be ignored if the process assign them
client.getParams().setParameter(HostParams.DEFAULT_HEADERS, Collections.EMPTY_LIST);
-
// proxy configuration
if (ProxyConf.isProxyEnabled(params, targetURI.getHost())) {
if (log.isDebugEnabled()) log.debug("ProxyConf");
@@ -78,8 +81,39 @@
// security
// ...
-
-
+ // authentication
+ /*
+ We're expecting the following element:
+ <xs:complexType name="credentialType">
+ <xs:attribute name="scheme" type="xs:string" default="server-decide" />
+ <xs:attribute name="username" type="xs:string" />
+ <xs:attribute name="password" type="xs:string" />
+ </xs:complexType>
+ <xs:element type="rest_connector:credentialType" name="credentials" />
+ */
+ if (authPart != null) {
+ // the part must be defined with an element, so take the fist child
+ Element credentialsElement = DOMUtils.getFirstChildElement(authPart);
+ if (credentialsElement != null && credentialsElement.getAttributes().getLength() != 0) {
+ String scheme = DOMUtils.getAttribute(credentialsElement, "scheme");
+ String username = DOMUtils.getAttribute(credentialsElement, "username");
+ String password = DOMUtils.getAttribute(credentialsElement, "password");
+
+ if (scheme != null
+ && !"server-decides".equalsIgnoreCase(scheme)
+ && !"basic".equalsIgnoreCase(scheme)
+ && !"digest".equalsIgnoreCase(scheme)) {
+ throw new IllegalArgumentException("Unknown Authentication scheme: [" + scheme + "] Accepted values are: Basic, Digest, Server-Decides");
+ } else {
+ if(log.isDebugEnabled()) log.debug("credentials provided");
+ client.getState().setCredentials(
+ new AuthScope(targetURI.getHost(), targetURI.getPort(), AuthScope.ANY_REALM, scheme),
+ new UsernamePasswordCredentials(username, password));
+ // save one round trip if basic
+ client.getParams().setAuthenticationPreemptive("basic".equalsIgnoreCase(scheme));
+ }
+ }
+ }
}
/**
@@ -90,11 +124,15 @@
* @throws HttpException
* @see #statusLineToElement(org.w3c.dom.Document, org.apache.commons.httpclient.StatusLine)
*/
- public static Element statusLineToElement(String statusLine) throws HttpException {
+ public static Element statusLineToElement
+ (String
+ statusLine) throws HttpException {
return statusLineToElement(new StatusLine(statusLine));
}
- public static Element statusLineToElement(StatusLine statusLine) {
+ public static Element statusLineToElement
+ (StatusLine
+ statusLine) {
return statusLineToElement(DOMUtils.newDocument(), statusLine);
}
@@ -111,7 +149,10 @@
* @param doc - the document to use to create new nodes
* @return an Element
*/
- public static Element statusLineToElement(Document doc, StatusLine statusLine) {
+ public static Element statusLineToElement
+ (Document
+ doc, StatusLine
+ statusLine) {
Element statusLineEl = doc.createElementNS(null, "Status-Line");
Element versionEl = doc.createElementNS(null, "HTTP-Version");
Element codeEl = doc.createElementNS(null, "Status-Code");
@@ -142,7 +183,9 @@
* @return
* @throws IOException
*/
- public static Element prepareDetailsElement(HttpMethod method) {
+ public static Element prepareDetailsElement
+ (HttpMethod
+ method) {
Header h = method.getResponseHeader("Content-Type");
String receivedType = h != null ? h.getValue() : null;
boolean bodyIsXml = receivedType != null && HttpUtils.isXml(receivedType);
@@ -209,7 +252,9 @@
* @param header
* @return the string properly ready to be used as an HTTP header field-content
*/
- public static String replaceCRLFwithLWS(String header) {
+ public static String replaceCRLFwithLWS
+ (String
+ header) {
Matcher m = NON_LWS_PATTERN.matcher(header);
StringBuffer sb = new StringBuffer(header.length());
while (m.find()) {
@@ -220,7 +265,9 @@
return sb.toString();
}
- public static String requestToString(HttpMethod m) {
+ public static String requestToString
+ (HttpMethod
+ m) {
StringBuilder sb = new StringBuilder(256);
try {
sb.append("HTTP Request Details: \n").append(m.getName()).append(" ").append(m.getURI());
@@ -251,7 +298,9 @@
return sb.toString();
}
- public static String responseToString(HttpMethod m) {
+ public static String responseToString
+ (HttpMethod
+ m) {
StringBuilder sb = new StringBuilder(256);
try {
sb.append("HTTP Response Details: \n").append(m.getName()).append(" ").append(m.getURI());
@@ -283,11 +332,12 @@
}
/**
- *
* @param s, the status code to test, must be in [400, 600[
* @return 1 if fault, -1 if failure, 0 if undetermined
*/
- public static int isFaultOrFailure(int s) {
+ public static int isFaultOrFailure
+ (
+ int s) {
if (s < 400 || s >= 600) {
throw new IllegalArgumentException("Status-Code must be in interval [400;600[");
}