Author: tommaso
Date: Fri Dec 5 09:19:24 2014
New Revision: 1643201
URL: http://svn.apache.org/viewvc?rev=1643201&view=rev
Log:
SLING-4153 - fixed transport API to just expose the secret
Added:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java
(with props)
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java
(with props)
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java
(with props)
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java
(with props)
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.osgi.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
Added:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java
(added)
+++
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,56 @@
+/*
+ * 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.transport;
+
+import javax.annotation.CheckForNull;
+import java.io.InputStream;
+import java.util.Map;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * The secret to be transported for authenticating transport layer connecting
two instances.
+ * <p/>
+ * Secrets can take different forms, like e.g. username and password, tokens,
public keys, etc. and are meant to be used
+ * by transport implementations lying under {@link
org.apache.sling.distribution.packaging.DistributionPackageImporter importers}
+ * and / or {@link
org.apache.sling.distribution.packaging.DistributionPackageExporter exporters}.
+ */
+@ConsumerType
+public interface DistributionTransportSecret {
+
+ /**
+ * Get the secret as a {@link java.util.Map} of credentials, this can
contain, for example, entries holding information
+ * about username and password for HTTP authentication.
+ *
+ * @return the credentials as a {@link java.util.Map}, or {@code null} if
{@code secret} cannot be represented in terms
+ * of a set of key -> value entries
+ */
+ @CheckForNull
+ Map<String, String> asCredentialsMap();
+
+ /**
+ * Get the secrete as a raw {@link java.io.InputStream binary}.
+ * Note that each call to this method will create a new stream, so the
caller will be responsible of closing it.
+ *
+ * @return the secret as an {@link java.io.InputStream}, or {@code null}
if such a secret cannot represented as a stream.
+ */
+ @CheckForNull
+ InputStream asStream();
+
+}
Propchange:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecret.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java
(added)
+++
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,44 @@
+/*
+ * 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.transport;
+
+import javax.annotation.CheckForNull;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * A provider for {@link
org.apache.sling.distribution.transport.DistributionTransportSecret}s
+ * <p/>
+ * Such providers can be used by {@link
org.apache.sling.distribution.packaging.DistributionPackageExporter exporters}
or
+ * {@link org.apache.sling.distribution.packaging.DistributionPackageImporter
importers} implementations in order to plug
+ * in different types of {@link
org.apache.sling.distribution.transport.DistributionTransportSecret secrets} to
be used
+ * to authenticate the underlying Sling instances.
+ */
+@ConsumerType
+public interface DistributionTransportSecretProvider {
+
+ /**
+ * Get a {@link
org.apache.sling.distribution.transport.DistributionTransportSecret}
+ *
+ * @return a {@link
org.apache.sling.distribution.transport.DistributionTransportSecret secret}, or
{@code null} if
+ * that cannot be obtained
+ */
+ @CheckForNull
+ DistributionTransportSecret getSecret();
+}
Propchange:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/DistributionTransportSecretProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java
(added)
+++
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+@Version("0.1.0")
+package org.apache.sling.distribution.transport;
+
+import aQute.bnd.annotation.Version;
+
Propchange:
sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/transport/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,67 @@
+/*
+ * 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.transport;
+
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.communication.DistributionRequest;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+
+/**
+ * A transport layer implementation to transport data between two (or
eventually more) Sling instances.
+ * <p/>
+ * Each implementation is meant to be stateful in the sense that it will hide
the details about the sending / receiving
+ * endpoints of the transport.
+ */
+public interface DistributionTransport {
+
+ /**
+ * Deliver a {@link
org.apache.sling.distribution.packaging.DistributionPackage} to a target
instance using this
+ * transport layer implementation.
+ *
+ * @param resourceResolver a resolver used to eventually access local
resources needed by the transport algorithm
+ * @param distributionPackage a {@link
org.apache.sling.distribution.packaging.DistributionPackage} to transport
+ * @param secret the {@link
org.apache.sling.distribution.transport.DistributionTransportSecret} used to
authenticate
+ * against the target instance according to an
authentication algorithm implemented by the transport.
+ * @throws DistributionTransportException if the {@link
org.apache.sling.distribution.packaging.DistributionPackage}
+ * fails to be delivered to the
target instance (e.g. because of network, I/O issues)
+ */
+ void deliverPackage(@Nonnull ResourceResolver resourceResolver, @Nonnull
DistributionPackage
+ distributionPackage, @Nonnull DistributionTransportSecret secret)
throws DistributionTransportException;
+
+ /**
+ * Retrieve {@link
org.apache.sling.distribution.packaging.DistributionPackage}s from a target
Sling instance, which
+ * will create them according to {@link
org.apache.sling.distribution.communication.DistributionRequest}.
+ *
+ * @param resourceResolver a resolver used to eventually access local
resources needed by the transport algorithm
+ * @param request a {@link
org.apache.sling.distribution.communication.DistributionRequest} to be
forwarded to the target
+ * instance
+ * @param secret the {@link
org.apache.sling.distribution.transport.DistributionTransportSecret} used to
authenticate
+ * against the target instance according to an
authentication algorithm implemented by the transport.
+ * @return an {@link java.lang.Iterable} of {@link
org.apache.sling.distribution.packaging.DistributionPackage}s fetched
+ * from the target instance.
+ * @throws DistributionTransportException if the {@link
org.apache.sling.distribution.packaging.DistributionPackage}s
+ * fail to be retrieved from the
target instance
+ */
+ @Nonnull
+ Iterable<DistributionPackage> retrievePackages(@Nonnull ResourceResolver
resourceResolver, @Nonnull DistributionRequest
+ request, @Nonnull DistributionTransportSecret secret) throws
DistributionTransportException;
+
+}
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/DistributionTransport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,180 @@
+/*
+ * 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.transport.impl;
+
+import javax.annotation.Nonnull;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.client.fluent.Content;
+import org.apache.http.client.fluent.Executor;
+import org.apache.http.client.fluent.Request;
+import org.apache.http.client.fluent.Response;
+import org.apache.http.entity.ContentType;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
+import org.apache.sling.distribution.transport.DistributionTransportException;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Advanced HTTP {@link
org.apache.sling.distribution.transport.DistributionTransport} supporting
custom HTTP headers
+ * and body.
+ */
+public class AdvancedHttpDistributionTransport extends
SimpleHttpDistributionTransport {
+
+ private static final String PATH_VARIABLE_NAME = "{path}";
+
+ private static final Logger log =
LoggerFactory.getLogger(AdvancedHttpDistributionTransport.class);
+
+ private final DistributionEndpoint distributionEndpoint;
+
+ private final boolean useCustomHeaders;
+
+ private final String[] customHeaders;
+
+ private final boolean useCustomBody;
+
+ private final String customBody;
+
+ public AdvancedHttpDistributionTransport(boolean useCustomHeaders,
+ String[] customHeaders,
+ boolean useCustomBody,
+ String customBody,
+ DistributionEndpoint
distributionEndpoint,
+ DistributionPackageBuilder
packageBuilder,
+ int maxNoOfPackages) {
+
+
+ super(distributionEndpoint, packageBuilder, maxNoOfPackages);
+ this.useCustomHeaders = useCustomHeaders;
+ this.customHeaders = customHeaders;
+ this.useCustomBody = useCustomBody;
+ this.customBody = customBody;
+
+ this.distributionEndpoint = distributionEndpoint;
+ }
+
+ @Override
+ public void deliverPackage(@Nonnull ResourceResolver resourceResolver,
@Nonnull DistributionPackage distributionPackage,
+ @Nonnull DistributionTransportSecret secret)
throws DistributionTransportException {
+ log.info("delivering package {} to {} using auth {}",
+ new Object[]{distributionPackage.getId(),
+ distributionEndpoint.getUri(), secret});
+
+ try {
+ Executor executor = authenticate(secret, Executor.newInstance());
+
+ deliverPackage(executor, distributionPackage,
distributionEndpoint);
+
+ } catch (Exception ex) {
+ throw new DistributionTransportException(ex);
+ }
+
+ }
+
+ public static String[] getCustomizedHeaders(String[] additionalHeaders,
String action, String[] paths) {
+ List<String> headers = new ArrayList<String>();
+
+ for (String additionalHeader : additionalHeaders) {
+ int idx = additionalHeader.indexOf("->");
+
+ if (idx < 0) {
+ headers.add(additionalHeader);
+ } else {
+ String actionSelector = additionalHeader.substring(0,
idx).trim();
+ String header = additionalHeader.substring(idx + 2).trim();
+
+ if (actionSelector.equalsIgnoreCase(action) ||
actionSelector.equals("*")) {
+ headers.add(header);
+ }
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+
+ if (paths != null && paths.length > 0) {
+ sb.append(paths[0]);
+ for (int i = 1; i < paths.length; i++) {
+ sb.append(", ").append(paths[i]);
+ }
+ }
+
+ String path = sb.toString();
+
+ List<String> boundHeaders = new ArrayList<String>();
+
+ for (String header : headers) {
+ boundHeaders.add(header.replace(PATH_VARIABLE_NAME, path));
+ }
+
+ return boundHeaders.toArray(new String[boundHeaders.size()]);
+ }
+
+ private void deliverPackage(Executor executor, DistributionPackage
distributionPackage,
+ DistributionEndpoint
distributionEndpoint) throws IOException {
+ String type = distributionPackage.getType();
+
+ Request req =
Request.Post(distributionEndpoint.getUri()).useExpectContinue();
+
+ if (useCustomHeaders) {
+ String[] customizedHeaders = getCustomizedHeaders(customHeaders,
distributionPackage.getInfo().getRequestType().name(),
+ distributionPackage.getInfo().getPaths());
+ for (String header : customizedHeaders) {
+ addHeader(req, header);
+ }
+ }
+
+ InputStream inputStream = null;
+ Response response = null;
+ try {
+ if (useCustomBody) {
+ String body = customBody == null ? "" : customBody;
+ inputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
+ } else {
+ inputStream = distributionPackage.createInputStream();
+ }
+
+ req = req.bodyStream(inputStream,
ContentType.APPLICATION_OCTET_STREAM);
+
+ response = executor.execute(req);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+
+ Content content = response.returnContent();
+ log.info("Distribution content of type {} for {} delivered: {}", new
Object[]{
+ type,
Arrays.toString(distributionPackage.getInfo().getPaths()), content});
+ }
+
+ private static void addHeader(Request req, String header) {
+ int idx = header.indexOf(":");
+ if (idx < 0) return;
+ String headerName = header.substring(0, idx).trim();
+ String headerValue = header.substring(idx + 1).trim();
+ req.addHeader(headerName, headerValue);
+ }
+}
\ No newline at end of file
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,92 @@
+/*
+ * 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.transport.impl;
+
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.communication.DistributionRequest;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.transport.DistributionTransport;
+import org.apache.sling.distribution.transport.DistributionTransportException;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+
+/**
+ * {@link org.apache.sling.distribution.transport.DistributionTransport}
supporting delivery / retrieval from multiple
+ * endpoints.
+ */
+public class MultipleEndpointDistributionTransport implements
DistributionTransport {
+
+ private final List<DistributionTransport> transportHelpers;
+ private final TransportEndpointStrategyType endpointStrategyType;
+ private int lastSuccessfulEndpointId = 0;
+
+ public MultipleEndpointDistributionTransport(List<DistributionTransport>
transportHelpers,
+ TransportEndpointStrategyType
endpointStrategyType) {
+ this.transportHelpers = transportHelpers;
+ this.endpointStrategyType = endpointStrategyType;
+ }
+
+ private List<DistributionPackage> doTransport(ResourceResolver
resourceResolver, DistributionRequest distributionRequest,
+ DistributionPackage
distributionPackage, DistributionTransportSecret secret) throws
DistributionTransportException {
+
+ int offset = 0;
+ if (endpointStrategyType.equals(TransportEndpointStrategyType.One)) {
+ offset = lastSuccessfulEndpointId;
+ }
+
+ int length = transportHelpers.size();
+ List<DistributionPackage> result = new
ArrayList<DistributionPackage>();
+
+ for (int i = 0; i < length; i++) {
+ int currentId = (offset + i) % length;
+
+ DistributionTransport transportHelper =
transportHelpers.get(currentId);
+ if (distributionPackage != null) {
+ transportHelper.deliverPackage(resourceResolver,
distributionPackage, secret);
+ } else if (distributionRequest != null) {
+ Iterable<DistributionPackage> distributionPackages =
transportHelper.retrievePackages(resourceResolver, distributionRequest, secret);
+ for (DistributionPackage retrievedPackage :
distributionPackages) {
+ result.add(retrievedPackage);
+ }
+ }
+
+ lastSuccessfulEndpointId = currentId;
+ if (endpointStrategyType.equals(TransportEndpointStrategyType.One))
+ break;
+ }
+
+ return result;
+ }
+
+ public void deliverPackage(@Nonnull ResourceResolver resourceResolver,
@Nonnull DistributionPackage distributionPackage,
+ @Nonnull
DistributionTransportSecret secret) throws DistributionTransportException {
+ doTransport(resourceResolver, null, distributionPackage, secret);
+ }
+
+ @Nonnull
+ public List<DistributionPackage> retrievePackages(@Nonnull
ResourceResolver resourceResolver, @Nonnull DistributionRequest
distributionRequest,
+ @Nonnull
DistributionTransportSecret secret) throws DistributionTransportException {
+ return doTransport(resourceResolver, distributionRequest, null,
secret);
+ }
+
+
+}
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
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=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,185 @@
+/*
+ * 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.transport.impl;
+
+import javax.annotation.Nonnull;
+import java.io.InputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.fluent.Content;
+import org.apache.http.client.fluent.Executor;
+import org.apache.http.client.fluent.Request;
+import org.apache.http.client.fluent.Response;
+import org.apache.http.conn.HttpHostConnectException;
+import org.apache.http.entity.ContentType;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.communication.DistributionRequest;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
+import org.apache.sling.distribution.transport.DistributionTransport;
+import org.apache.sling.distribution.transport.DistributionTransportException;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+import org.apache.sling.distribution.util.RequestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SimpleHttpDistributionTransport implements DistributionTransport {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final DistributionEndpoint distributionEndpoint;
+ private final DistributionPackageBuilder packageBuilder;
+ private final int maxNumberOfPackages;
+
+ public SimpleHttpDistributionTransport(DistributionEndpoint
distributionEndpoint,
+ DistributionPackageBuilder
packageBuilder,
+ int maxNumberOfPackages) {
+
+ this.distributionEndpoint = distributionEndpoint;
+ this.packageBuilder = packageBuilder;
+ this.maxNumberOfPackages = maxNumberOfPackages;
+ }
+
+ public void deliverPackage(@Nonnull ResourceResolver resourceResolver,
@Nonnull DistributionPackage distributionPackage,
+ @Nonnull DistributionTransportSecret secret)
throws DistributionTransportException {
+ String hostAndPort = getHostAndPort(distributionEndpoint.getUri());
+
+ URI packageOrigin = distributionPackage.getInfo().getOrigin();
+ if (packageOrigin != null &&
hostAndPort.equals(getHostAndPort(packageOrigin))) {
+ log.info("skipping distribution of package {}Â to same origin {}",
distributionPackage.getId(), hostAndPort);
+ } else {
+ log.info("delivering package {} to {} using secret {}", new
Object[]{
+ distributionPackage.getId(),
+ distributionEndpoint.getUri(),
+ secret
+ });
+
+ try {
+ Executor executor = Executor.newInstance();
+
+ executor = authenticate(secret, executor);
+
+ Request req =
Request.Post(distributionEndpoint.getUri()).useExpectContinue();
+
+ InputStream inputStream = null;
+ Response response = null;
+ try {
+ inputStream = distributionPackage.createInputStream();
+
+ req = req.bodyStream(inputStream,
ContentType.APPLICATION_OCTET_STREAM);
+ response = executor.execute(req);
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+
+ Content content = response.returnContent();
+ log.info("distribution content of type {} for {} delivered:
{}", new Object[]{
+ distributionPackage.getType(),
+
Arrays.toString(distributionPackage.getInfo().getPaths()),
+ content
+ });
+ } catch (Exception ex) {
+ throw new DistributionTransportException(ex);
+ }
+ }
+
+ }
+
+ @Nonnull
+ public List<DistributionPackage> retrievePackages(@Nonnull
ResourceResolver resourceResolver, @Nonnull DistributionRequest
+ distributionRequest, @Nonnull DistributionTransportSecret secret)
throws DistributionTransportException {
+ log.debug("pulling from {}", distributionEndpoint.getUri());
+
+ try {
+ URI distributionURI =
RequestUtils.appendDistributionRequest(distributionEndpoint.getUri(),
distributionRequest);
+ List<DistributionPackage> result = new
ArrayList<DistributionPackage>();
+
+ // TODO : executor should be cached and reused
+
+ Executor executor = Executor.newInstance();
+
+ executor = authenticate(secret, executor);
+
+ Request req = Request.Post(distributionURI).useExpectContinue();
+
+ // TODO : add queue parameter
+
+ // continuously requests package streams as long as type header is
received with the response (meaning there's a package of a certain type)
+ HttpResponse httpResponse;
+ try {
+
+ int pulls = 0;
+ while ((httpResponse = executor.execute(req).returnResponse())
+ .getStatusLine().getStatusCode() == 200
+ && pulls < maxNumberOfPackages) {
+ HttpEntity entity = httpResponse.getEntity();
+ if (entity != null) {
+ final DistributionPackage responsePackage =
packageBuilder.readPackage(resourceResolver, entity.getContent());
+ if (responsePackage != null) {
+
responsePackage.getInfo().setOrigin(distributionURI);
+ result.add(responsePackage);
+ } else {
+ log.warn("responsePackage is null");
+ }
+
+ pulls++;
+ } else {
+ log.info("");
+ break;
+ }
+ }
+
+ log.info("pulled {} packages from {}", pulls,
distributionEndpoint.getUri());
+
+ } catch (HttpHostConnectException e) {
+ log.info("could not connect to {} - skipping",
distributionEndpoint.getUri());
+ }
+
+ return result;
+
+ } catch (Exception ex) {
+ throw new DistributionTransportException(ex);
+ }
+
+ }
+
+ protected Executor authenticate(DistributionTransportSecret secret,
Executor executor) {
+ Map<String, String> credentialsMap = secret.asCredentialsMap();
+ if (credentialsMap != null) {
+ executor = executor.auth(new
HttpHost(distributionEndpoint.getUri().getHost(),
distributionEndpoint.getUri().getPort()),
+ credentialsMap.get("username"),
credentialsMap.get("password")).authPreemptive(
+ new HttpHost(distributionEndpoint.getUri().getHost(),
distributionEndpoint.getUri().getPort()));
+ log.debug("authenticated executor HTTP client with user and
password");
+ }
+ return executor;
+ }
+
+ private String getHostAndPort(URI uri) {
+ return uri.getHost() + ":" + uri.getPort();
+ }
+
+}
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,87 @@
+/*
+ * 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.transport.impl;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+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.commons.osgi.PropertiesUtil;
+import org.apache.sling.distribution.component.impl.DistributionComponentUtils;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+import
org.apache.sling.distribution.transport.DistributionTransportSecretProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(label = "User Credentials based
DistributionTransportSecretProvider",
+ configurationFactory = true,
+ specVersion = "1.1",
+ policy = ConfigurationPolicy.REQUIRE)
+@Service(value = DistributionTransportSecretProvider.class)
+public class UserCredentialsDistributionTransportSecretProvider implements
+ DistributionTransportSecretProvider {
+
+ /**
+ * name of this component.
+ */
+ @Property
+ public static final String NAME = DistributionComponentUtils.PN_NAME;
+
+ @Property
+ public final static String USERNAME = "username";
+
+ @Property
+ public final static String PASSWORD = "password";
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private String username;
+ private String password;
+
+ @Activate
+ protected void activate(Map<String, Object> config) {
+ username = PropertiesUtil.toString(config.get(USERNAME), "").trim();
+ password = PropertiesUtil.toString(config.get(PASSWORD), "").trim();
+ }
+
+ public DistributionTransportSecret getSecret() {
+ return new DistributionTransportSecret() {
+ public String asToken() {
+ return null;
+ }
+
+ public InputStream asStream() {
+ return null;
+ }
+
+ public Map<String, String> asCredentialsMap() {
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(USERNAME, username);
+ map.put(PASSWORD, password);
+ return Collections.unmodifiableMap(map);
+ }
+ };
+ }
+}
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/transport/impl/UserCredentialsDistributionTransportSecretProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,79 @@
+/*
+ * 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.transport.impl;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static org.junit.Assert.assertArrayEquals;
+
+/**
+ * Testcase for {@link AdvancedHttpDistributionTransport}
+ */
+@RunWith(Parameterized.class)
+public class AdvancedHttpDistributionTransportTest {
+
+ private final String[] inputTransportProperties;
+ private final String inputSelector;
+ private final String[] inputPaths;
+
+ private final String[] outputHeaders;
+
+
+ @Parameterized.Parameters
+ public static Iterable<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {new String[]{}, "", new String[]{},
+ new String[]{}},
+ {new String[]{}, "add", new String[]{},
+ new String[]{}},
+ {new String[]{"add -> Header: Add"}, "add", new String[]{},
+ new String[]{"Header: Add"}},
+ {new String[]{"add -> Header: Add", "Header: Always"}, "add",
new String[]{},
+ new String[]{"Header: Add", "Header: Always"}},
+ {new String[]{"add -> Header: Add", "* -> Header: Always",
"delete -> Header:Del"}, "add", new String[]{},
+ new String[]{"Header: Add", "Header: Always"}},
+ {new String[]{"add -> Header: Add", "Header: Always"},
"delete", new String[]{},
+ new String[]{"Header: Always"}},
+ {new String[]{"add -> Header: Add", "Header: Always"}, "add",
new String[]{},
+ new String[]{"Header: Add", "Header: Always"}},
+ {new String[]{"add -> Header: Add", "Header: Always",
"PathHeader: {path}"}, "add", new String[]{"/content"},
+ new String[]{"Header: Add", "Header: Always",
"PathHeader: /content"}},
+ });
+
+ }
+
+ public AdvancedHttpDistributionTransportTest(String[]
inputTransportProperties, String inputSelector, String[] inputPaths,
+ String[] outputHeaders) {
+ this.inputTransportProperties = inputTransportProperties;
+ this.inputSelector = inputSelector;
+ this.outputHeaders = outputHeaders;
+ this.inputPaths = inputPaths;
+ }
+
+ @Test
+ public void testHttpTransportProperties() {
+ String[] headers =
AdvancedHttpDistributionTransport.getCustomizedHeaders(inputTransportProperties,
inputSelector, inputPaths);
+
+ assertArrayEquals(outputHeaders, headers);
+ }
+}
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/AdvancedHttpDistributionTransportTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,208 @@
+/*
+ * 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.transport.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.communication.DistributionRequest;
+import org.apache.sling.distribution.communication.DistributionRequestType;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.transport.DistributionTransport;
+import org.apache.sling.distribution.transport.DistributionTransport;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Testcase for {@link MultipleEndpointDistributionTransport}
+ */
+public class MultipleEndpointDistributionTransportTest {
+
+ @Test
+ public void testDeliverPackageWithoutSubHandlers() throws Exception {
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionPackage distributionPackage =
mock(DistributionPackage.class);
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ for (TransportEndpointStrategyType strategy :
TransportEndpointStrategyType.values()) {
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(subHandlers, strategy);
+
multipleEndpointDistributionTransport.deliverPackage(resourceResolver,
distributionPackage, secret);
+ }
+ }
+
+ @Test
+ public void testRetrievePackagesWithoutSubHandlers() throws Exception {
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ for (TransportEndpointStrategyType strategy :
TransportEndpointStrategyType.values()) {
+ MultipleEndpointDistributionTransport
multipleEndpointdistributionTransport = new
MultipleEndpointDistributionTransport(subHandlers, strategy);
+ List<DistributionPackage> distributionPackages =
multipleEndpointdistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertTrue(distributionPackages.isEmpty());
+ }
+ }
+
+ @Test
+ public void testDeliverPackageWithSubHandlers() throws Exception {
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport first = mock(DistributionTransport.class);
+ subHandlers.add(first);
+ DistributionTransport second = mock(DistributionTransport.class);
+ subHandlers.add(second);
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionPackage distributionPackage =
mock(DistributionPackage.class);
+ for (TransportEndpointStrategyType strategy :
TransportEndpointStrategyType.values()) {
+ MultipleEndpointDistributionTransport
multipleEndpointdistributionTransport = new
MultipleEndpointDistributionTransport(subHandlers, strategy);
+
multipleEndpointdistributionTransport.deliverPackage(resourceResolver,
distributionPackage, secret);
+ }
+ }
+
+ @Test
+ public void testRetrievePackagesWithSubHandlers() throws Exception {
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport first = mock(DistributionTransport.class);
+ Iterable<DistributionPackage> packages = Collections.emptyList();
+ when(first.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages);
+ subHandlers.add(first);
+ DistributionTransport second = mock(DistributionTransport.class);
+ when(second.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages);
+ subHandlers.add(second);
+ for (TransportEndpointStrategyType strategy :
TransportEndpointStrategyType.values()) {
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(subHandlers, strategy);
+ List<DistributionPackage> distributionPackages =
multipleEndpointDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertTrue(distributionPackages.isEmpty());
+ }
+ }
+
+ @Test
+ public void testRetrievePackagesWithOneReturningSubHandlerAndAllStrategy()
throws Exception {
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport handler1 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages1 = new
ArrayList<DistributionPackage>();
+ packages1.add(mock(DistributionPackage.class));
+ packages1.add(mock(DistributionPackage.class));
+ when(handler1.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages1);
+ subHandlers.add(handler1);
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(
+ subHandlers, TransportEndpointStrategyType.All);
+ List<DistributionPackage> distributionPackages =
multipleEndpointDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertFalse(distributionPackages.isEmpty());
+ assertEquals(2, distributionPackages.size());
+ }
+
+ @Test
+ public void
testRetrievePackagesWithOneEmptyOneReturningSubHandlerAndOneStrategy() throws
Exception {
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport handler = mock(DistributionTransport.class);
+ when(handler.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(new ArrayList<DistributionPackage>());
+ subHandlers.add(handler);
+ DistributionTransport handler2 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages2 = new
ArrayList<DistributionPackage>();
+ packages2.add(mock(DistributionPackage.class));
+ packages2.add(mock(DistributionPackage.class));
+ when(handler2.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages2);
+ subHandlers.add(handler2);
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(
+ subHandlers, TransportEndpointStrategyType.One);
+ List<DistributionPackage> distributionPackages =
multipleEndpointDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertTrue(distributionPackages.isEmpty());
+ }
+
+ @Test
+ public void
testRetrievePackagesWithTwoReturningSubHandlersAndAllStrategy() throws
Exception {
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport handler1 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages1 = new
ArrayList<DistributionPackage>();
+ packages1.add(mock(DistributionPackage.class));
+ packages1.add(mock(DistributionPackage.class));
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ when(handler1.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages1);
+ subHandlers.add(handler1);
+
+ DistributionTransport handler2 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages2 = new
ArrayList<DistributionPackage>();
+ packages2.add(mock(DistributionPackage.class));
+ packages2.add(mock(DistributionPackage.class));
+ packages2.add(mock(DistributionPackage.class));
+ when(handler2.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages2);
+ subHandlers.add(handler2);
+
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(
+ subHandlers, TransportEndpointStrategyType.All);
+ List<DistributionPackage> distributionPackages =
multipleEndpointDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertFalse(distributionPackages.isEmpty());
+ assertEquals(5, distributionPackages.size());
+ }
+
+ @Test
+ public void
testRetrievePackagesWithTwoReturningSubHandlersAndOneStrategy() throws
Exception {
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ List<DistributionTransport> subHandlers = new
ArrayList<DistributionTransport>();
+ DistributionTransport handler1 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages1 = new
ArrayList<DistributionPackage>();
+ packages1.add(mock(DistributionPackage.class));
+ packages1.add(mock(DistributionPackage.class));
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ when(handler1.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages1);
+ subHandlers.add(handler1);
+
+ DistributionTransport handler2 = mock(DistributionTransport.class);
+ List<DistributionPackage> packages2 = new
ArrayList<DistributionPackage>();
+ packages2.add(mock(DistributionPackage.class));
+ packages2.add(mock(DistributionPackage.class));
+ packages2.add(mock(DistributionPackage.class));
+ when(handler2.retrievePackages(resourceResolver, distributionRequest,
secret)).thenReturn(packages2);
+ subHandlers.add(handler2);
+
+ MultipleEndpointDistributionTransport
multipleEndpointDistributionTransport = new
MultipleEndpointDistributionTransport(
+ subHandlers, TransportEndpointStrategyType.One);
+ List<DistributionPackage> distributionPackages =
multipleEndpointDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(distributionPackages);
+ assertFalse(distributionPackages.isEmpty());
+ assertEquals(2, distributionPackages.size());
+ }
+}
\ No newline at end of file
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/MultipleEndpointDistributionTransportTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java
(added)
+++
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,142 @@
+/*
+ * 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.transport.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.client.fluent.Executor;
+import org.apache.http.client.fluent.Request;
+import org.apache.http.client.fluent.Response;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.distribution.communication.DistributionRequest;
+import org.apache.sling.distribution.communication.DistributionRequestType;
+import org.apache.sling.distribution.packaging.DistributionPackage;
+import org.apache.sling.distribution.packaging.DistributionPackageInfo;
+import org.apache.sling.distribution.serialization.DistributionPackageBuilder;
+import org.apache.sling.distribution.transport.DistributionTransportSecret;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Testcase for {@link SimpleHttpDistributionTransport}
+ */
+@Ignore
+public class SimpleHttpDistributionTransportTest {
+
+ @Test
+ public void testDeliverPackage() throws Exception {
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ Map<String, String> credentialsMap = new HashMap<String, String>();
+ credentialsMap.put("username", "foo");
+ credentialsMap.put("password", "foo");
+ when(secret.asCredentialsMap()).thenReturn(credentialsMap);
+ Executor executor = mock(Executor.class);
+ Response response = mock(Response.class);
+ when(executor.execute(any(Request.class))).thenReturn(response);
+ DistributionEndpoint endpoint = new
DistributionEndpoint("http://127.0.0.1:8080/some/resource");
+ DistributionPackageBuilder packageBuilder =
mock(DistributionPackageBuilder.class);
+ int maxNoOfPackages = Integer.MAX_VALUE;
+ SimpleHttpDistributionTransport simpleHttpDistributionTransport = new
SimpleHttpDistributionTransport(
+ endpoint, packageBuilder, maxNoOfPackages);
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionPackage distributionPackage =
mock(DistributionPackage.class);
+ when(distributionPackage.getInfo()).thenReturn(new
DistributionPackageInfo());
+ InputStream stream = mock(InputStream.class);
+ when(distributionPackage.createInputStream()).thenReturn(stream);
+ simpleHttpDistributionTransport.deliverPackage(resourceResolver,
distributionPackage, secret);
+ }
+
+ @Test
+ public void testRetrievePackagesRemotelyFailing() throws Exception {
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ Map<String, String> credentialsMap = new HashMap<String, String>();
+ credentialsMap.put("username", "foo");
+ credentialsMap.put("password", "foo");
+ when(secret.asCredentialsMap()).thenReturn(credentialsMap);
+ Executor executor = mock(Executor.class);
+ Response response = mock(Response.class);
+ HttpResponse httpResponse = mock(HttpResponse.class);
+ StatusLine statusLine = mock(StatusLine.class);
+ when(statusLine.getStatusCode()).thenReturn(404);
+ when(httpResponse.getStatusLine()).thenReturn(statusLine);
+ when(response.returnResponse()).thenReturn(httpResponse);
+ when(executor.execute(any(Request.class))).thenReturn(response);
+ DistributionEndpoint endpoint = new
DistributionEndpoint("http://127.0.0.1:8080/some/resource");
+ DistributionPackageBuilder packageBuilder =
mock(DistributionPackageBuilder.class);
+ int maxNoOfPackages = 1;
+ SimpleHttpDistributionTransport simpleHttpDistributionTransport = new
SimpleHttpDistributionTransport(
+ endpoint, packageBuilder, maxNoOfPackages);
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ List<DistributionPackage> packages =
simpleHttpDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(packages);
+ assertTrue(packages.isEmpty());
+ }
+
+ @Test
+ public void testRetrievePackagesRemotelyWorking() throws Exception {
+ DistributionTransportSecret secret =
mock(DistributionTransportSecret.class);
+ Map<String, String> credentialsMap = new HashMap<String, String>();
+ credentialsMap.put("username", "foo");
+ credentialsMap.put("password", "foo");
+ when(secret.asCredentialsMap()).thenReturn(credentialsMap);
+ Executor executor = mock(Executor.class);
+ Response response = mock(Response.class);
+ HttpResponse httpResponse = mock(HttpResponse.class);
+ StatusLine statusLine = mock(StatusLine.class);
+ when(statusLine.getStatusCode()).thenReturn(200);
+ when(httpResponse.getStatusLine()).thenReturn(statusLine);
+ HttpEntity entity = mock(HttpEntity.class);
+ InputStream stream = new ByteArrayInputStream("package binary
stuff".getBytes("UTF-8"));
+ when(entity.getContent()).thenReturn(stream);
+ when(httpResponse.getEntity()).thenReturn(entity);
+ when(response.returnResponse()).thenReturn(httpResponse);
+ when(executor.execute(any(Request.class))).thenReturn(response);
+ DistributionEndpoint endpoint = new
DistributionEndpoint("http://127.0.0.1:8080/some/resource");
+ DistributionPackageBuilder packageBuilder =
mock(DistributionPackageBuilder.class);
+ DistributionPackage distributionPackage =
mock(DistributionPackage.class);
+ when(distributionPackage.getInfo()).thenReturn(new
DistributionPackageInfo());
+ when(packageBuilder.readPackage(any(ResourceResolver.class),
any(InputStream.class))).thenReturn(distributionPackage);
+ int maxNoOfPackages = 1;
+ SimpleHttpDistributionTransport simpleHttpDistributionTransport = new
SimpleHttpDistributionTransport(
+ endpoint, packageBuilder, maxNoOfPackages);
+ ResourceResolver resourceResolver = mock(ResourceResolver.class);
+ DistributionRequest distributionRequest = new
DistributionRequest(DistributionRequestType.ADD, "/");
+ List<DistributionPackage> packages =
simpleHttpDistributionTransport.retrievePackages(resourceResolver,
distributionRequest, secret);
+ assertNotNull(packages);
+ assertFalse(packages.isEmpty());
+ assertEquals(1, packages.size());
+ assertNotNull(packages.get(0));
+ }
+}
\ No newline at end of file
Propchange:
sling/trunk/contrib/extensions/distribution/core/src/test/java/org/apache/sling/distribution/transport/impl/SimpleHttpDistributionTransportTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
(added)
+++
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,6 @@
+{
+ "jcr:primaryType": "sling:OsgiConfig",
+ "name": "publishAdmin",
+ "username": "admin",
+ "password": "admin"
+}
\ No newline at end of file
Added:
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.osgi.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.osgi.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json?rev=1643201&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.osgi.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
(added)
+++
sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.osgi.author/org.apache.sling.distribution.transport.impl.UserCredentialsDistributionTransportSecretProvider-publishAdmin.json
Fri Dec 5 09:19:24 2014
@@ -0,0 +1,6 @@
+{
+ "jcr:primaryType": "sling:OsgiConfig",
+ "name": "publishAdmin",
+ "username": "admin",
+ "password": "admin"
+}
\ No newline at end of file