Author: amitj
Date: Thu Oct 5 09:47:39 2017
New Revision: 1811179
URL: http://svn.apache.org/viewvc?rev=1811179&view=rev
Log:
OAK-6575: Provide a secure external URL to a DataStore binary
Patch from Ian Boston
Added:
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java
(with props)
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java
(with props)
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java
(with props)
jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-blob-cloud/pom.xml
Added:
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java?rev=1811179&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java
(added)
+++
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java
Thu Oct 5 09:47:39 2017
@@ -0,0 +1,38 @@
+/*
+ * 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.jackrabbit.oak.api.conversion;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+import javax.jcr.Value;
+import java.net.URI;
+
+/**
+ *
+ * Provides a URI in exchange for a Value.
+ * Typically the Value will represent something where a URI is valuable and
useful.
+ * Implementations of this interface must ensure that the Oak security model
is delegated
+ * securely and not circumvented. Only Oak bundles should implement this
provider as in most cases
+ * internal implementation details of Oak will be required to achieve the
implementation. Ideally
+ * implementations should be carefully reviewed by peers.
+ */
+@ProviderType
+public interface URIProvider {
+
+ URI toURI(Value value);
+}
Propchange:
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/URIProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java?rev=1811179&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java
(added)
+++
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java
Thu Oct 5 09:47:39 2017
@@ -0,0 +1,20 @@
+/*
+ * 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("1.0.0")
+package org.apache.jackrabbit.oak.api.conversion;
+
+import org.osgi.annotation.versioning.Version;
Propchange:
jackrabbit/oak/trunk/oak-api/src/main/java/org/apache/jackrabbit/oak/api/conversion/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-blob-cloud/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-cloud/pom.xml?rev=1811179&r1=1811178&r2=1811179&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-blob-cloud/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-blob-cloud/pom.xml Thu Oct 5 09:47:39 2017
@@ -120,6 +120,12 @@
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.24</version>
</dependency>
+ <dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-cloudfront</artifactId>
+ <version>1.11.24</version>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -171,6 +177,11 @@
<version>1.10.19</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <version>2.0.1</version>
+ </dependency>
</dependencies>
</project>
Added:
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java?rev=1811179&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java
(added)
+++
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java
Thu Oct 5 09:47:39 2017
@@ -0,0 +1,236 @@
+/*
+ * 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.jackrabbit.oak.blob.cloud.aws.s3;
+
+import com.amazonaws.services.cloudfront.CloudFrontUrlSigner;
+import com.google.common.io.Closeables;
+import org.apache.commons.codec.binary.Base64;
+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.Deactivate;
+import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.api.conversion.URIProvider;
+import org.apache.jackrabbit.oak.plugins.value.OakValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import javax.jcr.Value;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * Adapts from Value to URI where Value has a Binary value.
+ * If running as an OSGi Component would expect an OSGi AdapterManager to pick
it up.
+ * other.
+ *
+ * To generate keys in PKCS8 format use OpenSSL
+ * openssl genrsa -out private_key.pem 1024
+ * openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in private_key.pem
-out private_key.pkcs8
+ * See
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-creating-cloudfront-key-pairs
for
+ * details on how to configure CloudFront.
+ */
+@Component(immediate = true, metatype = true, policy =
ConfigurationPolicy.REQUIRE)
+@Service(URIProvider.class)
+public class CloudFrontS3SignedUrlProvider implements URIProvider {
+
+ @Property( description = "The cloud front URL, including a trailing slash.
Normally this is the http://<coudfrontdomain>/")
+ public static final String CLOUD_FRONT_URL = "cloudFrontUrl";
+
+ @Property(intValue = 60, description = "Time each signed url is valid for
before it expires, in seconds.")
+ public static final String TTL = "ttl";
+
+ @Property(intValue = 100, description = "Minimum size over which a binary
is redirected, in kb.")
+ public static final String MIN_SIZE = "minSize";
+
+ @Property(description = "Path to the PKCS8 formatted private key file,
probably an absolute path.")
+ public static final String PRIVATE_KEY_FILE = "privateKeyFile";
+
+ @Property(description = "The keypair ID generated by AWS Console when the
public key was generated or uploaded.")
+ public static final String KEY_PAIR_ID = "keyPairId";
+
+ public static final String BEGIN_PRIVATE_KEY = "-----BEGIN PRIVATE
KEY-----";
+ public static final String END_PRIVATE_KEY = "-----END PRIVATE KEY-----";
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(CloudFrontS3SignedUrlProvider.class);
+ private String cloudFrontUrl;
+ private long ttl;
+ private String keyPairId;
+ private RSAPrivateKey privateKey;
+ private long minimumSize;
+
+ /**
+ * Default Constructor used by OSGi.
+ */
+ public CloudFrontS3SignedUrlProvider() {
+ }
+
+ /**
+ * Non OSGi IoC constructor, close must be called when done.
+ * @param cloudFrontUrl
+ * @param ttl
+ * @param privateKeyPEM
+ * @param privateKeyId
+ * @throws InvalidKeySpecException
+ * @throws NoSuchAlgorithmException
+ */
+ public CloudFrontS3SignedUrlProvider(String cloudFrontUrl,
+ long ttl,
+ long minSize,
+ String privateKeyPEM,
+ String privateKeyId) throws
InvalidKeySpecException, NoSuchAlgorithmException {
+ init(cloudFrontUrl, ttl, minSize, privateKeyPEM, privateKeyId);
+ }
+
+ public void close() {
+ deactivate(new HashMap<String, Object>());
+ }
+
+ @Deactivate
+ public void deactivate(Map<String, Object> properties) {
+ }
+
+
+ @Activate
+ public void activate(Map<String, Object> properties) throws
InvalidKeySpecException, NoSuchAlgorithmException, IOException {
+ LOGGER.debug("Property {}: {} ",CLOUD_FRONT_URL,
properties.get(CLOUD_FRONT_URL));
+ LOGGER.debug("Property {}: {} ",TTL, properties.get(TTL));
+ LOGGER.debug("Property {}: {} ", PRIVATE_KEY_FILE,
properties.get(PRIVATE_KEY_FILE));
+ LOGGER.debug("Property {}: {} ",KEY_PAIR_ID,
properties.get(KEY_PAIR_ID));
+ LOGGER.debug("Property {}: {} ",MIN_SIZE, properties.get(MIN_SIZE));
+ init((String) properties.get(CLOUD_FRONT_URL),
+ (Integer) properties.get(TTL),
+ (Integer) properties.get(MIN_SIZE),
+ loadPrivateKey((String) properties.get(PRIVATE_KEY_FILE)),
+ (String) properties.get(KEY_PAIR_ID));
+ }
+
+ private String loadPrivateKey(String keyFile) throws IOException {
+ FileReader fr = null;
+ StringBuilder key = new StringBuilder();
+ try {
+ fr = new FileReader(keyFile);
+ char[] b = new char[4096];
+ for (; ; ) {
+ int i = fr.read(b);
+ if (i < 0) {
+ break;
+ }
+ key.append(b, 0, i);
+ }
+ } finally {
+ Closeables.close(fr, false);
+ }
+ return key.toString();
+ }
+
+ private void init(String cloudFrontUrl, long ttl, long minSize, String
privateKeyPEM, String privateKeyId)
+ throws InvalidKeySpecException, NoSuchAlgorithmException {
+ this.cloudFrontUrl = cloudFrontUrl;
+ this.ttl = ttl;
+ this.minimumSize = minSize*1024;
+ this.privateKey = getPrivateKey(privateKeyPEM);
+ this.keyPairId = privateKeyId;
+ }
+
+
+ @Override
+ public URI toURI(Value value) {
+ // The conversion is javax.jcr.Value -> URI, but for Oak all Values
are OakValues and we can only do it for Values.
+ if ( value instanceof OakValue ) {
+ try {
+ Blob b = ((OakValue) value).getBlob();
+ if (b != null) {
+ if ( b.length() > minimumSize ) {
+ String contentId = b.getContentIdentity();
+ if (contentId != null) {
+ URI uri = new URI(signS3Url(contentId, ttl,
cloudFrontUrl, keyPairId, privateKey));
+ LOGGER.info("Generated URI {} ", uri.toString());
+ return uri;
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("Unable to get or sign content identity",e);
+ }
+
+ }
+ return null;
+ }
+
+
+ /**
+ * Convert the content identity to a S3 url, see the {@link
org.apache.jackrabbit.oak.blob.cloud.s3.S3Backend} class.
+ * @param contentIdentity
+ * @return
+ */
+ @Nonnull
+ private String getS3Key(@Nonnull String contentIdentity) {
+ return contentIdentity.substring(0, 4) + "-" +
contentIdentity.substring(4);
+ }
+
+ @Nonnull
+ private String signS3Url(@Nonnull String contentIdentity, long ttl,
@Nonnull String cloudFrontUrl,
+ @Nonnull String keyPairId, @Nonnull RSAPrivateKey
privateKey)
+ throws InvalidKeySpecException, NoSuchAlgorithmException,
InvalidKeyException, SignatureException, UnsupportedEncodingException {
+
+ long expiry = (System.currentTimeMillis()/1000)+ttl;
+ StringBuilder urlToSign = new StringBuilder();
+
+ urlToSign.append(cloudFrontUrl)
+ .append(getS3Key(contentIdentity));
+ return
CloudFrontUrlSigner.getSignedURLWithCannedPolicy(urlToSign.toString(),
keyPairId, privateKey, new Date(expiry));
+ }
+
+
+ private RSAPrivateKey getPrivateKey(String privateKeyPKCS8) throws
NoSuchAlgorithmException, InvalidKeySpecException {
+ int is = privateKeyPKCS8.indexOf(BEGIN_PRIVATE_KEY);
+ int ie = privateKeyPKCS8.indexOf(END_PRIVATE_KEY);
+ if (ie < 0 || is < 0) {
+ throw new IllegalArgumentException("Private Key is not correctly
encoded, need a PEM encoded key with " +
+ "-----BEGIN PRIVATE KEY----- headers to indicate PKCS8
encoding.");
+ }
+ privateKeyPKCS8 = privateKeyPKCS8.substring(is +
BEGIN_PRIVATE_KEY.length(), ie).trim();
+ byte[] privateKeyBytes = Base64.decodeBase64(privateKeyPKCS8);
+
+ // load the private key
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ KeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);
+ return (RSAPrivateKey) keyFactory.generatePrivate(ks);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java?rev=1811179&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java
(added)
+++
jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java
Thu Oct 5 09:47:39 2017
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.jackrabbit.oak.blob.cloud.aws.s3;
+
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.plugins.value.OakValue;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import java.net.URI;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * Tests Signing URLS with a 1024 key and a 4096 key.
+ */
+public class CloudFrontS3SignedUrlProviderTest {
+
+
+ /**
+ * To generate keys in PKCS8 format use OpenSSL
+ * openssl genrsa -out private_key.pem 1024
+ * openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in
private_key.pem -out private_key.pkcs8
+ */
+
+ private static final String PRIVATE_KEY_4096 =
+
+ "-----BEGIN PRIVATE KEY-----\n"+
+ "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\n"+
+ "UzLAsK9qu+BccvxEnDDUQIxMjGUa1w==\n"+
+ "-----END PRIVATE KEY-----\n";
+
+ private static final String PRIVATE_KEY_1024 =
+
+ "-----BEGIN PRIVATE KEY-----\n" +
+ "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJsc0nqu+4mRGu2P\n" +
+ "E39fD8awAwYRS4HyIujJaVKqXNgVTBd8R8ocSaMYPBYURQMuhKEyzc197pAxEDN8\n" +
+ "g+d0pnRXS5YFUspPCehH6vsXaJSF1tW9T9J4aGSvQU+DD4G6UP9GciD2V9RRlrns\n" +
+ "1K8VzJn4YvWnym5nIH/2ld1HnK8DAgMBAAECgYBCzrgtFR7L0o65kO1B5+zAk+DJ\n" +
+ "hTtzXZoBj3Zon23bt9iNKP82otZog7ClhddvlmKTl3Eit8G/oxIqSs/5KbnjKFn2\n" +
+ "JzHgltA64t4E+g2wfjfX/THGgq4Gf2qLABJ8XPzl4lhNhBjcp/yls+R/aaXO6Tpg\n" +
+ "ot7PdSstlCJH4iHJSQJBAMzHlSXPysV4K8goh8FC392Nif4u42sMulS3yh/8hWoZ\n" +
+ "zGftc/1Av9HxLYYPI7VojGVl8ZEi7mWWFpYhnjGi4MUCQQDB6Pe603RFg8EPX49Z\n" +
+ "3BNuxk4/17znWktbhCzo/MxOGZ/xoCqEIO59jIUYgrWzp4PD7tLd8uPw8CKyV6RA\n" +
+ "H70nAkEAtxg4Rd+dmKQS2VtLzkOh7/FOkYOQ+TUfIQJXafQZwb0hY0cPbz/GgssW\n" +
+ "fgfpUJkS9tKIg9FswE3LEh8q14yfVQJBAJhDG8tq4QD4zS8KJWE1K1kvhCAjgmTU\n" +
+ "BRpOdolYgADPpEUyNFBeH4ccQSKW+KCiaBgBPzki0ZPOrCAIK6Rih78CQQDIICap\n" +
+ "QByVjsFDed4Te13qthgFthy6iGyk1JZFu9lCnAaiAdg4AA0OyF9FxFUzCsOGD1HS\n" +
+ "GoRuVX4I/AZR74Sx \n" +
+ "-----END PRIVATE KEY-----";
+ private static final Logger LOGGER =
LoggerFactory.getLogger(CloudFrontS3SignedUrlProviderTest.class);
+ @Mock
+ private Blob blob;
+
+ interface MockJCRValue extends Value, OakValue {
+ }
+
+ @Mock
+ private MockJCRValue value;
+
+
+ public CloudFrontS3SignedUrlProviderTest() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testSignedURL() throws InvalidKeySpecException,
NoSuchAlgorithmException, RepositoryException {
+ long t2 = System.currentTimeMillis();
+ CloudFrontS3SignedUrlProvider provider = new
CloudFrontS3SignedUrlProvider(
+ "http://applicationA1.cloudfront.net/",
+ 60,
+ 1,
+ PRIVATE_KEY_1024,
+ "123");
+ LOGGER.info("Loaded 1024 private key in {} ms
"+(System.currentTimeMillis()-t2));
+
+ long t = System.currentTimeMillis();
+ CloudFrontS3SignedUrlProvider provider4096 = new
CloudFrontS3SignedUrlProvider(
+ "http://applicationA1.cloudfront.net/",
+ 60,
+ 1,
+ PRIVATE_KEY_4096,
+ "PRIVATE_KEY_4096");
+ LOGGER.info("Loaded 4096 private key in {} ms
"+(System.currentTimeMillis()-t));
+
+
+
+ t = System.currentTimeMillis();
+ Mockito.when(blob.length()).thenReturn((long)1024*1024); // 1MB
+ Mockito.when(value.getBlob()).thenReturn(blob);
+
Mockito.when(blob.getContentIdentity()).thenReturn("1234567891ABCDEFGH");
+ URI u = provider4096.toURI(value);
+ Assert.assertNotNull(u);
+ LOGGER.info("Signed with 4096 key in {} ms
",(System.currentTimeMillis()-t));
+
+ t = System.currentTimeMillis();
+ Mockito.when(blob.length()).thenReturn((long)1024*1024); // 1MB
+ Mockito.when(value.getBlob()).thenReturn(blob);
+
Mockito.when(blob.getContentIdentity()).thenReturn("1234567891ABCDEFGH");
+ u = provider.toURI(value);
+ Assert.assertNotNull(u);
+ LOGGER.info("Signed with 1024 key in {} ms
",(System.currentTimeMillis()-t));
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-blob-cloud/src/test/java/org/apache/jackrabbit/oak/blob/cloud/aws/s3/CloudFrontS3SignedUrlProviderTest.java
------------------------------------------------------------------------------
svn:eol-style = native