You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:23:51 UTC

[sling-org-apache-sling-distribution-avro-serializer] branch master created (now 5fdd80d)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git.


      at 5fdd80d  SLING-7167 Adjust READMEs

This branch includes the following new commits:

     new 23e0d7a  SLING-6325 - split Avro and Kryo serializers into own bundles
     new 358bb60  SLING-4075 - added some tests, minor static analysis related fixes
     new 7bc73c7  SLING-6894: Remove commons.json from Content Distribution Avro Serializer
     new fcb5d7c  use latest org.apache.sling.distribution.core snapshot dependency
     new 5fdd80d  SLING-7167 Adjust READMEs

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-distribution-avro-serializer] 01/05: SLING-6325 - split Avro and Kryo serializers into own bundles

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git

commit 23e0d7acb72bbbe6ba70a45418700b7cd1eaa340
Author: Tommaso Teofili <to...@apache.org>
AuthorDate: Thu Feb 23 15:28:47 2017 +0000

    SLING-6325 - split Avro and Kryo serializers into own bundles
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1784154 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 340 +++++++++++++++++++
 src/main/avro/shallowresource.avsc                 |  11 +
 .../impl/avro/AvroContentSerializer.java           | 234 +++++++++++++
 .../AvroDistributionContentSerializerFactory.java  |  91 +++++
 .../impl/avro/AvroShallowResource.java             | 376 +++++++++++++++++++++
 .../impl/avro/AvroContentSerializerTest.java       | 177 ++++++++++
 src/test/resources/avro/dp.avro                    | Bin 0 -> 564 bytes
 7 files changed, 1229 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5ae5a3b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,340 @@
+<?xml version="1.0"?>
+<!--
+    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.
+-->
+<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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <!-- ======================================================================= -->
+    <!-- P A R E N T   P R O J E C T                                             -->
+    <!-- ======================================================================= -->
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>26</version>
+    </parent>
+
+    <!-- ======================================================================= -->
+    <!-- P R O J E C T                                                           -->
+    <!-- ======================================================================= -->
+    <artifactId>org.apache.sling.distribution.avro-serializer</artifactId>
+    <version>0.0.9-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Distribution Avro Serializer</name>
+    <description>
+        The Apache Sling Distribution Avro Serializer extensions bundle provides an Avro serialization implementation for Sling Content Distribution
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/distribution/avro-serializer</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/distribution/avro-serializer</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/avro-serializer</url>
+    </scm>
+
+    <!-- ======================================================================= -->
+    <!-- B U I L D                                                               -->
+    <!-- ======================================================================= -->
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>src/main/avro</directory>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/*.avsc</exclude>
+                        <exclude>**/*.avro</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.avro</groupId>
+                <artifactId>avro-maven-plugin</artifactId>
+                <version>1.7.7</version>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>schema</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
+                            <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>maven-sling-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>org.apache.sling.distribution.extensions</Bundle-SymbolicName>
+                        <Embed-Dependency>avro,avro-ipc,
+                            jackson-core-asl,
+                            jackson-mapper-asl,
+                            paranamer,
+                            commons-compress,
+                            org.apache.sling.jcr.resource;inline="org/apache/sling/jcr/resource/internal/helper/jcr/JcrNodeResource.*|
+                            org/apache/sling/jcr/resource/internal/helper/jcr/JcrItemResource.*|
+                            org/apache/sling/jcr/resource/internal/helper/LazyInputStream.*|
+                            org/apache/sling/jcr/resource/internal/HelperData*|
+                            org/apache/sling/jcr/resource/internal/JcrModifiableValueMap*|"
+                            org/apache/sling/jcr/resource/internal/JcrValueMap*|"
+                            org/apache/sling/jcr/resource/internal/helper/jcr/PathMapper*|"
+                            org/apache/sling/jcr/resource/internal/helper/JcrPropertyMapCacheEntry*"
+                        </Embed-Dependency>
+                        <Import-Package>
+                            !sun.*,
+                            !org.joda.time.*,
+                            !org.tukaani.xz,
+                            !org.xerial.snappy,
+                            !sun.misc,
+                            !javax.inject,
+                            !org.apache.velocity.*,
+                            !org.jboss.netty.*,
+                            !org.mortbay.jetty.*,
+                            !org.mortbay.resource.*,
+                            !org.apache.sling.api.resource,
+                            !org.apache.sling.distribution.component.*,
+                            !org.apache.sling.distribution.packaging.*,
+                            !org.apache.sling.distribution.serialization.impl.vlt.*,
+                            *
+                        </Import-Package>
+                        <DynamicImport-Package>
+                            org.apache.sling.api.resource
+                        </DynamicImport-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!-- ======================================================================= -->
+    <!-- D E P E N D E N C I E S                                                 -->
+    <!-- ======================================================================= -->
+    <dependencies>
+        <!-- TESTING -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-spi-commons</artifactId>
+            <version>2.6.4</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
+            <version>1.1.12</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- SLING -->
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.distribution.api</artifactId>
+            <version>0.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.distribution.core</artifactId>
+            <version>0.2.5-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.scheduler</artifactId>
+            <version>2.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.api</artifactId>
+            <version>2.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.event</artifactId>
+            <version>3.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.hc.core</artifactId>
+            <version>1.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.settings</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>2.0.8</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.event.dea</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- LOGGING -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.6.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>1.6.2</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- SPECs -->
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <!-- JACKRABBIT -->
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-jcr-commons</artifactId>
+            <version>2.6.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit</groupId>
+            <artifactId>jackrabbit-api</artifactId>
+            <version>2.6.2</version>
+        </dependency>
+        <!-- COMMONS -->
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+            <version>2.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- avro -->
+        <dependency>
+            <groupId>org.apache.avro</groupId>
+            <artifactId>avro</artifactId>
+            <version>1.7.7</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.avro</groupId>
+            <artifactId>avro-ipc</artifactId>
+            <version>1.7.7</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-core-asl</artifactId>
+            <version>1.9.13</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>1.9.13</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.thoughtworks.paranamer</groupId>
+            <artifactId>paranamer</artifactId>
+            <version>2.3</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.4.1</version>
+            <scope>provided</scope>
+        </dependency>
+
+    </dependencies>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>2.5.3</version>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
diff --git a/src/main/avro/shallowresource.avsc b/src/main/avro/shallowresource.avsc
new file mode 100644
index 0000000..3430342
--- /dev/null
+++ b/src/main/avro/shallowresource.avsc
@@ -0,0 +1,11 @@
+{"namespace": "org.apache.sling.distribution.serialization.impl.avro",
+  "type": "record",
+  "name": "AvroShallowResource",
+  "fields": [
+    {"name": "name", "type": "string"},
+    {"name": "valueMap",  "type": {"type": "map", "values": ["int","long","float","double","string","boolean","bytes",{"type":"array","items":["int","long","float","double","string","boolean","bytes"]}]}},
+    {"name": "path", "type": ["string", "null"]},
+    {"name": "children", "type": [{"type": "array", "items": "AvroShallowResource"},"null"]},
+    {"name": "resourceType", "type": ["string", "null"]}
+  ]
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java
new file mode 100644
index 0000000..5c21d8d
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java
@@ -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.sling.distribution.serialization.impl.avro;
+
+import javax.annotation.Nonnull;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.avro.Schema;
+import org.apache.avro.file.DataFileReader;
+import org.apache.avro.file.DataFileWriter;
+import org.apache.avro.file.SeekableByteArrayInput;
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.io.DatumReader;
+import org.apache.avro.io.DatumWriter;
+import org.apache.avro.specific.SpecificDatumReader;
+import org.apache.avro.specific.SpecificDatumWriter;
+import org.apache.avro.util.Utf8;
+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.ValueMap;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Apache Avro based {@link DistributionContentSerializer}
+ */
+public class AvroContentSerializer implements DistributionContentSerializer {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final String name;
+    private final Schema schema;
+    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.sss+hh:mm");
+
+    public AvroContentSerializer(String name) {
+        try {
+            schema = new Schema.Parser().parse(getClass().getResourceAsStream("/shallowresource.avsc"));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        this.name = name;
+    }
+
+    @Override
+    public void exportToStream(ResourceResolver resourceResolver, DistributionExportOptions options, OutputStream outputStream) throws DistributionException {
+
+        DatumWriter<AvroShallowResource> datumWriter = new SpecificDatumWriter<AvroShallowResource>(AvroShallowResource.class);
+        DataFileWriter<AvroShallowResource> writer = new DataFileWriter<AvroShallowResource>(datumWriter);
+        try {
+            writer.create(schema, outputStream);
+        } catch (IOException e) {
+            throw new DistributionException(e);
+        }
+
+        try {
+            DistributionExportFilter filter = options.getFilter();
+            for (DistributionExportFilter.TreeFilter treeFilter : filter.getNodeFilters()) {
+                String path = treeFilter.getPath();
+                Resource resource = resourceResolver.getResource(path);
+                AvroShallowResource avroShallowResource = getAvroShallowResource(treeFilter, filter.getPropertyFilter(),
+                        resource);
+                writer.append(avroShallowResource);
+            }
+            outputStream.flush();
+        } catch (Exception e) {
+            throw new DistributionException(e);
+        } finally {
+            try {
+                writer.close();
+            } catch (IOException e) {
+                // do nothing
+            }
+        }
+    }
+
+    @Override
+    public void importFromStream(ResourceResolver resourceResolver, InputStream stream) throws DistributionException {
+        try {
+            byte[] bin = IOUtils.toByteArray(stream); // TODO : avoid byte[] conversion
+            Collection<AvroShallowResource> avroShallowResources = readAvroResources(bin);
+            for (AvroShallowResource ar : avroShallowResources) {
+                persistResource(resourceResolver, ar);
+            }
+            resourceResolver.commit();
+        } catch (Exception e) {
+            throw new DistributionException(e);
+        }
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean isRequestFiltering() {
+        return false;
+    }
+
+    private AvroShallowResource getAvroShallowResource(DistributionExportFilter.TreeFilter nodeFilter,
+                                                       DistributionExportFilter.TreeFilter propertyFilter,
+                                                       Resource resource) throws IOException {
+        AvroShallowResource avroShallowResource = new AvroShallowResource();
+        avroShallowResource.setName("avro_" + System.nanoTime());
+        avroShallowResource.setPath(resource.getPath());
+        avroShallowResource.setResourceType(resource.getResourceType());
+        ValueMap valueMap = resource.getValueMap();
+        Map<CharSequence, Object> map = new HashMap<CharSequence, Object>();
+        for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
+            String property = entry.getKey();
+            if (propertyFilter.matches(property)) {
+                Object value = entry.getValue();
+                if (value instanceof GregorianCalendar) {
+                    value = dateFormat.format(((GregorianCalendar) value).getTime());
+                } else if (value instanceof Object[]) {
+                    Object[] ar = (Object[]) value;
+                    value = Arrays.asList(ar);
+                } else if (value instanceof InputStream) {
+                    value = ByteBuffer.wrap(IOUtils.toByteArray(((InputStream) value)));
+                }
+                map.put(property, value);
+            }
+        }
+        avroShallowResource.setValueMap(map);
+        List<AvroShallowResource> children = new LinkedList<AvroShallowResource>();
+        for (Resource child : resource.getChildren()) {
+            if (nodeFilter.matches(child.getPath())) {
+                children.add(getAvroShallowResource(nodeFilter, propertyFilter, child));
+            }
+        }
+        avroShallowResource.setChildren(children);
+        return avroShallowResource;
+    }
+
+    private Collection<AvroShallowResource> readAvroResources(byte[] bytes) throws IOException {
+        DatumReader<AvroShallowResource> datumReader = new SpecificDatumReader<AvroShallowResource>(AvroShallowResource.class);
+        DataFileReader<AvroShallowResource> dataFileReader = new DataFileReader<AvroShallowResource>(new SeekableByteArrayInput(bytes), datumReader);
+        Collection<AvroShallowResource> avroResources = new LinkedList<AvroShallowResource>();
+        try {
+            for (AvroShallowResource avroResource : dataFileReader) {
+                avroResources.add(avroResource);
+            }
+        } finally {
+            dataFileReader.close();
+        }
+        return avroResources;
+    }
+
+    private void persistResource(@Nonnull ResourceResolver resourceResolver, AvroShallowResource r) throws PersistenceException {
+        String path = r.getPath().toString().trim();
+        String name = path.substring(path.lastIndexOf('/') + 1);
+        String substring = path.substring(0, path.lastIndexOf('/'));
+        String parentPath = substring.length() == 0 ? "/" : substring;
+        Map<String, Object> map = new HashMap<String, Object>();
+        Map<CharSequence, Object> valueMap = r.getValueMap();
+        for (Map.Entry<CharSequence, Object> entry : valueMap.entrySet()) {
+            Object value = entry.getValue();
+            if (value instanceof GenericData.Array) {
+                GenericData.Array array = (GenericData.Array) value;
+                String[] s = new String[array.size()];
+                for (int i = 0; i < s.length; i++) {
+                    Object gd = array.get(i);
+                    s[i] = gd.toString();
+                }
+                value = s;
+            } else if (value instanceof Utf8) {
+                value = value.toString();
+            } else if (value instanceof ByteBuffer) {
+                byte[] bytes = ((ByteBuffer) value).array();
+                value = new BufferedInputStream(new ByteArrayInputStream(bytes));
+            }
+            map.put(entry.getKey().toString(), value);
+        }
+        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, map);
+        log.debug("created resource {}", createdResource);
+        for (AvroShallowResource child : r.getChildren()) {
+            persistResource(createdResource.getResourceResolver(), child);
+        }
+    }
+
+    private Resource createParent(ResourceResolver resourceResolver, String path) throws PersistenceException {
+        String parentPath = path.substring(0, path.lastIndexOf('/'));
+        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);
+    }
+}
diff --git a/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java
new file mode 100644
index 0000000..351a1b7
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java
@@ -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.avro;
+
+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 Apache Avro.
+ */
+@Component(metatype = true,
+        label = "Apache Sling Distribution Packaging - Avro Serialization Format Factory",
+        description = "OSGi configuration for Avro serializers",
+        configurationFactory = true,
+        specVersion = "1.1",
+        policy = ConfigurationPolicy.REQUIRE
+)
+@Service(DistributionContentSerializer.class)
+@Property(name = "webconsole.configurationFactory.nameHint", value = "Content serializer name: {name}")
+public class AvroDistributionContentSerializerFactory implements DistributionContentSerializer {
+
+    /**
+     * name of this package builder.
+     */
+    @Property(label = "Name", description = "The name of the avro format.")
+    public static final String NAME = "name";
+
+    private DistributionContentSerializer format;
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Activate
+    public void activate(Map<String, Object> config) {
+
+        String name = PropertiesUtil.toString(config.get(NAME), null);
+
+        format = new AvroContentSerializer(name);
+        log.info("started avro 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();
+    }
+}
diff --git a/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroShallowResource.java b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroShallowResource.java
new file mode 100644
index 0000000..1139e24
--- /dev/null
+++ b/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroShallowResource.java
@@ -0,0 +1,376 @@
+/*
+ * 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.avro;  
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class AvroShallowResource extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroShallowResource\",\"namespace\":\"org.apache.sling.distribution.serialization.impl.avro\",\"fields\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"valueMap\",\"type\":{\"type\":\"map\",\"values\":[\"int\",\"long\",\"float\",\"double\",\"string\",\"boolean\",\"bytes\",{\"type\":\"array\",\"items\":[\"int\",\"long\",\"float\",\"double\",\"string\",\"b [...]
+  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+  @Deprecated
+  public java.lang.CharSequence name;
+  @Deprecated
+  public java.util.Map<java.lang.CharSequence,java.lang.Object> valueMap;
+  @Deprecated
+  public java.lang.CharSequence path;
+  @Deprecated
+  public java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> children;
+  @Deprecated
+  public java.lang.CharSequence resourceType;
+
+  /**
+   * Default constructor.  Note that this does not initialize fields
+   * to their default values from the schema.  If that is desired then
+   * one should use <code>newBuilder()</code>.
+   */
+  public AvroShallowResource() {}
+
+  /**
+   * All-args constructor.
+   */
+  public AvroShallowResource(java.lang.CharSequence name, java.util.Map<java.lang.CharSequence,java.lang.Object> valueMap, java.lang.CharSequence path, java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> children, java.lang.CharSequence resourceType) {
+    this.name = name;
+    this.valueMap = valueMap;
+    this.path = path;
+    this.children = children;
+    this.resourceType = resourceType;
+  }
+
+  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+  // Used by DatumWriter.  Applications should not call.
+  public java.lang.Object get(int field$) {
+    switch (field$) {
+    case 0: return name;
+    case 1: return valueMap;
+    case 2: return path;
+    case 3: return children;
+    case 4: return resourceType;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+  // Used by DatumReader.  Applications should not call.
+  @SuppressWarnings(value="unchecked")
+  public void put(int field$, java.lang.Object value$) {
+    switch (field$) {
+    case 0: name = (java.lang.CharSequence)value$; break;
+    case 1: valueMap = (java.util.Map<java.lang.CharSequence,java.lang.Object>)value$; break;
+    case 2: path = (java.lang.CharSequence)value$; break;
+    case 3: children = (java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource>)value$; break;
+    case 4: resourceType = (java.lang.CharSequence)value$; break;
+    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+    }
+  }
+
+  /**
+   * Gets the value of the 'name' field.
+   */
+  public java.lang.CharSequence getName() {
+    return name;
+  }
+
+  /**
+   * Sets the value of the 'name' field.
+   * @param value the value to set.
+   */
+  public void setName(java.lang.CharSequence value) {
+    this.name = value;
+  }
+
+  /**
+   * Gets the value of the 'valueMap' field.
+   */
+  public java.util.Map<java.lang.CharSequence,java.lang.Object> getValueMap() {
+    return valueMap;
+  }
+
+  /**
+   * Sets the value of the 'valueMap' field.
+   * @param value the value to set.
+   */
+  public void setValueMap(java.util.Map<java.lang.CharSequence,java.lang.Object> value) {
+    this.valueMap = value;
+  }
+
+  /**
+   * Gets the value of the 'path' field.
+   */
+  public java.lang.CharSequence getPath() {
+    return path;
+  }
+
+  /**
+   * Sets the value of the 'path' field.
+   * @param value the value to set.
+   */
+  public void setPath(java.lang.CharSequence value) {
+    this.path = value;
+  }
+
+  /**
+   * Gets the value of the 'children' field.
+   */
+  public java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> getChildren() {
+    return children;
+  }
+
+  /**
+   * Sets the value of the 'children' field.
+   * @param value the value to set.
+   */
+  public void setChildren(java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> value) {
+    this.children = value;
+  }
+
+  /**
+   * Gets the value of the 'resourceType' field.
+   */
+  public java.lang.CharSequence getResourceType() {
+    return resourceType;
+  }
+
+  /**
+   * Sets the value of the 'resourceType' field.
+   * @param value the value to set.
+   */
+  public void setResourceType(java.lang.CharSequence value) {
+    this.resourceType = value;
+  }
+
+  /** Creates a new AvroShallowResource RecordBuilder */
+  public static org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder newBuilder() {
+    return new org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder();
+  }
+
+  /** Creates a new AvroShallowResource RecordBuilder by copying an existing Builder */
+  public static org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder newBuilder(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder other) {
+    return new org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder(other);
+  }
+
+  /** Creates a new AvroShallowResource RecordBuilder by copying an existing AvroShallowResource instance */
+  public static org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder newBuilder(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource other) {
+    return new org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder(other);
+  }
+
+  /**
+   * RecordBuilder for AvroShallowResource instances.
+   */
+  public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase<AvroShallowResource>
+    implements org.apache.avro.data.RecordBuilder<AvroShallowResource> {
+
+    private java.lang.CharSequence name;
+    private java.util.Map<java.lang.CharSequence,java.lang.Object> valueMap;
+    private java.lang.CharSequence path;
+    private java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> children;
+    private java.lang.CharSequence resourceType;
+
+    /** Creates a new Builder */
+    private Builder() {
+      super(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.SCHEMA$);
+    }
+
+    /** Creates a Builder by copying an existing Builder */
+    private Builder(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder other) {
+      super(other);
+      if (isValidValue(fields()[0], other.name)) {
+        this.name = data().deepCopy(fields()[0].schema(), other.name);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.valueMap)) {
+        this.valueMap = data().deepCopy(fields()[1].schema(), other.valueMap);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.path)) {
+        this.path = data().deepCopy(fields()[2].schema(), other.path);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.children)) {
+        this.children = data().deepCopy(fields()[3].schema(), other.children);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.resourceType)) {
+        this.resourceType = data().deepCopy(fields()[4].schema(), other.resourceType);
+        fieldSetFlags()[4] = true;
+      }
+    }
+
+    /** Creates a Builder by copying an existing AvroShallowResource instance */
+    private Builder(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource other) {
+            super(org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.SCHEMA$);
+      if (isValidValue(fields()[0], other.name)) {
+        this.name = data().deepCopy(fields()[0].schema(), other.name);
+        fieldSetFlags()[0] = true;
+      }
+      if (isValidValue(fields()[1], other.valueMap)) {
+        this.valueMap = data().deepCopy(fields()[1].schema(), other.valueMap);
+        fieldSetFlags()[1] = true;
+      }
+      if (isValidValue(fields()[2], other.path)) {
+        this.path = data().deepCopy(fields()[2].schema(), other.path);
+        fieldSetFlags()[2] = true;
+      }
+      if (isValidValue(fields()[3], other.children)) {
+        this.children = data().deepCopy(fields()[3].schema(), other.children);
+        fieldSetFlags()[3] = true;
+      }
+      if (isValidValue(fields()[4], other.resourceType)) {
+        this.resourceType = data().deepCopy(fields()[4].schema(), other.resourceType);
+        fieldSetFlags()[4] = true;
+      }
+    }
+
+    /** Gets the value of the 'name' field */
+    public java.lang.CharSequence getName() {
+      return name;
+    }
+
+    /** Sets the value of the 'name' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder setName(java.lang.CharSequence value) {
+      validate(fields()[0], value);
+      this.name = value;
+      fieldSetFlags()[0] = true;
+      return this;
+    }
+
+    /** Checks whether the 'name' field has been set */
+    public boolean hasName() {
+      return fieldSetFlags()[0];
+    }
+
+    /** Clears the value of the 'name' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder clearName() {
+      name = null;
+      fieldSetFlags()[0] = false;
+      return this;
+    }
+
+    /** Gets the value of the 'valueMap' field */
+    public java.util.Map<java.lang.CharSequence,java.lang.Object> getValueMap() {
+      return valueMap;
+    }
+
+    /** Sets the value of the 'valueMap' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder setValueMap(java.util.Map<java.lang.CharSequence,java.lang.Object> value) {
+      validate(fields()[1], value);
+      this.valueMap = value;
+      fieldSetFlags()[1] = true;
+      return this;
+    }
+
+    /** Checks whether the 'valueMap' field has been set */
+    public boolean hasValueMap() {
+      return fieldSetFlags()[1];
+    }
+
+    /** Clears the value of the 'valueMap' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder clearValueMap() {
+      valueMap = null;
+      fieldSetFlags()[1] = false;
+      return this;
+    }
+
+    /** Gets the value of the 'path' field */
+    public java.lang.CharSequence getPath() {
+      return path;
+    }
+
+    /** Sets the value of the 'path' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder setPath(java.lang.CharSequence value) {
+      validate(fields()[2], value);
+      this.path = value;
+      fieldSetFlags()[2] = true;
+      return this;
+    }
+
+    /** Checks whether the 'path' field has been set */
+    public boolean hasPath() {
+      return fieldSetFlags()[2];
+    }
+
+    /** Clears the value of the 'path' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder clearPath() {
+      path = null;
+      fieldSetFlags()[2] = false;
+      return this;
+    }
+
+    /** Gets the value of the 'children' field */
+    public java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> getChildren() {
+      return children;
+    }
+
+    /** Sets the value of the 'children' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder setChildren(java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource> value) {
+      validate(fields()[3], value);
+      this.children = value;
+      fieldSetFlags()[3] = true;
+      return this;
+    }
+
+    /** Checks whether the 'children' field has been set */
+    public boolean hasChildren() {
+      return fieldSetFlags()[3];
+    }
+
+    /** Clears the value of the 'children' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder clearChildren() {
+      children = null;
+      fieldSetFlags()[3] = false;
+      return this;
+    }
+
+    /** Gets the value of the 'resourceType' field */
+    public java.lang.CharSequence getResourceType() {
+      return resourceType;
+    }
+
+    /** Sets the value of the 'resourceType' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder setResourceType(java.lang.CharSequence value) {
+      validate(fields()[4], value);
+      this.resourceType = value;
+      fieldSetFlags()[4] = true;
+      return this;
+    }
+
+    /** Checks whether the 'resourceType' field has been set */
+    public boolean hasResourceType() {
+      return fieldSetFlags()[4];
+    }
+
+    /** Clears the value of the 'resourceType' field */
+    public org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource.Builder clearResourceType() {
+      resourceType = null;
+      fieldSetFlags()[4] = false;
+      return this;
+    }
+
+    @Override
+    public AvroShallowResource build() {
+      try {
+        AvroShallowResource record = new AvroShallowResource();
+        record.name = fieldSetFlags()[0] ? this.name : (java.lang.CharSequence) defaultValue(fields()[0]);
+        record.valueMap = fieldSetFlags()[1] ? this.valueMap : (java.util.Map<java.lang.CharSequence,java.lang.Object>) defaultValue(fields()[1]);
+        record.path = fieldSetFlags()[2] ? this.path : (java.lang.CharSequence) defaultValue(fields()[2]);
+        record.children = fieldSetFlags()[3] ? this.children : (java.util.List<org.apache.sling.distribution.serialization.impl.avro.AvroShallowResource>) defaultValue(fields()[3]);
+        record.resourceType = fieldSetFlags()[4] ? this.resourceType : (java.lang.CharSequence) defaultValue(fields()[4]);
+        return record;
+      } catch (Exception e) {
+        throw new org.apache.avro.AvroRuntimeException(e);
+      }
+    }
+  }
+}
diff --git a/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java b/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java
new file mode 100644
index 0000000..f8d4811
--- /dev/null
+++ b/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.avro;
+
+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 AvroContentSerializer}
+ */
+public class AvroContentSerializerTest {
+
+    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 testExtractDeep() throws Exception {
+        AvroContentSerializer avroContentSerializer = new AvroContentSerializer("avro");
+        DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.ADD, true, "/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);
+            avroContentSerializer.exportToStream(resourceResolver, new DistributionExportOptions(request, filter), outputStream);
+            byte[] bytes = outputStream.toByteArray();
+            assertNotNull(bytes);
+            assertTrue(bytes.length > 0);
+        } finally {
+            outputStream.close();
+        }
+    }
+
+    @Test
+    public void testExtractShallow() throws Exception {
+        AvroContentSerializer avroContentSerializer = new AvroContentSerializer("avro");
+        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);
+            avroContentSerializer.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 {
+        AvroContentSerializer avroContentSerializer = new AvroContentSerializer("avro");
+        InputStream inputStream = getClass().getResourceAsStream("/avro/dp.avro");
+        avroContentSerializer.importFromStream(resourceResolver, inputStream);
+    }
+
+    @Test
+    public void testBuildAndInstallOnSingleDeepPath() throws Exception {
+        String type = "avro";
+        DistributionContentSerializer contentSerializer = new AvroContentSerializer(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 = "avro";
+        DistributionContentSerializer contentSerializer = new AvroContentSerializer(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 = "avro";
+        DistributionContentSerializer contentSerializer = new AvroContentSerializer(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"));
+    }
+}
diff --git a/src/test/resources/avro/dp.avro b/src/test/resources/avro/dp.avro
new file mode 100644
index 0000000..51c61a2
Binary files /dev/null and b/src/test/resources/avro/dp.avro differ

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-distribution-avro-serializer] 02/05: SLING-4075 - added some tests, minor static analysis related fixes

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git

commit 358bb60469e045620bd310d2824f4db256838e07
Author: Tommaso Teofili <to...@apache.org>
AuthorDate: Tue Apr 11 09:04:05 2017 +0000

    SLING-4075 - added some tests, minor static analysis related fixes
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1790941 13f79535-47bb-0310-9956-ffa450edef68
---
 .../serialization/impl/avro/AvroContentSerializerTest.java             | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java b/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java
index f8d4811..69745cc 100644
--- a/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java
+++ b/src/test/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializerTest.java
@@ -48,13 +48,12 @@ import static org.junit.Assert.assertTrue;
  */
 public class AvroContentSerializerTest {
 
-    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")
+        MockHelper helper = MockHelper.create(resourceResolver).resource("/libs").p("prop", "value")
                 .resource("sub").p("sub", "hello")
                 .resource(".sameLevel")
                 .resource("/apps").p("foo", "baa");

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-distribution-avro-serializer] 04/05: use latest org.apache.sling.distribution.core snapshot dependency

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git

commit fcb5d7c969dbb2c2fe6b6415d145e260a628b4d9
Author: Timothée Maret <tm...@apache.org>
AuthorDate: Wed Jun 7 10:48:54 2017 +0000

    use latest org.apache.sling.distribution.core snapshot dependency
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1797909 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index cf61b74..4abee58 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,7 +187,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.distribution.core</artifactId>
-            <version>0.2.7-SNAPSHOT</version>
+            <version>0.2.9-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-distribution-avro-serializer] 03/05: SLING-6894: Remove commons.json from Content Distribution Avro Serializer

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git

commit 7bc73c7b5ca702da3620fcd3ff5692b1f70762a0
Author: Karl Pauls <pa...@apache.org>
AuthorDate: Tue May 30 22:53:33 2017 +0000

    SLING-6894: Remove commons.json from Content Distribution Avro Serializer
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1796953 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5ae5a3b..cf61b74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -187,7 +187,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.distribution.core</artifactId>
-            <version>0.2.5-SNAPSHOT</version>
+            <version>0.2.7-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
@@ -224,12 +224,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.json</artifactId>
-            <version>2.0.8</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.event.dea</artifactId>
             <version>1.0.0</version>
             <scope>provided</scope>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-distribution-avro-serializer] 05/05: SLING-7167 Adjust READMEs

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-distribution-avro-serializer.git

commit 5fdd80d3ab2003f789b979abab1e2dde9930ffce
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Oct 3 09:28:04 2017 +0000

    SLING-7167 Adjust READMEs
    
    add missing README
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1810731 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4945a99
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Apache Sling Distribution Avro Serializer
+
+This module is part of the [Apache Sling](https://sling.apache.org) project.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.