Return-Path: X-Original-To: apmail-ace-commits-archive@www.apache.org Delivered-To: apmail-ace-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 13A0FDF2D for ; Thu, 5 Jul 2012 12:12:44 +0000 (UTC) Received: (qmail 4008 invoked by uid 500); 5 Jul 2012 12:12:43 -0000 Delivered-To: apmail-ace-commits-archive@ace.apache.org Received: (qmail 3944 invoked by uid 500); 5 Jul 2012 12:12:43 -0000 Mailing-List: contact commits-help@ace.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ace.apache.org Delivered-To: mailing list commits@ace.apache.org Received: (qmail 3899 invoked by uid 99); 5 Jul 2012 12:12:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jul 2012 12:12:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jul 2012 12:12:10 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id B24E72388B9B for ; Thu, 5 Jul 2012 12:10:36 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1357570 [25/34] - in /ace/sandbox/marrs: cnf/ cnf/ext/ cnf/lib/ cnf/releaserepo/ cnf/repo/ cnf/repo/.obrcache/ cnf/repo/.obrcache/http%3A%2F%2Fbundles.bndtools.org.s3.amazonaws.com%2Fcom.jcraft.jsch/ cnf/repo/.obrcache/http%3A%2F%2Fbundles... Date: Thu, 05 Jul 2012 12:10:06 -0000 To: commits@ace.apache.org From: marrs@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120705121036.B24E72388B9B@eris.apache.org> Added: ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfigAdmin.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfigAdmin.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfigAdmin.java (added) +++ ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfigAdmin.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,54 @@ +/* + * 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.ace.configurator; + +import java.io.IOException; + +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; + +public class MockConfigAdmin implements ConfigurationAdmin { + + private Configuration m_configuration = new MockConfiguration(); + + public Configuration createFactoryConfiguration(String arg0) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public Configuration createFactoryConfiguration(String arg0, String arg1) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public Configuration getConfiguration(String pid) throws IOException { + return m_configuration; + } + + public Configuration getConfiguration(String arg0, String arg1) throws IOException { + // TODO Auto-generated method stub + return m_configuration; + } + + public Configuration[] listConfigurations(String arg0) throws IOException, InvalidSyntaxException { + return new Configuration[] {m_configuration}; + } + +} Added: ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfiguration.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfiguration.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfiguration.java (added) +++ ace/sandbox/marrs/org.apache.ace.configurator/test/org/apache/ace/configurator/MockConfiguration.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,75 @@ +/* + * 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.ace.configurator; + +import java.io.IOException; +import java.util.Dictionary; + +import org.osgi.service.cm.Configuration; + +public class MockConfiguration implements Configuration { + + @SuppressWarnings("unchecked") + private Dictionary m_properties = null; + private boolean m_isDeleted = false; + + public void delete() throws IOException { + m_isDeleted = true; + } + + public String getBundleLocation() { + // TODO Auto-generated method stub + return null; + } + + public String getFactoryPid() { + // TODO Auto-generated method stub + return null; + } + + public String getPid() { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + public synchronized Dictionary getProperties() { + return m_properties; + } + + public void setBundleLocation(String arg0) { + // TODO Auto-generated method stub + + } + + public void update() throws IOException { + // TODO Auto-generated method stub + + } + + @SuppressWarnings("unchecked") + public synchronized void update(Dictionary newConfiguration) throws IOException { + m_properties = newConfiguration; + } + + public boolean isDeleted() { + return m_isDeleted; + } + +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/.classpath URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/.classpath?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/.classpath (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/.classpath Thu Jul 5 12:09:30 2012 @@ -0,0 +1,9 @@ + + + + + + + + + Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/.project URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/.project?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/.project (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/.project Thu Jul 5 12:09:30 2012 @@ -0,0 +1,23 @@ + + + org.apache.ace.connectionfactory + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/bnd.bnd URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/bnd.bnd?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/bnd.bnd (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/bnd.bnd Thu Jul 5 12:09:30 2012 @@ -0,0 +1,9 @@ +-buildpath: osgi.core,\ + osgi.cmpn,\ + org.apache.ace.util;version=latest,\ + ../cnf/lib/commons-codec-1.4.jar;version=file +Private-Package: org.apache.ace.connectionfactory.impl,\ + org.apache.commons.codec,\ + org.apache.commons.codec.binary +Bundle-Activator: org.apache.ace.connectionfactory.impl.Activator +Export-Package: org.apache.ace.connectionfactory \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/build.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/build.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/build.xml (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/build.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,4 @@ + + + + Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/pom.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/pom.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/pom.xml (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/pom.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,82 @@ + + + + + + 4.0.0 + + + org.apache.ace + ace-pom + 0.8.1-SNAPSHOT + ../pom/pom.xml + + + org.apache.ace.connectionfactory + + Apache ACE :: Connection Factory + Provides a service for creating connections to remote resources. + bundle + + + scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-connectionfactory + scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-connectionfactory + http://svn.apache.org/repos/asf/ace/trunk/ace-connectionfactory + + + + + !org.junit, + javax.net.ssl, + org.apache.ace.connectionfactory;version=${project.version}, + org.osgi.framework, + org.osgi.service.cm, + org.osgi.service.useradmin + + + org.apache.ace.connectionfactory;version=${project.version}, + + + org.apache.ace.connectionfactory.impl, + org.apache.commons.codec, + org.apache.commons.codec.binary + + org.apache.ace.connectionfactory.impl.Activator + + + + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + + + commons-codec + commons-codec + + + org.apache.ace + org.apache.ace.util + test + + + Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/ConnectionFactory.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/ConnectionFactory.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/ConnectionFactory.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/ConnectionFactory.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,53 @@ +/* + * 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.ace.connectionfactory; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; + +import org.osgi.service.useradmin.User; + +/** + * Provides a service to create {@link URLConnection}s. The connection factory will be responsible + * for supplying the necessary credentials to ensure the authentication of the connection succeeds. + */ +public interface ConnectionFactory { + + /** + * Creates a new connection using the given URL, using the (optional) credentials. + * + * @param url the URL to connect to, cannot be null. + * @return a {@link URLConnection} instance, never null. + * @throws IllegalArgumentException in case the given URL was null; + * @throws IOException in case the creation of the connection failed. + */ + URLConnection createConnection(URL url) throws IOException; + + /** + * Creates a new connection using the given URL, using the (optional) credentials. + * + * @param url the URL to connect to, cannot be null; + * @param user the user to fetch the credentials from, cannot be null. + * @return a {@link URLConnection} instance, never null. + * @throws IllegalArgumentException in case the given URL was null, or when the supplied credentials are missing information; + * @throws IOException in case the creation of the connection failed. + */ + URLConnection createConnection(URL url, User user) throws IOException; +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/Activator.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/Activator.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/Activator.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/Activator.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,53 @@ +/* + * 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.ace.connectionfactory.impl; + +import java.util.Properties; + +import org.apache.ace.connectionfactory.ConnectionFactory; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ManagedServiceFactory; + +/** + * Provides the bundle activator for the {@link ConnectionFactoryImpl} service. + */ +public class Activator implements BundleActivator { + + /** + * {@inheritDoc} + */ + public void start(BundleContext context) throws Exception { + Properties props = new Properties(); + props.put(Constants.SERVICE_PID, ConnectionFactoryImpl.FACTORY_PID); + props.put("impl.type", "jdk"); + + context.registerService(new String[]{ ConnectionFactory.class.getName(), ManagedServiceFactory.class.getName() }, + new ConnectionFactoryImpl(), props); + } + + /** + * {@inheritDoc} + */ + public void stop(BundleContext context) throws Exception { + // Nop + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/ConnectionFactoryImpl.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/ConnectionFactoryImpl.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/ConnectionFactoryImpl.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/ConnectionFactoryImpl.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,234 @@ +/* + * 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.ace.connectionfactory.impl; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; + +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; + +import org.apache.ace.connectionfactory.ConnectionFactory; +import org.apache.ace.connectionfactory.impl.UrlCredentials.AuthType; +import org.apache.ace.connectionfactory.impl.UrlCredentialsFactory.MissingValueException; +import org.apache.commons.codec.binary.Base64; +import org.osgi.service.cm.ConfigurationException; +import org.osgi.service.cm.ManagedServiceFactory; +import org.osgi.service.useradmin.User; + +/** + * Provides a default implementation for {@link ConnectionFactory} based on the standard java.net + * implementation of {@link URLConnection}. + */ +public class ConnectionFactoryImpl implements ConnectionFactory, ManagedServiceFactory { + + public static final String FACTORY_PID = "org.apache.ace.connectionfactory"; + + private static final String HTTP_HEADER_AUTHORIZATION = "Authorization"; + + private final Map m_credentialMapping; + + /** + * Creates a new {@link ConnectionFactoryImpl}. + */ + public ConnectionFactoryImpl() { + m_credentialMapping = new HashMap(); + } + + /** + * {@inheritDoc} + */ + public URLConnection createConnection(URL url) throws IOException { + if (url == null) { + throw new IllegalArgumentException("URL cannot be null!"); + } + + URLConnection conn = url.openConnection(); + + UrlCredentials creds = getCredentials(url); + if (creds != null) { + supplyCredentials(conn, creds); + } + + return conn; + } + + /** + * {@inheritDoc} + */ + public URLConnection createConnection(URL url, User user) throws IOException { + if (url == null) { + throw new IllegalArgumentException("URL cannot be null!"); + } + if (user == null) { + throw new IllegalArgumentException("User cannot be null!"); + } + + URLConnection conn = url.openConnection(); + + UrlCredentials creds = getCredentials(url); + if (creds != null) { + // TODO apply user! + supplyCredentials(conn, creds); + } + + return conn; + } + + /** + * {@inheritDoc} + */ + public void deleted(String pid) { + synchronized (m_credentialMapping) { + m_credentialMapping.remove(pid); + } + } + + /** + * {@inheritDoc} + */ + public String getName() { + return "HTTP Connection Factory"; + } + + /** + * {@inheritDoc} + */ + public void updated(String pid, Dictionary properties) throws ConfigurationException { + UrlCredentials creds; + synchronized (m_credentialMapping) { + creds = m_credentialMapping.get(pid); + } + + try { + creds = UrlCredentialsFactory.getCredentials(properties); + + synchronized (m_credentialMapping) { + m_credentialMapping.put(pid, creds); + } + } + catch (MissingValueException e) { + throw new ConfigurationException(e.getProperty(), e.getMessage()); + } + } + + /** + * Returns the credentials to access the given URL. + * + * @param url the URL to find the credentials for, cannot be null. + * @return a {@link UrlCredentials} instance for the given URL, or null + * if none were found, or if none were necessary. + */ + final UrlCredentials getCredentials(URL url) { + Collection creds; + synchronized (m_credentialMapping) { + creds = new ArrayList(m_credentialMapping.values()); + } + + for (UrlCredentials c : creds) { + if (c.matches(url)) { + return c; + } + } + + return null; + } + + /** + * Returns the authorization header for HTTP Basic Authentication. + * + * @param values the credential values to supply, cannot be null and should be an array of two elements. + * @return a string that denotes the basic authentication header ("Basic " + encoded credentials), never null. + */ + final String getBasicAuthCredentials(Object[] values) { + if ((values == null) || values.length < 2) { + throw new IllegalArgumentException("Insufficient credentials passed: expected 2 values!"); + } + + StringBuilder sb = new StringBuilder(); + if (values[0] instanceof String) { + sb.append((String) values[0]); + } + else if (values[0] instanceof byte[]) { + sb.append(new String((byte[]) values[0])); + } + sb.append(':'); + if (values[1] instanceof String) { + sb.append((String) values[1]); + } + else if (values[1] instanceof byte[]) { + sb.append(new String((byte[]) values[1])); + } + + return "Basic " + new String(Base64.encodeBase64(sb.toString().getBytes())); + } + + /** + * Applies basic authentication to the given connection, if it is a {@link HttpURLConnection}. + * + * @param conn the connection to apply basic authentication to; + * @param values the credentials to apply. + */ + private void applyBasicAuthentication(URLConnection conn, Object[] values) { + if (conn instanceof HttpURLConnection) { + conn.setRequestProperty(HTTP_HEADER_AUTHORIZATION, getBasicAuthCredentials(values)); + } + } + + /** + * Applies the use of client certificates to the given connection, if it a {@link HttpsURLConnection}. + * + * @param conn the connection to apply client certs to; + * @param values the credentials to apply. + */ + private void applyClientCertificate(URLConnection conn, Object[] values) { + if (conn instanceof HttpsURLConnection) { + ((HttpsURLConnection) conn).setSSLSocketFactory(((SSLContext) values[0]).getSocketFactory()); + } + } + + /** + * Supplies the actual credentials to the given {@link URLConnection}. + * + * @param conn the connection to supply the credentials to, cannot be null; + * @param urlCreds the URL credentials to supply, cannot be null. + * @throws IOException in case of I/O problems. + */ + private void supplyCredentials(URLConnection conn, UrlCredentials urlCreds) throws IOException { + final AuthType type = urlCreds.getType(); + final Object[] creds = urlCreds.getCredentials(); + + if (AuthType.BASIC.equals(type)) { + applyBasicAuthentication(conn, creds); + } + else if (AuthType.CLIENT_CERT.equals(type)) { + applyClientCertificate(conn, creds); + } + else if (!AuthType.NONE.equals(type)) { + throw new IllegalArgumentException("Unknown authentication type: " + type); + } + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentials.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentials.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentials.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentials.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,146 @@ +/* + * 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.ace.connectionfactory.impl; + +import java.net.URL; +import java.util.Arrays; + +/** + * Small container for holding URL credentials. + */ +final class UrlCredentials { + + static enum AuthType { + /** Indicates no authentication. */ + NONE, + /** Indicates basic HTTP authentication. */ + BASIC, + /** Indicates the use of client certificates. */ + CLIENT_CERT; + } + + private final AuthType m_type; + private final URL m_baseURL; + private final Object[] m_credentials; + + /** + * Creates a new, anonymous, {@link UrlCredentials} instance. + * + * @param baseURL the base URL for which to apply the credentials, cannot be null. + */ + public UrlCredentials(URL baseURL) { + this(AuthType.NONE, baseURL); + } + + /** + * Creates a new {@link UrlCredentials} instance. + * + * @param type the authentication type to use for the authentication of the URL, cannot be null; + * @param baseURL the base URL for which to apply the credentials, cannot be null; + * @param credentials the credentials to use, cannot be null, but may be empty. + */ + public UrlCredentials(AuthType type, URL baseURL, Object... credentials) { + if (type == null) { + throw new IllegalArgumentException("Type cannot be null!"); + } + if (baseURL == null) { + throw new IllegalArgumentException("BaseURL cannot be null!"); + } + m_type = type; + m_baseURL = baseURL; + m_credentials = (credentials == null) ? new Object[0] : credentials.clone(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + + UrlCredentials other = (UrlCredentials) obj; + if (m_type != other.m_type) { + return false; + } + if (!m_baseURL.equals(other.m_baseURL)) { + return false; + } + if (!Arrays.equals(m_credentials, other.m_credentials)) { + return false; + } + return true; + } + + /** + * Returns whether or not the given URL can be mapped to our own base URL. + * + * @param url the URL to map, may be null in which case false will be returned. + * @return true if the given URL maps to our base URL, false otherwise. + */ + public boolean matches(URL url) { + if (url == null) { + return false; + } + + String baseURL = m_baseURL.toExternalForm(); + return url.toExternalForm().startsWith(baseURL); + } + + /** + * Returns the credentials for a URL. + * + * @return the credentials, never null. + */ + public Object[] getCredentials() { + return m_credentials.clone(); + } + + /** + * Returns the authentication type. + * + * @return the type of authentication to use. + */ + public AuthType getType() { + return m_type; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((m_type == null) ? 0 : m_type.hashCode()); + result = prime * result + ((m_baseURL == null) ? 0 : m_baseURL.hashCode()); + result = prime * result + Arrays.hashCode(m_credentials); + return result; + } + + /** + * @return the base URL these credentials apply to, cannot be null. + */ + final URL getBaseURL() { + return m_baseURL; + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentialsFactory.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentialsFactory.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentialsFactory.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/impl/UrlCredentialsFactory.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,281 @@ +/* + * 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.ace.connectionfactory.impl; + +import java.io.Closeable; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.util.Dictionary; + +import javax.net.ssl.KeyManager; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; + +import org.apache.ace.connectionfactory.impl.UrlCredentials.AuthType; + +/** + * Provides a helper class for obtaining access credentials from a dictionary. + */ +final class UrlCredentialsFactory { + + public static final class MissingValueException extends RuntimeException { + private final String m_property; + + /** + * @param property the name of the missing property; + * @param message the message explaining the missing property. + */ + public MissingValueException(String property) { + this(property, "No value for " + property + " given!"); + } + + /** + * @param property the name of the missing property; + * @param message the message explaining the missing property. + */ + public MissingValueException(String property, String message) { + super(message); + m_property = property; + } + + /** + * Returns the name of the missing property. + * @return the property name, never null. + */ + public String getProperty() { + return m_property; + } + } + + public static final String KEY_AUTH_BASE_URL = "authentication.baseURL"; + public static final String KEY_AUTH_TYPE = "authentication.type"; + public static final String KEY_AUTH_USER_NAME = "authentication.user.name"; + public static final String KEY_AUTH_USER_PASSWORD = "authentication.user.password"; + public static final String KEY_AUTH_KEYSTORE_FILE = "authentication.keystore.file"; + public static final String KEY_AUTH_KEYSTORE_PASS = "authentication.keystore.storepass"; + public static final String KEY_AUTH_TRUSTSTORE_FILE = "authentication.truststore.file"; + public static final String KEY_AUTH_TRUSTSTORE_PASS = "authentication.truststore.storepass"; + + /** + * Not used. + */ + private UrlCredentialsFactory() { + // Nop + } + + /** + * @param props the properties to take the access credentials from. + * @throws MissingValueException in case the given properties is missing values. + */ + public static UrlCredentials getCredentials(Dictionary props) throws MissingValueException { + return getCredentials(props, ""); + } + + /** + * @param props the properties to take the access credentials from; + * @param prefix the prefix to use to lookup the correct values in the given dictionary. + * @throws MissingValueException in case the given properties is missing values. + */ + public static UrlCredentials getCredentials(Dictionary props, String prefix) throws MissingValueException { + if (props == null) { + throw new IllegalArgumentException("Properties cannot be null!"); + } + if (prefix == null) { + throw new IllegalArgumentException("Prefix cannot be null!"); + } + + AuthType type; + URL baseURL; + Object[] creds; + + String baseUrlValue = getStringProperty(props, prefix.concat(KEY_AUTH_BASE_URL)); + if (baseUrlValue == null) { + throw new MissingValueException(KEY_AUTH_BASE_URL); + } + + try { + baseURL = new URL(baseUrlValue); + } + catch (MalformedURLException e) { + throw new MissingValueException(KEY_AUTH_BASE_URL, "Invalid base URL!"); + } + + String authType = getStringProperty(props, prefix.concat(KEY_AUTH_TYPE), "none"); + try { + type = AuthType.valueOf(authType.toUpperCase()); + } + catch (Exception e) { + throw new IllegalArgumentException("Unsupported authentication type: " + authType); + } + + if (AuthType.NONE.equals(type)) { + creds = new Object[0]; + } else if (AuthType.BASIC.equals(type)) { + String userName = getStringProperty(props, prefix.concat(KEY_AUTH_USER_NAME)); + if (userName == null) { + throw new MissingValueException(prefix.concat(KEY_AUTH_USER_NAME)); + } + + String password = getStringProperty(props, prefix.concat(KEY_AUTH_USER_PASSWORD)); + if (password == null) { + throw new MissingValueException(prefix.concat(KEY_AUTH_USER_PASSWORD)); + } + + creds = new Object[] { userName, password }; + } else if (AuthType.CLIENT_CERT.equals(type)) { + String keystoreFile = getStringProperty(props, prefix.concat(KEY_AUTH_KEYSTORE_FILE)); + String keystorePass = getStringProperty(props, prefix.concat(KEY_AUTH_KEYSTORE_PASS)); + if ((keystoreFile != null) && (keystorePass == null)) { + throw new MissingValueException(prefix.concat(KEY_AUTH_KEYSTORE_PASS)); + } + if ((keystoreFile == null) && (keystorePass != null)) { + throw new MissingValueException(prefix.concat(KEY_AUTH_KEYSTORE_FILE)); + } + + String truststoreFile = getStringProperty(props, prefix.concat(KEY_AUTH_TRUSTSTORE_FILE)); + String truststorePass = getStringProperty(props, prefix.concat(KEY_AUTH_TRUSTSTORE_PASS)); + if ((truststoreFile != null) && (truststorePass == null)) { + throw new MissingValueException(prefix.concat(KEY_AUTH_TRUSTSTORE_PASS)); + } + if ((truststoreFile == null) && (truststorePass != null)) { + throw new MissingValueException(prefix.concat(KEY_AUTH_TRUSTSTORE_FILE)); + } + + if ((keystoreFile == null) && (truststoreFile == null)) { + try { + // No configuration given; use the system-wide defaults... + creds = new Object[] { SSLContext.getDefault() }; + } + catch (Exception e) { + throw new IllegalArgumentException("Failed to obtain SSL context!", e); + } + } else { + try { + KeyManager[] keyManagers = getKeyManagerFactory(keystoreFile, keystorePass); + TrustManager[] trustManagers = getTrustManagerFactory(truststoreFile, truststorePass); + + SSLContext context = SSLContext.getInstance("TLS"); + context.init(keyManagers, trustManagers, new SecureRandom()); + + creds = new Object[] { context }; + } + catch (Exception e) { + throw new IllegalArgumentException("Failed to load keystore!", e); + } + } + } else { + throw new IllegalArgumentException("Invalid/unhandled authentication type: " + authType); + } + + return new UrlCredentials(type, baseURL, creds); + } + + private static String getStringProperty(Dictionary dict, String key) { + Object value = dict.get(key); + if (value instanceof String) { + return (String) value; + } else if (value instanceof byte[]) { + return new String((byte[]) value); + } + return null; + } + + private static String getStringProperty(Dictionary dict, String key, String defaultValue) { + String value = getStringProperty(dict, key); + return (value == null) ? defaultValue : value; + } + + /** + * @param keystoreFile + * @param storePass + * @return + * @throws IOException + * @throws GeneralSecurityException + */ + private static KeyManager[] getKeyManagerFactory(String keystoreFile, String storePass) throws IOException, GeneralSecurityException { + if (keystoreFile == null) { + return null; + } + + InputStream keyInput = null; + try { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + + keyInput = new FileInputStream(keystoreFile); + + keyStore.load(keyInput, storePass.toCharArray()); + + keyManagerFactory.init(keyStore, storePass.toCharArray()); + return keyManagerFactory.getKeyManagers(); + } + finally { + closeSafely(keyInput); + } + } + + /** + * @param truststoreFile + * @param storePass + * @return + * @throws IOException + * @throws GeneralSecurityException + */ + private static TrustManager[] getTrustManagerFactory(String truststoreFile, String storePass) throws IOException, GeneralSecurityException { + if (truststoreFile == null) { + return null; + } + + InputStream trustInput = null; + try { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + + trustInput = new FileInputStream(truststoreFile); + + trustStore.load(trustInput, storePass.toCharArray()); + + trustManagerFactory.init(trustStore); + return trustManagerFactory.getTrustManagers(); + } + finally { + closeSafely(trustInput); + } + } + + private static void closeSafely(Closeable resource) { + try { + if (resource != null) { + resource.close(); + } + } + catch (IOException e) { + // Ignore; nothing we can/will do... + } + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/packageinfo URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/packageinfo?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/packageinfo (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/src/org/apache/ace/connectionfactory/packageinfo Thu Jul 5 12:09:30 2012 @@ -0,0 +1 @@ +version 1.0 \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/ConnectionFactoryImplTest.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/ConnectionFactoryImplTest.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/ConnectionFactoryImplTest.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/ConnectionFactoryImplTest.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,169 @@ +/* + * 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.ace.connectionfactory.impl; + +import static org.apache.ace.test.utils.TestUtils.UNIT; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.Properties; + +import org.testng.annotations.Test; + +/** + * Test cases for {@link ConnectionFactoryImpl}. + */ +public class ConnectionFactoryImplTest { + + private static final URL TEST_URL; + + static { + try { + TEST_URL = new URL("http://localhost:8080/"); + } + catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#createConnection(java.net.URL)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testCreateConnectionNullUrlFail() throws Exception { + new ConnectionFactoryImpl().createConnection(null); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#createConnection(java.net.URL, org.osgi.service.useradmin.User)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testCreateConnectionNullUserFail() throws Exception { + new ConnectionFactoryImpl().createConnection(new URL("file:///tmp/foo"), null); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#createConnection(java.net.URL, org.osgi.service.useradmin.User)}. + */ + @Test(groups = { UNIT }) + public void testCreateConnectionOk() throws Exception { + URLConnection conn = new ConnectionFactoryImpl().createConnection(new URL("file:///tmp/foo")); + assert conn != null : "Expected valid connection to be created!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#deleted(java.lang.String)}. + */ + @Test(groups = { UNIT }) + public void testDeleted() throws Exception { + ConnectionFactoryImpl connFactory = new ConnectionFactoryImpl(); + + Properties props = createBasicAuthConfig(TEST_URL.toExternalForm()); + + connFactory.updated("pid1", props); + + UrlCredentials credentials = connFactory.getCredentials(TEST_URL); + assert credentials != null : "Expected valid credentials to be found!"; + + connFactory.deleted("pid1"); + + credentials = connFactory.getCredentials(TEST_URL); + assert credentials == null : "Expected no credentials to be found!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#getBasicAuthCredentials(UrlCredentials)}. + */ + @Test(groups = { UNIT }) + public void testGetBasicAuthCredentialsOk() throws Exception { + ConnectionFactoryImpl connFactory = new ConnectionFactoryImpl(); + + Properties props = createBasicAuthConfig(TEST_URL.toExternalForm()); + + connFactory.updated("pid1", props); + + UrlCredentials credentials = connFactory.getCredentials(TEST_URL); + assert credentials != null : "Expected valid credentials to be found!"; + + String header = new ConnectionFactoryImpl().getBasicAuthCredentials(credentials.getCredentials()); + assert header != null : "Expected valid HTTP header to be returned!"; + assert header.equals(header.trim()) : "Expected HTTP header not to contain any leading/trailing whitespace!"; + assert "Basic Zm9vOmJhcg==".equals(header) : "Expected HTTP header to be constant!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#updated(java.lang.String, java.util.Dictionary)}. + */ + @Test(groups = { UNIT }) + public void testUpdatedInsertsCredentialsOk() throws Exception { + ConnectionFactoryImpl connFactory = new ConnectionFactoryImpl(); + + UrlCredentials credentials = connFactory.getCredentials(TEST_URL); + assert credentials == null : "Expected no credentials to be found!"; + + Properties props = createBasicAuthConfig(TEST_URL.toExternalForm()); + + connFactory.updated("pid1", props); + + credentials = connFactory.getCredentials(TEST_URL); + assert credentials != null : "Expected valid credentials to be found!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl#updated(java.lang.String, java.util.Dictionary)}. + */ + @Test(groups = { UNIT }) + public void testUpdatedUpdatesCredentialsOk() throws Exception { + ConnectionFactoryImpl connFactory = new ConnectionFactoryImpl(); + + Properties props = createBasicAuthConfig(TEST_URL.toExternalForm()); + + connFactory.updated("pid1", props); + + UrlCredentials credentials1 = connFactory.getCredentials(TEST_URL); + assert credentials1 != null : "Expected valid credentials to be found!"; + + URL newURL = new URL("http://localhost:8181/test/"); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, newURL.toExternalForm()); + + connFactory.updated("pid1", props); + + UrlCredentials credentials2 = connFactory.getCredentials(TEST_URL); + assert credentials2 == null : "Expected no credentials to be found!"; + + credentials2 = connFactory.getCredentials(newURL); + assert credentials2 != null : "Expected valid credentials to be found!"; + + assert credentials1 != credentials2 && !credentials1.equals(credentials2) : "Expected not the same credentials to be returned!"; + } + + /** + * @return a dictionary containing a configuration for basic authentication, never null. + */ + private Properties createBasicAuthConfig(String url) { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, url); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "basic"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_NAME, "foo"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_PASSWORD, "bar"); + return props; + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsFactoryTest.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsFactoryTest.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsFactoryTest.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsFactoryTest.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,205 @@ +/* + * 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.ace.connectionfactory.impl; + +import static org.apache.ace.test.utils.TestUtils.UNIT; + +import java.util.Properties; + +import org.apache.ace.connectionfactory.impl.UrlCredentialsFactory.MissingValueException; +import org.testng.annotations.Test; + +/** + * Test cases for {@link UrlCredentialsFactory}. + */ +public class UrlCredentialsFactoryTest { + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryBasicTypeMissingPasswordFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "basic"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_NAME, "bar"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryClientCertTypeMissingKeystorePasswordFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "client_cert"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_FILE, "bar"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_PASS, "qux"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_FILE, "foo"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryClientCertTypeMissingKeystoreFileFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "client_cert"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_FILE, "bar"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_PASS, "qux"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_PASS, "foo"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }) + public void testGetCredentialsWithDictionaryClientCertTypeOk() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "client_cert"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_FILE, "foo"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_PASS, "bar"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_FILE, "qux"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_PASS, "quu"); + + try { + UrlCredentialsFactory.getCredentials(props); + } + catch (IllegalArgumentException e) { + // Ok; expected as the implementation tries to open the files "foo" and "qux"... + } + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryClientCertTypeMissingTruststorePasswordFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "client_cert"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_FILE, "bar"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_PASS, "qux"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_FILE, "foo"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryClientCertTypeMissingTruststoreFileFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "client_cert"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_FILE, "bar"); + props.put(UrlCredentialsFactory.KEY_AUTH_KEYSTORE_PASS, "qux"); + props.put(UrlCredentialsFactory.KEY_AUTH_TRUSTSTORE_PASS, "foo"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryBasicTypeMissingUserNameFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "basic"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_PASSWORD, "bar"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }) + public void testGetCredentialsWithDictionaryBasicTypeOk() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "basic"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_NAME, "foo"); + props.put(UrlCredentialsFactory.KEY_AUTH_USER_PASSWORD, "bar"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testGetCredentialsWithDictionaryInvalidAuthTypeFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "nonsense"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = MissingValueException.class) + public void testGetCredentialsWithDictionaryMissingBaseUrlFail() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "none"); + + UrlCredentialsFactory.getCredentials(props); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testGetCredentialsWithNullDictionaryFail() { + UrlCredentialsFactory.getCredentials(null); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary, java.lang.String)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testGetCredentialsWithNullPrefixFail() { + UrlCredentialsFactory.getCredentials(new Properties(), null); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentialsFactory#getCredentials(java.util.Dictionary)}. + */ + @Test(groups = { UNIT }) + public void testGetCredentialsWithValidDictionaryOk() { + Properties props = new Properties(); + props.put(UrlCredentialsFactory.KEY_AUTH_BASE_URL, "http://localhost:8080/"); + props.put(UrlCredentialsFactory.KEY_AUTH_TYPE, "none"); + + UrlCredentialsFactory.getCredentials(props); + } +} Added: ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsTest.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsTest.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsTest.java (added) +++ ace/sandbox/marrs/org.apache.ace.connectionfactory/test/org/apache/ace/connectionfactory/impl/UrlCredentialsTest.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,116 @@ +/* + * 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.ace.connectionfactory.impl; + +import static org.apache.ace.test.utils.TestUtils.UNIT; + +import java.net.URL; + +import org.apache.ace.connectionfactory.impl.UrlCredentials.AuthType; +import org.testng.annotations.Test; + +/** + * Test cases for {@link UrlCredentials}. + */ +public class UrlCredentialsTest { + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#UrlCredentials(java.net.URL)}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testUrlCredentialsNullURLFail() throws Exception { + new UrlCredentials(null); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#UrlCredentials(java.net.URL)}. + */ + @Test(groups = { UNIT }) + public void testUrlCredentialsURLOk() throws Exception { + new UrlCredentials(new URL("http://localhost:8080/")); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#UrlCredentials(org.apache.ace.connectionfactory.impl.UrlCredentials.AuthType, java.net.URL, java.lang.Object[])}. + */ + @Test(groups = { UNIT }, expectedExceptions = IllegalArgumentException.class) + public void testUrlCredentialsNullTypeFail() throws Exception { + new UrlCredentials(null, new URL("http://localhost:8080/")); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#UrlCredentials(org.apache.ace.connectionfactory.impl.UrlCredentials.AuthType, java.net.URL, java.lang.Object[])}. + */ + @Test(groups = { UNIT }) + public void testUrlCredentialsTypeAndURLOk() throws Exception { + new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/")); + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#matches(java.net.URL)}. + */ + @Test(groups = { UNIT }) + public void testMatchesNullURLOk() throws Exception { + UrlCredentials creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/")); + assert creds.matches(null) == false : "Null URL should never match any credentials!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#matches(java.net.URL)}. + */ + @Test(groups = { UNIT }) + public void testMatchesValidURLOk() throws Exception { + UrlCredentials creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/")); + assert creds.matches(new URL("http://localhost:8080/obr")) : "Base URL should match given URL!"; + assert creds.matches(new URL("http://localhost:8080")) == false : "Base URL shouldn't match given URL!"; + assert creds.matches(new URL("http://localhost:8081/")) == false : "Base URL shouldn't match given URL!"; + } + + /** + * Test method for {@link org.apache.ace.connectionfactory.impl.UrlCredentials#getCredentials()}. + */ + @Test(groups = { UNIT }) + public void testGetCredentialsOk() throws Exception { + UrlCredentials creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/")); + assertArrayEquals(new Object[0], creds.getCredentials()); + + creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/"), "foo"); + assertArrayEquals(new Object[] { "foo" }, creds.getCredentials()); + + creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/"), (Object[]) null ); + assertArrayEquals(new Object[0], creds.getCredentials()); + + creds = new UrlCredentials(AuthType.NONE, new URL("http://localhost:8080/"), (Object) null); + assertArrayEquals(new Object[] { null }, creds.getCredentials()); + } + + /** + * Asserts that two given arrays are equal with respect to their content. + * + * @param expected the expected array; + * @param given the given array to test. + */ + private void assertArrayEquals(Object[] expected, Object[] given) { + assert expected != null && given != null : "Both arrays should never be null!"; + assert expected.length == given.length : "Length mismatch!"; + for (int i = 0; i < expected.length; i++) { + assert (expected[i] == given[i]) || (expected[i] != null && expected[i].equals(given[i])) : "Elements at index #" + i + " do not match!"; + } + } +} Added: ace/sandbox/marrs/org.apache.ace.consolelogger/.classpath URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/.classpath?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/.classpath (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/.classpath Thu Jul 5 12:09:30 2012 @@ -0,0 +1,7 @@ + + + + + + + Added: ace/sandbox/marrs/org.apache.ace.consolelogger/.project URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/.project?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/.project (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/.project Thu Jul 5 12:09:30 2012 @@ -0,0 +1,23 @@ + + + org.apache.ace.consolelogger + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + Added: ace/sandbox/marrs/org.apache.ace.consolelogger/bnd.bnd URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/bnd.bnd?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/bnd.bnd (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/bnd.bnd Thu Jul 5 12:09:30 2012 @@ -0,0 +1,5 @@ +-buildpath: osgi.core,\ + osgi.cmpn,\ + org.apache.felix.dependencymanager +Private-Package: org.apache.ace.consolelogger +Bundle-Activator: org.apache.ace.consolelogger.Activator \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.consolelogger/build.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/build.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/build.xml (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/build.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,4 @@ + + + + Added: ace/sandbox/marrs/org.apache.ace.consolelogger/pom.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/pom.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/pom.xml (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/pom.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,71 @@ + + + + + + 4.0.0 + + + org.apache.ace + ace-pom + 0.8.1-SNAPSHOT + ../pom/pom.xml + + + 0.8.1-SNAPSHOT + org.apache.ace.consolelogger + bundle + + Apache ACE :: ConsoleLogger + + + + scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-consolelogger + scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-consolelogger + http://svn.apache.org/repos/asf/ace/trunk/ace-consolelogger + + + + + * + + + org.apache.ace.consolelogger + + + org.apache.ace.consolelogger.Activator + + + + + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + + + org.apache.felix + org.apache.felix.dependencymanager + + + + Added: ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Activator.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Activator.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Activator.java (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Activator.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,36 @@ +/* + * 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.ace.consolelogger; + +import org.apache.felix.dm.DependencyActivatorBase; +import org.apache.felix.dm.DependencyManager; +import org.osgi.framework.BundleContext; +import org.osgi.service.log.LogService; + +public class Activator extends DependencyActivatorBase { + public void init(BundleContext context, DependencyManager manager) throws Exception { + manager.add(createComponent() + .setInterface(LogService.class.getName(), null) + .setImplementation(Logger.class) + ); + } + + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + } +} \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Logger.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Logger.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Logger.java (added) +++ ace/sandbox/marrs/org.apache.ace.consolelogger/src/org/apache/ace/consolelogger/Logger.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,72 @@ +/* + * 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.ace.consolelogger; + +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.service.log.LogService; + +/** + * An implementation of the OSGi LogService that directly outputs each log message + * to System.out. It does not implement the LogReader or LogListeners. + */ +public class Logger implements LogService { + private static String[] LEVEL = { "", "Error", "Warn ", "Info ", "Debug" }; + + public void log(int level, String message) { + log(null, level, message, null); + } + + public void log(int level, String message, Throwable throwable) { + log(null, level, message, throwable); + } + + public void log(ServiceReference reference, int level, String message) { + log(reference, level, message, null); + } + + public void log(ServiceReference reference, int level, String message, Throwable throwable) { + String bundle = " [ ]"; + String service = " "; + if (reference != null) { + bundle = "00" + reference.getBundle().getBundleId(); + bundle = " [" + bundle.substring(bundle.length() - 3) + "]"; + Object objectClass = reference.getProperty(Constants.OBJECTCLASS); + if (objectClass instanceof String[]) { + StringBuffer buffer = new StringBuffer(); + String[] objClassArr = ((String[]) objectClass); + for (int i = 0; i < objClassArr.length; i++) { + String svc = objClassArr[i]; + if (buffer.length() > 0) { + buffer.append(';'); + } + buffer.append(svc); + service = buffer.toString() + ": "; + } + } + else { + service = objectClass.toString() + ": "; + } + } + System.out.println("[" + LEVEL[level] + "]" + bundle + service + message); + if (throwable != null) { + throwable.printStackTrace(); + } + } +} \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.deployment.api/.classpath URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/.classpath?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/.classpath (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/.classpath Thu Jul 5 12:09:30 2012 @@ -0,0 +1,7 @@ + + + + + + + Added: ace/sandbox/marrs/org.apache.ace.deployment.api/.project URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/.project?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/.project (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/.project Thu Jul 5 12:09:30 2012 @@ -0,0 +1,23 @@ + + + org.apache.ace.deployment.api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + bndtools.core.bndbuilder + + + + + + org.eclipse.jdt.core.javanature + bndtools.core.bndnature + + Added: ace/sandbox/marrs/org.apache.ace.deployment.api/bnd.bnd URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/bnd.bnd?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/bnd.bnd (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/bnd.bnd Thu Jul 5 12:09:30 2012 @@ -0,0 +1,3 @@ +-buildpath: osgi.core,\ + osgi.cmpn +Export-Package: org.apache.ace.deployment \ No newline at end of file Added: ace/sandbox/marrs/org.apache.ace.deployment.api/build.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/build.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/build.xml (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/build.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,4 @@ + + + + Added: ace/sandbox/marrs/org.apache.ace.deployment.api/pom.xml URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/pom.xml?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/pom.xml (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/pom.xml Thu Jul 5 12:09:30 2012 @@ -0,0 +1,65 @@ + + + + + + 4.0.0 + + + org.apache.ace + ace-pom + 0.8.1-SNAPSHOT + ../pom/pom.xml + + + 0.8.1-SNAPSHOT + org.apache.ace.deployment.api + bundle + + Apache ACE :: Deployment :: API + + + + scm:svn:http://svn.apache.org/repos/asf/ace/trunk/ace-deployment-api + scm:svn:https://svn.apache.org/repos/asf/ace/trunk/ace-deployment-api + http://svn.apache.org/repos/asf/ace/trunk/ace-deployment-api + + + + + org.apache.ace.deployment;version=${project.version} + + + !org.apache.ace.deployment, + * + + + + + + org.osgi + org.osgi.core + + + org.osgi + org.osgi.compendium + + + + Added: ace/sandbox/marrs/org.apache.ace.deployment.api/src/org/apache/ace/deployment/Deployment.java URL: http://svn.apache.org/viewvc/ace/sandbox/marrs/org.apache.ace.deployment.api/src/org/apache/ace/deployment/Deployment.java?rev=1357570&view=auto ============================================================================== --- ace/sandbox/marrs/org.apache.ace.deployment.api/src/org/apache/ace/deployment/Deployment.java (added) +++ ace/sandbox/marrs/org.apache.ace.deployment.api/src/org/apache/ace/deployment/Deployment.java Thu Jul 5 12:09:30 2012 @@ -0,0 +1,68 @@ +/* + * 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.ace.deployment; + +import java.io.InputStream; +import org.osgi.framework.Version; + +/** + * Service that abstracts the actual implementation that manages components that are to be deployed. + * Implementations of this interface could for example make use of the DeploymentAdmin + * from the OSGi spec to actually deploy packages. The objects used as arguments and return values + * must all be of the same type, which type depends on the implementation. + */ +public interface Deployment { + + /** + * Deploys the contents of the stream onto the system. + * + * @param inputStream Stream containing new components. + * @return The update package that was installed, may be null if the implementation does not support this. + * @throws Exception If the specified stream could not be deployed. + */ + public Object install(InputStream inputStream) throws Exception; + + /** + * Gets the name of the specified update package. Guaranteed to work with Objects returned + * by the same implementation of this interface. + * + * @param object The update package + * @return the name + * @throws IllegalArgumentException when the specified object is an invalid update package, only Objects returned by the same implementation of this interface should be used. + */ + public String getName(Object object) throws IllegalArgumentException; + + /** + * Gets the version of the specified update package. Guaranteed to work with Objects returned + * by the same implementation of this interface. + * + * @param object The update package + * @return the version + * @throws IllegalArgumentException when the specified object is an invalid update package, only Objects returned by the same implementation of this interface should be used. + */ + public Version getVersion(Object object) throws IllegalArgumentException; + + /** + * Retrieve a list of installed update packages. + * + * @return list of installed update packages or an empty array if none are available. + */ + public Object[] list(); + +} \ No newline at end of file