Author: jcian
Date: Tue Nov 15 16:25:34 2011
New Revision: 1202283
URL: http://svn.apache.org/viewvc?rev=1202283&view=rev
Log:
SHINDIG-1660: Allow ContainerConfig stack to load property values from external
resources and update BlobCrypterSecurityTokenCodec to use this new feature.
Added:
shindig/trunk/java/common/src/test/resources/classpath-accessible-test-file.txt
Modified:
shindig/trunk/config/container.js
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/util/ResourceLoader.java
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/JsonContainerConfigLoader.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
shindig/trunk/java/common/src/test/java/org/apache/shindig/config/JsonContainerConfigLoaderTest.java
Modified: shindig/trunk/config/container.js
URL:
http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Tue Nov 15 16:25:34 2011
@@ -44,6 +44,9 @@
// Container must be an array; this allows multiple containers
// to share configuration.
+
+// Note that you can embed values directly or you can choose to have values
read from a file on disk
+// or read from the classpath ("foo-key" : "file:///foo-file.txt" || "foo-key"
: "res://foo-file.txt")
// TODO: Move out accel container config into a separate accel.js file.
{"gadgets.container" : ["default", "accel"],
@@ -88,22 +91,23 @@
// Callback URL. Scheme relative URL for easy switch between https/http.
"gadgets.uri.oauth.callbackTemplate" :
"//%host%${CONTEXT_ROOT}/gadgets/oauthcallback",
-// Use an insecure security token by default
-"gadgets.securityTokenType" : "insecure",
-
// Config param to load Opensocial data for social
// preloads in data pipelining. %host% will be
// substituted with the current host.
"gadgets.osDataUri" : "http://%host%${CONTEXT_ROOT}/rpc",
-// Uncomment these to switch to a secure version. If both a key file and key
are provided, the key
-// will take precedence; thus, to use a key file, you must explicitly not
provide a key. The
-// best way to generate a key is to do something like this:
+// Use an insecure security token by default
+"gadgets.securityTokenType" : "insecure",
+
+// Uncomment the securityTokenType and one of the securityTokenKey's to switch
to a secure version.
+// Note that you can choose to use an embedded key, a filesystem reference or
a classpath reference.
+// The best way to generate a key is to do something like this:
// dd if=/dev/random bs=32 count=1 | openssl base64
//
-// "gadgets.securityTokenType" : "secure",
-// "gadgets.securityTokenKeyFile" : "/path/to/key/file.txt",
-// "gadgets.securityTokenKey" : "",
+//"gadgets.securityTokenType" : "secure",
+//"gadgets.securityTokenKey" : "default-insecure-embedded-key",
+//"gadgets.securityTokenKey" : "file:///path/to/key/file.txt",
+//"gadgets.securityTokenKey" : "res://some-file-on-the-classpath.txt",
// OS 2.0 Gadget DOCTYPE: used in Gadgets with @specificationVersion 2.0 or
greater and
// quirksmode on Gadget has not been set.
Modified:
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
(original)
+++
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodec.java
Tue Nov 15 16:25:34 2011
@@ -24,15 +24,12 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shindig.common.crypto.BasicBlobCrypter;
import org.apache.shindig.common.crypto.BlobCrypter;
import org.apache.shindig.common.crypto.BlobCrypterException;
-import org.apache.shindig.common.util.ResourceLoader;
import org.apache.shindig.config.ContainerConfig;
-import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -56,8 +53,6 @@ import com.google.inject.Singleton;
public class BlobCrypterSecurityTokenCodec implements SecurityTokenCodec,
ContainerConfig.ConfigObserver {
private static final Logger LOG =
Logger.getLogger(BlobCrypterSecurityTokenCodec.class.getName());
- public static final String SECURITY_TOKEN_KEY_FILE =
"gadgets.securityTokenKeyFile";
-
public static final String SECURITY_TOKEN_KEY = "gadgets.securityTokenKey";
public static final String SIGNED_FETCH_DOMAIN = "gadgets.signedFetchDomain";
@@ -109,14 +104,10 @@ public class BlobCrypterSecurityTokenCod
private void loadContainers(ContainerConfig config, Collection<String>
containers,
Map<String, BlobCrypter> crypters, Map<String, String> domains) throws
IOException {
for (String container : containers) {
- String keyFile = config.getString(container, SECURITY_TOKEN_KEY_FILE);
String key = config.getString(container, SECURITY_TOKEN_KEY);
if (key != null) {
BlobCrypter crypter = loadCrypter(key);
crypters.put(container, crypter);
- } else if (keyFile != null) {
- BlobCrypter crypter = loadCrypter(getKeyFromFile(keyFile));
- crypters.put(container, crypter);
}
String domain = config.getString(container, SIGNED_FETCH_DOMAIN);
domains.put(container, domain);
@@ -124,26 +115,13 @@ public class BlobCrypterSecurityTokenCod
}
/**
- * Gets a key from the given keyFile.
- *
- * @param keyFile the key file from which to read the key
- * @return the key
- * @throws IOException if there was an error read the key file
- */
- @VisibleForTesting
- protected String getKeyFromFile(String keyFile) throws IOException {
- return IOUtils.toString(ResourceLoader.open(keyFile), "UTF-8");
- }
-
- /**
- * Load a BlobCrypter from the key file. Override this if you have your own
- * BlobCrypter implementation.
+ * Load a BlobCrypter using the specified key. Override this if you have
your own BlobCrypter
+ * implementation.
*
- * @param key The key to use for encryption
+ * @param key The security token key.
* @return The BlobCrypter.
- * @throws IOException If the key file is invalid.
*/
- protected BlobCrypter loadCrypter(String key) throws IOException {
+ protected BlobCrypter loadCrypter(String key) {
return new BasicBlobCrypter(key);
}
Modified:
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
(original)
+++
shindig/trunk/java/common/src/main/java/org/apache/shindig/auth/DefaultSecurityTokenCodec.java
Tue Nov 15 16:25:34 2011
@@ -18,6 +18,7 @@
*/
package org.apache.shindig.auth;
+import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -75,6 +76,11 @@ public class DefaultSecurityTokenCodec i
return codec.encodeToken(token);
}
+ @VisibleForTesting
+ protected SecurityTokenCodec getCodec() {
+ return codec;
+ }
+
public int getTokenTimeToLive() {
return codec.getTokenTimeToLive();
}
Modified:
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/util/ResourceLoader.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/util/ResourceLoader.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/util/ResourceLoader.java
(original)
+++
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/util/ResourceLoader.java
Tue Nov 15 16:25:34 2011
@@ -31,19 +31,24 @@ import java.io.InputStream;
* Handles loading contents from resource and file system files.
*/
public final class ResourceLoader {
+ public static final String RESOURCE_PREFIX = "res://";
+ public static final String FILE_PREFIX = "file://";
+
private ResourceLoader() {}
/**
* Opens a given path as either a resource or a file, depending on the path
* name.
*
* If path starts with res://, we interpret it as a resource.
- * Otherwise we attempt to load it as a file.
+ * If path starts with file://, or path has no prefix, we interpret it as a
file.
* @param path
* @return The opened input stream
*/
public static InputStream open(String path) throws IOException {
- if (path.startsWith("res://")) {
- return openResource(path.substring(6));
+ if (path.startsWith(RESOURCE_PREFIX)) {
+ return openResource(path.substring(RESOURCE_PREFIX.length()));
+ } else if (path.startsWith(FILE_PREFIX)) {
+ path = path.substring(FILE_PREFIX.length());
}
File file = new File(path);
return new FileInputStream(file);
Modified:
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/JsonContainerConfigLoader.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/config/JsonContainerConfigLoader.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/JsonContainerConfigLoader.java
(original)
+++
shindig/trunk/java/common/src/main/java/org/apache/shindig/config/JsonContainerConfigLoader.java
Tue Nov 15 16:25:34 2011
@@ -25,6 +25,7 @@ import com.google.common.collect.Immutab
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.apache.commons.io.IOUtils;
import org.apache.shindig.common.logging.i18n.MessageKeys;
import org.apache.shindig.common.util.ResourceLoader;
import org.apache.shindig.config.ContainerConfig.Transaction;
@@ -273,6 +274,20 @@ public class JsonContainerConfigLoader {
Map<String, Object> values = new HashMap<String, Object>(json.length(), 1);
for (String key : keys) {
Object val = jsonToConfig(json.opt(key));
+ //If this is a string see if its a pointer to an external resource, and
if so, load the resource
+ if (val instanceof String) {
+ String stringVal = (String) val;
+ if (stringVal.startsWith(ResourceLoader.RESOURCE_PREFIX) ||
+ stringVal.startsWith(ResourceLoader.FILE_PREFIX)) {
+ try {
+ val = IOUtils.toString(ResourceLoader.open(stringVal), "UTF-8");
+ } catch (IOException e) {
+ if (LOG.isLoggable(Level.WARNING)) {
+ LOG.logp(Level.WARNING, classname, "jsonToMap",
MessageKeys.READING_CONFIG, e);
+ }
+ }
+ }
+ }
values.put(key, val);
}
return Collections.unmodifiableMap(values);
Modified:
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
(original)
+++
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/BlobCrypterSecurityTokenCodecTest.java
Tue Nov 15 16:25:34 2011
@@ -22,14 +22,12 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.shindig.auth.AbstractSecurityToken.Keys;
import org.apache.shindig.common.crypto.BasicBlobCrypter;
import org.apache.shindig.common.crypto.BlobCrypter;
-import org.apache.shindig.common.util.CharsetUtil;
import org.apache.shindig.common.util.FakeTimeSource;
import org.apache.shindig.config.BasicContainerConfig;
import org.apache.shindig.config.ContainerConfig;
@@ -56,71 +54,32 @@ public class BlobCrypterSecurityTokenCod
.addContainer(makeContainer("default"))
.addContainer(makeContainer("container"))
.addContainer(makeContainer("example"))
- .addContainer(makeContainer("keyOnlyNoFile", true))
.commit();
- codec = new CodecWithLoadStubbedOut(config);
+ codec = new BlobCrypterSecurityTokenCodec(config);
timeSource = new FakeTimeSource();
}
protected Map<String, Object> makeContainer(String container) {
- return makeContainer(container, false);
- }
-
- protected Map<String, Object> makeContainer(String container, boolean
insertKey) {
- if (insertKey) {
- return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
- ImmutableList.of(container),
- BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY_FILE,
- container,
- BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY,
- getContainerKey(container),
- BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
- container + ".com");
- } else {
- return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
- ImmutableList.of(container),
- BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY_FILE,
- container,
- BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
- container + ".com");
- }
+ return ImmutableMap.<String, Object>of(ContainerConfig.CONTAINER_KEY,
+ ImmutableList.of(container),
+ BlobCrypterSecurityTokenCodec.SECURITY_TOKEN_KEY,
+ getContainerKey(container),
+ BlobCrypterSecurityTokenCodec.SIGNED_FETCH_DOMAIN,
+ container + ".com");
}
protected String getContainerKey(String container) {
return "KEY FOR CONTAINER " + container;
}
- protected BlobCrypter getBlobCrypter(String fileName) {
- BasicBlobCrypter c = new
BasicBlobCrypter(CharsetUtil.getUtf8Bytes(fileName));
+ protected BlobCrypter getBlobCrypter(String key) {
+ BasicBlobCrypter c = new BasicBlobCrypter(key);
c.timeSource = timeSource;
return c;
}
- /**
- * Stubs out loading the key file.
- */
- private class CodecWithLoadStubbedOut extends BlobCrypterSecurityTokenCodec {
-
- public CodecWithLoadStubbedOut(ContainerConfig config) {
- super(config);
- }
-
- /**
- * @param file the location of the file.
- * @return a crypter based on the name of the file passed in, rather than
the contents.
- * @throws IOException when passed a filename with 'fail' in it.
- */
- @Override
- protected String getKeyFromFile(String file) throws IOException {
- if (file.contains("fail")) {
- throw new IOException("Load failed: " + file);
- }
- return getContainerKey(file);
- }
- }
-
@Test
- public void testCreateTokenUsingKeyFile() throws Exception {
+ public void testCreateToken() throws Exception {
Map<String, String> values = new HashMap<String, String>();
values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
@@ -227,18 +186,6 @@ public class BlobCrypterSecurityTokenCod
}
@Test
- public void testLoadFailure() throws Exception {
- config.newTransaction().addContainer(makeContainer("failure")).commit();
-
- try {
- new CodecWithLoadStubbedOut(config);
- fail("Should have failed to load crypter");
- } catch (RuntimeException e) {
- assertTrue(e.getMessage(), e.getMessage().contains("Load failed"));
- }
- }
-
- @Test
public void testChangingContainers() throws Exception {
String newContainer = "newcontainer";
Map<String, String> values = new HashMap<String, String>();
@@ -270,27 +217,4 @@ public class BlobCrypterSecurityTokenCod
// pass
}
}
-
- @Test
- public void testCreateTokenUsingKey() throws Exception {
- Map<String, String> values = new HashMap<String, String>();
- values.put(Keys.APP_URL.getKey(), "http://www.example.com/gadget.xml");
- values.put(Keys.MODULE_ID.getKey(), Long.toString(12345L, 10));
- values.put(Keys.OWNER.getKey(), "owner");
- values.put(Keys.VIEWER.getKey(), "viewer");
- values.put(Keys.TRUSTED_JSON.getKey(), "trusted");
-
- BlobCrypterSecurityToken t = new BlobCrypterSecurityToken("keyOnlyNoFile",
null, null, values);
- String encrypted = t.getContainer() + ":" +
getBlobCrypter(getContainerKey("keyOnlyNoFile")).wrap(t.toMap());
-
- SecurityToken t2 =
codec.createToken(ImmutableMap.of(SecurityTokenCodec.SECURITY_TOKEN_NAME,
encrypted));
-
- assertEquals("http://www.example.com/gadget.xml", t2.getAppId());
- assertEquals("http://www.example.com/gadget.xml", t2.getAppUrl());
- assertEquals("keyOnlyNoFile.com", t2.getDomain());
- assertEquals(12345L, t2.getModuleId());
- assertEquals("owner", t2.getOwnerId());
- assertEquals("viewer", t2.getViewerId());
- assertEquals("trusted", t2.getTrustedJson());
- }
}
Modified:
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
(original)
+++
shindig/trunk/java/common/src/test/java/org/apache/shindig/auth/DefaultSecurityTokenCodecTest.java
Tue Nov 15 16:25:34 2011
@@ -22,7 +22,6 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@@ -50,7 +49,7 @@ public class DefaultSecurityTokenCodecTe
if ("default".equals(container)) {
return tokenType;
}
- } else if ("gadgets.securityTokenKeyFile".equals(parameter)) {
+ } else if ("gadgets.securityTokenKey".equals(parameter)) {
return "container key file: " + container;
}
return null;
@@ -101,12 +100,7 @@ public class DefaultSecurityTokenCodecTe
@Test
public void testRealDecoder() throws Exception {
// Just verifies that "secure" tokens get routed to the right decoder
class.
- try {
- new DefaultSecurityTokenCodec(new FakeContainerConfig("secure"));
- fail("Should have thrown");
- } catch (RuntimeException e) {
- assertTrue("root cause should have been FileNotFoundException: " + e,
- e.getCause() instanceof FileNotFoundException);
- }
+ DefaultSecurityTokenCodec securityTokenCodec = new
DefaultSecurityTokenCodec(new FakeContainerConfig("secure"));
+ assertTrue(securityTokenCodec.getCodec() instanceof
BlobCrypterSecurityTokenCodec);
}
}
Modified:
shindig/trunk/java/common/src/test/java/org/apache/shindig/config/JsonContainerConfigLoaderTest.java
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/config/JsonContainerConfigLoaderTest.java?rev=1202283&r1=1202282&r2=1202283&view=diff
==============================================================================
---
shindig/trunk/java/common/src/test/java/org/apache/shindig/config/JsonContainerConfigLoaderTest.java
(original)
+++
shindig/trunk/java/common/src/test/java/org/apache/shindig/config/JsonContainerConfigLoaderTest.java
Tue Nov 15 16:25:34 2011
@@ -23,7 +23,9 @@ import static org.apache.shindig.config.
import static org.apache.shindig.config.ContainerConfig.CONTAINER_KEY;
import static org.apache.shindig.config.ContainerConfig.PARENT_KEY;
import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import org.apache.shindig.common.util.ResourceLoader;
import org.apache.shindig.expressions.Expressions;
import org.json.JSONObject;
import org.junit.Before;
@@ -55,13 +57,15 @@ public class JsonContainerConfigLoaderTe
private static final String[] ARRAY_VALUE = {"Hello", "World"};
private static final String ARRAY_ALT_VALUE = "Not an array";
+ public static final String DYNAMICALLY_LOADED_VALUE_KEY =
"dynamicallyLoadedValueKey";
+
private ExpressionContainerConfig config;
- private File createContainer(JSONObject json) throws Exception {
- File file = File.createTempFile(getClass().getName(), ".json");
+ private File createTemporaryFile(Object content, String extension) throws
Exception {
+ File file = File.createTempFile(getClass().getName(), extension);
file.deleteOnExit();
BufferedWriter out = new BufferedWriter(new FileWriter(file));
- out.write(json.toString());
+ out.write(content.toString());
out.close();
return file;
}
@@ -79,7 +83,7 @@ public class JsonContainerConfigLoaderTe
nested.put(NESTED_NAME, NESTED_VALUE);
json.put(NESTED_KEY, nested);
- return createContainer(json);
+ return createTemporaryFile(json, ".json");
}
private void createConfigForTest(String containers) throws
ContainerConfigException {
@@ -117,7 +121,7 @@ public class JsonContainerConfigLoaderTe
.put(NESTED_KEY, NESTED_VALUE);
File parentFile = createDefaultContainer();
- File childFile = createContainer(json);
+ File childFile = createTemporaryFile(json, ".json");
createConfigForTest(childFile.getAbsolutePath() +
JsonContainerConfigLoader.FILE_SEPARATOR +
parentFile.getAbsolutePath());
@@ -139,7 +143,7 @@ public class JsonContainerConfigLoaderTe
json.put(NESTED_KEY, nested);
- File childFile = createContainer(json);
+ File childFile = createTemporaryFile(json, ".json");
File parentFile = createDefaultContainer();
createConfigForTest(childFile.getAbsolutePath() +
JsonContainerConfigLoader.FILE_SEPARATOR +
parentFile.getAbsolutePath());
@@ -179,7 +183,7 @@ public class JsonContainerConfigLoaderTe
json.put(PARENT_KEY, "bad bad bad parent!");
json.put(ARRAY_NAME, ARRAY_ALT_VALUE);
- createConfigForTest(createContainer(json).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
}
@Test
@@ -198,7 +202,7 @@ public class JsonContainerConfigLoaderTe
json.put("expression", "Hello, ${world}!");
json.put("world", "Earth");
- createConfigForTest(createContainer(json).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
assertEquals("Hello, Earth!", config.getString(DEFAULT_CONTAINER,
"expression"));
}
@@ -210,7 +214,7 @@ public class JsonContainerConfigLoaderTe
json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
json.put("expression", "port=${SERVER_PORT}");
- createConfigForTest(createContainer(json).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
assertEquals("port=8080", config.getString(DEFAULT_CONTAINER,
"expression"));
}
@@ -223,7 +227,7 @@ public class JsonContainerConfigLoaderTe
json.put("port", "${SERVER_PORT}");
json.put("host", "${SERVER_HOST}");
- createConfigForTest(createContainer(json).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
assertEquals("8080", config.getString(DEFAULT_CONTAINER, "port"));
assertEquals("8080", config.getString("testContainer", "port"));
@@ -239,7 +243,7 @@ public class JsonContainerConfigLoaderTe
json.put(PARENT_KEY, DEFAULT_CONTAINER);
json.put("parentExpression", "${parent['" + TOP_LEVEL_NAME + "']}");
- File childFile = createContainer(json);
+ File childFile = createTemporaryFile(json, ".json");
File parentFile = createDefaultContainer();
createConfigForTest(childFile.getAbsolutePath() +
JsonContainerConfigLoader.FILE_SEPARATOR +
parentFile.getAbsolutePath());
@@ -251,7 +255,7 @@ public class JsonContainerConfigLoaderTe
public void nullEntryEvaluation() throws Exception {
// We use a JSON Object here to guarantee that we're well formed up front.
JSONObject json = new JSONObject("{ 'gadgets.container' : ['default'],
features : { osapi : null }}");
- createConfigForTest(createContainer(json).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
assertNull(config.getMap("default", "features").get("osapi"));
}
@@ -261,11 +265,74 @@ public class JsonContainerConfigLoaderTe
JSONObject parent = new JSONObject("{ 'gadgets.container' : ['default'],
features : { osapi : 'foo' }}");
JSONObject child = new JSONObject("{ 'gadgets.container' : ['child'],
features : null}");
JSONObject grand = new JSONObject("{ 'gadgets.container' : ['grand'],
parent : 'child'}");
- createConfigForTest(createContainer(parent).getAbsolutePath());
- createConfigForTest(createContainer(child).getAbsolutePath());
- createConfigForTest(createContainer(grand).getAbsolutePath());
+ createConfigForTest(createTemporaryFile(parent,
".json").getAbsolutePath());
+ createConfigForTest(createTemporaryFile(child, ".json").getAbsolutePath());
+ createConfigForTest(createTemporaryFile(grand, ".json").getAbsolutePath());
assertEquals("foo", config.getMap("default", "features").get("osapi"));
assertNull(config.getProperty("child", "features"));
assertNull(config.getProperty("grand", "features"));
}
+
+ @Test
+ public void resourceLoaderClasspathTest() throws Exception {
+ // Pointer to a file that we'll load from the classpath
+ String testFile = "classpath-accessible-test-file.txt";
+
+ // We use a JSON Object here to guarantee that we're well formed up front.
+ JSONObject json = new JSONObject();
+ json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
+ json.put(DYNAMICALLY_LOADED_VALUE_KEY, ResourceLoader.RESOURCE_PREFIX +
testFile);
+
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
+
+ assertEquals(testFile, config.getString(DEFAULT_CONTAINER,
DYNAMICALLY_LOADED_VALUE_KEY).trim());
+ }
+
+ @Test
+ public void resourceLoaderFileTest() throws Exception {
+ // Create a temporary file that we can load from
+ String dynamicValue = "dynamic value";
+ File temporaryFile = createTemporaryFile(dynamicValue, ".txt");
+
+ // We use a JSON Object here to guarantee that we're well formed up front.
+ JSONObject json = new JSONObject();
+ json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
+ json.put(DYNAMICALLY_LOADED_VALUE_KEY, ResourceLoader.FILE_PREFIX +
temporaryFile.getAbsolutePath());
+
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
+
+ assertEquals(dynamicValue, config.getString(DEFAULT_CONTAINER,
DYNAMICALLY_LOADED_VALUE_KEY).trim());
+ }
+
+ @Test
+ public void resourceLoaderClasspathFailureTest() throws Exception {
+ // Pointer to an invalid resource reference
+ String invalidResource = ResourceLoader.RESOURCE_PREFIX + "does-not-exist";
+
+ // We use a JSON Object here to guarantee that we're well formed up front.
+ JSONObject json = new JSONObject();
+ json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
+ json.put(DYNAMICALLY_LOADED_VALUE_KEY, invalidResource);
+
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
+
+ // If we fail to load a resource a warning is logged and we just end up
with the raw value back
+ assertEquals(invalidResource, config.getString(DEFAULT_CONTAINER,
DYNAMICALLY_LOADED_VALUE_KEY));
+ }
+
+ @Test
+ public void resourceLoaderFileFailureTest() throws Exception {
+ // Pointer to an invalid resource reference
+ String invalidResource = ResourceLoader.FILE_PREFIX + "does-not-exist";
+
+ // We use a JSON Object here to guarantee that we're well formed up front.
+ JSONObject json = new JSONObject();
+ json.put(CONTAINER_KEY, new String[]{DEFAULT_CONTAINER});
+ json.put(DYNAMICALLY_LOADED_VALUE_KEY, invalidResource);
+
+ createConfigForTest(createTemporaryFile(json, ".json").getAbsolutePath());
+
+ // If we fail to load a resource a warning is logged and we just end up
with the raw value back
+ assertEquals(invalidResource, config.getString(DEFAULT_CONTAINER,
DYNAMICALLY_LOADED_VALUE_KEY));
+ }
}
Added:
shindig/trunk/java/common/src/test/resources/classpath-accessible-test-file.txt
URL:
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/resources/classpath-accessible-test-file.txt?rev=1202283&view=auto
==============================================================================
---
shindig/trunk/java/common/src/test/resources/classpath-accessible-test-file.txt
(added)
+++
shindig/trunk/java/common/src/test/resources/classpath-accessible-test-file.txt
Tue Nov 15 16:25:34 2011
@@ -0,0 +1 @@
+classpath-accessible-test-file.txt
\ No newline at end of file