You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jb...@apache.org on 2003/08/12 06:16:47 UTC
cvs commit: incubator-geronimo/modules/core/src/test/org/apache/geronimo/deployment/repository DownloadTest.java
jboynes 2003/08/11 21:16:47
Added: modules/core/src/java/org/apache/geronimo/deployment/repository
ComponentDescription.java ComponentRepository.java
ComponentRepositoryMBean.java
modules/core/src/test/org/apache/geronimo/deployment/repository
DownloadTest.java
Log:
Add repository concept for components downloaded on demand
Revision Changes Path
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/repository/ComponentDescription.java
Index: ComponentDescription.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.deployment.repository;
import java.net.URL;
import java.io.Serializable;
/**
* Description of a component stored in a repository.
* Information used to describe a component that may be deployed into a server.
* Attributes are:
* <table>
* <tr><td>Group</td><td>Optional</td><td>A project or product name</td></tr>
* <tr><td>Name</td><td>Required</td><td>Component name</td></tr>
* <tr><td>Version</td><td>Required</td><td>Component version</td></tr>
* <tr><td>Description</td><td>Optional</td><td>Wordy description</td></tr>
* <tr><td>Homepage</td><td>Optional</td><td>Product home page</td></tr>
* <tr><td>Location</td><td>Required</td><td>Specific location to download from</td></tr>
* </table>
* @version $Revision: 1.1 $ $Date: 2003/08/12 04:16:47 $
*/
public class ComponentDescription implements Serializable {
private String group;
private String name;
private String version;
private String description;
private URL homepage;
private String location;
public ComponentDescription() {
}
public ComponentDescription(String name, String version, String location) {
this.name = name;
this.version = version;
this.location = location;
}
/**
* Return the description of this component
* @return the description
*/
public String getDescription() {
return description;
}
/**
* Set the description for this component
* @param description a description of this component
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Return the group for this component
* @return the group
*/
public String getGroup() {
return group;
}
/**
* Set the group to which this component belongs.
* @param group the group for this project
*/
public void setGroup(String group) {
this.group = group;
}
/**
* Return the homepage for this component
* @return the homepage for this component
*/
public URL getHomepage() {
return homepage;
}
/**
* Set the homepage for this component
* @param homepage the homepage
*/
public void setHomepage(URL homepage) {
this.homepage = homepage;
}
/**
* Return the location of this component in the repository
* @return the path to the component
*/
public String getLocation() {
return location;
}
/**
* Set the location of this component in the repository
* @param location the path to this component relative to the root of the repository
*/
public void setLocation(String location) {
this.location = location;
}
/**
* Return the name of this component
* @return the name
*/
public String getName() {
return name;
}
/**
* Set the name of this component
* @param name the name
*/
public void setName(String name) {
this.name = name;
}
/**
* Get the version id for this component. No meaning should be attached
* to the syntax of the version
* @return the version id
*/
public String getVersion() {
return version;
}
/**
* Set the version for this component
* @param version the version
*/
public void setVersion(String version) {
this.version = version;
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/repository/ComponentRepository.java
Index: ComponentRepository.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.deployment.repository;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.List;
import java.util.Collections;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.ReflectionException;
import javax.management.MBeanServerFactory;
import javax.management.MBeanRegistration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.deployment.DeploymentException;
import org.apache.geronimo.jmx.JMXUtil;
/**
* A proxy for a repository of components that can accessed remotely and
* downloaded to the local machine.
*
* @version $Revision: 1.1 $ $Date: 2003/08/12 04:16:47 $
*/
public class ComponentRepository implements ComponentRepositoryMBean,MBeanRegistration {
private final Log log = LogFactory.getLog(getClass().getName());
private final File localRoot;
private MBeanServer server;
private Set remoteRoots = new HashSet();
/**
* Construct a repository using the specified local directory as root.
* It will be created if it does not exists
* @param localRoot the local root directory
*/
public ComponentRepository(File localRoot) {
if (!localRoot.exists()) {
localRoot.mkdirs();
} else if (!localRoot.isDirectory()) {
throw new IllegalArgumentException("Local root is not a directory: " + localRoot);
}
this.localRoot = localRoot;
}
public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) throws Exception {
this.server = mBeanServer;
return objectName;
}
public void postRegister(Boolean aBoolean) {
}
public void preDeregister() throws Exception {
}
public void postDeregister() {
}
public File getLocalRoot() {
return localRoot;
}
public Set getRemoteRoots() {
return Collections.unmodifiableSet(remoteRoots);
}
public void addRemoteRoot(URL root) {
remoteRoots.add(root);
}
public void removeRemoteRoot(URL root) {
remoteRoots.remove(root);
}
public void ensureLocal(String name, String version, String location) {
// @todo get rid of this and use a property editor
ComponentDescription desc = new ComponentDescription(name, version, location);
ensureLocal(desc);
}
public boolean ensureLocal(ComponentDescription desc) {
String location = desc.getLocation();
File localFile = new File(localRoot, location);
if (localFile.exists()) {
// is exists - we do not check for SNAPSHOT updates
log.debug("Local copy exists for "+location);
return true;
}
for (Iterator i = remoteRoots.iterator(); i.hasNext();) {
URL root = (URL) i.next();
URL remoteURL = null;
try {
remoteURL = new URL(root, location);
} catch (MalformedURLException e) {
continue;
}
log.debug("Checking for archive at "+remoteURL);
InputStream is = null;
FileOutputStream os = null;
try {
URLConnection con = remoteURL.openConnection();
con.connect();
is = con.getInputStream();
log.debug("Downloading archive "+remoteURL);
localFile.getParentFile().mkdirs();
localFile.createNewFile();
os = new FileOutputStream(localFile);
byte[] buffer = new byte[4096];
int count;
while ((count = is.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
os.close();
is.close();
log.debug("Downloaded archive "+remoteURL);
return true;
} catch (IOException e) {
// remove a potentially partially copied file
localFile.delete();
continue;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
// ignore
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
}
return false;
}
public void removeLocal(String name, String version, String location) {
// @todo get rid of this and use a property editor
ComponentDescription desc = new ComponentDescription(name, version, location);
removeLocal(desc);
}
public void removeLocal(ComponentDescription desc) {
String location = desc.getLocation();
File localFile = new File(localRoot, location);
if (localFile.exists()) {
localFile.delete();
}
}
public void deploy(String name, String version, String location) throws DeploymentException {
// @todo get rid of this and use a property editor
ComponentDescription desc = new ComponentDescription(name, version, location);
deploy(desc);
}
public void deploy(ComponentDescription desc) throws DeploymentException {
if (!ensureLocal(desc)) {
throw new DeploymentException("Could not obtain local copy of "+desc.getName()+" "+desc.getVersion());
}
URL url = null;
try {
url = new File(localRoot, desc.getLocation()).toURL();
} catch (MalformedURLException e) {
throw new DeploymentException(e);
}
// @todo replace with relation-based proxy
ObjectName controller = JMXUtil.getObjectName("geronimo.deployment:role=DeploymentController");
try {
server.invoke(controller, "deploy", new Object[] { url }, new String[] { "java.net.URL"});
} catch (InstanceNotFoundException e) {
throw new DeploymentException(e);
} catch (MBeanException e) {
if (e.getCause() instanceof DeploymentException) {
throw (DeploymentException) e.getCause();
} else {
throw new DeploymentException(e);
}
} catch (ReflectionException e) {
throw new DeploymentException(e);
}
}
}
1.1 incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/repository/ComponentRepositoryMBean.java
Index: ComponentRepositoryMBean.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.deployment.repository;
import java.io.File;
import java.net.URL;
import java.util.Set;
import org.apache.geronimo.deployment.DeploymentException;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/08/12 04:16:47 $
*/
public interface ComponentRepositoryMBean {
/**
* Return the local root directory
* @return the local root directory
*/
File getLocalRoot();
/**
* Add a remote repository
* @param root the location of the remote repository
*/
void addRemoteRoot(URL root);
/**
* Remove a remote repository
* @param root the location to remove
*/
void removeRemoteRoot(URL root);
/**
* Ensure a component is available in the local repository
* @param desc the component to add
* @return true if the component is present; false if it could not be found or downloaded
*/
boolean ensureLocal(ComponentDescription desc);
/**
* Remove a local copy
* @param desc the component to remove from the local repository
*/
void removeLocal(ComponentDescription desc);
void ensureLocal(String name, String version, String location);
void deploy(String name, String version, String location) throws DeploymentException;
void deploy(ComponentDescription desc) throws DeploymentException;
Set getRemoteRoots();
void removeLocal(String name, String version, String location);
}
1.1 incubator-geronimo/modules/core/src/test/org/apache/geronimo/deployment/repository/DownloadTest.java
Index: DownloadTest.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Geronimo" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Geronimo", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* ====================================================================
*/
package org.apache.geronimo.deployment.repository;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.net.URL;
import junit.framework.TestCase;
/**
*
*
* @version $Revision: 1.1 $ $Date: 2003/08/12 04:16:47 $
*/
public class DownloadTest extends TestCase {
private File localRoot;
private File fakeRemoteRoot;
private ComponentRepository repo;
private ComponentDescription desc;
private ComponentDescription desc2;
private ComponentDescription desc3;
private File testArchive;
public void testLocalCopy() throws Exception {
assertTrue(repo.ensureLocal(desc));
File localFile = new File(localRoot, desc.getLocation());
assertTrue(localFile.exists());
long ts = localFile.lastModified();
sleep(50);
assertTrue(repo.ensureLocal(desc));
assertTrue(ts == localFile.lastModified());
repo.removeLocal(desc);
assertFalse(localFile.exists());
}
public void testRemoteCopy() throws Exception {
assertTrue(repo.ensureLocal(desc2));
File localFile = new File(localRoot, desc2.getLocation());
assertTrue(localFile.exists());
long ts = localFile.lastModified();
sleep(50);
assertTrue(repo.ensureLocal(desc));
assertTrue(ts == localFile.lastModified());
repo.removeLocal(desc2);
assertFalse(localFile.exists());
}
public void testNotFound() throws Exception {
assertFalse(repo.ensureLocal(desc3));
File localFile = new File(localRoot, desc3.getLocation());
assertFalse(localFile.exists());
}
private void sleep(long naptime) {
try {
Thread.sleep(naptime);
} catch (InterruptedException e) {
// ignore
}
}
protected void setUp() throws Exception {
super.setUp();
File temp = new File(System.getProperty("java.io.tmpdir"));
localRoot = new File(temp, "localRepo");
desc = new ComponentDescription("product", "1.1.1", "myproduct/product-1.1.1.txt");
fakeRemoteRoot = new File(temp, "remoteRepo");
testArchive = new File(fakeRemoteRoot, desc.getLocation());
testArchive.getParentFile().mkdirs();
testArchive.createNewFile();
FileOutputStream fos = new FileOutputStream(testArchive);
PrintWriter writer = new PrintWriter(fos);
writer.println("Hello World");
writer.flush();
writer.close();
desc2 = new ComponentDescription("commons-logging", "1.0.1", "commons-logging/jars/commons-logging-1.0.1.jar");
desc3 = new ComponentDescription("nosuchfile", "noversion", "nolocation");
repo = new ComponentRepository(localRoot);
repo.addRemoteRoot(fakeRemoteRoot.toURL());
repo.addRemoteRoot(new URL("http://www.ibiblio.org/maven/"));
}
protected void tearDown() throws Exception {
super.tearDown();
recursiveDelete(localRoot);
recursiveDelete(fakeRemoteRoot);
}
private void recursiveDelete(File root) throws Exception {
File[] files = root.listFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.isDirectory()) {
recursiveDelete(file);
} else {
file.delete();
}
}
root.delete();
}
}