From 82bb9e98f70830569d0145d868f6f27716acdf91 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sat, 24 Apr 2010 11:09:47 -0700 Subject: [PATCH] updated ec2 to support instances without a keypair to exist and not break computeservice --- .../aws/ec2/compute/domain/RegionTag.java | 5 + .../RunningInstanceToNodeMetadata.java | 56 +-- .../jclouds/aws/ec2/services/AMIClient.java | 2 +- .../compute/functions/ImageParserTest.java | 2 +- .../RunningInstanceToNodeMetadataTest.java | 150 ++++++++ .../compute/BaseComputeServiceLiveTest.java | 18 +- .../http/options/BaseHttpRequestOptions.java | 62 ++++ .../src/main/java/org/jclouds/util/Utils.java | 321 +++++++++--------- 8 files changed, 423 insertions(+), 193 deletions(-) create mode 100644 aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/RegionTag.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/RegionTag.java index 128dd3c1fa..885ab27e5b 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/RegionTag.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/domain/RegionTag.java @@ -72,4 +72,9 @@ public class RegionTag { return tag; } + @Override + public String toString() { + return "RegionTag [region=" + region + ", tag=" + tag + "]"; + } + } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadata.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadata.java index acfcd0b5b5..80afa80ab8 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadata.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadata.java @@ -19,6 +19,7 @@ package org.jclouds.aws.ec2.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.util.Utils.nullSafeSet; import java.net.InetAddress; import java.net.URI; @@ -28,7 +29,6 @@ import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; -import com.google.common.collect.Maps; import org.jclouds.aws.ec2.compute.domain.RegionTag; import org.jclouds.aws.ec2.domain.Image; import org.jclouds.aws.ec2.domain.InstanceState; @@ -46,8 +46,8 @@ import org.jclouds.domain.Credentials; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; /** * @author Adrian Cole @@ -76,16 +76,23 @@ public class RunningInstanceToNodeMetadata implements Function userMetadata = ImmutableMap. of(); - String tag = instance.getKeyName().replaceAll("-[0-9]+", ""); + NodeState state = instanceToNodeState.get(instance.getInstanceState()); Set publicAddresses = nullSafeSet(instance.getIpAddress()); Set privateAddresses = nullSafeSet(instance.getPrivateIpAddress()); - Credentials credentials = new Credentials(getLoginAccountFor(instance), getPrivateKeyOrNull( - instance, tag)); - String locationId = instance.getAvailabilityZone().toString(); Map extra = getExtra(instance); @@ -94,25 +101,25 @@ public class RunningInstanceToNodeMetadata implements Function getExtra(RunningInstance instance) { - Map extra = Maps.newHashMap(); + Map extra = Maps.newHashMap(); - //put storage info - /* TODO: only valid for UNIX */ - InstanceTypeToStorageMappingUnix instanceToStorageMapping = - new InstanceTypeToStorageMappingUnix(); - extra.putAll(instanceToStorageMapping.apply(instance.getInstanceType())); + // put storage info + /* TODO: only valid for UNIX */ + InstanceTypeToStorageMappingUnix instanceToStorageMapping = new InstanceTypeToStorageMappingUnix(); + extra.putAll(instanceToStorageMapping.apply(instance.getInstanceType())); - return extra; + return extra; } @VisibleForTesting @@ -131,11 +138,4 @@ public class RunningInstanceToNodeMetadata implements Function nullSafeSet(InetAddress in) { - if (in == null) { - return ImmutableSet. of(); - } - return ImmutableSet. of(in); - } - } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java index 1f15d8365a..ffea2bec28 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/AMIClient.java @@ -55,7 +55,7 @@ public interface AMIClient { * /> * @see DescribeImagesOptions */ - @Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) + @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) Set describeImagesInRegion(Region region, DescribeImagesOptions... options); /** diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/ImageParserTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/ImageParserTest.java index e1ae31ba80..3e110b13d0 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/ImageParserTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/ImageParserTest.java @@ -42,7 +42,7 @@ import com.google.common.collect.Iterables; /** * @author Adrian Cole */ -@Test(groups = "unit", testName = "compute.PropertiesTest") +@Test(groups = "unit", testName = "compute.ImageParserTest") public class ImageParserTest extends BaseHandlerTest { public void testParseAlesticCanonicalImage() { diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java new file mode 100644 index 0000000000..0fa27778bc --- /dev/null +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java @@ -0,0 +1,150 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.aws.ec2.compute.functions; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.testng.Assert.assertEquals; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; + +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.compute.domain.RegionTag; +import org.jclouds.aws.ec2.domain.AvailabilityZone; +import org.jclouds.aws.ec2.domain.Image; +import org.jclouds.aws.ec2.domain.InstanceState; +import org.jclouds.aws.ec2.domain.InstanceType; +import org.jclouds.aws.ec2.domain.KeyPair; +import org.jclouds.aws.ec2.domain.RunningInstance; +import org.jclouds.aws.ec2.services.AMIClient; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; +import org.jclouds.domain.Credentials; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ec2.RunningInstanceToNodeMetadataTest") +public class RunningInstanceToNodeMetadataTest { + + @SuppressWarnings("unchecked") + @Test + public void testApplyWithNoKeyPairCreatesTagOfIdPrefixedByTagAndNullCredentials() + throws UnknownHostException { + AMIClient amiClient = createMock(AMIClient.class); + Map credentialsMap = createMock(Map.class); + PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); + RunningInstance instance = createMock(RunningInstance.class); + + expect(instance.getId()).andReturn("id").atLeastOnce(); + expect(instance.getKeyName()).andReturn(null).atLeastOnce(); + expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); + + expect(instance.getIpAddress()).andReturn( + InetAddress.getByAddress(new byte[] { 12, 10, 10, 1 })); + expect(instance.getPrivateIpAddress()).andReturn( + InetAddress.getByAddress(new byte[] { 10, 10, 10, 1 })); + + expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); + + expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); + + replay(amiClient); + replay(credentialsMap); + replay(credentialProvider); + replay(instance); + + RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(amiClient, + credentialsMap, credentialProvider); + + NodeMetadata metadata = parser.apply(instance); + + assertEquals(metadata.getTag(), "NOTAG-id"); + assertEquals(metadata.getCredentials(), null); + + verify(amiClient); + verify(credentialsMap); + verify(credentialProvider); + verify(instance); + } + + @SuppressWarnings("unchecked") + @Test + public void testApplyWithKeyPairCreatesTagOfParsedKeyPairAndCredentialsBasedOnIt() + throws UnknownHostException { + AMIClient amiClient = createMock(AMIClient.class); + Map credentialsMap = createMock(Map.class); + PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); + RunningInstance instance = createMock(RunningInstance.class); + Image image = createMock(Image.class); + + expect(instance.getId()).andReturn("id").atLeastOnce(); + expect(instance.getKeyName()).andReturn("keyName-100").atLeastOnce(); + expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); + + expect(instance.getIpAddress()).andReturn( + InetAddress.getByAddress(new byte[] { 12, 10, 10, 1 })); + expect(instance.getPrivateIpAddress()).andReturn( + InetAddress.getByAddress(new byte[] { 10, 10, 10, 1 })); + + expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); + + expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); + + expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn( + ImmutableSet. of(image)); + + expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); + + expect(credentialsMap.get(new RegionTag(Region.US_EAST_1, "keyName-100"))).andReturn( + new KeyPair(Region.US_EAST_1, "keyName-100", "keyFingerprint", "pass")); + + expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); + + expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); + + replay(amiClient); + replay(credentialsMap); + replay(credentialProvider); + replay(instance); + + RunningInstanceToNodeMetadata parser = new RunningInstanceToNodeMetadata(amiClient, + credentialsMap, credentialProvider); + + NodeMetadata metadata = parser.apply(instance); + + assertEquals(metadata.getTag(), "keyName"); + + assertEquals(metadata.getCredentials(), new Credentials("user", "pass")); + + verify(amiClient); + verify(credentialsMap); + verify(credentialProvider); + verify(instance); + } + +} diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index 9b3a4c0142..105258775f 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -304,16 +304,20 @@ public abstract class BaseComputeServiceLiveTest { } public void testGetNodesWithDetails() throws Exception { - for (Entry node : client.getNodes(new GetNodesOptions().withDetails()).entrySet()) { + for (Entry node : client.getNodes( + new GetNodesOptions().withDetails()).entrySet()) { assertEquals(node.getKey(), node.getValue().getId()); - assert node.getValue().getId() != null; - assert node.getValue().getLocationId() != null; + assert node.getValue().getId() != null : node; + assert node.getValue().getLocationId() != null : node; assertEquals(node.getValue().getType(), ComputeType.NODE); assert node.getValue() instanceof NodeMetadata; - NodeMetadata nodeMetadata = (NodeMetadata)node.getValue(); - assertNotNull(nodeMetadata.getName()); - assertNotNull(nodeMetadata.getPublicAddresses()); - assert nodeMetadata.getPublicAddresses().size() > 1; + NodeMetadata nodeMetadata = (NodeMetadata) node.getValue(); + assert nodeMetadata.getId() != null : nodeMetadata; + // user specified name is not always supported + // assert nodeMetadata.getName() != null : nodeMetadata; + assert nodeMetadata.getPublicAddresses() != null : nodeMetadata; + + assert nodeMetadata.getPublicAddresses().size() > 1 : nodeMetadata; assertNotNull(nodeMetadata.getPrivateAddresses()); } } diff --git a/core/src/main/java/org/jclouds/http/options/BaseHttpRequestOptions.java b/core/src/main/java/org/jclouds/http/options/BaseHttpRequestOptions.java index 34254c29e4..c5ee6aaec1 100644 --- a/core/src/main/java/org/jclouds/http/options/BaseHttpRequestOptions.java +++ b/core/src/main/java/org/jclouds/http/options/BaseHttpRequestOptions.java @@ -96,4 +96,66 @@ public class BaseHttpRequestOptions implements HttpRequestOptions { return formParameters; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((formParameters == null) ? 0 : formParameters.hashCode()); + result = prime * result + ((headers == null) ? 0 : headers.hashCode()); + result = prime * result + ((matrixParameters == null) ? 0 : matrixParameters.hashCode()); + result = prime * result + ((pathSuffix == null) ? 0 : pathSuffix.hashCode()); + result = prime * result + ((payload == null) ? 0 : payload.hashCode()); + result = prime * result + ((queryParameters == null) ? 0 : queryParameters.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BaseHttpRequestOptions other = (BaseHttpRequestOptions) obj; + if (formParameters == null) { + if (other.formParameters != null) + return false; + } else if (!formParameters.equals(other.formParameters)) + return false; + if (headers == null) { + if (other.headers != null) + return false; + } else if (!headers.equals(other.headers)) + return false; + if (matrixParameters == null) { + if (other.matrixParameters != null) + return false; + } else if (!matrixParameters.equals(other.matrixParameters)) + return false; + if (pathSuffix == null) { + if (other.pathSuffix != null) + return false; + } else if (!pathSuffix.equals(other.pathSuffix)) + return false; + if (payload == null) { + if (other.payload != null) + return false; + } else if (!payload.equals(other.payload)) + return false; + if (queryParameters == null) { + if (other.queryParameters != null) + return false; + } else if (!queryParameters.equals(other.queryParameters)) + return false; + return true; + } + + @Override + public String toString() { + return "[formParameters=" + formParameters + ", headers=" + headers + ", matrixParameters=" + + matrixParameters + ", pathSuffix=" + pathSuffix + ", payload=" + payload + + ", queryParameters=" + queryParameters + "]"; + } + } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/util/Utils.java b/core/src/main/java/org/jclouds/util/Utils.java index 97ea4bbb72..7201fab2cb 100644 --- a/core/src/main/java/org/jclouds/util/Utils.java +++ b/core/src/main/java/org/jclouds/util/Utils.java @@ -29,6 +29,7 @@ import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.Collection; import java.util.Map; +import java.util.Set; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -40,187 +41,195 @@ import org.jclouds.logging.Logger; import com.google.common.base.Charsets; import com.google.common.base.Supplier; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; import com.google.common.io.Closeables; import com.google.common.io.OutputSupplier; /** * General utilities used in jclouds code. - * + * * @author Adrian Cole */ public class Utils { - public static final String UTF8_ENCODING = "UTF-8"; + public static final String UTF8_ENCODING = "UTF-8"; - public static Object propagateOrNull(Exception from) { - Throwables.propagate(from); - assert false : "exception should have propogated"; - return null; - } + public static Set nullSafeSet(T in) { + if (in == null) { + return ImmutableSet. of(); + } + return ImmutableSet. of(in); + } - public static String replaceTokens(String value, Collection> tokenValues) { - for (Entry tokenValue : tokenValues) { - value = replaceAll(value, TOKEN_TO_PATTERN.get(tokenValue.getKey()), tokenValue.getValue()); - } - return value; - } + public static Object propagateOrNull(Exception from) { + Throwables.propagate(from); + assert false : "exception should have propogated"; + return null; + } - public static String replaceAll(String returnVal, Pattern pattern, String replace) { - Matcher m = pattern.matcher(returnVal); - returnVal = m.replaceAll(replace); - return returnVal; - } + public static String replaceTokens(String value, Collection> tokenValues) { + for (Entry tokenValue : tokenValues) { + value = replaceAll(value, TOKEN_TO_PATTERN.get(tokenValue.getKey()), tokenValue.getValue()); + } + return value; + } - public static String replaceAll(String input, char ifMatch, Pattern pattern, String replacement) { - if (input.indexOf(ifMatch) != -1) { - input = pattern.matcher(input).replaceAll(replacement); - } - return input; - } + public static String replaceAll(String returnVal, Pattern pattern, String replace) { + Matcher m = pattern.matcher(returnVal); + returnVal = m.replaceAll(replace); + return returnVal; + } - public static String replaceAll(String input, char match, String replacement) { - if (input.indexOf(match) != -1) { - input = CHAR_TO_PATTERN.get(match).matcher(input).replaceAll(replacement); - } - return input; - } + public static String replaceAll(String input, char ifMatch, Pattern pattern, String replacement) { + if (input.indexOf(ifMatch) != -1) { + input = pattern.matcher(input).replaceAll(replacement); + } + return input; + } - /** - * converts an {@link OutputStream} to an {@link OutputSupplier} - * - */ - public static OutputSupplier newOutputStreamSupplier(final OutputStream output) { - checkNotNull(output, "output"); - return new OutputSupplier() { - public OutputStream getOutput() throws IOException { - return output; - } - }; - } + public static String replaceAll(String input, char match, String replacement) { + if (input.indexOf(match) != -1) { + input = CHAR_TO_PATTERN.get(match).matcher(input).replaceAll(replacement); + } + return input; + } - public static boolean enventuallyTrue(Supplier assertion, long inconsistencyMillis) + /** + * converts an {@link OutputStream} to an {@link OutputSupplier} + * + */ + public static OutputSupplier newOutputStreamSupplier(final OutputStream output) { + checkNotNull(output, "output"); + return new OutputSupplier() { + public OutputStream getOutput() throws IOException { + return output; + } + }; + } + + public static boolean enventuallyTrue(Supplier assertion, long inconsistencyMillis) throws InterruptedException { - for (int i = 0; i < 30; i++) { - if (!assertion.get()) { - Thread.sleep(inconsistencyMillis / 30); - continue; - } - return true; - } - return false; + for (int i = 0; i < 30; i++) { + if (!assertion.get()) { + Thread.sleep(inconsistencyMillis / 30); + continue; + } + return true; + } + return false; - } + } - @Resource - protected static Logger logger = Logger.NULL; + @Resource + protected static Logger logger = Logger.NULL; - public static String toStringAndClose(InputStream input) throws IOException { - checkNotNull(input, "input"); - try { - return new String(ByteStreams.toByteArray(input), Charsets.UTF_8); - } catch (IOException e) { - logger.warn(e, "Failed to read from stream"); - return null; - } catch (NullPointerException e) { - return null; - } finally { - Closeables.closeQuietly(input); - } - } + public static String toStringAndClose(InputStream input) throws IOException { + checkNotNull(input, "input"); + try { + return new String(ByteStreams.toByteArray(input), Charsets.UTF_8); + } catch (IOException e) { + logger.warn(e, "Failed to read from stream"); + return null; + } catch (NullPointerException e) { + return null; + } finally { + Closeables.closeQuietly(input); + } + } - public static InputStream toInputStream(String in) { - try { - return ByteStreams.newInputStreamSupplier(in.getBytes(Charsets.UTF_8)).getInput(); - } catch (IOException e) { - logger.warn(e, "Failed to convert %s to an inputStream", in); - throw new RuntimeException(e); - } - } + public static InputStream toInputStream(String in) { + try { + return ByteStreams.newInputStreamSupplier(in.getBytes(Charsets.UTF_8)).getInput(); + } catch (IOException e) { + logger.warn(e, "Failed to convert %s to an inputStream", in); + throw new RuntimeException(e); + } + } - /** - * Encode the given string with the given encoding, if possible. If the encoding fails with - * {@link UnsupportedEncodingException}, log a warning and fall back to the system's default - * encoding. - * - * @param str - * what to encode - * @param charsetName - * the name of a supported {@link java.nio.charset.Charset charset} - * @return properly encoded String. - */ - public static byte[] encodeString(String str, String charsetName) { - try { - return str.getBytes(charsetName); - } catch (UnsupportedEncodingException e) { - logger.warn(e, "Failed to encode string to bytes with encoding " + charsetName - + ". Falling back to system's default encoding"); - return str.getBytes(); - } - } + /** + * Encode the given string with the given encoding, if possible. If the encoding fails with + * {@link UnsupportedEncodingException}, log a warning and fall back to the system's default + * encoding. + * + * @param str + * what to encode + * @param charsetName + * the name of a supported {@link java.nio.charset.Charset charset} + * @return properly encoded String. + */ + public static byte[] encodeString(String str, String charsetName) { + try { + return str.getBytes(charsetName); + } catch (UnsupportedEncodingException e) { + logger.warn(e, "Failed to encode string to bytes with encoding " + charsetName + + ". Falling back to system's default encoding"); + return str.getBytes(); + } + } - /** - * Encode the given string with the UTF-8 encoding, the sane default. In the very unlikely event - * the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to - * the system's default encoding. - * - * @param str - * what to encode - * @return properly encoded String. - */ - public static byte[] encodeString(String str) { - return encodeString(str, UTF8_ENCODING); - } + /** + * Encode the given string with the UTF-8 encoding, the sane default. In the very unlikely event + * the encoding fails with {@link UnsupportedEncodingException}, log a warning and fall back to + * the system's default encoding. + * + * @param str + * what to encode + * @return properly encoded String. + */ + public static byte[] encodeString(String str) { + return encodeString(str, UTF8_ENCODING); + } - /** - * replaces tokens that are expressed as {token} - * - *

- * ex. if input is "hello {where}"
- * and replacements is "where" -> "world"
- * then replaceTokens returns "hello world" - * - * @param input - * source to replace - * @param replacements - * token/value pairs - */ - public static String replaceTokens(String input, Map replacements) { - Matcher matcher = Patterns.TOKEN_PATTERN.matcher(input); - StringBuilder builder = new StringBuilder(); - int i = 0; - while (matcher.find()) { - String replacement = replacements.get(matcher.group(1)); - builder.append(input.substring(i, matcher.start())); - if (replacement == null) - builder.append(matcher.group(0)); - else - builder.append(replacement); - i = matcher.end(); - } - builder.append(input.substring(i, input.length())); - return builder.toString(); - } + /** + * replaces tokens that are expressed as {token} + * + *

+ * ex. if input is "hello {where}"
+ * and replacements is "where" -> "world"
+ * then replaceTokens returns "hello world" + * + * @param input + * source to replace + * @param replacements + * token/value pairs + */ + public static String replaceTokens(String input, Map replacements) { + Matcher matcher = Patterns.TOKEN_PATTERN.matcher(input); + StringBuilder builder = new StringBuilder(); + int i = 0; + while (matcher.find()) { + String replacement = replacements.get(matcher.group(1)); + builder.append(input.substring(i, matcher.start())); + if (replacement == null) + builder.append(matcher.group(0)); + else + builder.append(replacement); + i = matcher.end(); + } + builder.append(input.substring(i, input.length())); + return builder.toString(); + } - /** - * Will throw an exception if the argument is null or empty. - * @param nullableString - * string to verify. Can be null or empty. - */ - public static void checkNotEmpty(String nullableString) { - checkNotEmpty(nullableString, "Argument can't be null or empty"); - } + /** + * Will throw an exception if the argument is null or empty. + * + * @param nullableString + * string to verify. Can be null or empty. + */ + public static void checkNotEmpty(String nullableString) { + checkNotEmpty(nullableString, "Argument can't be null or empty"); + } - /** - * Will throw an exception if the argument is null or empty. Accepts - * a custom error message. - * @param nullableString - * string to verify. Can be null or empty. - * @param message - * message to show in case of exception - */ - public static void checkNotEmpty(String nullableString, String message) { - checkArgument(nullableString != null && nullableString.length() > 0, - message); - } + /** + * Will throw an exception if the argument is null or empty. Accepts a custom error message. + * + * @param nullableString + * string to verify. Can be null or empty. + * @param message + * message to show in case of exception + */ + public static void checkNotEmpty(String nullableString, String message) { + checkArgument(nullableString != null && nullableString.length() > 0, message); + } }