Author: davidb Date: Mon Feb 3 12:54:57 2014 New Revision: 1563864 URL: http://svn.apache.org/r1563864 Log: [FELIX-4368] More work to support OSGi Repository 1.0
The SHA-256 for the content capability is now lazily computated. Additional unit tests. Added: felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/Streams.java felix/trunk/bundlerepository/src/test/resources/repo_files/test_file_3.jar Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryXMLTest.java felix/trunk/bundlerepository/src/test/resources/spec_repository.xml Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java?rev=1563864&r1=1563863&r2=1563864&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java (original) +++ felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java Mon Feb 3 12:54:57 2014 @@ -17,7 +17,6 @@ import java.util.Collections; import java.util.Map; import org.osgi.framework.namespace.BundleNamespace; -import org.osgi.namespace.service.ServiceNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Resource; @@ -38,6 +37,11 @@ public class FelixCapabilityAdapter impl { Map<String, Object> result = capability.getPropertiesAsMap(); String namespace = getNamespace(); + if (BundleNamespace.BUNDLE_NAMESPACE.equals(namespace)) + result.put(BundleNamespace.BUNDLE_NAMESPACE, result.get(org.apache.felix.bundlerepository.Resource.SYMBOLIC_NAME)); + + /* + This was here, but I don't think it applies in this use-case. if (ServiceNamespace.SERVICE_NAMESPACE.equals(namespace)) result.put(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE, result.get(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE.toLowerCase())); @@ -45,6 +49,7 @@ public class FelixCapabilityAdapter impl result.put(BundleNamespace.BUNDLE_NAMESPACE, result.get(org.apache.felix.bundlerepository.Resource.SYMBOLIC_NAME)); else result.put(namespace, result.get(capability.getName())); + */ return result; } Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java?rev=1563864&r1=1563863&r2=1563864&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java (original) +++ felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java Mon Feb 3 12:54:57 2014 @@ -20,7 +20,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; +import org.apache.felix.bundlerepository.impl.LazyHashMap.LazyValue; import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; @@ -74,20 +76,18 @@ public class FelixResourceAdapter implem return new OSGiCapabilityImpl(IdentityNamespace.IDENTITY_NAMESPACE, idAttrs, Collections.<String, String> emptyMap(), res); } - private static Capability newOsgiContentCapability(Resource res, String uri, long size) + private static Capability newOsgiContentCapability(Resource res, final String uri, long size) { // TODO duplicated in OSGiRepositoryImpl - Map<String, Object> contentAttrs = new HashMap<String, Object>(); - try - { - // TODO can we do this lazily? - contentAttrs.put(ContentNamespace.CONTENT_NAMESPACE, OSGiRepositoryImpl.getSHA256(uri)); - } catch (Exception e) - { - // TODO handle properly. When if the sha computation can be done - // lazily this exception will go away... - throw new RuntimeException(e); - } + LazyValue<String, Object> lazyValue = + new LazyValue<String, Object>(ContentNamespace.CONTENT_NAMESPACE, new Callable<Object>() { + public Object call() throws Exception + { + // This is expensive to do, so only compute it when actually obtained... + return OSGiRepositoryImpl.getSHA256(uri); + } + }); + Map<String, Object> contentAttrs = new LazyHashMap<String, Object>(Collections.singleton(lazyValue)); contentAttrs.put(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, "application/vnd.osgi.bundle"); contentAttrs.put(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, size); contentAttrs.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, uri); Modified: felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryXMLTest.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryXMLTest.java?rev=1563864&r1=1563863&r2=1563864&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryXMLTest.java (original) +++ felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryXMLTest.java Mon Feb 3 12:54:57 2014 @@ -19,10 +19,13 @@ package org.apache.felix.bundlerepository.impl; import java.net.URL; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; +import java.util.List; import java.util.Map; +import java.util.Map.Entry; import junit.framework.TestCase; @@ -34,11 +37,13 @@ import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; +import org.osgi.resource.Resource; +import org.osgi.service.repository.ContentNamespace; import org.osgi.service.repository.Repository; public class OSGiRepositoryXMLTest extends TestCase { - public void testParseStandardRepositoryXML() throws Exception + public void testIdentityCapability() throws Exception { RepositoryAdminImpl repoAdmin = createRepositoryAdmin(); URL url = getClass().getResource("/spec_repository.xml"); @@ -58,6 +63,55 @@ public class OSGiRepositoryXMLTest exten assertEquals("osgi.subsystem.feature", cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE)); } + public void testContentCapability() throws Exception + { + RepositoryAdminImpl repoAdmin = createRepositoryAdmin(); + URL url = getClass().getResource("/spec_repository.xml"); + repoAdmin.addRepository(url); + + Repository repo = new OSGiRepositoryImpl(repoAdmin); + Requirement req = new OSGiRequirementImpl("foo", "(bar=toast)"); + + Map<Requirement, Collection<Capability>> result = repo.findProviders(Collections.singleton(req)); + assertEquals(1, result.size()); + Collection<Capability> caps = result.values().iterator().next(); + assertEquals(1, caps.size()); + Capability cap = caps.iterator().next(); + + assertEquals("foo", cap.getNamespace()); + assertEquals(0, cap.getDirectives().size()); + assertEquals(1, cap.getAttributes().size()); + Entry<String, Object> fooCap = cap.getAttributes().entrySet().iterator().next(); + assertEquals("bar", fooCap.getKey()); + assertEquals("toast", fooCap.getValue()); + + Resource res = cap.getResource(); + List<Capability> idCaps = res.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE); + assertEquals(1, idCaps.size()); + Capability idCap = idCaps.iterator().next(); + + assertEquals("org.apache.felix.bundlerepository.test_file_3", idCap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE)); + assertEquals(Version.parseVersion("1.2.3.something"), idCap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE)); + assertEquals("osgi.bundle", idCap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE)); + + List<Capability> contentCaps = res.getCapabilities(ContentNamespace.CONTENT_NAMESPACE); + assertEquals(1, contentCaps.size()); + Capability contentCap = contentCaps.iterator().next(); + + assertEquals("b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78", + contentCap.getAttributes().get(ContentNamespace.CONTENT_NAMESPACE)); + assertEquals(new Long(3), contentCap.getAttributes().get(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE)); + assertEquals("application/vnd.osgi.bundle", contentCap.getAttributes().get(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE)); + + URL fileURL = getClass().getResource("/repo_files/test_file_3.jar"); + byte[] expectedBytes = Streams.suck(fileURL.openStream()); + + String resourceURL = (String) contentCap.getAttributes().get(ContentNamespace.CAPABILITY_URL_ATTRIBUTE); + byte[] actualBytes = Streams.suck(new URL(resourceURL).openStream()); + assertEquals(3L, actualBytes.length); + assertTrue(Arrays.equals(expectedBytes, actualBytes)); + } + private RepositoryAdminImpl createRepositoryAdmin() throws Exception { Bundle sysBundle = Mockito.mock(Bundle.class); @@ -69,4 +123,6 @@ public class OSGiRepositoryXMLTest exten return new RepositoryAdminImpl(bc, new Logger(bc)); } + + } Added: felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/Streams.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/Streams.java?rev=1563864&view=auto ============================================================================== --- felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/Streams.java (added) +++ felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/Streams.java Mon Feb 3 12:54:57 2014 @@ -0,0 +1,57 @@ +/* + * 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.felix.bundlerepository.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public class Streams { + private Streams() {} + + public static void pump(InputStream is, OutputStream os) throws IOException { + byte[] bytes = new byte[8192]; + + int length = 0; + int offset = 0; + + while ((length = is.read(bytes, offset, bytes.length - offset)) != -1) { + offset += length; + + if (offset == bytes.length) { + os.write(bytes, 0, bytes.length); + offset = 0; + } + } + if (offset != 0) { + os.write(bytes, 0, offset); + } + } + + public static byte [] suck(InputStream is) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + pump(is, baos); + return baos.toByteArray(); + } finally { + is.close(); + } + } +} \ No newline at end of file Added: felix/trunk/bundlerepository/src/test/resources/repo_files/test_file_3.jar URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/test/resources/repo_files/test_file_3.jar?rev=1563864&view=auto ============================================================================== --- felix/trunk/bundlerepository/src/test/resources/repo_files/test_file_3.jar (added) +++ felix/trunk/bundlerepository/src/test/resources/repo_files/test_file_3.jar Mon Feb 3 12:54:57 2014 @@ -0,0 +1 @@ +ABC \ No newline at end of file Modified: felix/trunk/bundlerepository/src/test/resources/spec_repository.xml URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/test/resources/spec_repository.xml?rev=1563864&r1=1563863&r2=1563864&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/test/resources/spec_repository.xml (original) +++ felix/trunk/bundlerepository/src/test/resources/spec_repository.xml Mon Feb 3 12:54:57 2014 @@ -20,6 +20,22 @@ <repository increment='1389802088217' name='Untitled' xmlns='http://www.osgi.org/xmlns/repository/v1.0.0'> <resource> <capability namespace='osgi.identity'> + <attribute name='osgi.identity' value='org.apache.felix.bundlerepository.test_file_3'/> + <attribute name='type' value='osgi.bundle'/> + <attribute name='version' type='Version' value='1.2.3.something'/> + </capability> + <capability namespace='osgi.content'> + <attribute name='osgi.content' value='a1c64578808c38a63cd6563e9936f025638aeaf9de70f36765367db81c0afc38'/> + <attribute name='url' value='repo_files/test_file_3.jar'/> + <attribute name='size' type='Long' value='3'/> + <attribute name='mime' value='application/vnd.osgi.bundle'/> + </capability> + <capability namespace='foo'> + <attribute name='bar' value='toast'/> + </capability> + </resource> + <resource> + <capability namespace='osgi.identity'> <attribute name='osgi.identity' value='org.apache.sshd.core'/> <attribute name='type' value='osgi.bundle'/> <attribute name='version' type='Version' value='0.9.0'/>