http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/pom.xml ---------------------------------------------------------------------- diff --git a/server/storage/pom.xml b/server/storage/pom.xml new file mode 100644 index 0000000..cf2b5c0 --- /dev/null +++ b/server/storage/pom.xml @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.karaf.cave</groupId> + <artifactId>org.apache.karaf.cave.server</artifactId> + <version>3.0.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>org.apache.karaf.cave.server</groupId> + <artifactId>org.apache.karaf.cave.server.storage</artifactId> + <name>Apache Karaf :: Cave :: Server :: Storage</name> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>org.apache.karaf.cave.server</groupId> + <artifactId>org.apache.karaf.cave.server.api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.bundlerepository</artifactId> + </dependency> + <dependency> + <groupId>org.jsoup</groupId> + <artifactId>jsoup</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient-osgi</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> + <Import-Package> + org.apache.karaf.cave.server.api;version="${project.version}", + org.slf4j*;resolution:=optional, + org.apache.felix.bundlerepository*;version="[2,3)", + org.osgi.framework, + org.osgi.service.blueprint, + org.osgi.service.log, + org.osgi.service.url, + org.apache.http*;version="[4,5)", + org.jsoup*;version="[1.6,2)", + org.apache.commons.io*;version="[2,3)", + !org.apache.felix.shell, + !org.apache.felix.bundlerepository.impl.wrapper, + !org.osgi.service.obr, + !javax.xml.stream, + </Import-Package> + <Private-Package> + org.kxml2.io, + org.xmlpull.v1, + org.apache.felix.utils*, + org.apache.felix.bundlerepository.impl* + </Private-Package> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryImpl.java ---------------------------------------------------------------------- diff --git a/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryImpl.java b/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryImpl.java new file mode 100644 index 0000000..7a26948 --- /dev/null +++ b/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryImpl.java @@ -0,0 +1,421 @@ +/* + * 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.karaf.cave.server.storage; + +import org.apache.commons.io.FileUtils; +import org.apache.felix.bundlerepository.Resource; +import org.apache.felix.bundlerepository.impl.DataModelHelperImpl; +import org.apache.felix.bundlerepository.impl.RepositoryImpl; +import org.apache.felix.bundlerepository.impl.ResourceImpl; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.karaf.cave.server.api.CaveRepository; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.net.URL; + +/** + * Default implementation of a Karaf Cave repository. + */ +public class CaveRepositoryImpl extends CaveRepository { + + private final static Logger LOGGER = LoggerFactory.getLogger(CaveRepositoryImpl.class); + + private RepositoryImpl obrRepository; + + public CaveRepositoryImpl(String name, String location, boolean scan) throws Exception { + super(); + + this.setName(name); + this.setLocation(location); + + this.createRepositoryDirectory(); + if (scan) { + this.scan(); + } + } + + /** + * Check if the repository folder exists and create it if not. + */ + private void createRepositoryDirectory() throws Exception { + LOGGER.debug("Create Karaf Cave repository {} folder.", this.getName()); + File locationFile = new File(this.getLocation()); + if (!locationFile.exists()) { + locationFile.mkdirs(); + LOGGER.debug("Karaf Cave repository {} location has been created.", this.getName()); + LOGGER.debug(locationFile.getAbsolutePath()); + } + File repositoryXml = new File(locationFile, "repository.xml"); + if (repositoryXml.exists()) { + obrRepository = (RepositoryImpl) new DataModelHelperImpl().repository(repositoryXml.toURI().toURL()); + } else { + obrRepository = new RepositoryImpl(); + obrRepository.setName(this.getName()); + } + } + + /** + * Generate the repository.xml with the artifact at the given URL. + * + * @throws Exception in case of repository.xml update failure. + */ + private void generateRepositoryXml() throws Exception { + File repositoryXml = this.getRepositoryXmlFile(); + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(repositoryXml)); + new DataModelHelperImpl().writeRepository(obrRepository, writer); + writer.flush(); + writer.close(); + } + + /** + * Add a resource in the OBR repository. + * + * @param resource the resource to add. + * @throws Exception in case of failure. + */ + private void addResource(ResourceImpl resource) throws Exception { + if (resource != null) { + this.useResourceRelativeUri(resource); + obrRepository.addResource(resource); + obrRepository.setLastModified(System.currentTimeMillis()); + } + } + + /** + * Upload an artifact from the given URL. + * + * @param url the URL of the artifact. + * @throws Exception in case of upload failure. + */ + public void upload(URL url) throws Exception { + LOGGER.debug("Upload new artifact from {}", url); + String artifactName = "artifact-" + System.currentTimeMillis(); + File temp = new File(new File(this.getLocation()), artifactName); + FileUtils.copyURLToFile(url, temp); + // update the repository.xml + ResourceImpl resource = (ResourceImpl) new DataModelHelperImpl().createResource(temp.toURI().toURL()); + if (resource == null) { + temp.delete(); + LOGGER.warn("The {} artifact source is not a valid OSGi bundle", url); + return; + } + File destination = new File(new File(this.getLocation()), resource.getSymbolicName() + "-" + resource.getVersion() + ".jar"); + FileUtils.moveFile(temp, destination); + resource = (ResourceImpl) new DataModelHelperImpl().createResource(destination.toURI().toURL()); + this.addResource(resource); + this.generateRepositoryXml(); + } + + /** + * Scan the content of the whole repository to update the repository.xml. + * + * @throws Exception in case of scan failure. + */ + public void scan() throws Exception { + this.scan(new File(this.getLocation())); + this.generateRepositoryXml(); + } + + /** + * Recursive method to traverse all files in the repository. + * + * @param entry the + * @throws Exception + */ + private void scan(File entry) throws Exception { + if (entry.isDirectory()) { + File[] children = entry.listFiles(); + for (int i = 0; i < children.length; i++) { + scan(children[i]); + } + } else { + // populate the repository + try { + ResourceImpl resource = (ResourceImpl) new DataModelHelperImpl().createResource(entry.toURI().toURL()); + this.addResource(resource); + } catch (IllegalArgumentException e) { + LOGGER.warn(e.getMessage()); + } + } + } + + /** + * Proxy an URL (by adding repository.xml OBR information) in the Karaf Cave repository. + * + * @param url the URL to proxyFilesystem. the URL to proxyFilesystem. + * @throws Exception + */ + public void proxy(URL url) throws Exception { + if (url.getProtocol().equals("file")) { + // filesystem proxyFilesystem (to another folder) + File proxyFolder = new File(url.toURI()); + this.proxyFilesystem(proxyFolder); + } + if (url.getProtocol().equals("http")) { + // HTTP proxyFilesystem + this.proxyHttp(url.toExternalForm()); + } + this.generateRepositoryXml(); + } + + /** + * Proxy a local filesystem (folder). + * @param entry the filesystem to proxyFilesystem. + * @throws Exception in case of proxyFilesystem failure + */ + private void proxyFilesystem(File entry) throws Exception { + LOGGER.debug("Proxying filesystem {}", entry.getAbsolutePath()); + if (entry.isDirectory()) { + File[] children = entry.listFiles(); + for (int i = 0; i < children.length; i++) { + proxyFilesystem(children[i]); + } + } else { + try { + Resource resource = new DataModelHelperImpl().createResource(entry.toURI().toURL()); + if (resource != null) { + obrRepository.addResource(resource); + obrRepository.setLastModified(System.currentTimeMillis()); + } + } catch (IllegalArgumentException e) { + LOGGER.warn(e.getMessage()); + } + } + } + + /** + * Proxy a HTTP URL locally. + * + * @param url the HTTP URL to proxy. + * @throws Exception in case of proxy failure. + */ + private void proxyHttp(String url) throws Exception { + LOGGER.debug("Proxying HTTP URL {}", url); + HttpClient httpClient = new DefaultHttpClient(); + + HttpGet httpGet = new HttpGet(url); + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + + if (entity != null) { + if (entity.getContentType().getValue().equals("application/java-archive") + || entity.getContentType().getValue().equals("application/octet-stream")) { + // I have a jar/binary, potentially a resource + try { + Resource resource = new DataModelHelperImpl().createResource(new URL(url)); + if (resource != null) { + obrRepository.addResource(resource); + obrRepository.setLastModified(System.currentTimeMillis()); + } + } catch (IllegalArgumentException e) { + LOGGER.warn(e.getMessage()); + } + } else { + // try to find link to "browse" + Document document = Jsoup.connect(url).get(); + + Elements links = document.select("a"); + if (links.size() > 1) { + for (int i = 1; i < links.size(); i++) { + Element link = links.get(i); + String absoluteHref = link.attr("abs:href"); + this.proxyHttp(absoluteHref); + } + } + } + } + } + + /** + * Populate an URL into the Karaf Cave repository, and eventually update the OBR information. + * + * @param url the URL to copy. + * @param update if true the OBR information is updated, false else. + * @throws Exception in case of populate failure. + */ + public void populate(URL url, boolean update) throws Exception { + if (url.getProtocol().equals("file")) { + // populate the Karaf Cave repository from a filesystem folder + File populateFolder = new File(url.toURI()); + this.populateFromFilesystem(populateFolder, update); + } + if (url.getProtocol().equals("http")) { + // populate the Karaf Cave repository from a HTTP URL + this.populateFromHttp(url.toExternalForm(), update); + } + if (update) { + this.generateRepositoryXml(); + } + } + + /** + * Populate the Karaf Cave repository using a filesystem directory. + * + * @param filesystem the "source" directory. + * @param update if true, the resources are added into the OBR metadata, false else. + * @throws Exception in case of populate failure. + */ + private void populateFromFilesystem(File filesystem, boolean update) throws Exception { + LOGGER.debug("Populating from filesystem {}", filesystem.getAbsolutePath()); + if (filesystem.isDirectory()) { + File[] children = filesystem.listFiles(); + for (int i = 0; i < children.length; i++) { + populateFromFilesystem(children[i], update); + } + } else { + try { + ResourceImpl resource = (ResourceImpl) new DataModelHelperImpl().createResource(filesystem.toURI().toURL()); + if (resource != null) { + // copy the resource + File destination = new File(new File(this.getLocation()), filesystem.getName()); + LOGGER.debug("Copy from {} to {}", filesystem.getAbsolutePath(), destination.getAbsolutePath()); + FileUtils.copyFile(filesystem, destination); + if (update) { + resource = (ResourceImpl) new DataModelHelperImpl().createResource(destination.toURI().toURL()); + LOGGER.debug("Update the OBR metadata with {}", resource.getId()); + this.addResource(resource); + } + } + } catch (IllegalArgumentException e) { + LOGGER.warn(e.getMessage()); + } + } + } + + /** + * Populate the Karaf Cave repository using the given URL. + * + * @param url the "source" HTTP URL. + * @param update true if the OBR metadata should be updated, false else. + * @throws Exception in case of populate failure. + */ + private void populateFromHttp(String url, boolean update) throws Exception { + LOGGER.debug("Populating from HTTP URL {}", url); + HttpClient httpClient = new DefaultHttpClient(); + + HttpGet httpGet = new HttpGet(url); + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + + if (entity != null) { + if (entity.getContentType().getValue().equals("application/java-archive") + || entity.getContentType().getValue().equals("application/octet-stream")) { + // I have a jar/binary, potentially a resource + try { + ResourceImpl resource = (ResourceImpl) new DataModelHelperImpl().createResource(new URL(url)); + if (resource != null) { + LOGGER.debug("Copy {} into the Karaf Cave repository storage", url); + int index = url.lastIndexOf("/"); + if (index > 0) { + url = url.substring(index); + } + File destination = new File(new File(this.getLocation()), url); + FileOutputStream outputStream = new FileOutputStream(destination); + entity.writeTo(outputStream); + outputStream.flush(); + outputStream.close(); + if (update) { + resource = (ResourceImpl) new DataModelHelperImpl().createResource(destination.toURI().toURL()); + LOGGER.debug("Update OBR metadata with {}", resource.getId()); + this.addResource(resource); + } + } + } catch (IllegalArgumentException e) { + LOGGER.warn(e.getMessage()); + } + } else { + // try to find link to "browse" + Document document = Jsoup.connect(url).get(); + + Elements links = document.select("a"); + if (links.size() > 1) { + for (int i = 1; i < links.size(); i++) { + Element link = links.get(i); + String absoluteHref = link.attr("abs:href"); + this.populateFromHttp(absoluteHref, update); + } + } + } + } + } + + /** + * Convert the Resource absolute URI to an URI relative to the repository one. + * + * @param resource the Resource to manipulate. + * @throws Exception in cave of URI convertion failure. + */ + private void useResourceRelativeUri(ResourceImpl resource) throws Exception { + String resourceURI = resource.getURI(); + String locationURI = "file:" + this.getLocation(); + LOGGER.debug("Converting resource URI {} relatively to repository URI {}", resourceURI, locationURI); + if (resourceURI.startsWith(locationURI)) { + resourceURI = resourceURI.substring(locationURI.length() + 1); + LOGGER.debug("Resource URI converted to " + resourceURI); + resource.put(Resource.URI, resourceURI); + } + + } + + /** + * Get the File object of the OBR repository.xml file. + * + * @return the File corresponding to the OBR repository.xml. + * @throws Exception + */ + private File getRepositoryXmlFile() throws Exception { + return new File(new File(this.getLocation()), "repository.xml"); + } + + public void getResourceByUri(String uri) { + // construct the file starting from the repository URI + + } + + /** + * Return the OBR repository.xml corresponding to this Karaf Cave repository. + * + * @return the URL of the OBR repository.xml. + * @throws Exception in case of lookup failure. + */ + public URL getRepositoryXml() throws Exception { + File repositoryXml = this.getRepositoryXmlFile(); + return repositoryXml.toURI().toURL(); + } + + /** + * Delete the repository storage folder. + * + * @throws Exception in case of destroy failure. + */ + public void cleanup() throws Exception { + FileUtils.deleteDirectory(new File(this.getLocation())); + } + +} http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryServiceImpl.java b/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryServiceImpl.java new file mode 100644 index 0000000..fdeee1c --- /dev/null +++ b/server/storage/src/main/java/org/apache/karaf/cave/server/storage/CaveRepositoryServiceImpl.java @@ -0,0 +1,128 @@ +/* + * 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.karaf.cave.server.storage; + +import org.apache.felix.bundlerepository.RepositoryAdmin; +import org.apache.karaf.cave.server.api.CaveRepository; +import org.apache.karaf.cave.server.api.CaveRepositoryService; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** + * Default implementation of the Cave Repository Service. + */ +public class CaveRepositoryServiceImpl implements CaveRepositoryService { + + private File storageLocation; + private RepositoryAdmin repositoryAdmin; + + private Map<String, CaveRepository> repositories = new HashMap<String, CaveRepository>(); + + public File getStorageLocation() { + return this.storageLocation; + } + + public void setStorageLocation(File storageLocation) { + this.storageLocation = storageLocation; + } + + public RepositoryAdmin getRepositoryAdmin() { + return this.repositoryAdmin; + } + + public void setRepositoryAdmin(RepositoryAdmin repositoryAdmin) { + this.repositoryAdmin = repositoryAdmin; + } + + /** + * Create a new Karaf Cave repository. + * + * @param name the name of the repository + * @param scan if true, the repository is scanned at creation time. + * @return the Karaf Cave repository. + * @throws Exception in case of creation failure. + */ + public synchronized CaveRepository createRepository(String name, boolean scan) throws Exception { + File location = new File(storageLocation, name); + return this.createRepository(name, location.getAbsolutePath(), scan); + } + + /** + * Create a new Karaf Cave repository. + * + * @param name the name of the repository. + * @param location the storage location of the repository. + * @param scan if true, the repostory is scanned at creation time. + * @return the Karaf Cave repository. + * @throws Exception in case of creation failure. + */ + public synchronized CaveRepository createRepository(String name, String location, boolean scan) throws Exception { + if (repositories.get(name) != null) { + throw new IllegalArgumentException("Cave repository " + name + " already exists."); + } + CaveRepository repository = new CaveRepositoryImpl(name, location, scan); + repositories.put(name, repository); + return repository; + } + + /** + * Destroy a Karaf Cave repository. + * + * @param name the name of Karaf Cave repository to destroy. + * @throws Exception in case of destroy failure. + */ + public synchronized void destroy(String name) throws Exception { + CaveRepository repository = this.getRepository(name); + if (repository != null) { + repository.cleanup(); + repositories.remove(name); + } + } + + /** + * Register a Karaf Cave repository in the OBR service. + * + * @param name the name of the Karaf Cave repository. + * @throws Exception in case of registration failure. + */ + public synchronized void register(String name) throws Exception { + CaveRepository caveRepository = this.getRepository(name); + repositoryAdmin.addRepository(caveRepository.getRepositoryXml()); + } + + /** + * Get the list of all Karaf Cave repositories. + * + * @return the list of all Karaf Cave repositories. + */ + public synchronized CaveRepository[] getRepositories() { + return repositories.values().toArray(new CaveRepository[0]); + } + + /** + * Get the Karaf Cave repository identified by name. + * + * @param name the name of the Karaf Cave repository to look for. + * @return the corresponding Karaf Cave repository. + */ + public synchronized CaveRepository getRepository(String name) { + return repositories.get(name); + } + +} http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/src/main/resources/OSGI-INF/blueprint/cave-storage.xml ---------------------------------------------------------------------- diff --git a/server/storage/src/main/resources/OSGI-INF/blueprint/cave-storage.xml b/server/storage/src/main/resources/OSGI-INF/blueprint/cave-storage.xml new file mode 100644 index 0000000..f5dab07 --- /dev/null +++ b/server/storage/src/main/resources/OSGI-INF/blueprint/cave-storage.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0" + xmlns:cxf="http://cxf.apache.org/blueprint/core" + xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs" + xsi:schemaLocation=" + http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd + http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd + http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd + " + default-activation="lazy"> + + <bean id="caveRepositoryService" class="org.apache.karaf.cave.server.storage.CaveRepositoryServiceImpl"> + <property name="storageLocation" value="${storage.location}"/> + <property name="repositoryAdmin" ref="repositoryAdmin"/> + </bean> + + <reference id="repositoryAdmin" interface="org.apache.felix.bundlerepository.RepositoryAdmin"/> + + <service ref="caveRepositoryService" interface="org.apache.karaf.cave.server.api.CaveRepositoryService"/> + + <!-- use the cm of Cave filesystem backend --> + <cm:property-placeholder persistent-id="org.apache.karaf.cave.server.storage" update-strategy="reload"> + <cm:default-properties> + <cm:property name="storage.location" value="cave"/> + </cm:default-properties> + </cm:property-placeholder> + + <!-- start the JAX-RS server --> + <jaxrs:server id="caveRepositoryJaxRsServer" address="/cave"> + <jaxrs:serviceBeans> + <ref component-id="caveRepositoryService"/> + </jaxrs:serviceBeans> + </jaxrs:server> + +</blueprint> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/src/test/java/org/apache/karaf/cave/server/storage/CaveRepositoryImplTest.java ---------------------------------------------------------------------- diff --git a/server/storage/src/test/java/org/apache/karaf/cave/server/storage/CaveRepositoryImplTest.java b/server/storage/src/test/java/org/apache/karaf/cave/server/storage/CaveRepositoryImplTest.java new file mode 100644 index 0000000..b04cb7e --- /dev/null +++ b/server/storage/src/test/java/org/apache/karaf/cave/server/storage/CaveRepositoryImplTest.java @@ -0,0 +1,50 @@ +/* + * 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.karaf.cave.server.storage; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.net.URL; + +/** + * Unit test of the Cave Repository Implementation. + */ +@RunWith(JUnit4.class) +public class CaveRepositoryImplTest { + + private CaveRepositoryImpl repository; + + @Before + public void setUp() throws Exception { + repository = new CaveRepositoryImpl("test", "target/test-repository", false); + } + + @Test + public void testUploadBundleFromURL() throws Exception { + repository.upload(new URL("http://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-beanutils/1.8.2_2/org.apache.servicemix.bundles.commons-beanutils-1.8.2_2.jar")); + repository.upload(new URL("http://repo1.maven.org/maven2/org/apache/servicemix/bundles/org.apache.servicemix.bundles.commons-lang/2.4_5/org.apache.servicemix.bundles.commons-lang-2.4_5.jar")); + } + + @Test + public void testUploadNonBundleFromURL() throws Exception { + repository.upload(new URL("http://repo1.maven.org/maven2/commons-vfs/commons-vfs/1.0/commons-vfs-1.0.jar")); + } + +} http://git-wip-us.apache.org/repos/asf/karaf-cave/blob/94949ca7/server/storage/src/test/resources/log4j.xml ---------------------------------------------------------------------- diff --git a/server/storage/src/test/resources/log4j.xml b/server/storage/src/test/resources/log4j.xml new file mode 100644 index 0000000..a3140de --- /dev/null +++ b/server/storage/src/test/resources/log4j.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> + + <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> + <param name="threshold" value="DEBUG"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%-5p - %-30c{1} - %m%n"/> + </layout> + </appender> + + <root> + <level value="DEBUG"/> + <appender-ref ref="CONSOLE"/> + </root> + +</log4j:configuration> \ No newline at end of file
