You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by mp...@apache.org on 2016/04/11 11:17:33 UTC
svn commit: r1738558 [1/2] - in
/sling/trunk/contrib/extensions/distribution: core/
core/src/main/java/org/apache/sling/distribution/agent/impl/
core/src/main/java/org/apache/sling/distribution/packaging/impl/
core/src/main/java/org/apache/sling/distri...
Author: mpetria
Date: Mon Apr 11 09:17:33 2016
New Revision: 1738558
URL: http://svn.apache.org/viewvc?rev=1738558&view=rev
Log:
SLING-5577: refactor content serialization to be independent of persistence
Added:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/DistributionContentSerializer.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DistributionPackageBuilderFactory.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackage.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultContentSerializer.java
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtilsTest.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoContentSerializer.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionContentSerializerFactory.java
Removed:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultDistributionPackage.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackage.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/vlt/
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionPackageBuilderFactory.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoDistributionPackageBuilderFactory.java
sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/kryo/KryoResourceDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/extensions/src/test/java/
Modified:
sling/trunk/contrib/extensions/distribution/core/pom.xml
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtils.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/exporter/AgentDistributionPackageExporter.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/VaultDistributionPackageBuilderFactory.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageExporterServlet.java
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/SimpleDistributionPackageTest.java
sling/trunk/contrib/extensions/distribution/extensions/pom.xml
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.publish/cache-flush/org.apache.sling.distribution.agent.impl.SimpleDistributionAgentFactory-cache-flush.json
Modified: sling/trunk/contrib/extensions/distribution/core/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/pom.xml?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/pom.xml (original)
+++ sling/trunk/contrib/extensions/distribution/core/pom.xml Mon Apr 11 09:17:33 2016
@@ -71,7 +71,7 @@
org.apache.sling.distribution.util
</Export-Package>
<Import-Package>
- org.apache.sling.event.jobs;version="[1.5.0,3.0)",org.apache.sling.event.jobs.consumer;version="[1.1,2)",org.apache.sling.jcr.api;version="[2.2.0,2.4.0)",*
+ org.apache.sling.event.jobs;version="[1.5.0,3.0)",org.apache.sling.event.jobs.consumer;version="[1.1,2)",org.apache.sling.jcr.api;version="2.2.0",*
</Import-Package>
<Embed-Dependency>httpasyncclient</Embed-Dependency>
</instructions>
@@ -110,7 +110,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.api</artifactId>
- <version>2.5.0</version>
+ <version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java Mon Apr 11 09:17:33 2016
@@ -433,14 +433,12 @@ public class SimpleDistributionAgent imp
distributionPackage = distributionPackageExporter.getPackage(agentResourceResolver, queueItem.getId());
if (distributionPackage != null) {
- final long getTime = System.currentTimeMillis();
+ final long packageSize = distributionPackage.getSize();
+ DistributionPackageUtils.mergeQueueEntry(distributionPackage.getInfo(), queueEntry);
final DistributionRequestType requestType = distributionPackage.getInfo().getRequestType();
- final long packageSize = distributionPackage.getSize();
final String[] paths = distributionPackage.getInfo().getPaths();
- DistributionPackageUtils.mergeQueueEntry(distributionPackage.getInfo(), queueEntry);
-
try {
distributionPackageImporter.importPackage(agentResourceResolver, distributionPackage);
generatePackageEvent(DistributionEventTopics.AGENT_PACKAGE_DISTRIBUTED, distributionPackage);
@@ -668,7 +666,8 @@ public class SimpleDistributionAgent imp
final long endTime = System.currentTimeMillis();
- log.debug("PACKAGE-QUEUED {}: packageId={}, queueTime={}ms, responses={}", requestId, distributionPackage.getId(), endTime - startTime, responses.size());
+ log.debug("PACKAGE-QUEUED {}: packageId={}, paths={}, queueTime={}ms, responses={}", requestId, distributionPackage.getId(),
+ distributionPackage.getInfo().getPaths(), endTime - startTime, responses.size());
}
}
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtils.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtils.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtils.java Mon Apr 11 09:17:33 2016
@@ -19,6 +19,11 @@
package org.apache.sling.distribution.packaging.impl;
+import org.apache.jackrabbit.commons.JcrUtils;
+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.ResourceUtil;
import org.apache.sling.distribution.DistributionRequest;
import org.apache.sling.distribution.queue.DistributionQueueEntry;
import org.apache.sling.distribution.serialization.DistributionPackage;
@@ -28,8 +33,23 @@ import org.apache.sling.distribution.que
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.SequenceInputStream;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* Package related utility methods
@@ -38,6 +58,12 @@ public class DistributionPackageUtils {
private static final Logger log = LoggerFactory.getLogger(DistributionPackageUtils.class);
+ private final static String META_START = "DSTRPACKMETA";
+
+ private static Object repolock = new Object();
+
+
+
/**
* distribution package origin queue
*/
@@ -174,4 +200,90 @@ public class DistributionPackageUtils {
return deepPaths.toArray(new String[deepPaths.size()]);
}
+ public static InputStream createStreamWithHeader(DistributionPackage distributionPackage) throws IOException {
+
+ DistributionPackageInfo packageInfo = distributionPackage.getInfo();
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ Map<String, Object> headerInfo = new HashMap<String, Object>();
+ headerInfo.put(DistributionPackageInfo.PROPERTY_REQUEST_TYPE, packageInfo.getRequestType());
+ headerInfo.put(DistributionPackageInfo.PROPERTY_REQUEST_PATHS, packageInfo.getPaths());
+ writeInfo(outputStream, headerInfo);
+
+ InputStream headerStream = new ByteArrayInputStream(outputStream.toByteArray());
+ InputStream bodyStream = distributionPackage.createInputStream();
+ return new SequenceInputStream(headerStream, bodyStream);
+ }
+
+
+ public static void readInfo(InputStream inputStream, Map<String, Object> info) {
+
+ try {
+ int size = META_START.getBytes("UTF-8").length;
+ inputStream.mark(size);
+ byte[] buffer = new byte[size];
+ int bytesRead = inputStream.read(buffer, 0, size);
+ String s = new String(buffer, "UTF-8");
+
+ if (bytesRead > 0 && buffer[0] > 0 && META_START.equals(s)) {
+ ObjectInputStream stream = new ObjectInputStream(inputStream);
+ HashMap<String, Object> map = (HashMap<String, Object>) stream.readObject();
+ info.putAll(map);
+ } else {
+ inputStream.reset();
+ }
+ } catch (IOException e) {
+ log.error("Cannot read stream info", e);
+ } catch (ClassNotFoundException e) {
+ log.error("Cannot read stream info", e);
+ }
+
+ }
+
+ public static void writeInfo(OutputStream outputStream, Map<String, Object> info) {
+
+ HashMap<String, Object> map = new HashMap<String, Object>(info);
+
+
+ try {
+ outputStream.write(META_START.getBytes("UTF-8"));
+
+ ObjectOutputStream stream = new ObjectOutputStream(outputStream);
+
+ stream.writeObject(map);
+
+ } catch (IOException e) {
+ log.error("Cannot read stream info", e);
+ }
+ }
+
+
+ public static Resource getPackagesRoot(ResourceResolver resourceResolver, String packagesRootPath) throws PersistenceException {
+ Resource packagesRoot = resourceResolver.getResource(packagesRootPath);
+
+ if (packagesRoot != null) {
+ return packagesRoot;
+ }
+
+ synchronized (repolock) {
+ resourceResolver.refresh();
+ packagesRoot = ResourceUtil.getOrCreateResource(resourceResolver, packagesRootPath, "sling:Folder", "sling:Folder", true);
+ }
+
+ return packagesRoot;
+ }
+
+ public static InputStream getStream(Resource resource) throws RepositoryException {
+ Node parent = resource.adaptTo(Node.class);
+ InputStream in = parent.getProperty("bin/jcr:content/jcr:data").getBinary().getStream();
+ return in;
+ }
+
+ public static void uploadStream(Resource resource, InputStream stream) throws RepositoryException {
+ Node parent = resource.adaptTo(Node.class);
+ Node file = JcrUtils.getOrAddNode(parent, "bin", NodeType.NT_FILE);
+ Node content = JcrUtils.getOrAddNode(file, Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+ Binary binary = parent.getSession().getValueFactory().createBinary(stream);
+ content.setProperty(Property.JCR_DATA, binary);
+ }
+
}
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/exporter/AgentDistributionPackageExporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/exporter/AgentDistributionPackageExporter.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/exporter/AgentDistributionPackageExporter.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/packaging/impl/exporter/AgentDistributionPackageExporter.java Mon Apr 11 09:17:33 2016
@@ -88,6 +88,7 @@ public class AgentDistributionPackageExp
if (packageBuilder != null) {
distributionPackage = packageBuilder.getPackage(resourceResolver, queueItem.getId());
+ distributionPackage.getInfo().putAll(info);
log.debug("item {} fetched from the queue", info);
if (distributionPackage != null) {
@@ -113,7 +114,8 @@ public class AgentDistributionPackageExp
log.debug("getting package from queue {}", queueName);
DistributionQueue queue = agent.getQueue(queueName);
- DistributionQueueEntry entry = queue.getHead();
+ String itemId = distributionPackageId;
+ DistributionQueueEntry entry = queue.getItem(itemId);
DistributionPackage distributionPackage;
if (entry != null) {
@@ -124,6 +126,8 @@ public class AgentDistributionPackageExp
if (packageBuilder != null) {
distributionPackage = packageBuilder.getPackage(resourceResolver, queueItem.getId());
+ distributionPackage.getInfo().putAll(info);
+
log.debug("item {} fetched from the queue", info);
if (distributionPackage != null) {
return new AgentDistributionPackage(distributionPackage, queue);
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/DistributionContentSerializer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/DistributionContentSerializer.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/DistributionContentSerializer.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/DistributionContentSerializer.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+
+/**
+ * A content serializer used to extract and import distribution packages.
+ */
+public interface DistributionContentSerializer {
+
+ /**
+ * extracts the resources identified by the given request into the given outputStream
+ * @param resourceResolver the user resource resolver
+ * @param request a distribution request
+ * @param outputStream the output stream
+ * @throws DistributionException if extraction fails for some reason
+ */
+ void exportToStream(ResourceResolver resourceResolver, DistributionRequest request, OutputStream outputStream) throws DistributionException;
+
+ /**
+ * imports the given stream
+ * @param resourceResolver the user resource resolver
+ * @param stream the stream to import
+ * @throws DistributionException if importing fails for some reason
+ */
+ void importFromStream(ResourceResolver resourceResolver, InputStream stream) throws DistributionException;
+
+ /**
+ * retrieve the name of this content serializer
+ * @return the name of this content serializer
+ */
+ String getName();
+}
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java Mon Apr 11 09:17:33 2016
@@ -24,6 +24,8 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import java.io.BufferedInputStream;
import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.distribution.DistributionRequest;
@@ -85,6 +87,9 @@ public abstract class AbstractDistributi
if (!stream.markSupported()) {
stream = new BufferedInputStream(stream);
}
+ Map<String, Object> headerInfo = new HashMap<String, Object>();
+ DistributionPackageUtils.readInfo(stream, headerInfo);
+
DistributionPackage distributionPackage = SimpleDistributionPackage.fromStream(stream, type);
stream.mark(-1);
@@ -93,6 +98,8 @@ public abstract class AbstractDistributi
if (distributionPackage == null) {
distributionPackage = readPackageInternal(resourceResolver, stream);
}
+
+ distributionPackage.getInfo().putAll(headerInfo);
return distributionPackage;
}
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DistributionPackageBuilderFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DistributionPackageBuilderFactory.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DistributionPackageBuilderFactory.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DistributionPackageBuilderFactory.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.distribution.serialization.impl;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import java.io.InputStream;
+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.PropertyOption;
+import org.apache.felix.scr.annotations.Reference;
+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.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.component.impl.DistributionComponentConstants;
+import org.apache.sling.distribution.component.impl.SettingsUtils;
+import org.apache.sling.distribution.serialization.DistributionPackage;
+import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+
+/**
+ * A factory for package builders
+ */
+@Component(metatype = true,
+ label = "Apache Sling Distribution Packaging - Package Builder Factory",
+ description = "OSGi configuration for package builders",
+ configurationFactory = true,
+ specVersion = "1.1",
+ policy = ConfigurationPolicy.REQUIRE
+)
+@Service(DistributionPackageBuilder.class)
+@Property(name = "webconsole.configurationFactory.nameHint", value = "Builder name: {name}")
+public class DistributionPackageBuilderFactory implements DistributionPackageBuilder {
+
+ /**
+ * name of this package builder.
+ */
+ @Property(label = "Name", description = "The name of the package builder.")
+ private static final String NAME = DistributionComponentConstants.PN_NAME;
+
+ /**
+ * type of this package builder.
+ */
+ @Property(options = {
+ @PropertyOption(name = "resource",
+ value = "resource packages"
+ ),
+ @PropertyOption(name = "file",
+ value = "file packages"
+ )},
+ value = "resource", label = "type", description = "The persistence type used by this package builder")
+ private static final String PERSISTENCE = DistributionComponentConstants.PN_TYPE;
+
+ @Property(name = "format.target", label = "Content Serializer", description = "The target reference for the DistributionSerializationFormat used to (de)serialize packages, " +
+ "e.g. use target=(name=...) to bind to services by name.", value = SettingsUtils.COMPONENT_NAME_DEFAULT)
+ @Reference(name = "format")
+ private DistributionContentSerializer contentSerializer;
+
+
+ /**
+ * Temp file folder
+ */
+ @Property(label = "Temp Filesystem Folder", description = "The filesystem folder where the temporary files should be saved.")
+ private static final String TEMP_FS_FOLDER = "tempFsFolder";
+
+ private DistributionPackageBuilder packageBuilder;
+
+ @Activate
+ public void activate(Map<String, Object> config) {
+
+ String persistenceType = PropertiesUtil.toString(config.get(PERSISTENCE), null);
+ String tempFsFolder = SettingsUtils.removeEmptyEntry(PropertiesUtil.toString(config.get(TEMP_FS_FOLDER), null));
+
+
+ if ("file".equals(persistenceType)) {
+ packageBuilder = new FileDistributionPackageBuilder(contentSerializer.getName(), contentSerializer, tempFsFolder);
+ } else {
+ packageBuilder = new ResourceDistributionPackageBuilder(contentSerializer.getName(), contentSerializer, tempFsFolder);
+ }
+
+
+ }
+
+ public String getType() {
+ return packageBuilder.getType();
+ }
+
+ @Nonnull
+ public DistributionPackage createPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionRequest request) throws DistributionException {
+ return packageBuilder.createPackage(resourceResolver, request);
+ }
+
+ @Nonnull
+ public DistributionPackage readPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull InputStream stream) throws DistributionException {
+ return packageBuilder.readPackage(resourceResolver, stream);
+ }
+
+ @CheckForNull
+ public DistributionPackage getPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull String id) throws DistributionException {
+ return packageBuilder.getPackage(resourceResolver, id);
+ }
+
+ public boolean installPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionPackage distributionPackage) throws DistributionException {
+ return packageBuilder.installPackage(resourceResolver, distributionPackage);
+ }
+}
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackage.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,104 @@
+/*
+ * 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;
+
+import javax.annotation.Nonnull;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.sling.distribution.DistributionRequestType;
+import org.apache.sling.distribution.serialization.DistributionPackage;
+import org.apache.sling.distribution.serialization.DistributionPackageInfo;
+
+/**
+ * A {@link DistributionPackage} based on a {@link File}.
+ */
+public class FileDistributionPackage implements DistributionPackage {
+
+ private final File file;
+ private final String type;
+ private final DistributionPackageInfo info;
+
+ public FileDistributionPackage(@Nonnull File file, @Nonnull String type) {
+ this.info = new DistributionPackageInfo(type);
+ this.file = file;
+ this.type = type;
+
+ this.getInfo().put(DistributionPackageInfo.PROPERTY_REQUEST_TYPE, DistributionRequestType.ADD);
+ }
+
+ @Nonnull
+ public String getId() {
+ return file.getAbsolutePath();
+ }
+
+ @Nonnull
+ public String getType() {
+ return type;
+ }
+
+ @Nonnull
+ public InputStream createInputStream() throws IOException {
+ return new PackageInputStream(file);
+ }
+
+ @Override
+ public long getSize() {
+ return file.length();
+ }
+
+ public void close() {
+ // do nothing
+ }
+
+ public void delete() {
+ assert file.delete();
+ }
+
+ @Nonnull
+ @Override
+ public DistributionPackageInfo getInfo() {
+ return info;
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+
+ public class PackageInputStream extends BufferedInputStream {
+ private final File file;
+
+ public PackageInputStream(File file) throws IOException {
+ super(FileUtils.openInputStream(file));
+
+ this.file = file;
+ }
+
+
+ public File getFile() {
+ return file;
+ }
+ }
+
+}
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackageBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackageBuilder.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackageBuilder.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/FileDistributionPackageBuilder.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.DistributionPackage;
+import org.apache.sling.distribution.serialization.impl.vlt.VltUtils;
+
+import javax.annotation.Nonnull;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+public class FileDistributionPackageBuilder extends AbstractDistributionPackageBuilder {
+
+ private final File tempDirectory;
+ private final DistributionContentSerializer distributionContentSerializer;
+
+ public FileDistributionPackageBuilder(String type, DistributionContentSerializer distributionContentSerializer, String tempFilesFolder) {
+ super(type);
+ this.distributionContentSerializer = distributionContentSerializer;
+ this.tempDirectory = VltUtils.getTempFolder(tempFilesFolder);
+
+ }
+
+ @Override
+ protected DistributionPackage createPackageForAdd(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionRequest request) throws DistributionException {
+ DistributionPackage distributionPackage;
+ OutputStream outputStream = null;
+
+ try {
+ File file = File.createTempFile("distrpck-create-" + System.nanoTime(), "." + getType(), tempDirectory);
+ outputStream = new BufferedOutputStream(new FileOutputStream(file));
+
+ distributionContentSerializer.exportToStream(resourceResolver, request, outputStream);
+ outputStream.flush();
+
+ distributionPackage = new FileDistributionPackage(file, getType());
+ } catch (IOException e) {
+ throw new DistributionException(e);
+ } finally {
+ IOUtils.closeQuietly(outputStream);
+ }
+
+ return distributionPackage;
+ }
+
+ @Override
+ protected DistributionPackage readPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull InputStream stream)
+ throws DistributionException {
+ DistributionPackage distributionPackage;
+
+ OutputStream outputStream = null;
+ try {
+ File file = File.createTempFile("distrpck-read-" + System.nanoTime(), "." + getType(), tempDirectory);
+ outputStream = new BufferedOutputStream(new FileOutputStream(file));
+
+ IOUtils.copy(stream, outputStream);
+ outputStream.flush();
+
+ distributionPackage = new FileDistributionPackage(file, getType());
+ } catch (Exception e) {
+ throw new DistributionException(e);
+ } finally {
+ IOUtils.closeQuietly(outputStream);
+ }
+
+ return distributionPackage;
+ }
+
+ @Override
+ protected boolean installPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionPackage distributionPackage)
+ throws DistributionException {
+ InputStream inputStream = null;
+ try {
+ inputStream = distributionPackage.createInputStream();
+ distributionContentSerializer.importFromStream(resourceResolver, inputStream);
+ return true;
+ } catch (IOException e) {
+ throw new DistributionException(e);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
+ @Override
+ protected DistributionPackage getPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull String id) {
+ return new FileDistributionPackage(new File(id), getType());
+ }
+}
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackage.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackage.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackage.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackage.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,105 @@
+/*
+ * 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;
+
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+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.DistributionRequestType;
+import org.apache.sling.distribution.packaging.impl.DistributionPackageUtils;
+import org.apache.sling.distribution.serialization.DistributionPackage;
+import org.apache.sling.distribution.serialization.DistributionPackageInfo;
+
+/**
+ * {@link Resource} based {@link DistributionPackage}
+ */
+public class ResourceDistributionPackage implements DistributionPackage {
+
+ private final String type;
+ private final Resource resource;
+ private final ResourceResolver resourceResolver;
+ private final DistributionPackageInfo info;
+
+ ResourceDistributionPackage(Resource resource, String type, ResourceResolver resourceResolver) {
+ this.info = new DistributionPackageInfo(type);
+ this.resourceResolver = resourceResolver;
+ this.type = type;
+ ValueMap valueMap = resource.getValueMap();
+ assert type.equals(valueMap.get("type")) : "wrong resource type";
+ this.resource = resource;
+
+ this.getInfo().put(DistributionPackageInfo.PROPERTY_REQUEST_TYPE, DistributionRequestType.ADD);
+ }
+
+ @Nonnull
+ @Override
+ public String getId() {
+ return resource.getPath();
+ }
+
+ @Nonnull
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ @Nonnull
+ @Override
+ public InputStream createInputStream() throws IOException {
+ try {
+ return new BufferedInputStream(DistributionPackageUtils.getStream(resource));
+ } catch (RepositoryException e) {
+ throw new IOException("Cannot create stream", e);
+ }
+ }
+
+ @Override
+ public long getSize() {
+ Object size = resource.getValueMap().get("size");
+ return size == null ? -1 : Long.parseLong(size.toString());
+ }
+
+ @Override
+ public void close() {
+ // do nothing
+ }
+
+ @Override
+ public void delete() {
+ try {
+ resourceResolver.delete(resource);
+ resourceResolver.commit();
+ } catch (PersistenceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Nonnull
+ @Override
+ public DistributionPackageInfo getInfo() {
+ return info;
+ }
+}
\ No newline at end of file
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackageBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackageBuilder.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackageBuilder.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/ResourceDistributionPackageBuilder.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,162 @@
+/*
+ * 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;
+
+import org.apache.commons.io.FileUtils;
+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.distribution.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.packaging.impl.DistributionPackageUtils;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.DistributionPackage;
+import org.apache.sling.distribution.serialization.impl.vlt.VltUtils;
+
+import javax.annotation.Nonnull;
+import javax.jcr.RepositoryException;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+
+public class ResourceDistributionPackageBuilder extends AbstractDistributionPackageBuilder {
+ private static final String PREFIX_PATH = "/var/sling/distribution/packages/";
+
+ private final String packagesPath;
+ private final File tempDirectory;
+ private final DistributionContentSerializer distributionContentSerializer;
+
+ public ResourceDistributionPackageBuilder(String type, DistributionContentSerializer distributionContentSerializer, String tempFilesFolder) {
+ super(type);
+ this.distributionContentSerializer = distributionContentSerializer;
+ this.packagesPath = PREFIX_PATH + type + "/data";
+ this.tempDirectory = VltUtils.getTempFolder(tempFilesFolder);
+
+ }
+
+ @Override
+ protected DistributionPackage createPackageForAdd(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionRequest request) throws DistributionException {
+ DistributionPackage distributionPackage;
+ // TODO : write to file if size > threshold
+
+ File file = null;
+ try {
+ file = File.createTempFile("distrpck-create-" + System.nanoTime(), "." + getType(), tempDirectory);
+
+ OutputStream outputStream = null;
+
+ try {
+ outputStream = new BufferedOutputStream(new FileOutputStream(file));
+ distributionContentSerializer.exportToStream(resourceResolver, request, outputStream);
+ outputStream.flush();
+ } finally {
+ IOUtils.closeQuietly(outputStream);
+ }
+
+
+ Resource packagesRoot = DistributionPackageUtils.getPackagesRoot(resourceResolver, packagesPath);
+
+ InputStream inputStream = null;
+ Resource packageResource = null;
+
+ try {
+ inputStream = new BufferedInputStream(new FileInputStream(file));
+
+ packageResource = uploadStream(packagesRoot, inputStream, file.length());
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+
+ distributionPackage = new ResourceDistributionPackage(packageResource, getType(), resourceResolver);
+ } catch (IOException e) {
+ throw new DistributionException(e);
+ } finally {
+ FileUtils.deleteQuietly(file);
+ }
+ return distributionPackage;
+ }
+
+ @Override
+ protected DistributionPackage readPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull InputStream inputStream)
+ throws DistributionException {
+ try {
+ Resource packagesRoot = DistributionPackageUtils.getPackagesRoot(resourceResolver, packagesPath);
+
+ Resource packageResource = uploadStream(packagesRoot, inputStream, -1);
+ return new ResourceDistributionPackage(packageResource, getType(), resourceResolver);
+ } catch (PersistenceException e) {
+ throw new DistributionException(e);
+ }
+ }
+
+ @Override
+ protected boolean installPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull DistributionPackage distributionPackage)
+ throws DistributionException {
+ InputStream inputStream = null;
+ try {
+ inputStream = distributionPackage.createInputStream();
+ distributionContentSerializer.importFromStream(resourceResolver, inputStream);
+ return true;
+ } catch (IOException e) {
+ throw new DistributionException(e);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
+ @Override
+ protected DistributionPackage getPackageInternal(@Nonnull ResourceResolver resourceResolver, @Nonnull String id) {
+ return new ResourceDistributionPackage(resourceResolver.getResource(id), getType(), resourceResolver);
+ }
+
+
+ Resource uploadStream(Resource parent, InputStream stream, long size) throws PersistenceException {
+ String name = "dstrpck-" + System.currentTimeMillis() + "-" + UUID.randomUUID().toString();
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, "sling:Folder");
+ props.put("type", getType());
+
+ if (size != -1) {
+ props.put("size", size);
+ }
+
+ Resource resource = parent.getResourceResolver().create(parent, name, props);
+ try {
+ DistributionPackageUtils.uploadStream(resource, stream);
+ } catch (RepositoryException e) {
+ throw new PersistenceException("cannot upload stream", e);
+
+ }
+
+ parent.getResourceResolver().commit();
+
+ return resource;
+ }
+}
Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultContentSerializer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultContentSerializer.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultContentSerializer.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/FileVaultContentSerializer.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,174 @@
+/*
+ * 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.vlt;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.vault.fs.api.ImportMode;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.io.AccessControlHandling;
+import org.apache.jackrabbit.vault.fs.io.ImportOptions;
+import org.apache.jackrabbit.vault.packaging.ExportOptions;
+import org.apache.jackrabbit.vault.packaging.PackageManager;
+import org.apache.jackrabbit.vault.packaging.Packaging;
+import org.apache.jackrabbit.vault.packaging.VaultPackage;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+import org.apache.sling.distribution.serialization.impl.FileDistributionPackage;
+import org.apache.sling.distribution.util.DistributionJcrUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@link DistributionContentSerializer} based on Apache Jackrabbit FileVault
+ */
+public class FileVaultContentSerializer implements DistributionContentSerializer {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ static final String TYPE = "filevault";
+ private static final String VERSION = "0.0.1";
+ private static final String PACKAGE_GROUP = "sling/distribution";
+
+ private final Packaging packaging;
+ private final ImportMode importMode;
+ private final AccessControlHandling aclHandling;
+ private final String[] packageRoots;
+ private final int autosaveThreshold;
+ private final TreeMap<String, List<String>> filters;
+ private final boolean useBinaryReferences;
+ private final String name;
+
+ public FileVaultContentSerializer(String name, Packaging packaging, ImportMode importMode, AccessControlHandling aclHandling, String[] packageRoots,
+ String[] filters, boolean useBinaryReferences, int autosaveThreshold) {
+ this.name = name;
+ this.packaging = packaging;
+ this.importMode = importMode;
+ this.aclHandling = aclHandling;
+ this.packageRoots = packageRoots;
+ this.autosaveThreshold = autosaveThreshold;
+ this.filters = VltUtils.parseFilters(filters);;
+ this.useBinaryReferences = useBinaryReferences;
+ }
+
+ @Override
+ public void exportToStream(ResourceResolver resourceResolver, DistributionRequest request, OutputStream outputStream) throws DistributionException {
+ Session session = null;
+ try {
+ session = getSession(resourceResolver);
+ String packageGroup = PACKAGE_GROUP;
+ String packageName = TYPE + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID();
+
+ WorkspaceFilter filter = VltUtils.createFilter(request, filters);
+ ExportOptions opts = VltUtils.getExportOptions(filter, packageRoots, packageGroup, packageName, VERSION, useBinaryReferences);
+
+ log.debug("assembling package {} user {}", packageGroup + '/' + packageName + "-" + VERSION, resourceResolver.getUserID());
+
+ packaging.getPackageManager().assemble(session, opts, outputStream);
+ } catch (Exception e) {
+ throw new DistributionException(e);
+ } finally {
+ ungetSession(session);
+ }
+
+ }
+
+ @Override
+ public void importFromStream(ResourceResolver resourceResolver, InputStream inputStream) throws DistributionException {
+
+ Session session = null;
+ OutputStream outputStream = null;
+ File file = null;
+ boolean isTmp = true;
+ try {
+ session = getSession(resourceResolver);
+ ImportOptions importOptions = VltUtils.getImportOptions(aclHandling, importMode, autosaveThreshold);
+
+
+ if (inputStream instanceof FileDistributionPackage.PackageInputStream) {
+ file = ((FileDistributionPackage.PackageInputStream) inputStream).getFile();
+ isTmp = false;
+ } else {
+ file = File.createTempFile("distrpck-tmp-" + System.nanoTime(), "." + TYPE);
+ }
+
+ outputStream = new BufferedOutputStream(new FileOutputStream(file));
+
+ IOUtils.copy(inputStream, outputStream);
+ IOUtils.closeQuietly(outputStream);
+
+ PackageManager packageManager = packaging.getPackageManager();
+ VaultPackage vaultPackage = packageManager.open(file);
+
+ vaultPackage.extract(session, importOptions);
+
+ vaultPackage.close();
+ } catch (Exception e) {
+ throw new DistributionException(e);
+ } finally {
+ IOUtils.closeQuietly(outputStream);
+ if (isTmp) {
+ FileUtils.deleteQuietly(file);
+ }
+
+ ungetSession(session);
+ }
+
+ }
+
+ protected Session getSession(ResourceResolver resourceResolver) throws RepositoryException {
+ Session session = resourceResolver.adaptTo(Session.class);
+ if (session != null) {
+ DistributionJcrUtils.setDoNotDistribute(session);
+ } else {
+ throw new RepositoryException("could not obtain a session from calling user " + resourceResolver.getUserID());
+ }
+ return session;
+ }
+
+ protected void ungetSession(Session session) {
+ if (session != null) {
+ try {
+ if (session.hasPendingChanges()) {
+ session.save();
+ }
+ } catch (RepositoryException e) {
+ log.error("Cannot save session", e);
+ }
+ }
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+}
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/VaultDistributionPackageBuilderFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/VaultDistributionPackageBuilderFactory.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/VaultDistributionPackageBuilderFactory.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/VaultDistributionPackageBuilderFactory.java Mon Apr 11 09:17:33 2016
@@ -36,12 +36,14 @@ import org.apache.jackrabbit.vault.packa
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.distribution.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.component.impl.DistributionComponentConstants;
import org.apache.sling.distribution.component.impl.SettingsUtils;
-import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
import org.apache.sling.distribution.serialization.DistributionPackage;
import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
-import org.apache.sling.distribution.serialization.impl.DefaultSharedDistributionPackageBuilder;
+import org.apache.sling.distribution.serialization.impl.FileDistributionPackageBuilder;
+import org.apache.sling.distribution.serialization.impl.ResourceDistributionPackageBuilder;
/**
* A package builder for Apache Jackrabbit FileVault based implementations.
@@ -147,10 +149,13 @@ public class VaultDistributionPackageBui
aclHandling = AccessControlHandling.valueOf(aclHandlingString.trim());
}
+ DistributionContentSerializer contentSerializer = new FileVaultContentSerializer(name, packaging, importMode, aclHandling,
+ packageRoots, packageFilters, useBinaryReferences, autosaveThreshold);
+
if ("filevlt".equals(type)) {
- packageBuilder = new FileVaultDistributionPackageBuilder(name, packaging, importMode, aclHandling, packageRoots, packageFilters, tempFsFolder, useBinaryReferences, autosaveThreshold);
+ packageBuilder = new FileDistributionPackageBuilder(name, contentSerializer, tempFsFolder);
} else {
- packageBuilder = new JcrVaultDistributionPackageBuilder(name, packaging, importMode, aclHandling, packageRoots, packageFilters, tempFsFolder, useBinaryReferences, autosaveThreshold);
+ packageBuilder = new ResourceDistributionPackageBuilder(name, contentSerializer, tempFsFolder);
}
}
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageExporterServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageExporterServlet.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageExporterServlet.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageExporterServlet.java Mon Apr 11 09:17:33 2016
@@ -33,6 +33,7 @@ import org.apache.sling.api.servlets.Sli
import org.apache.sling.distribution.DistributionRequest;
import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.packaging.DistributionPackageProcessor;
+import org.apache.sling.distribution.packaging.impl.DistributionPackageUtils;
import org.apache.sling.distribution.serialization.DistributionPackage;
import org.apache.sling.distribution.packaging.DistributionPackageExporter;
import org.apache.sling.distribution.resources.DistributionResourceTypes;
@@ -103,7 +104,7 @@ public class DistributionPackageExporter
try {
response.addHeader(HttpTransportUtils.HEADER_DISTRIBUTION_ORIGINAL_ID, distributionPackage.getId());
- inputStream = distributionPackage.createInputStream();
+ inputStream = DistributionPackageUtils.createStreamWithHeader(distributionPackage);
bytesCopied = IOUtils.copy(inputStream, response.getOutputStream());
} catch (IOException e) {
Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java Mon Apr 11 09:17:33 2016
@@ -30,8 +30,6 @@ import java.util.UUID;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
@@ -43,6 +41,7 @@ import org.apache.sling.distribution.Dis
import org.apache.sling.distribution.common.DistributionException;
import org.apache.sling.distribution.common.RecoverableDistributionException;
import org.apache.sling.distribution.log.impl.DefaultDistributionLog;
+import org.apache.sling.distribution.packaging.impl.DistributionPackageUtils;
import org.apache.sling.distribution.serialization.DistributionPackage;
import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
import org.apache.sling.distribution.transport.DistributionTransportSecret;
@@ -96,7 +95,7 @@ public class SimpleHttpDistributionTrans
InputStream inputStream = null;
try {
- inputStream = distributionPackage.createInputStream();
+ inputStream = DistributionPackageUtils.createStreamWithHeader(distributionPackage);
req = req.bodyStream(inputStream, ContentType.APPLICATION_OCTET_STREAM);
Added: sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtilsTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtilsTest.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtilsTest.java (added)
+++ sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/packaging/impl/DistributionPackageUtilsTest.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,106 @@
+/*
+ * 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.packaging.impl;
+
+import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.junit.Test;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class DistributionPackageUtilsTest {
+
+
+ @Test
+ public void testInfoEmptyStreams(){
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ Map<String, Object> info = new HashMap<String, Object>();
+ DistributionPackageUtils.writeInfo(outputStream, info);
+
+ InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+
+ Map<String, Object> resultInfo = new HashMap<String, Object>();
+ DistributionPackageUtils.readInfo(inputStream, resultInfo);
+
+ assertEquals(info.size(), resultInfo.size());
+
+ }
+
+
+ @Test
+ public void testInfoFullStreams(){
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ Map<String, Object> info = new HashMap<String, Object>();
+ info.put("test1", "value1");
+ info.put("test2", "value2");
+ info.put("test3", new String[] { "value1", "value2" });
+
+ DistributionPackageUtils.writeInfo(outputStream, info);
+
+ InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+
+ Map<String, Object> resultInfo = new HashMap<String, Object>();
+ DistributionPackageUtils.readInfo(inputStream, resultInfo);
+
+ assertEquals(info.size(), resultInfo.size());
+ assertEquals("value1", resultInfo.get("test1"));
+ assertEquals("value2", resultInfo.get("test2"));
+ String[] array = (String[]) resultInfo.get("test3");
+
+ assertEquals("value1", array[0]);
+ assertEquals("value2", array[1]);
+ }
+
+
+ @Test
+ public void testStreamsWithoutInfo() throws IOException {
+
+ byte[] bytes =new byte[100];
+ for (int i=0; i< bytes.length; i++) {
+ bytes[i] = (byte) i;
+ }
+
+ InputStream inputStream = new BufferedInputStream(new ByteArrayInputStream(bytes));
+
+ Map<String, Object> resultInfo = new HashMap<String, Object>();
+ DistributionPackageUtils.readInfo(inputStream, resultInfo);
+
+ assertEquals(0, resultInfo.size());
+
+ byte[] resultBytes = new byte[100];
+
+ inputStream.read(resultBytes, 0, 100);
+
+ assertEquals(-1, inputStream.read());
+
+ for (int i=0; i < bytes.length; i++) {
+ assertEquals((byte)i, resultBytes[i]);
+ }
+
+ }
+}
Modified: sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/SimpleDistributionPackageTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/SimpleDistributionPackageTest.java?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/SimpleDistributionPackageTest.java (original)
+++ sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/serialization/impl/SimpleDistributionPackageTest.java Mon Apr 11 09:17:33 2016
@@ -28,6 +28,7 @@ import org.apache.sling.distribution.Sim
import org.junit.Test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
@@ -40,6 +41,7 @@ public class SimpleDistributionPackageTe
DistributionRequest request = new SimpleDistributionRequest(DistributionRequestType.DELETE, "/abc");
SimpleDistributionPackage createdPackage = new SimpleDistributionPackage(request, "VOID");
SimpleDistributionPackage readPackage = SimpleDistributionPackage.fromStream(new ByteArrayInputStream(("DSTRPCK:DELETE|/abc").getBytes()), "VOID");
+ assertNotNull(readPackage);
assertEquals(createdPackage.getType(), readPackage.getType());
assertEquals(createdPackage.getInfo().getRequestType(), readPackage.getInfo().getRequestType());
assertEquals(Arrays.toString(createdPackage.getInfo().getPaths()), Arrays.toString(readPackage.getInfo().getPaths()));
Modified: sling/trunk/contrib/extensions/distribution/extensions/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/extensions/pom.xml?rev=1738558&r1=1738557&r2=1738558&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/distribution/extensions/pom.xml (original)
+++ sling/trunk/contrib/extensions/distribution/extensions/pom.xml Mon Apr 11 09:17:33 2016
@@ -188,7 +188,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.distribution.core</artifactId>
- <version>0.1.15-SNAPSHOT</version>
+ <version>0.1.17-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
Added: sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java (added)
+++ sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroContentSerializer.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,253 @@
+/*
+ * 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.Collections;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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.jackrabbit.JcrConstants;
+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.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+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 DataFileWriter<AvroShallowResource> dataFileWriter;
+ private final Schema schema;
+ private final Set<String> ignoredProperties;
+ private final Set<String> ignoredNodeNames;
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.sss+hh:mm");
+
+ public AvroContentSerializer(String name) {
+ DatumWriter<AvroShallowResource> datumWriter = new SpecificDatumWriter<AvroShallowResource>(AvroShallowResource.class);
+ this.dataFileWriter = new DataFileWriter<AvroShallowResource>(datumWriter);
+ try {
+ schema = new Schema.Parser().parse(getClass().getResourceAsStream("/shallowresource.avsc"));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ Set<String> iProps = new HashSet<String>();
+ iProps.add(JcrConstants.JCR_FROZENMIXINTYPES);
+ iProps.add(JcrConstants.JCR_FROZENPRIMARYTYPE);
+ iProps.add(JcrConstants.JCR_FROZENUUID);
+ iProps.add(JcrConstants.JCR_VERSIONHISTORY);
+ iProps.add(JcrConstants.JCR_BASEVERSION);
+ iProps.add(JcrConstants.JCR_PREDECESSORS);
+ iProps.add(JcrConstants.JCR_SUCCESSORS);
+ iProps.add(JcrConstants.JCR_ISCHECKEDOUT);
+ iProps.add(JcrConstants.JCR_UUID);
+ ignoredProperties = Collections.unmodifiableSet(iProps);
+
+ Set<String> iNames = new HashSet<String>();
+ iNames.add("rep:policy");
+ ignoredNodeNames = Collections.unmodifiableSet(iNames);
+ this.name = name;
+ }
+
+ @Override
+ public void exportToStream(ResourceResolver resourceResolver, DistributionRequest request, OutputStream outputStream) throws DistributionException {
+
+ DataFileWriter<AvroShallowResource> writer;
+ try {
+ writer = dataFileWriter.create(schema, outputStream);
+ } catch (IOException e) {
+ throw new DistributionException(e);
+ }
+
+ try {
+
+ for (String path : request.getPaths()) {
+ Resource resource = resourceResolver.getResource(path);
+ AvroShallowResource avroShallowResource = getAvroShallowResource(request.isDeep(path), path, resource);
+ writer.append(avroShallowResource);
+ }
+ outputStream.flush();
+
+ } catch (Exception e) {
+ throw new DistributionException(e);
+ } finally {
+ try {
+ outputStream.close();
+ 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;
+ }
+
+ private AvroShallowResource getAvroShallowResource(boolean deep, String path, Resource resource) throws IOException {
+ AvroShallowResource avroShallowResource = new AvroShallowResource();
+ avroShallowResource.setName("avro_" + System.nanoTime());
+ avroShallowResource.setPath(path);
+ avroShallowResource.setResourceType(resource.getResourceType());
+ ValueMap valueMap = resource.getValueMap();
+ Map<CharSequence, Object> map = new HashMap<CharSequence, Object>();
+ for (Map.Entry<String, Object> entry : valueMap.entrySet()) {
+ if (!ignoredProperties.contains(entry.getKey())) {
+ 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(entry.getKey(), value);
+ }
+ }
+ avroShallowResource.setValueMap(map);
+ List<AvroShallowResource> children = new LinkedList<AvroShallowResource>();
+ if (deep) {
+ for (Resource child : resource.getChildren()) {
+ String childPath = child.getPath();
+ if (!ignoredNodeNames.contains(child.getName())) {
+ children.add(getAvroShallowResource(true, childPath, 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);
+ AvroShallowResource avroResource = null;
+ Collection<AvroShallowResource> avroResources = new LinkedList<AvroShallowResource>();
+ while (dataFileReader.hasNext()) {
+// Reuse avroResource object by passing it to next(). This saves us from
+// allocating and garbage collecting many objects for files with
+// many items.
+ avroResource = dataFileReader.next(avroResource);
+ avroResources.add(avroResource);
+ }
+ 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.info("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);
+ }
+}
Added: sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java?rev=1738558&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java (added)
+++ sling/trunk/contrib/extensions/distribution/extensions/src/main/java/org/apache/sling/distribution/serialization/impl/avro/AvroDistributionContentSerializerFactory.java Mon Apr 11 09:17:33 2016
@@ -0,0 +1,86 @@
+/*
+ * 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.DistributionRequest;
+import org.apache.sling.distribution.common.DistributionException;
+import org.apache.sling.distribution.serialization.DistributionContentSerializer;
+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 serialization formats",
+ configurationFactory = true,
+ specVersion = "1.1",
+ policy = ConfigurationPolicy.REQUIRE
+)
+@Service(DistributionContentSerializer.class)
+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);
+ log.info("starting avro format {}", name);
+
+ format = new AvroContentSerializer(name);
+ log.info("started avro resource package builder");
+ }
+
+
+ @Override
+ public void exportToStream(ResourceResolver resourceResolver, DistributionRequest request, OutputStream outputStream) throws DistributionException {
+ format.exportToStream(resourceResolver, request, outputStream);
+ }
+
+ @Override
+ public void importFromStream(ResourceResolver resourceResolver, InputStream stream) throws DistributionException {
+ format.importFromStream(resourceResolver, stream);
+ }
+
+ @Override
+ public String getName() {
+ return format.getName();
+ }
+}