http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindFiltersToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindFiltersToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindFiltersToIndexedFormParams.java new file mode 100644 index 0000000..5478d64 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindFiltersToIndexedFormParams.java @@ -0,0 +1,55 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.Multimap; + +/** + * Binds the Multimap to form parameters for filtering. + * + * <pre> + * https://ec2.amazonaws.com/?Action=DescribeTags + * &Filter.1.Name=resource-type + * &Filter.1.Value.1=instance + * &Filter.2.Name=key + * &Filter.2.Value.1=stack + * &Filter.3.Name=value + * &Filter.3.Value.1=Test + * &Filter.3.Value.2=Production + * &AUTHPARAMS + * </pre> + */ +@Singleton +public class BindFiltersToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Multimap, "this binder is only valid for Multimap"); + @SuppressWarnings("unchecked") + Multimap<String, String> filters = (Multimap<String, String>) input; + return AWSUtils.indexMultimapToFormValuesWithPrefix(request, "Filter", "Name", "Value", filters); + } + +}
http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupIdsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupIdsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupIdsToIndexedFormParams.java new file mode 100644 index 0000000..bec6dd7 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupIdsToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to query parameters named with GroupId.index + */ +@Singleton +public class BindGroupIdsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "GroupId", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupNamesToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupNamesToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupNamesToIndexedFormParams.java new file mode 100644 index 0000000..71a0114 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindGroupNamesToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to query parameters named with GroupName.index + */ +@Singleton +public class BindGroupNamesToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "GroupName", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindInstanceIdsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindInstanceIdsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindInstanceIdsToIndexedFormParams.java new file mode 100644 index 0000000..ca0ab58 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindInstanceIdsToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to form parameters named with InstanceId.index + */ +@Singleton +public class BindInstanceIdsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "InstanceId", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java new file mode 100644 index 0000000..0a058f6 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionToIndexedFormParams.java @@ -0,0 +1,37 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.ec2.util.IpPermissions; +import org.jclouds.http.HttpRequest; +import org.jclouds.net.domain.IpPermission; +import org.jclouds.rest.Binder; + +public class BindIpPermissionToIndexedFormParams implements Binder { + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof IpPermission, "this binder is only valid for IpPermission"); + IpPermission perm = (IpPermission) input; + return (R) request.toBuilder().replaceFormParams(IpPermissions.buildFormParametersForIndex(0, perm)).build(); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java new file mode 100644 index 0000000..f8030e9 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindIpPermissionsToIndexedFormParams.java @@ -0,0 +1,45 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.ec2.util.IpPermissions; +import org.jclouds.http.HttpRequest; +import org.jclouds.net.domain.IpPermission; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; + +public class BindIpPermissionsToIndexedFormParams implements Binder { + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Iterable, + "this binder is only valid for Iterable<IpPermission>"); + Builder<String, String> formBuilder = ImmutableMultimap.builder(); + int index = 0; + for (IpPermission perm : (Iterable<IpPermission>) input) + formBuilder.putAll(IpPermissions.buildFormParametersForIndex(index++, perm)); + ImmutableMultimap<String, String> forms = formBuilder.build(); + return forms.size() == 0 ? request : (R) request.toBuilder().replaceFormParams(forms).build(); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindKeyNamesToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindKeyNamesToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindKeyNamesToIndexedFormParams.java new file mode 100644 index 0000000..c1b72f1 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindKeyNamesToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to query parameters named with KeyName.index + */ +@Singleton +public class BindKeyNamesToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "KeyName", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindProductCodesToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindProductCodesToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindProductCodesToIndexedFormParams.java new file mode 100644 index 0000000..4651807 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindProductCodesToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the Iterable to form parameters named with ProductCode.index + */ +@Singleton +public class BindProductCodesToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexIterableToFormValuesWithPrefix(request, "ProductCode", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindPublicIpsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindPublicIpsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindPublicIpsToIndexedFormParams.java new file mode 100644 index 0000000..12dc23f --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindPublicIpsToIndexedFormParams.java @@ -0,0 +1,40 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to form parameters named with InstanceId.index + */ +@Singleton +public class BindPublicIpsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof String[], "this binder is only valid for String[] : " + + input.getClass()); + String[] addressStrings = (String[]) input; + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "PublicIp", addressStrings); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindResourceIdsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindResourceIdsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindResourceIdsToIndexedFormParams.java new file mode 100644 index 0000000..f9d2b96 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindResourceIdsToIndexedFormParams.java @@ -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.jclouds.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds Ids to query parameters named with ResourceId.index + */ +@Singleton +public class BindResourceIdsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Iterable, "this binder is only valid for Iterable<String>"); + return AWSUtils.indexIterableToFormValuesWithPrefix(request, "ResourceId", input); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignature.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignature.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignature.java new file mode 100644 index 0000000..bc5b9fd --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignature.java @@ -0,0 +1,53 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Charsets.UTF_8; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.io.BaseEncoding.base64; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; + +@Singleton +public class BindS3UploadPolicyAndSignature implements Binder { + private final FormSigner signer; + + @Inject + BindS3UploadPolicyAndSignature(FormSigner signer) { + this.signer = signer; + } + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + String encodedJson = base64().encode(checkNotNull(input, "json").toString().getBytes(UTF_8)); + Builder<String, String> builder = ImmutableMultimap.builder(); + builder.put("Storage.S3.UploadPolicy", encodedJson); + String signature = signer.sign(encodedJson); + builder.put("Storage.S3.UploadPolicySignature", signature); + return (R) request.toBuilder().replaceFormParams(builder.build()).build(); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagKeysToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagKeysToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagKeysToIndexedFormParams.java new file mode 100644 index 0000000..7b19cc7 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagKeysToIndexedFormParams.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.Iterables; + +/** + * Binds the Iterable<String> to form parameters named with Tag.index.Key + */ +@Singleton +public class BindTagKeysToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Iterable, "This binder is only valid for Iterable<String>"); + @SuppressWarnings("unchecked") + Iterable<String> keys = (Iterable<String>) input; + return AWSUtils.indexStringArrayToFormValuesWithStringFormat(request, "Tag.%s.Key", + Iterables.toArray(keys, String.class)); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagsToIndexedFormParams.java new file mode 100644 index 0000000..55801fb --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindTagsToIndexedFormParams.java @@ -0,0 +1,51 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.aws.util.AWSUtils.indexMapToFormValuesWithPrefix; + +import java.util.Map; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; + +public class BindTagsToIndexedFormParams implements Binder { + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkNotNull(input, "tags"); + Map<String, String> tagValues; + if (input instanceof Iterable) { + Builder<String, String> builder = ImmutableMap.<String, String> builder(); + for (String key : (Iterable<String>) input) { + builder.put(key, ""); + } + tagValues = builder.build(); + } else if (input instanceof Map) { + tagValues = Map.class.cast(input); + } else { + throw new IllegalArgumentException("This binder is only valid for Map<String,String> or Iterable<String>"); + } + return indexMapToFormValuesWithPrefix(request, "Tag", "Key", "Value", tagValues); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserGroupsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserGroupsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserGroupsToIndexedFormParams.java new file mode 100644 index 0000000..8faf0f4 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserGroupsToIndexedFormParams.java @@ -0,0 +1,50 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.Iterables; + +/** + * Binds the Iterable to query parameters named with UserGroup.index + */ +@Singleton +public class BindUserGroupsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable<?>: " + + input.getClass()); + checkValidUserGroup(input); + return AWSUtils.indexIterableToFormValuesWithPrefix(request, "UserGroup", input); + } + + private void checkValidUserGroup(Object input) { + Iterable<?> values = (Iterable<?>) input; + long size = Iterables.size(values); + checkArgument(size == 0 || (size == 1 && Iterables.getOnlyElement(values).equals("all")), + "only supported UserGroup is 'all'"); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdGroupPairToSourceSecurityGroupFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdGroupPairToSourceSecurityGroupFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdGroupPairToSourceSecurityGroupFormParams.java new file mode 100644 index 0000000..e1b6995 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdGroupPairToSourceSecurityGroupFormParams.java @@ -0,0 +1,47 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Singleton; + +import org.jclouds.ec2.domain.UserIdGroupPair; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; + +/** + * Binds the String [] to query parameters named with GroupName.index + */ +@Singleton +public class BindUserIdGroupPairToSourceSecurityGroupFormParams implements Binder { + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + checkArgument(checkNotNull(input, "input") instanceof UserIdGroupPair, + "this binder is only valid for UserIdGroupPair!"); + UserIdGroupPair pair = (UserIdGroupPair) input; + Builder<String, String> builder = ImmutableMultimap.builder(); + builder.put("SourceSecurityGroupOwnerId", pair.getUserId()); + builder.put("SourceSecurityGroupName", pair.getGroupName()); + return (R) request.toBuilder().replaceFormParams(builder.build()).build(); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdsToIndexedFormParams.java new file mode 100644 index 0000000..d57022a --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindUserIdsToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the Iterable to form parameters named with UserId.index + */ +@Singleton +public class BindUserIdsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexIterableToFormValuesWithPrefix(request, "UserId", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindVolumeIdsToIndexedFormParams.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindVolumeIdsToIndexedFormParams.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindVolumeIdsToIndexedFormParams.java new file mode 100644 index 0000000..cf9d8b3 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/BindVolumeIdsToIndexedFormParams.java @@ -0,0 +1,35 @@ +/* + * 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.ec2.binders; + +import javax.inject.Singleton; + +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the String [] to form parameters named with VolumeId.index + */ +@Singleton +public class BindVolumeIdsToIndexedFormParams implements Binder { + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "VolumeId", input); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java new file mode 100644 index 0000000..8013c1b --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/binders/IfNotNullBindAvailabilityZoneToFormParam.java @@ -0,0 +1,53 @@ +/* + * 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.ec2.binders; + +import static com.google.common.base.Preconditions.checkArgument; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.Binder; + +/** + * Binds the AvailabilityZone to a form parameter if set. + */ +@Singleton +public class IfNotNullBindAvailabilityZoneToFormParam implements Binder { + private final String param; + + @Inject + protected IfNotNullBindAvailabilityZoneToFormParam() { + this("Placement.AvailabilityZone"); + } + + protected IfNotNullBindAvailabilityZoneToFormParam(String param) { + this.param = param; + } + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Object input) { + if (input != null) { + checkArgument(input instanceof String, "this binder is only valid for String!"); + return (R) request.toBuilder().replaceFormParam(param, String.class.cast(input)).build(); + } + return request; + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java new file mode 100644 index 0000000..682786e --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -0,0 +1,328 @@ +/* + * 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.ec2.compute; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Lists.newArrayList; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromValuesOfEmptyString; +import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsValuesOfEmptyString; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_GENERATE_INSTANCE_NAMES; +import static org.jclouds.ec2.util.Tags.resourceToTagsAsMap; +import static org.jclouds.util.Predicates2.retry; + +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicReference; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; +import org.jclouds.Constants; +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.RunNodesException; +import org.jclouds.compute.callables.RunScriptOnNode; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.extensions.ImageExtension; +import org.jclouds.compute.extensions.SecurityGroupExtension; +import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.compute.functions.GroupNamingConvention.Factory; +import org.jclouds.compute.internal.BaseComputeService; +import org.jclouds.compute.internal.PersistNodeCredentials; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; +import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; +import org.jclouds.compute.strategy.ResumeNodeStrategy; +import org.jclouds.compute.strategy.SuspendNodeStrategy; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.ec2.EC2Api; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.domain.Tag; +import org.jclouds.ec2.util.TagFilterBuilder; +import org.jclouds.scriptbuilder.functions.InitAdminAccess; +import org.jclouds.util.Strings2; + +@Singleton +public class EC2ComputeService extends BaseComputeService { + private final EC2Api client; + private final ConcurrentMap<RegionAndName, KeyPair> credentialsMap; + private final LoadingCache<RegionAndName, String> securityGroupMap; + private final Factory namingConvention; + private final boolean generateInstanceNames; + + @Inject + protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore, + @Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes, + @Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, + SuspendNodeStrategy stopNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider, + @Named("DEFAULT") Provider<TemplateOptions> templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate<AtomicReference<NodeMetadata>> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate<AtomicReference<NodeMetadata>> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, + PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, EC2Api client, + ConcurrentMap<RegionAndName, KeyPair> credentialsMap, + @Named("SECURITY") LoadingCache<RegionAndName, String> securityGroupMap, + Optional<ImageExtension> imageExtension, GroupNamingConvention.Factory namingConvention, + @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames, + Optional<SecurityGroupExtension> securityGroupExtension) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, + getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, + startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, + nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, + persistNodeCredentials, timeouts, userExecutor, imageExtension, securityGroupExtension); + this.client = client; + this.credentialsMap = credentialsMap; + this.securityGroupMap = securityGroupMap; + this.namingConvention = namingConvention; + this.generateInstanceNames = generateInstanceNames; + } + + @Override + public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, final Template template) + throws RunNodesException { + Set<? extends NodeMetadata> nodes = super.createNodesInGroup(group, count, template); + String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation()); + + if (client.getTagApiForRegion(region).isPresent()) { + Map<String, String> common = metadataAndTagsAsValuesOfEmptyString(template.getOptions()); + if (generateInstanceNames || !common.isEmpty() || !template.getOptions().getNodeNames().isEmpty()) { + return addTagsAndNamesToInstancesInRegion(common, template.getOptions().getNodeNames(), + nodes, region, group); + } + } + return nodes; + } + + private static final Function<NodeMetadata, String> instanceId = new Function<NodeMetadata, String>() { + @Override + public String apply(NodeMetadata in) { + return in.getProviderId(); + } + }; + + private Set<NodeMetadata> addTagsAndNamesToInstancesInRegion(Map<String, String> common, Set<String> nodeNames, + Set<? extends NodeMetadata> input, String region, + String group) { + Map<String, ? extends NodeMetadata> instancesById = Maps.uniqueIndex(input, instanceId); + ImmutableSet.Builder<NodeMetadata> builder = ImmutableSet.<NodeMetadata> builder(); + + List<String> namesToUse = newArrayList(nodeNames); + if (generateInstanceNames && !common.containsKey("Name")) { + for (Map.Entry<String, ? extends NodeMetadata> entry : instancesById.entrySet()) { + String id = entry.getKey(); + String name; + if (!namesToUse.isEmpty()) { + name = namesToUse.remove(0); + } else { + name = id.replaceAll(".*-", group + "-"); + } + Map<String, String> tags = ImmutableMap.<String, String> builder().putAll(common) + .put("Name", name).build(); + logger.debug(">> applying tags %s to instance %s in region %s", tags, id, region); + client.getTagApiForRegion(region).get().applyToResources(tags, ImmutableSet.of(id)); + builder.add(addTagsForInstance(tags, instancesById.get(id))); + } + } else { + Iterable<String> ids = instancesById.keySet(); + logger.debug(">> applying tags %s to instances %s in region %s", common, ids, region); + client.getTagApiForRegion(region).get().applyToResources(common, ids); + for (NodeMetadata in : input) + builder.add(addTagsForInstance(common, in)); + } + if (logger.isDebugEnabled()) { + Multimap<String, String> filter = new TagFilterBuilder().resourceIds(instancesById.keySet()).build(); + FluentIterable<Tag> tags = client.getTagApiForRegion(region).get().filter(filter); + logger.debug("<< applied tags in region %s: %s", region, resourceToTagsAsMap(tags)); + } + return builder.build(); + } + + private static NodeMetadata addTagsForInstance(Map<String, String> tags, NodeMetadata input) { + NodeMetadataBuilder builder = NodeMetadataBuilder.fromNodeMetadata(input).name(tags.get("Name")); + return addMetadataAndParseTagsFromValuesOfEmptyString(builder, tags).build(); + } + + @Inject(optional = true) + @Named(RESOURCENAME_DELIMITER) + char delimiter = '#'; + + /** + * @throws IllegalStateException If the security group was in use + */ + @VisibleForTesting + void deleteSecurityGroup(String region, String group) { + checkNotNull(emptyToNull(region), "region must be defined"); + checkNotNull(emptyToNull(group), "group must be defined"); + String groupName = namingConvention.create().sharedNameForGroup(group); + + if (client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, groupName).size() > 0) { + logger.debug(">> deleting securityGroup(%s)", groupName); + client.getSecurityGroupApi().get().deleteSecurityGroupInRegion(region, groupName); + // TODO: test this clear happens + securityGroupMap.invalidate(new RegionNameAndIngressRules(region, groupName, null, false)); + logger.debug("<< deleted securityGroup(%s)", groupName); + } + } + + @VisibleForTesting + void deleteKeyPair(String region, String group) { + for (KeyPair keyPair : client.getKeyPairApi().get().describeKeyPairsInRegionWithFilter(region, + ImmutableMultimap.<String, String>builder() + .put("key-name", Strings2.urlEncode( + String.format("jclouds#%s#%s*", group, region).replace('#', delimiter))) + .build())) { + String keyName = keyPair.getKeyName(); + Predicate<String> keyNameMatcher = namingConvention.create().containsGroup(group); + String oldKeyNameRegex = String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+").replace('#', delimiter); + // old keypair pattern too verbose as it has an unnecessary region qualifier + + if (keyNameMatcher.apply(keyName) || keyName.matches(oldKeyNameRegex)) { + Set<String> instancesUsingKeyPair = extractIdsFromInstances(concat(client.getInstanceApi().get() + .describeInstancesInRegionWithFilter(region, ImmutableMultimap.<String, String>builder() + .put("instance-state-name", InstanceState.TERMINATED.toString()) + .put("instance-state-name", InstanceState.SHUTTING_DOWN.toString()) + .put("key-name", keyPair.getKeyName()).build()))); + + if (instancesUsingKeyPair.size() > 0) { + logger.debug("<< inUse keyPair(%s), by (%s)", keyPair.getKeyName(), instancesUsingKeyPair); + } else { + logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName()); + client.getKeyPairApi().get().deleteKeyPairInRegion(region, keyPair.getKeyName()); + // TODO: test this clear happens + credentialsMap.remove(new RegionAndName(region, keyPair.getKeyName())); + credentialsMap.remove(new RegionAndName(region, group)); + logger.debug("<< deleted keyPair(%s)", keyPair.getKeyName()); + } + } + } + } + + protected ImmutableSet<String> extractIdsFromInstances(Iterable<? extends RunningInstance> deadOnes) { + return ImmutableSet.copyOf(transform(deadOnes, new Function<RunningInstance, String>() { + + @Override + public String apply(RunningInstance input) { + return input.getId(); + } + + })); + } + + /** + * Cleans implicit keypairs and security groups. + */ + @Override + protected void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) { + Builder<String, String> regionGroups = ImmutableMultimap.builder(); + for (NodeMetadata nodeMetadata : deadNodes) { + if (nodeMetadata.getGroup() != null) + regionGroups.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup()); + } + for (Entry<String, String> regionGroup : regionGroups.build().entries()) { + cleanUpIncidentalResources(regionGroup.getKey(), regionGroup.getValue()); + } + } + + protected void cleanUpIncidentalResources(final String region, final String group) { + // For issue #445, tries to delete security groups first: ec2 throws exception if in use, but + // deleting a key pair does not. + // This is "belt-and-braces" because deleteKeyPair also does extractIdsFromInstances & usingKeyPairAndNotDead + // for us to check if any instances are using the key-pair before we delete it. + // There is (probably?) still a race if someone is creating instances at the same time as deleting them: + // we may delete the key-pair just when the node-being-created was about to rely on the incidental + // resources existing. + + // Also in #445, in aws-ec2 the deleteSecurityGroup sometimes fails after terminating the final VM using a + // given security group, if called very soon after the VM's state reports terminated. Empirically, it seems that + // waiting a small time (e.g. enabling logging or debugging!) then the tests pass. We therefore retry. + // TODO: this could be moved to a config module, also the narrative above made more concise + retry(new Predicate<RegionAndName>() { + public boolean apply(RegionAndName input) { + try { + logger.debug(">> deleting incidentalResources(%s)", input); + deleteSecurityGroup(input.getRegion(), input.getName()); + deleteKeyPair(input.getRegion(), input.getName()); // not executed if securityGroup was in use + logger.debug("<< deleted incidentalResources(%s)", input); + return true; + } catch (IllegalStateException e) { + logger.debug("<< inUse incidentalResources(%s)", input); + return false; + } + } + }, SECONDS.toMillis(3), 50, 1000, MILLISECONDS).apply(new RegionAndName(region, group)); + } + + /** + * returns template options, except of type {@link EC2TemplateOptions}. + */ + @Override + public EC2TemplateOptions templateOptions() { + return EC2TemplateOptions.class.cast(super.templateOptions()); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeServiceContext.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeServiceContext.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeServiceContext.java new file mode 100644 index 0000000..4e4d4db --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/EC2ComputeServiceContext.java @@ -0,0 +1,29 @@ +/* + * 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.ec2.compute; + +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.ec2.compute.internal.EC2ComputeServiceContextImpl; + +import com.google.inject.ImplementedBy; + +@ImplementedBy(EC2ComputeServiceContextImpl.class) +public interface EC2ComputeServiceContext extends ComputeServiceContext { + + @Override + EC2ComputeService getComputeService(); +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java new file mode 100644 index 0000000..91cb116 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java @@ -0,0 +1,94 @@ +/* + * 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.ec2.compute.config; + +import org.jclouds.compute.config.BindComputeStrategiesByClass; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; +import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; +import org.jclouds.compute.strategy.ResumeNodeStrategy; +import org.jclouds.compute.strategy.SuspendNodeStrategy; +import org.jclouds.ec2.compute.strategy.EC2CreateNodesInGroupThenAddToSet; +import org.jclouds.ec2.compute.strategy.EC2DestroyNodeStrategy; +import org.jclouds.ec2.compute.strategy.EC2GetImageStrategy; +import org.jclouds.ec2.compute.strategy.EC2GetNodeMetadataStrategy; +import org.jclouds.ec2.compute.strategy.EC2ListNodesStrategy; +import org.jclouds.ec2.compute.strategy.EC2RebootNodeStrategy; +import org.jclouds.ec2.compute.strategy.EC2ResumeNodeStrategy; +import org.jclouds.ec2.compute.strategy.EC2SuspendNodeStrategy; + +public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClass { + @Override + protected Class<? extends CreateNodesInGroupThenAddToSet> defineRunNodesAndAddToSetStrategy() { + return EC2CreateNodesInGroupThenAddToSet.class; + } + + /** + * not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based. + */ + @Override + protected Class<? extends CreateNodeWithGroupEncodedIntoName> defineAddNodeWithTagStrategy() { + return null; + } + + /** + * not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based. + */ + @Override + protected void bindAddNodeWithTagStrategy(Class<? extends CreateNodeWithGroupEncodedIntoName> clazz) { + } + + @Override + protected Class<? extends DestroyNodeStrategy> defineDestroyNodeStrategy() { + return EC2DestroyNodeStrategy.class; + } + + @Override + protected Class<? extends GetNodeMetadataStrategy> defineGetNodeMetadataStrategy() { + return EC2GetNodeMetadataStrategy.class; + } + + @Override + protected Class<? extends GetImageStrategy> defineGetImageStrategy() { + return EC2GetImageStrategy.class; + } + + @Override + protected Class<? extends ListNodesStrategy> defineListNodesStrategy() { + return EC2ListNodesStrategy.class; + } + + @Override + protected Class<? extends RebootNodeStrategy> defineRebootNodeStrategy() { + return EC2RebootNodeStrategy.class; + } + + @Override + protected Class<? extends ResumeNodeStrategy> defineStartNodeStrategy() { + return EC2ResumeNodeStrategy.class; + } + + @Override + protected Class<? extends SuspendNodeStrategy> defineStopNodeStrategy() { + return EC2SuspendNodeStrategy.class; + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeSuppliersByClass.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeSuppliersByClass.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeSuppliersByClass.java new file mode 100644 index 0000000..84f1067 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeSuppliersByClass.java @@ -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.jclouds.ec2.compute.config; + +import java.util.Set; + +import org.jclouds.compute.config.BindComputeSuppliersByClass; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier; +import org.jclouds.ec2.compute.suppliers.EC2ImageSupplier; + +import com.google.common.base.Supplier; +public class EC2BindComputeSuppliersByClass extends BindComputeSuppliersByClass { + @Override + protected Class<? extends Supplier<Set<? extends Hardware>>> defineHardwareSupplier() { + return EC2HardwareSupplier.class; + } + + @Override + protected Class<? extends Supplier<Set<? extends Image>>> defineImageSupplier() { + return EC2ImageSupplier.class; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java new file mode 100644 index 0000000..1aa7f5b --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.ec2.compute.config; + +import static com.google.common.collect.Iterables.toArray; +import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; + +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.config.BaseComputeServiceContextModule; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.extensions.ImageExtension; +import org.jclouds.compute.extensions.SecurityGroupExtension; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.loaders.RegionAndIdToImage; +import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.suppliers.SetAndThrowAuthorizationExceptionSupplier; + +import com.google.common.base.Optional; +import com.google.common.base.Splitter; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.base.Throwables; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.Atomics; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +/** + * Configures the {@link ComputeServiceContext}; requires {@link EC2ComputeService} bound. + */ +public class EC2ComputeServiceContextModule extends BaseComputeServiceContextModule { + @Override + protected void configure() { + installDependencies(); + install(new EC2BindComputeStrategiesByClass()); + install(new EC2BindComputeSuppliersByClass()); + super.configure(); + } + + protected void installDependencies() { + install(new EC2ComputeServiceDependenciesModule()); + } + + @Override + protected boolean shouldEagerlyParseImages(Injector injector) { + // If no owners to query, then will never lookup all images + String[] amiOwners = injector.getInstance(Key.get(String[].class, Names.named(PROPERTY_EC2_AMI_OWNERS))); + return amiOwners.length > 0; + } + + @Override + protected Supplier<Set<? extends Image>> supplyNonParsingImageCache( + AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds, + final Supplier<Set<? extends Image>> imageSupplier, Injector injector) { + final Supplier<LoadingCache<RegionAndName, ? extends Image>> cache = injector.getInstance(Key.get(new TypeLiteral<Supplier<LoadingCache<RegionAndName, ? extends Image>>>() {})); + return new Supplier<Set<? extends Image>>() { + @Override + public Set<? extends Image> get() { + return ImmutableSet.copyOf(cache.get().asMap().values()); + } + }; + } + + @Provides + @Singleton + protected Supplier<LoadingCache<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache( + final RegionAndNameToImageSupplier supplier) { + return supplier; + } + + @Provides + @Singleton + protected Supplier<CacheLoader<RegionAndName, Image>> provideRegionAndNameToImageSupplierCacheLoader( + final RegionAndIdToImage delegate) { + return Suppliers.<CacheLoader<RegionAndName, Image>>ofInstance(new CacheLoader<RegionAndName, Image>() { + private final AtomicReference<AuthorizationException> authException = Atomics.newReference(); + + @Override + public Image load(final RegionAndName key) throws Exception { + // raw lookup of an image + Supplier<Image> rawSupplier = new Supplier<Image>() { + @Override public Image get() { + try { + return delegate.load(key); + } catch (ExecutionException e) { + throw Throwables.propagate(e); + } + } + }; + return new SetAndThrowAuthorizationExceptionSupplier<Image>(rawSupplier, authException).get(); + } + + }); + } + + @Provides + @Singleton + @Named(PROPERTY_EC2_AMI_OWNERS) + String[] amiOwners(@Named(PROPERTY_EC2_AMI_OWNERS) String amiOwners) { + if (amiOwners.trim().equals("")) + return new String[] {}; + return toArray(Splitter.on(',').split(amiOwners), String.class); + } + + @Override + protected Optional<ImageExtension> provideImageExtension(Injector i) { + return Optional.of(i.getInstance(ImageExtension.class)); + } + + @Override + protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) { + return Optional.of(i.getInstance(SecurityGroupExtension.class)); + } +} + http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java new file mode 100644 index 0000000..b9ef0ca --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java @@ -0,0 +1,193 @@ +/* + * 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.ec2.compute.config; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT; +import static org.jclouds.util.Predicates2.retry; + +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadata.Status; +import org.jclouds.compute.domain.SecurityGroup; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.extensions.ImageExtension; +import org.jclouds.compute.extensions.SecurityGroupExtension; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.extensions.EC2ImageExtension; +import org.jclouds.ec2.compute.extensions.EC2SecurityGroupExtension; +import org.jclouds.ec2.compute.functions.AddElasticIpsToNodemetadata; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.EC2ImageParser; +import org.jclouds.ec2.compute.functions.EC2SecurityGroupIdFromName; +import org.jclouds.ec2.compute.functions.EC2SecurityGroupToSecurityGroup; +import org.jclouds.ec2.compute.functions.PasswordCredentialsFromWindowsInstance; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.loaders.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.loaders.LoadPublicIpForInstanceOrNull; +import org.jclouds.ec2.compute.loaders.RegionAndIdToImage; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.predicates.SecurityGroupPresent; +import org.jclouds.ec2.domain.Image.ImageState; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.reference.EC2Constants; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +public class EC2ComputeServiceDependenciesModule extends AbstractModule { + + public static final Map<InstanceState, Status> toPortableNodeStatus = ImmutableMap + .<InstanceState, Status> builder() + .put(InstanceState.PENDING, Status.PENDING) + .put(InstanceState.RUNNING, Status.RUNNING) + .put(InstanceState.SHUTTING_DOWN, Status.PENDING) + .put(InstanceState.TERMINATED, Status.TERMINATED) + .put(InstanceState.STOPPING, Status.PENDING) + .put(InstanceState.STOPPED, Status.SUSPENDED) + .put(InstanceState.UNRECOGNIZED, Status.UNRECOGNIZED) + .build(); + + @Singleton + @Provides + protected Map<InstanceState, NodeMetadata.Status> toPortableNodeStatus() { + return toPortableNodeStatus; + } + + @VisibleForTesting + public static final Map<ImageState, Image.Status> toPortableImageStatus = ImmutableMap + .<ImageState, Image.Status> builder() + .put(ImageState.AVAILABLE, Image.Status.AVAILABLE) + .put(ImageState.DEREGISTERED, Image.Status.DELETED) + .put(ImageState.UNRECOGNIZED, Image.Status.UNRECOGNIZED).build(); + + @Singleton + @Provides + protected Map<ImageState, Image.Status> toPortableImageStatus() { + return toPortableImageStatus; + } + + @Override + protected void configure() { + bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class); + bind(TemplateOptions.class).to(EC2TemplateOptions.class); + bind(ComputeService.class).to(EC2ComputeService.class); + bind(new TypeLiteral<CacheLoader<RunningInstance, Optional<LoginCredentials>>>() { + }).to(CredentialsForInstance.class); + bind(new TypeLiteral<Function<RegionAndName, KeyPair>>() { + }).to(CreateUniqueKeyPair.class); + bind(new TypeLiteral<CacheLoader<RegionAndName, Image>>() { + }).to(RegionAndIdToImage.class); + bind(new TypeLiteral<CacheLoader<RegionAndName, String>>() { + }).annotatedWith(Names.named("SECURITY")).to(CreateSecurityGroupIfNeeded.class); + bind(new TypeLiteral<CacheLoader<RegionAndName, String>>() { + }).annotatedWith(Names.named("ELASTICIP")).to(LoadPublicIpForInstanceOrNull.class); + bind(new TypeLiteral<Function<String, String>>() { + }).annotatedWith(Names.named("SECGROUP_NAME_TO_ID")).to(EC2SecurityGroupIdFromName.class); + bind(new TypeLiteral<Function<PasswordDataAndPrivateKey, LoginCredentials>>() { + }).to(WindowsLoginCredentialsFromEncryptedData.class); + bind(new TypeLiteral<Function<RunningInstance, LoginCredentials>>() { + }).to(PasswordCredentialsFromWindowsInstance.class); + bind(new TypeLiteral<Function<org.jclouds.ec2.domain.Image, Image>>() { + }).to(EC2ImageParser.class); + bind(new TypeLiteral<Function<org.jclouds.ec2.domain.SecurityGroup, SecurityGroup>>() { + }).to(EC2SecurityGroupToSecurityGroup.class); + bind(new TypeLiteral<ImageExtension>() { + }).to(EC2ImageExtension.class); + bind(new TypeLiteral<SecurityGroupExtension>() { + }).to(EC2SecurityGroupExtension.class); + } + + /** + * only add the overhead of looking up ips when we have enabled the auto-allocate functionality + */ + @Provides + @Singleton + public Function<RunningInstance, NodeMetadata> bindNodeConverter(RunningInstanceToNodeMetadata baseConverter, + AddElasticIpsToNodemetadata addElasticIpsToNodemetadata, + @Named(EC2Constants.PROPERTY_EC2_AUTO_ALLOCATE_ELASTIC_IPS) boolean autoAllocateElasticIps) { + if (!autoAllocateElasticIps) + return baseConverter; + return Functions.compose(addElasticIpsToNodemetadata, baseConverter); + } + + @Provides + @Singleton + protected LoadingCache<RunningInstance, Optional<LoginCredentials>> credentialsMap(CacheLoader<RunningInstance, Optional<LoginCredentials>> in) { + return CacheBuilder.newBuilder().build(in); + } + + @Provides + @Singleton + protected ConcurrentMap<RegionAndName, KeyPair> keypairMap(Injector i) { + return Maps.newConcurrentMap(); + } + + @Provides + @Singleton + @Named("SECURITY") + protected LoadingCache<RegionAndName, String> securityGroupMap( + @Named("SECURITY") CacheLoader<RegionAndName, String> in) { + return CacheBuilder.newBuilder().build(in); + } + + @Provides + @Singleton + @Named("ELASTICIP") + protected LoadingCache<RegionAndName, String> instanceToElasticIp( + @Named("ELASTICIP") CacheLoader<RegionAndName, String> in) { + return CacheBuilder.newBuilder().build(in); + } + + @Provides + @Singleton + @Named("SECURITY") + protected Predicate<RegionAndName> securityGroupEventualConsistencyDelay(SecurityGroupPresent in, + @Named(PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) { + return retry(in, msDelay, 100l, MILLISECONDS); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/397d9926/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ResolveImagesModule.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ResolveImagesModule.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ResolveImagesModule.java new file mode 100644 index 0000000..7805fc0 --- /dev/null +++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/config/EC2ResolveImagesModule.java @@ -0,0 +1,33 @@ +/* + * 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.ec2.compute.config; + +import org.jclouds.compute.config.ResolvesImages; +import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; +import org.jclouds.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy; + +import com.google.inject.AbstractModule; + +@ResolvesImages +public class EC2ResolveImagesModule extends AbstractModule { + + @Override + protected void configure() { + bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(EC2PopulateDefaultLoginCredentialsForImageStrategy.class); + } + +}
