mirror of https://github.com/apache/jclouds.git
JCLOUDS-897: Remove the Rocoto dependency
This commit is contained in:
parent
68a429f366
commit
7053a7870d
|
@ -17,3 +17,5 @@ TAGS
|
|||
atlassian-ide-plugin.xml
|
||||
.DS_Store
|
||||
.java-version
|
||||
.factorypath
|
||||
.apt_generated
|
||||
|
|
|
@ -20,27 +20,31 @@ import static org.jclouds.reflect.Reflection2.method;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.functions.ExpandProperties;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.openstack.swift.SwiftApiMetadata;
|
||||
import org.jclouds.reflect.Invocation;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.nnsoft.guice.rocoto.Rocoto;
|
||||
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
public class BasePayloadTest {
|
||||
protected Injector i = Guice.createInjector(Rocoto.expandVariables(new ConfigurationModule() {
|
||||
protected void bindConfigurations() {
|
||||
bindProperties(new SwiftApiMetadata().getDefaultProperties());
|
||||
protected Injector i = Guice.createInjector(new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
Properties expanded = new ExpandProperties().apply(new SwiftApiMetadata().getDefaultProperties());
|
||||
Names.bindProperties(binder(), expanded);
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
}
|
||||
}), new GsonModule());
|
||||
}, new GsonModule());
|
||||
|
||||
protected GeneratedHttpRequest requestForArgs(List<Object> args) {
|
||||
try {
|
||||
|
|
10
core/pom.xml
10
core/pom.xml
|
@ -38,10 +38,7 @@
|
|||
</scm>
|
||||
|
||||
<properties>
|
||||
<jclouds.osgi.import>
|
||||
org.nnsoft.guice.rocoto*;version="[6.1,7)",
|
||||
*
|
||||
</jclouds.osgi.import>
|
||||
<jclouds.osgi.import>*</jclouds.osgi.import>
|
||||
<jclouds.osgi.export>org.jclouds*;version=${project.version};-noimport:=true</jclouds.osgi.export>
|
||||
<jclouds.osgi.activator>org.jclouds.osgi.Activator</jclouds.osgi.activator>
|
||||
</properties>
|
||||
|
@ -60,11 +57,6 @@
|
|||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.99soft.guice</groupId>
|
||||
<artifactId>rocoto</artifactId>
|
||||
<version>6.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
|
|
|
@ -58,10 +58,10 @@ import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
|||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||
import org.jclouds.config.BindApiContextWithWildcardExtendsExplicitAndRawType;
|
||||
import org.jclouds.config.BindNameToContext;
|
||||
import org.jclouds.config.BindPropertiesToExpandedValues;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.events.config.ConfiguresEventBus;
|
||||
import org.jclouds.events.config.EventBusModule;
|
||||
import org.jclouds.functions.ExpandProperties;
|
||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
@ -314,7 +314,7 @@ public class ContextBuilder {
|
|||
|
||||
Properties resolved = resolveProperties(unexpanded, providerId, keysToResolve, optionalKeys);
|
||||
|
||||
Properties expanded = expandProperties(resolved);
|
||||
Properties expanded = new ExpandProperties().apply(resolved);
|
||||
|
||||
Supplier<Credentials> credentialsSupplier = buildCredentialsSupplier(expanded);
|
||||
|
||||
|
@ -351,10 +351,10 @@ public class ContextBuilder {
|
|||
|
||||
private Properties currentStateToUnexpandedProperties() {
|
||||
Properties defaults = new Properties();
|
||||
defaults.putAll(apiMetadata.getDefaultProperties());
|
||||
putAllAsString(apiMetadata.getDefaultProperties(), defaults);
|
||||
defaults.setProperty(PROPERTY_PROVIDER, providerId);
|
||||
if (providerMetadata.isPresent()) {
|
||||
defaults.putAll(providerMetadata.get().getDefaultProperties());
|
||||
putAllAsString(providerMetadata.get().getDefaultProperties(), defaults);
|
||||
defaults.setProperty(PROPERTY_ISO3166_CODES, Joiner.on(',').join(providerMetadata.get().getIso3166Codes()));
|
||||
}
|
||||
if (endpoint.isPresent())
|
||||
|
@ -367,21 +367,22 @@ public class ContextBuilder {
|
|||
if (credential != null)
|
||||
defaults.setProperty(PROPERTY_CREDENTIAL, credential);
|
||||
if (overrides.isPresent())
|
||||
defaults.putAll(checkNotNull(overrides.get(), "overrides"));
|
||||
defaults.putAll(propertiesPrefixedWithJcloudsApiOrProviderId(getSystemProperties(), apiMetadata.getId(), providerId));
|
||||
putAllAsString(overrides.get(), defaults);
|
||||
putAllAsString(propertiesPrefixedWithJcloudsApiOrProviderId(getSystemProperties(), apiMetadata.getId(), providerId), defaults);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
private static void putAllAsString(Map<?, ?> source, Properties target) {
|
||||
for (Map.Entry<?, ?> entry : source.entrySet()) {
|
||||
target.setProperty(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected Properties getSystemProperties() {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
|
||||
private Properties expandProperties(final Properties resolved) {
|
||||
return Guice.createInjector(GUICE_STAGE, new BindPropertiesToExpandedValues(resolved)).getInstance(Properties.class);
|
||||
}
|
||||
|
||||
public static Injector buildInjector(String name, ProviderMetadata providerMetadata, Supplier<Credentials> creds, List<Module> inputModules) {
|
||||
List<Module> modules = newArrayList();
|
||||
modules.addAll(inputModules);
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
||||
import org.nnsoft.guice.rocoto.Rocoto;
|
||||
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* expands properties.
|
||||
*/
|
||||
public class BindPropertiesToExpandedValues extends AbstractModule {
|
||||
private final Properties resolved;
|
||||
|
||||
public BindPropertiesToExpandedValues(Properties resolved) {
|
||||
this.resolved = checkNotNull(resolved, "resolved");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(Rocoto.expandVariables(new ConfigurationModule() {
|
||||
|
||||
@Override
|
||||
protected void bindConfigurations() {
|
||||
bindProperties(resolved);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Properties expanded(FilterStringsBoundToInjectorByName filterStringsBoundByName) {
|
||||
Properties props = new Properties();
|
||||
props.putAll(filterStringsBoundByName.apply(Predicates.<String> alwaysTrue()));
|
||||
return props;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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.jclouds.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* Resolves the values of the properties so they can be inferred from other
|
||||
* properties.
|
||||
*/
|
||||
public class ExpandProperties implements Function<Properties, Properties> {
|
||||
|
||||
// Matches variables in a string such as ${foo.bar}
|
||||
private static final Pattern VAR = Pattern.compile("\\$\\{[^\\}]+}");
|
||||
|
||||
@Override
|
||||
public Properties apply(final Properties properties) {
|
||||
checkNotNull(properties, "properties cannot be null");
|
||||
|
||||
// Only expand the properties that are Strings
|
||||
Map<String, String> stringProperties = Maps.toMap(properties.stringPropertyNames(),
|
||||
new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(String input) {
|
||||
return properties.getProperty(input);
|
||||
}
|
||||
});
|
||||
|
||||
boolean pendingReplacements = true;
|
||||
Map<String, String> propertiesToResolve = new HashMap<String, String>(stringProperties);
|
||||
|
||||
while (pendingReplacements) {
|
||||
Map<String, String> leafs = leafs(propertiesToResolve);
|
||||
if (leafs.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
pendingReplacements = resolveProperties(propertiesToResolve, leafs);
|
||||
}
|
||||
|
||||
// Replace the values with the resolved ones
|
||||
Properties resolved = new Properties();
|
||||
resolved.putAll(properties);
|
||||
for (Map.Entry<String, String> entry : propertiesToResolve.entrySet()) {
|
||||
resolved.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private Map<String, String> leafs(Map<String, String> input) {
|
||||
return Maps.filterValues(input, new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
Matcher m = VAR.matcher(input);
|
||||
return !m.find();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean resolveProperties(Map<String, String> properties, Map<String, String> variables) {
|
||||
boolean anyReplacementDone = false;
|
||||
for (String key : properties.keySet()) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
Matcher m = VAR.matcher(properties.get(key));
|
||||
while (m.find()) {
|
||||
String match = m.group();
|
||||
// Remove the ${} from the matched variable
|
||||
String var = match.substring(2, match.length() - 1);
|
||||
// Avoid recursive properties. Only get he value if the variable
|
||||
// is different than the current key
|
||||
Optional<String> value = var.equals(key) ? Optional.<String> absent() : Optional.fromNullable(variables
|
||||
.get(var));
|
||||
// Replace by the value or leave the original value
|
||||
m.appendReplacement(sb, value.or("\\" + match));
|
||||
if (value.isPresent()) {
|
||||
anyReplacementDone = true;
|
||||
}
|
||||
}
|
||||
m.appendTail(sb);
|
||||
properties.put(key, sb.toString());
|
||||
}
|
||||
return anyReplacementDone;
|
||||
}
|
||||
|
||||
}
|
|
@ -74,13 +74,13 @@ public class ContextBuilderTest {
|
|||
assertEquals(endpoint, URI.create("http://foo.service.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContextName() {
|
||||
ContextBuilder withNoName = testContextBuilder().endpoint("http://${jclouds.identity}.service.com").name("mytest")
|
||||
.credentials("foo", "bar");
|
||||
Context context = withNoName.build();
|
||||
assertEquals(context.getName(), "mytest");
|
||||
}
|
||||
@Test
|
||||
public void testContextName() {
|
||||
ContextBuilder withNoName = testContextBuilder().endpoint("http://${jclouds.identity}.service.com").name("mytest")
|
||||
.credentials("foo", "bar");
|
||||
Context context = withNoName.build();
|
||||
assertEquals(context.getName(), "mytest");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderMetadataBoundWithCorrectEndpoint() {
|
||||
|
@ -129,7 +129,28 @@ public class ContextBuilderTest {
|
|||
String version = withVersionInProps.buildInjector().getInstance(Key.get(String.class, ApiVersion.class));
|
||||
assertEquals(version, "1.1");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAllPropertiesAreStrings() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty("foo", "bar");
|
||||
overrides.put("one", 1);
|
||||
overrides.put("two", 2.0f);
|
||||
overrides.put("true", true);
|
||||
overrides.put("object", new Object() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "object";
|
||||
}
|
||||
});
|
||||
Context withObjectsInProps = testContextBuilder().overrides(overrides).build();
|
||||
Properties resolved = withObjectsInProps.getProviderMetadata().getDefaultProperties();
|
||||
assertEquals(resolved.getProperty("foo"), "bar");
|
||||
assertEquals(resolved.getProperty("one"), "1");
|
||||
assertEquals(resolved.getProperty("true"), "true");
|
||||
assertEquals(resolved.getProperty("object"), "object");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddHttpModuleIfNotPresent() {
|
||||
List<Module> modules = Lists.newArrayList();
|
||||
|
|
|
@ -27,7 +27,7 @@ import com.google.auto.service.AutoService;
|
|||
* Implementation of {@link ApiMetadata} for testing.
|
||||
*/
|
||||
@AutoService(ApiMetadata.class)
|
||||
public class JcloudsTestBlobStoreApiMetadata extends BaseHttpApiMetadata {
|
||||
public class JcloudsTestBlobStoreApiMetadata extends BaseHttpApiMetadata<IntegrationTestClient> {
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.config;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
|
||||
/**
|
||||
* Tests behavior of BindPropertiesToExpandedValues
|
||||
*/
|
||||
@Test(groups = "unit", testName = "BindPropertiesToExpandedValuesTest")
|
||||
public class BindPropertiesToExpandedValuesTest {
|
||||
|
||||
@Test
|
||||
public void testExpand() {
|
||||
Properties input = new Properties();
|
||||
input.setProperty("id", "1234");
|
||||
input.setProperty("path", "path:${id}");
|
||||
Properties output = Guice.createInjector(new BindPropertiesToExpandedValues(input)).getInstance(Properties.class);
|
||||
|
||||
Properties expected = new Properties();
|
||||
expected.setProperty("id", "1234");
|
||||
expected.setProperty("path", "path:1234");
|
||||
assertEquals(output, expected);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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.jclouds.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = "unit", testName = "ExpandPropertiesTest")
|
||||
public class ExpandPropertiesTest {
|
||||
|
||||
@Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "properties cannot be null")
|
||||
public void testPropertiesMandatory() {
|
||||
new ExpandProperties().apply(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResolveProperties() {
|
||||
Properties props = new Properties();
|
||||
props.put("number", 1);
|
||||
props.put("two", "2");
|
||||
props.put("greeting", "hello");
|
||||
props.put("simple", "simple: ${greeting}");
|
||||
props.put("nested", "nested: ${simple}");
|
||||
props.put("mixed", "mixed: ${nested} and ${simple}");
|
||||
props.put("unexisting", "${foobar} substitution");
|
||||
props.put("recursive", "variable5 ${recursive} recursive ${unexisting}");
|
||||
props.put("characters{{$$", "characters");
|
||||
props.put("ugly", "substitute: ${characters{{$$}");
|
||||
|
||||
Properties resolved = new ExpandProperties().apply(props);
|
||||
|
||||
assertEquals(resolved.size(), props.size());
|
||||
assertEquals(resolved.get("number"), 1);
|
||||
assertEquals(resolved.get("two"), "2");
|
||||
assertEquals(resolved.get("greeting"), "hello");
|
||||
assertEquals(resolved.get("simple"), "simple: hello");
|
||||
assertEquals(resolved.get("nested"), "nested: simple: hello");
|
||||
assertEquals(resolved.get("mixed"), "mixed: nested: simple: hello and simple: hello");
|
||||
assertEquals(resolved.get("unexisting"), "${foobar} substitution");
|
||||
assertEquals(resolved.get("recursive"), "variable5 ${recursive} recursive ${unexisting}");
|
||||
assertEquals(resolved.get("ugly"), "substitute: characters");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoLeafs() {
|
||||
Properties props = new Properties();
|
||||
props.put("one", "${two}");
|
||||
props.put("two", "${one}");
|
||||
|
||||
Properties resolved = new ExpandProperties().apply(props);
|
||||
|
||||
assertEquals(resolved.size(), props.size());
|
||||
assertEquals(resolved.get("one"), "${two}");
|
||||
assertEquals(resolved.get("two"), "${one}");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue