You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by to...@apache.org on 2017/02/23 15:28:47 UTC
svn commit: r1784154 [2/2] - in
/sling/trunk/contrib/extensions/distribution: ./ avro-serializer/
avro-serializer/src/ avro-serializer/src/main/
avro-serializer/src/main/avro/ avro-serializer/src/main/java/
avro-serializer/src/main/java/org/ avro-seria...
Added: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java?rev=1784154&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java (added)
+++ sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java Thu Feb 23 15:28:47 2017
@@ -0,0 +1,242 @@
+/*
+ * 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.sling.distribution.serialization.impl.kryo;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.DistributionExportFilter;
+import org.apache.sling.distribution.serialization.DistributionExportOptions;
+import org.objenesis.strategy.StdInstantiatorStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Kryo based {@link DistributionContentSerializer}
+ */
+public class KryoContentSerializer implements DistributionContentSerializer {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final String name;
+
+ public KryoContentSerializer(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public void exportToStream(ResourceResolver resourceResolver, DistributionExportOptions options, OutputStream outputStream) throws DistributionException {
+
+ DistributionExportFilter filter = options.getFilter();
+
+ Kryo kryo = new Kryo();
+ kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
+ kryo.addDefaultSerializer(Resource.class, new ResourceSerializer(filter.getPropertyFilter()));
+ kryo.addDefaultSerializer(InputStream.class, new InputStreamSerializer());
+
+ Output output = new Output(outputStream);
+ LinkedList<Resource> resources = new LinkedList<Resource>();
+ for (DistributionExportFilter.TreeFilter nodeFilter : filter.getNodeFilters()) {
+ Resource resource = resourceResolver.getResource(nodeFilter.getPath());
+ if (resource != null) {
+ addResource(nodeFilter, resources, resource);
+ }
+ }
+ kryo.writeObject(output, resources);
+ output.flush();
+
+ }
+
+ @Override
+ public void importFromStream(ResourceResolver resourceResolver, InputStream stream) throws DistributionException {
+ Kryo kryo = new Kryo();
+ kryo.setInstantiatorStrategy(new Kryo.DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
+ kryo.addDefaultSerializer(Resource.class, new ResourceSerializer(null));
+ kryo.addDefaultSerializer(InputStream.class, new InputStreamSerializer());
+ try {
+ Input input = new Input(stream);
+ LinkedList<Resource> resources = (LinkedList<Resource>) kryo.readObject(input, LinkedList.class);
+ input.close();
+ for (Resource resource : resources) {
+ persistResource(resourceResolver, resource);
+ }
+ resourceResolver.commit();
+ } catch (Exception e) {
+ throw new DistributionException(e);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean isRequestFiltering() {
+ return false;
+ }
+
+ private void persistResource(@Nonnull ResourceResolver resourceResolver, Resource resource) throws PersistenceException {
+ String path = resource.getPath().trim();
+ String name = path.substring(path.lastIndexOf('/') + 1);
+ String substring = path.substring(0, path.lastIndexOf('/'));
+ String parentPath = substring.length() == 0 ? "/" : substring;
+ Resource existingResource = resourceResolver.getResource(path);
+ if (existingResource != null) {
+ resourceResolver.delete(existingResource);
+ }
+ Resource parent = resourceResolver.getResource(parentPath);
+ if (parent == null) {
+ parent = createParent(resourceResolver, parentPath);
+ }
+ Resource createdResource = resourceResolver.create(parent, name, resource.getValueMap());
+ log.debug("created resource {}", createdResource);
+ }
+
+ private Resource createParent(ResourceResolver resourceResolver, String path) throws PersistenceException {
+ String parentPath = path.substring(0, path.lastIndexOf('/'));
+ if (parentPath.length() == 0) {
+ parentPath = "/";
+ }
+ String name = path.substring(path.lastIndexOf('/') + 1);
+ Resource parentResource = resourceResolver.getResource(parentPath);
+ if (parentResource == null) {
+ parentResource = createParent(resourceResolver, parentPath);
+ }
+ Map<String, Object> properties = new HashMap<String, Object>();
+ return resourceResolver.create(parentResource, name, properties);
+ }
+
+ private class ResourceSerializer extends Serializer<Resource> {
+
+ private final DistributionExportFilter.TreeFilter propertyFilter;
+
+ private ResourceSerializer(@Nullable DistributionExportFilter.TreeFilter propertyFilter) {
+ this.propertyFilter = propertyFilter;
+ }
+
+ @Override
+ public void write(Kryo kryo, Output output, Resource resource) {
+ ValueMap valueMap = resource.getValueMap();
+
+ output.writeString(resource.getPath());
+ output.writeString(resource.getResourceType());
+
+ HashMap map = new HashMap<String, Object>();
+ for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
+ if (propertyFilter == null || propertyFilter.matches(entry.getKey())) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ kryo.writeObjectOrNull(output, map, HashMap.class);
+ }
+
+ @Override
+ public Resource read(Kryo kryo, Input input, Class<Resource> type) {
+
+ String path = input.readString();
+ String resourceType = input.readString();
+
+ final HashMap<String, Object> map = kryo.readObjectOrNull(input, HashMap.class);
+
+ return new SyntheticResource(null, path, resourceType) {
+ @Override
+ public ValueMap getValueMap() {
+ return new ValueMapDecorator(map);
+ }
+ };
+ }
+
+ }
+
+ private class ValueMapSerializer extends Serializer<ValueMap> {
+ @Override
+ public void write(Kryo kryo, Output output, ValueMap valueMap) {
+ for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
+ output.writeString(entry.getKey());
+ output.writeString(entry.getValue().toString());
+ }
+ }
+
+ @Override
+ public ValueMap read(Kryo kryo, Input input, Class<ValueMap> type) {
+ final Map<String, Object> map = new HashMap<String, Object>();
+
+ String key;
+ while ((key = input.readString()) != null) {
+ String value = input.readString();
+ map.put(key, value);
+ }
+ return new ValueMapDecorator(map);
+ }
+ }
+
+ private class InputStreamSerializer extends Serializer<InputStream> {
+ @Override
+ public void write(Kryo kryo, Output output, InputStream stream) {
+ try {
+ byte[] bytes = IOUtils.toByteArray(stream);
+ output.writeInt(bytes.length);
+ output.write(bytes);
+ } catch (IOException e) {
+ log.warn("could not serialize input stream", e);
+ }
+ }
+
+ @Override
+ public InputStream read(Kryo kryo, Input input, Class<InputStream> type) {
+ int size = input.readInt();
+ byte[] bytes = new byte[size];
+ input.readBytes(bytes);
+ return new ByteArrayInputStream(bytes);
+ }
+ }
+
+ private void addResource(DistributionExportFilter.TreeFilter nodeFilter, LinkedList<Resource> resources, Resource resource) {
+ resources.add(resource);
+ for (Resource child : resource.getChildren()) {
+ if (nodeFilter.matches(child.getPath())) {
+ addResource(nodeFilter, resources, child);
+ }
+ }
+ }
+
+
+}
Propchange: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java?rev=1784154&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java (added)
+++ sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java Thu Feb 23 15:28:47 2017
@@ -0,0 +1,91 @@
+/*
+ * 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.sling.distribution.serialization.impl.kryo;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.ConfigurationPolicy;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.DistributionExportOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Factory for {@link DistributionContentSerializer}s based on Kryo.
+ */
+@Component(metatype = true,
+ label = "Apache Sling Distribution Packaging - Kryo Serialization Format Factory",
+ description = "OSGi configuration for Kryo serializers",
+ configurationFactory = true,
+ specVersion = "1.1",
+ policy = ConfigurationPolicy.REQUIRE
+)
+@Service(DistributionContentSerializer.class)
+@Property(name = "webconsole.configurationFactory.nameHint", value = "Content serializer name: {name}")
+public class KryoDistributionContentSerializerFactory implements DistributionContentSerializer {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * name of this package builder.
+ */
+ @Property(label = "Name", description = "The name of the package builder.")
+ public static final String NAME = "name";
+
+ private KryoContentSerializer format;
+
+ @Activate
+ public void activate(Map<String, Object> config) {
+
+ String name = PropertiesUtil.toString(config.get(NAME), null);
+
+ format = new KryoContentSerializer(name);
+ log.info("started Kryo content serializer {}", name);
+ }
+
+
+ @Override
+ public void exportToStream(ResourceResolver resourceResolver, DistributionExportOptions options, OutputStream outputStream) throws DistributionException {
+ format.exportToStream(resourceResolver, options, outputStream);
+ }
+
+ @Override
+ public void importFromStream(ResourceResolver resourceResolver, InputStream stream) throws DistributionException {
+ format.importFromStream(resourceResolver, stream);
+ }
+
+ @Override
+ public String getName() {
+ return format.getName();
+ }
+
+ @Override
+ public boolean isRequestFiltering() {
+ return format.isRequestFiltering();
+ }
+}
Propchange: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializerTest.java?rev=1784154&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializerTest.java (added)
+++ sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializerTest.java Thu Feb 23 15:28:47 2017
@@ -0,0 +1,160 @@
+/*
+ * 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.sling.distribution.serialization.impl.kryo;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.List;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.DistributionRequest;
+import org.apache.sling.distribution.DistributionRequestType;
+import org.apache.sling.distribution.SimpleDistributionRequest;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.packaging.DistributionPackageBuilder;
+import org.apache.sling.distribution.packaging.impl.FileDistributionPackageBuilder;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.DistributionExportFilter;
+import org.apache.sling.distribution.serialization.DistributionExportOptions;
+import org.apache.sling.testing.resourceresolver.MockHelper;
+import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link KryoContentSerializer}
+ */
+public class KryoContentSerializerTest {
+
+ private MockHelper helper;
+ private ResourceResolver resourceResolver;
+
+ @Before
+ public void setUp() throws Exception {
+ resourceResolver = new MockResourceResolverFactory().getResourceResolver(null);
+ helper = MockHelper.create(resourceResolver).resource("/libs").p("prop", "value")
+ .resource("sub").p("sub", "hello")
+ .resource(".sameLevel")
+ .resource("/apps").p("foo", "baa");
+ helper.commit();
+ }
+
+ @Test
+ public void testExtract() throws Exception {
+ KryoContentSerializer kryoContentSerializer = new KryoContentSerializer("kryo");
+ DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.ADD, "/libs");
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ NavigableMap<String, List<String>> nodeFilters = new TreeMap<String, List<String>>();
+ NavigableMap<String, List<String>> propertyFilters = new TreeMap<String, List<String>>();
+ try {
+ DistributionExportFilter filter = DistributionExportFilter.createFilter(request, nodeFilters, propertyFilters);
+ kryoContentSerializer.exportToStream(resourceResolver, new DistributionExportOptions(request, filter), outputStream);
+ byte[] bytes = outputStream.toByteArray();
+ assertNotNull(bytes);
+ assertTrue(bytes.length > 0);
+ } finally {
+ outputStream.close();
+ }
+ }
+
+ @Test
+ public void testImport() throws Exception {
+ KryoContentSerializer kryoContentSerializer = new KryoContentSerializer("avro");
+ InputStream inputStream = getClass().getResourceAsStream("/kryo/dp.kryo");
+ kryoContentSerializer.importFromStream(resourceResolver, inputStream);
+ }
+
+ @Test
+ public void testBuildAndInstallOnSingleDeepPath() throws Exception {
+ String type = "kryo";
+ DistributionContentSerializer contentSerializer = new KryoContentSerializer(type);
+ String tempFilesFolder = "target";
+ String[] nodeFilters = new String[0];
+ String[] propertyFilters = new String[0];
+ DistributionPackageBuilder packageBuilder = new FileDistributionPackageBuilder(type, contentSerializer,
+ tempFilesFolder, null, nodeFilters, propertyFilters);
+ DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.ADD, true, "/libs");
+ DistributionPackage distributionPackage = packageBuilder.createPackage(resourceResolver, request);
+
+ Resource resource = resourceResolver.getResource("/libs/sub");
+ resourceResolver.delete(resource);
+ resourceResolver.commit();
+
+ assertTrue(packageBuilder.installPackage(resourceResolver, distributionPackage));
+
+ assertNotNull(resourceResolver.getResource("/libs"));
+ assertNotNull(resourceResolver.getResource("/libs/sub"));
+ assertNotNull(resourceResolver.getResource("/libs/sameLevel"));
+ }
+
+ @Test
+ public void testBuildAndInstallOnSingleShallowPath() throws Exception {
+ String type = "kryo";
+ DistributionContentSerializer contentSerializer = new KryoContentSerializer(type);
+ String tempFilesFolder = "target";
+ String[] nodeFilters = new String[0];
+ String[] propertyFilters = new String[0];
+ DistributionPackageBuilder packageBuilder = new FileDistributionPackageBuilder(type, contentSerializer,
+ tempFilesFolder, null, nodeFilters, propertyFilters);
+ DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.ADD, "/libs/sub");
+ DistributionPackage distributionPackage = packageBuilder.createPackage(resourceResolver, request);
+
+ Resource resource = resourceResolver.getResource("/libs/sub");
+ resourceResolver.delete(resource);
+ resourceResolver.commit();
+
+ assertTrue(packageBuilder.installPackage(resourceResolver, distributionPackage));
+
+ assertNotNull(resourceResolver.getResource("/libs"));
+ assertNotNull(resourceResolver.getResource("/libs/sub"));
+ assertNotNull(resourceResolver.getResource("/libs/sameLevel"));
+ }
+
+ @Test
+ public void testBuildAndInstallOnMultipleShallowPaths() throws Exception {
+ String type = "kryo";
+ DistributionContentSerializer contentSerializer = new KryoContentSerializer(type);
+ String tempFilesFolder = "target";
+ String[] nodeFilters = new String[0];
+ String[] propertyFilters = new String[0];
+ DistributionPackageBuilder packageBuilder = new FileDistributionPackageBuilder(type, contentSerializer,
+ tempFilesFolder, null, nodeFilters, propertyFilters);
+ DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.ADD, "/libs/sub", "/libs/sameLevel");
+ DistributionPackage distributionPackage = packageBuilder.createPackage(resourceResolver, request);
+
+ Resource resource = resourceResolver.getResource("/libs/sub");
+ resourceResolver.delete(resource);
+ resource = resourceResolver.getResource("/libs/sameLevel");
+ resourceResolver.delete(resource);
+ resourceResolver.commit();
+
+ assertTrue(packageBuilder.installPackage(resourceResolver, distributionPackage));
+
+ assertNotNull(resourceResolver.getResource("/libs"));
+ assertNotNull(resourceResolver.getResource("/libs/sub"));
+ assertNotNull(resourceResolver.getResource("/libs/sameLevel"));
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/resources/kryo/dp.kryo
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/resources/kryo/dp.kryo?rev=1784154&view=auto
==============================================================================
Binary file - no diff available.
Propchange: sling/trunk/contrib/extensions/distribution/kryo-serializer/src/test/resources/kryo/dp.kryo
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: sling/trunk/contrib/extensions/distribution/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/pom.xml?rev=1784154&r1=1784153&r2=1784154&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/pom.xml (original)
+++ sling/trunk/contrib/extensions/distribution/pom.xml Thu Feb 23 15:28:47 2017
@@ -29,8 +29,9 @@
<modules>
<module>api</module>
<module>core</module>
- <module>extensions</module>
<module>it</module>
<module>sample</module>
+ <module>avro-serializer</module>
+ <module>kryo-serializer</module>
</modules>
</project>