mirror of https://github.com/apache/jclouds.git
Merge commit '6d187ed9baaad1e00dbe65b36ea2989c951a5a28', ssh client patch is reverted due to massive changes in code
Conflicts: drivers/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java
This commit is contained in:
commit
e1f0cdcfa5
|
@ -32,7 +32,8 @@ our dev version is 1.0-SNAPSHOT
|
|||
our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), deltacloud,
|
||||
cloudservers-uk, vcloud (generic), ec2 (generic), byon, nova,
|
||||
trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic),
|
||||
cloudsigma-zrh, elasticstack(generic), bluelock-vclouddirector,
|
||||
cloudsigma-zrh, elasticstack(generic), bluelock-vcloud-vcenterprise,
|
||||
bluelock-vcloud-zone01, stratogen-vcloud-mycloud, rimuhosting,
|
||||
slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1),
|
||||
elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare),
|
||||
openhosting-east1, serverlove-z1-man, skalicloud-sdg-my
|
||||
|
@ -54,7 +55,7 @@ our loadbalancer api supports: cloudloadbalancers-us
|
|||
* note * the pom dependency org.jclouds/jclouds-allloadbalancer gives you access to
|
||||
to all of these providers
|
||||
|
||||
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, rimuhosting, openstack nova,
|
||||
we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, openstack nova,
|
||||
azurequeue, simpledb, cloudstack as well as a async-http-client
|
||||
driver in the sandbox
|
||||
|
||||
|
|
|
@ -49,6 +49,11 @@
|
|||
<artifactId>aws-ec2</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>rimuhosting</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.api</groupId>
|
||||
<artifactId>nova</artifactId>
|
||||
|
@ -104,6 +109,21 @@
|
|||
<artifactId>bluelock-vcdirector</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>bluelock-vcloud-vcenterprise</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>bluelock-vcloud-zone01</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>stratogen-vcloud-mycloud</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>gogrid</artifactId>
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.jclouds.atmos.functions.AtmosObjectName;
|
|||
import org.jclouds.atmos.functions.ParseDirectoryListFromContentAndHeaders;
|
||||
import org.jclouds.atmos.functions.ParseObjectFromHeadersAndHttpContent;
|
||||
import org.jclouds.atmos.functions.ParseSystemMetadataFromHeaders;
|
||||
import org.jclouds.atmos.functions.ParseUserMetadataFromHeaders;
|
||||
import org.jclouds.atmos.functions.ReturnEndpointIfAlreadyExists;
|
||||
import org.jclouds.atmos.options.ListOptions;
|
||||
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
|
||||
|
@ -164,7 +165,7 @@ public interface AtmosAsyncClient {
|
|||
* @see AtmosClient#getUserMetadata
|
||||
*/
|
||||
@HEAD
|
||||
@ResponseParser(ParseSystemMetadataFromHeaders.class)
|
||||
@ResponseParser(ParseUserMetadataFromHeaders.class)
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@Path("/{path}")
|
||||
@QueryParams(keys = "metadata/user")
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
;
|
||||
;
|
||||
; Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
;
|
||||
; ====================================================================
|
||||
; 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.
|
||||
; ====================================================================
|
||||
;
|
||||
|
||||
(ns
|
||||
#^{:author "Juegen Hoetzel, juergen@archlinux.org"
|
||||
:doc "A clojure binding for the jclouds AWS security group interface."}
|
||||
org.jclouds.ec2.security-group2
|
||||
(:require (org.jclouds [compute2 :as compute])
|
||||
[org.jclouds.ec2.ebs :as ebs])
|
||||
(:import org.jclouds.ec2.domain.IpProtocol
|
||||
org.jclouds.ec2.domain.SecurityGroup
|
||||
org.jclouds.ec2.services.SecurityGroupClient))
|
||||
|
||||
(defn #^SecurityGroupClient
|
||||
sg-service
|
||||
"Returns the SecurityGroup Client associated with the specified compute service."
|
||||
[compute]
|
||||
(-> compute .getContext .getProviderSpecificContext .getApi .getSecurityGroupServices))
|
||||
|
||||
(defn create-group
|
||||
"Creates a new security group.
|
||||
|
||||
e.g. (create-group compute \"Database Server\" \"Description for group\" :region :us-west-1)"
|
||||
[compute name & {:keys [description region]}]
|
||||
(.createSecurityGroupInRegion (sg-service compute) (ebs/get-region region) name (or description name)))
|
||||
|
||||
(defn delete-group
|
||||
"Deletes a security group.
|
||||
|
||||
e.g. (delete-group compute \"Database Server\" :region :us-west-1)"
|
||||
[compute name & {:keys [region]}]
|
||||
(.deleteSecurityGroupInRegion (sg-service compute) (ebs/get-region region) name))
|
||||
|
||||
(defn groups
|
||||
"Returns a map of GroupName -> org.jclouds.ec2.domain.SecurityGroup instances.
|
||||
|
||||
e.g. (groups compute :region :us-east-1)"
|
||||
[compute & {:keys [region]}]
|
||||
(into {} (for [#^SecurityGroup group (.describeSecurityGroupsInRegion (sg-service compute)
|
||||
(ebs/get-region region)
|
||||
(into-array String '()))]
|
||||
[(.getName group) group])))
|
||||
|
||||
(defn get-protocol [v]
|
||||
"Coerce argument to a IP Protocol."
|
||||
(cond
|
||||
(instance? IpProtocol v) v
|
||||
(keyword? v) (if-let [p (get {:tcp IpProtocol/TCP
|
||||
:udp IpProtocol/UDP
|
||||
:icmp IpProtocol/ICMP}
|
||||
v)]
|
||||
p
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Can't obtain IP protocol from " v " (valid :tcp, :udp and :icmp)"))))
|
||||
(nil? v) IpProtocol/TCP
|
||||
:else (throw (IllegalArgumentException.
|
||||
(str "Can't obtain IP protocol from argument of type " (type v))))))
|
||||
|
||||
(defn authorize
|
||||
"Adds permissions to a security group.
|
||||
|
||||
e.g. (authorize compute \"jclouds#webserver#us-east-1\" 80 :ip-range \"0.0.0.0/0\")
|
||||
(authorize compute \"jclouds#webserver#us-east-1\" [1000,2000] :protocol :udp)"
|
||||
|
||||
[compute group-name port & {:keys [protocol ip-range region]}]
|
||||
(let [group ((groups compute :region region) group-name)
|
||||
[from-port to-port] (if (number? port) [port port] port)]
|
||||
(if group
|
||||
(.authorizeSecurityGroupIngressInRegion
|
||||
(sg-service compute) (ebs/get-region region) (.getName group) (get-protocol protocol) from-port to-port (or ip-range "0.0.0.0/0"))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Can't find security group for name " group-name))))))
|
||||
|
||||
(defn revoke
|
||||
"Revokes permissions from a security group.
|
||||
|
||||
e.g. (revoke compute 80 \"jclouds#webserver#us-east-1\" :protocol :tcp 80 80 :ip-range \"0.0.0.0/0\")"
|
||||
[compute group-name port & {:keys [protocol ip-range region]}]
|
||||
(let [group ((groups compute :region region) group-name)
|
||||
[from-port to-port] (if (number? port) [port port] port)]
|
||||
(if group
|
||||
(.revokeSecurityGroupIngressInRegion
|
||||
(sg-service compute) (ebs/get-region region) (.getName group) (get-protocol protocol) from-port to-port (or ip-range "0.0.0.0/0"))
|
||||
(throw (IllegalArgumentException.
|
||||
(str "Can't find security group for name " group-name))))))
|
|
@ -209,13 +209,23 @@ public class EC2HardwareBuilder extends HardwareBuilder {
|
|||
/**
|
||||
* @see InstanceType#M1_SMALL
|
||||
*/
|
||||
public static EC2HardwareBuilder m1_small() {
|
||||
public static EC2HardwareBuilder m1_small32() {
|
||||
return new EC2HardwareBuilder(InstanceType.M1_SMALL).ram(1740).processors(
|
||||
ImmutableList.of(new Processor(1.0, 1.0))).volumes(
|
||||
ImmutableList.<Volume> of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(150.0f,
|
||||
"/dev/sda2", false, false))).is64Bit(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see InstanceType#M1_SMALL
|
||||
*/
|
||||
public static EC2HardwareBuilder m1_small() {
|
||||
return new EC2HardwareBuilder(InstanceType.M1_SMALL).ram(1740).processors(
|
||||
ImmutableList.of(new Processor(1.0, 1.0))).volumes(
|
||||
ImmutableList.<Volume> of(new VolumeImpl(10.0f, "/dev/sda1", true, false), new VolumeImpl(150.0f,
|
||||
"/dev/sda2", false, false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see InstanceType#T1_MICRO
|
||||
*/
|
||||
|
|
|
@ -509,6 +509,6 @@ public class EC2TemplateOptions extends TemplateOptions implements Cloneable {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", userData="
|
||||
+ Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]";
|
||||
+ Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings.build() + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.jclouds.ec2.compute.suppliers;
|
||||
|
||||
import static org.jclouds.compute.predicates.ImagePredicates.any;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large;
|
||||
|
@ -43,7 +42,7 @@ public class EC2HardwareSupplier implements Supplier<Set<? extends Hardware>> {
|
|||
|
||||
@Override
|
||||
public Set<? extends Hardware> get() {
|
||||
return ImmutableSet.<Hardware> of(m1_small().supportsImage(any()).build(), c1_medium().build(), c1_xlarge()
|
||||
return ImmutableSet.<Hardware> of(m1_small().build(), c1_medium().build(), c1_xlarge()
|
||||
.build(), m1_large().build(), m1_xlarge().build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
|
@ -159,12 +160,16 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
|
||||
String group = this.group + "e";
|
||||
int volumeSize = 8;
|
||||
|
||||
final Template template = context.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL)
|
||||
.osFamily(OsFamily.UBUNTU).osVersionMatches("10.04").imageDescriptionMatches(".*ebs.*").build();
|
||||
|
||||
Location zone = Iterables.find(context.getComputeService().listAssignableLocations(), new Predicate<Location>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Location arg0) {
|
||||
return arg0.getScope() == LocationScope.ZONE;
|
||||
return arg0.getScope() == LocationScope.ZONE
|
||||
&& arg0.getParent().getId().equals(template.getLocation().getId());
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -174,9 +179,6 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
Snapshot snapshot = ebsClient.createSnapshotInRegion(volume.getRegion(), volume.getId());
|
||||
ebsClient.deleteVolumeInRegion(volume.getRegion(), volume.getId());
|
||||
|
||||
Template template = context.getComputeService().templateBuilder().locationId(volume.getRegion()).hardwareId(
|
||||
InstanceType.M1_SMALL).imageDescriptionMatches(".*ebs.*").build();
|
||||
|
||||
template.getOptions().as(EC2TemplateOptions.class)//
|
||||
// .unmapDeviceNamed("/dev/foo)
|
||||
.mapEphemeralDeviceToDeviceName("/dev/sdm", "ephemeral0")//
|
||||
|
@ -223,8 +225,8 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
return instance;
|
||||
}
|
||||
|
||||
protected void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String group)
|
||||
throws InterruptedException {
|
||||
protected void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient,
|
||||
String group) throws InterruptedException {
|
||||
try {
|
||||
for (SecurityGroup secgroup : securityGroupClient.describeSecurityGroupsInRegion(null))
|
||||
if (secgroup.getName().startsWith("jclouds#" + group) || secgroup.getName().equals(group)) {
|
||||
|
|
|
@ -26,7 +26,7 @@ import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium;
|
|||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small32;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge;
|
||||
|
@ -161,7 +161,7 @@ public class EC2TemplateBuilderTest {
|
|||
.build()));
|
||||
Supplier<Set<? extends Hardware>> sizes = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
|
||||
.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large().build(),
|
||||
m1_small().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(),
|
||||
m1_small32().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(),
|
||||
m2_4xlarge().build(), CC1_4XLARGE));
|
||||
|
||||
return new TemplateBuilderImpl(locations, images, sizes, Suppliers.ofInstance(location), optionsProvider,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.ec2.compute.functions;
|
||||
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small;
|
||||
import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small32;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
@ -129,7 +129,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
|
||||
@Test
|
||||
public void testApplyWhereTagDoesntMatchAndImageHardwareAndLocationFound() throws UnknownHostException {
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small().build()), ImmutableSet
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small32().build()), ImmutableSet
|
||||
.of(provider), EC2ImageParserTest.convertImages("/amzn_images.xml"), ImmutableMap
|
||||
.<String, Credentials> of());
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
|
||||
assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses(
|
||||
ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId(
|
||||
"us-east-1/ami-82e4b5c7").hardware(m1_small().build()).operatingSystem(
|
||||
"us-east-1/ami-82e4b5c7").hardware(m1_small32().build()).operatingSystem(
|
||||
new OperatingSystem.Builder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual").description(
|
||||
"137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-0799056f")
|
||||
.providerId("i-0799056f").location(provider).build());
|
||||
|
@ -158,7 +158,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
};
|
||||
Map<RegionAndName, Image> instanceToImage = new MapMaker().makeComputingMap(nullReturningFunction);
|
||||
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small().build()), ImmutableSet
|
||||
RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet.of(m1_small32().build()), ImmutableSet
|
||||
.of(provider), ImmutableMap.<String, Credentials> of(),
|
||||
EC2ComputeServiceDependenciesModule.instanceToNodeState, instanceToImage);
|
||||
|
||||
|
@ -167,7 +167,7 @@ public class RunningInstanceToNodeMetadataTest {
|
|||
assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses(
|
||||
ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId(
|
||||
"us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f").providerId("i-0799056f").hardware(
|
||||
m1_small().build()).location(provider).build());
|
||||
m1_small32().build()).location(provider).build());
|
||||
}
|
||||
|
||||
protected RunningInstance firstInstanceFromResource(String resource) {
|
||||
|
|
|
@ -69,7 +69,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
|||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
Hardware size = EC2HardwareBuilder.m1_small().build();
|
||||
Hardware size = EC2HardwareBuilder.m1_small32().build();
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
|
||||
|
@ -124,7 +124,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest {
|
|||
// setup constants
|
||||
String region = Region.AP_SOUTHEAST_1;
|
||||
String tag = "tag";
|
||||
Hardware size = EC2HardwareBuilder.m1_small().build();
|
||||
Hardware size = EC2HardwareBuilder.m1_small32().build();
|
||||
String systemGeneratedKeyPairName = "systemGeneratedKeyPair";
|
||||
String generatedGroup = "group";
|
||||
Set<String> generatedGroups = ImmutableSet.of(generatedGroup);
|
||||
|
|
|
@ -159,8 +159,8 @@ public class ElasticStackClientLiveTest {
|
|||
@Test
|
||||
public void testGetDrive() throws Exception {
|
||||
for (String driveUUID : client.listDrives()) {
|
||||
assert !"".equals(driveUUID);
|
||||
assertNotNull(client.getDriveInfo(driveUUID));
|
||||
assert !"".equals(driveUUID) : driveUUID;
|
||||
assert client.getDriveInfo(driveUUID) != null : driveUUID;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,13 +18,23 @@
|
|||
*/
|
||||
package org.jclouds.openstack.swift.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||
import org.jclouds.openstack.config.OpenStackAuthenticationModule.GetAuthenticationResponse;
|
||||
import org.jclouds.openstack.reference.AuthHeaders;
|
||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||
import org.jclouds.openstack.swift.SwiftAsyncClient;
|
||||
import org.jclouds.openstack.swift.SwiftClient;
|
||||
import org.jclouds.rest.AsyncClientFactory;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
|
@ -52,4 +62,28 @@ public class SwiftRestClientModule extends BaseSwiftRestClientModule<SwiftClient
|
|||
CommonSwiftAsyncClient provideCommonSwiftClient(SwiftAsyncClient in) {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class GetAuthenticationResponseForStorage extends GetAuthenticationResponse {
|
||||
@Inject
|
||||
public GetAuthenticationResponseForStorage(AsyncClientFactory factory,
|
||||
@Named(Constants.PROPERTY_IDENTITY) String user, @Named(Constants.PROPERTY_CREDENTIAL) String key) {
|
||||
super(factory, user, key);
|
||||
}
|
||||
|
||||
protected Future<AuthenticationResponse> authenticate() {
|
||||
return client.authenticateStorage(user, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected URI provideStorageUrl(AuthenticationResponse response) {
|
||||
return response.getServices().get(AuthHeaders.STORAGE_URL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(GetAuthenticationResponse.class).to(GetAuthenticationResponseForStorage.class);
|
||||
super.configure();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,50 +67,47 @@ public class VCloudDestroyNodeStrategy implements DestroyNodeStrategy {
|
|||
VApp vApp = client.getVAppClient().getVApp(vappId);
|
||||
if (vApp == null)
|
||||
return null;
|
||||
vApp = powerOffVAppIfDeployed(vApp);
|
||||
|
||||
waitForPendingTasksToComplete(vApp);
|
||||
|
||||
vApp = undeployVAppIfDeployed(vApp);
|
||||
deleteVApp(vappId);
|
||||
deleteVApp(vApp);
|
||||
try {
|
||||
return getNode.getNode(id);
|
||||
} catch (AuthorizationException e) {
|
||||
// vcloud bug will sometimes throw an exception getting the vapp right after deleting it.
|
||||
logger.trace("authorization error getting %s after deletion: %s", id, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteVApp(URI vappId) {
|
||||
logger.debug(">> deleting vApp(%s)", vappId);
|
||||
Task task = client.getVAppClient().deleteVApp(vappId);
|
||||
void waitForPendingTasksToComplete(VApp vApp) {
|
||||
for (Task task : vApp.getTasks())
|
||||
waitForTask(task, vApp);
|
||||
}
|
||||
|
||||
public void waitForTask(Task task, VApp vAppResponse) {
|
||||
if (!successTester.apply(task.getHref())) {
|
||||
throw new RuntimeException(String.format("failed to %s %s: %s", "delete", vappId, task));
|
||||
throw new RuntimeException(String.format("failed to %s %s: %s", task.getName(), vAppResponse.getName(), task));
|
||||
}
|
||||
logger.debug("<< deleted vApp(%s)", vappId);
|
||||
}
|
||||
|
||||
void deleteVApp(VApp vApp) {
|
||||
logger.debug(">> deleting vApp(%s)", vApp.getHref());
|
||||
waitForTask(client.getVAppClient().deleteVApp(vApp.getHref()), vApp);
|
||||
logger.debug("<< deleted vApp(%s)", vApp.getHref());
|
||||
}
|
||||
|
||||
VApp undeployVAppIfDeployed(VApp vApp) {
|
||||
if (vApp.getStatus().compareTo(Status.RESOLVED) > 0) {
|
||||
if (vApp.getStatus() != Status.OFF) {
|
||||
logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
|
||||
Task task = client.getVAppClient().undeployVApp(vApp.getHref());
|
||||
if (!successTester.apply(task.getHref())) {
|
||||
// TODO timeout
|
||||
throw new RuntimeException(String.format("failed to %s %s: %s", "undeploy", vApp.getName(), task));
|
||||
try {
|
||||
waitForTask(client.getVAppClient().undeployVApp(vApp.getHref()), vApp);
|
||||
vApp = client.getVAppClient().getVApp(vApp.getHref());
|
||||
logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
|
||||
} catch (IllegalStateException e) {
|
||||
logger.warn(e, "<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
|
||||
}
|
||||
vApp = client.getVAppClient().getVApp(vApp.getHref());
|
||||
logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
|
||||
}
|
||||
return vApp;
|
||||
}
|
||||
|
||||
VApp powerOffVAppIfDeployed(VApp vApp) {
|
||||
if (vApp.getStatus().compareTo(Status.OFF) > 0) {
|
||||
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getName(), vApp.getStatus());
|
||||
Task task = client.getVAppClient().powerOffVApp(vApp.getHref());
|
||||
if (!successTester.apply(task.getHref())) {
|
||||
// TODO timeout
|
||||
throw new RuntimeException(String.format("failed to %s %s: %s", "powerOff", vApp.getName(), task));
|
||||
}
|
||||
vApp = client.getVAppClient().getVApp(vApp.getHref());
|
||||
logger.debug("<< %s vApp(%s)", vApp.getStatus(), vApp.getName());
|
||||
}
|
||||
return vApp;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@ import org.jclouds.vcloud.domain.Catalog;
|
|||
import org.jclouds.vcloud.domain.CatalogItem;
|
||||
import org.jclouds.vcloud.domain.Org;
|
||||
import org.jclouds.vcloud.domain.ReferenceType;
|
||||
import org.jclouds.vcloud.domain.Status;
|
||||
import org.jclouds.vcloud.domain.Task;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||
import org.jclouds.vcloud.options.CatalogItemOptions;
|
||||
import org.jclouds.vcloud.predicates.TaskSuccess;
|
||||
|
@ -125,20 +127,17 @@ public class VAppTemplateClientLiveTest extends BaseVCloudClientLiveTest {
|
|||
Predicate<URI> taskTester = new RetryablePredicate<URI>(new TaskSuccess(getVCloudApi()), 600, 5,
|
||||
TimeUnit.SECONDS);
|
||||
|
||||
// I have to powerOff first
|
||||
Task task = getVCloudApi().getVAppClient().powerOffVApp(URI.create(node.getId()));
|
||||
|
||||
// wait up to ten minutes per above
|
||||
assert taskTester.apply(task.getHref()) : node;
|
||||
|
||||
// having a problem where the api is returning an error telling us to stop!
|
||||
|
||||
// I have to undeploy first
|
||||
task = getVCloudApi().getVAppClient().undeployVApp(URI.create(node.getId()));
|
||||
Task task = getVCloudApi().getVAppClient().undeployVApp(URI.create(node.getId()));
|
||||
|
||||
// wait up to ten minutes per above
|
||||
assert taskTester.apply(task.getHref()) : node;
|
||||
|
||||
VApp vApp = getVCloudApi().getVAppClient().getVApp(URI.create(node.getId()));
|
||||
|
||||
// wait up to ten minutes per above
|
||||
assertEquals(vApp.getStatus(), Status.OFF);
|
||||
|
||||
// vdc is equiv to the node's location
|
||||
// vapp uri is the same as the node's id
|
||||
vappTemplate = getVCloudApi().getVAppTemplateClient().captureVAppAsTemplateInVDC(URI.create(node.getId()),
|
||||
|
@ -155,11 +154,11 @@ public class VAppTemplateClientLiveTest extends BaseVCloudClientLiveTest {
|
|||
vappTemplate.getHref(),
|
||||
getVCloudApi().getCatalogClient().findCatalogInOrgNamed(null, null).getHref(), "fooname",
|
||||
CatalogItemOptions.Builder.description("description").properties(ImmutableMap.of("foo", "bar")));
|
||||
|
||||
|
||||
assertEquals(item.getName(), "fooname");
|
||||
assertEquals(item.getDescription(), "description");
|
||||
assertEquals(item.getProperties(), ImmutableMap.of("foo", "bar"));
|
||||
assertEquals(item.getEntity().getName(), vappTemplate.getName());
|
||||
assertEquals(item.getEntity().getName(), "fooname");
|
||||
assertEquals(item.getEntity().getHref(), vappTemplate.getHref());
|
||||
assertEquals(item.getEntity().getType(), vappTemplate.getType());
|
||||
|
||||
|
|
|
@ -161,9 +161,9 @@ public class VmClientLiveTest extends BaseVCloudClientLiveTest {
|
|||
}
|
||||
|
||||
protected void checkVmOutput(String fooTxtContentsMadeByVMwareTools, String decodedVMwareToolsOutput) {
|
||||
assertEquals(decodedVMwareToolsOutput, script);
|
||||
// note that vmwaretools throws in \r characters when executing scripts
|
||||
assertEquals(fooTxtContentsMadeByVMwareTools, iLoveAscii + "\r\n");
|
||||
assertEquals(decodedVMwareToolsOutput, script);
|
||||
}
|
||||
|
||||
protected IPSocket getSocket(NodeMetadata node) {
|
||||
|
|
|
@ -94,8 +94,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function<HttpRespo
|
|||
if (lastModified == null) {
|
||||
// scaleup-storage uses the wrong case for the last modified header
|
||||
if ((lastModified = from.getFirstHeaderOrNull("Last-modified")) == null)
|
||||
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: "
|
||||
+ from.getStatusLine());
|
||||
throw new HttpException(HttpHeaders.LAST_MODIFIED + " header not present in response: " + from);
|
||||
}
|
||||
|
||||
// Walrus
|
||||
|
|
|
@ -93,4 +93,10 @@ public interface OpenStackAuthAsyncClient {
|
|||
@ResponseParser(ParseAuthenticationResponseFromHeaders.class)
|
||||
ListenableFuture<AuthenticationResponse> authenticate(@HeaderParam(AuthHeaders.AUTH_USER) String user,
|
||||
@HeaderParam(AuthHeaders.AUTH_KEY) String key);
|
||||
|
||||
|
||||
@GET
|
||||
@ResponseParser(ParseAuthenticationResponseFromHeaders.class)
|
||||
ListenableFuture<AuthenticationResponse> authenticateStorage(@HeaderParam(AuthHeaders.STORAGE_USER) String user,
|
||||
@HeaderParam(AuthHeaders.STORAGE_PASS) String key);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.concurrent.Future;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -69,25 +70,44 @@ public class OpenStackAuthenticationModule extends AbstractModule {
|
|||
};
|
||||
}
|
||||
|
||||
@Singleton
|
||||
public static class GetAuthenticationResponse implements Supplier<AuthenticationResponse> {
|
||||
protected final OpenStackAuthAsyncClient client;
|
||||
protected final String user;
|
||||
protected final String key;
|
||||
|
||||
@Inject
|
||||
public GetAuthenticationResponse(AsyncClientFactory factory, @Named(Constants.PROPERTY_IDENTITY) String user,
|
||||
@Named(Constants.PROPERTY_CREDENTIAL) String key) {
|
||||
this.client = factory.create(OpenStackAuthAsyncClient.class);
|
||||
this.user = user;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationResponse get() {
|
||||
try {
|
||||
Future<AuthenticationResponse> response = authenticate();
|
||||
return response.get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Future<AuthenticationResponse> authenticate() {
|
||||
return client.authenticate(user, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Supplier<AuthenticationResponse> provideAuthenticationResponseCache(final AsyncClientFactory factory,
|
||||
@Named(Constants.PROPERTY_IDENTITY) final String user,
|
||||
@Named(Constants.PROPERTY_CREDENTIAL) final String key) {
|
||||
Supplier<AuthenticationResponse> provideAuthenticationResponseCache(
|
||||
final GetAuthenticationResponse getAuthenticationResponse) {
|
||||
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<AuthenticationResponse>(
|
||||
new Supplier<AuthenticationResponse>() {
|
||||
public AuthenticationResponse get() {
|
||||
try {
|
||||
Future<AuthenticationResponse> response = factory.create(OpenStackAuthAsyncClient.class)
|
||||
.authenticate(user, key);
|
||||
return response.get(30, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
Throwables.propagate(e);
|
||||
assert false : e;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}), 23, TimeUnit.HOURS);
|
||||
getAuthenticationResponse), 23, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
@ -29,6 +29,8 @@ public interface AuthHeaders {
|
|||
|
||||
public static final String AUTH_USER = "X-Auth-User";
|
||||
public static final String AUTH_KEY = "X-Auth-Key";
|
||||
public static final String STORAGE_USER = "X-Storage-User";
|
||||
public static final String STORAGE_PASS = "X-Storage-Pass";
|
||||
public static final String AUTH_TOKEN = "X-Auth-Token";
|
||||
public static final String URL_SUFFIX = "-Url";
|
||||
|
||||
|
|
|
@ -60,6 +60,20 @@ public class OpenStackAuthAsyncClientTest extends RestClientTest<OpenStackAuthAs
|
|||
|
||||
}
|
||||
|
||||
public void testAuthenticateStorage() throws SecurityException, NoSuchMethodException, IOException {
|
||||
Method method = OpenStackAuthAsyncClient.class.getMethod("authenticateStorage", String.class, String.class);
|
||||
HttpRequest httpRequest = processor.createRequest(method, "foo", "bar");
|
||||
|
||||
assertRequestLineEquals(httpRequest, "GET http://localhost:8080/v1.0 HTTP/1.1");
|
||||
assertNonPayloadHeadersEqual(httpRequest, "X-Storage-Pass: bar\nX-Storage-User: foo\n");
|
||||
assertPayloadEquals(httpRequest, null, null, false);
|
||||
|
||||
assertResponseParserClassEquals(method, httpRequest, ParseAuthenticationResponseFromHeaders.class);
|
||||
assertSaxResponseParserClassEquals(method, null);
|
||||
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestContextSpec<OpenStackAuthClient, OpenStackAuthAsyncClient> createContextSpec() {
|
||||
return contextSpec("test", "http://localhost:8080", "1.0", "", "identity", "credential",
|
||||
|
|
|
@ -18,15 +18,16 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.terremark.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.getLast;
|
||||
import static org.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.withDescription;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
@ -71,10 +72,10 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
|
||||
@Inject
|
||||
protected TerremarkVCloudComputeClient(TerremarkVCloudClient client,
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
@Named("PASSWORD") Provider<String> passwordGenerator, Predicate<URI> successTester,
|
||||
Map<Status, NodeState> vAppStatusToNodeState, Map<String, Credentials> credentialStore,
|
||||
InternetServiceAndPublicIpAddressSupplier internetServiceAndPublicIpAddressSupplier) {
|
||||
PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider,
|
||||
@Named("PASSWORD") Provider<String> passwordGenerator, Predicate<URI> successTester,
|
||||
Map<Status, NodeState> vAppStatusToNodeState, Map<String, Credentials> credentialStore,
|
||||
InternetServiceAndPublicIpAddressSupplier internetServiceAndPublicIpAddressSupplier) {
|
||||
super(client, successTester, vAppStatusToNodeState);
|
||||
this.client = client;
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
|
@ -85,7 +86,7 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
|
||||
@Override
|
||||
public VCloudExpressVApp start(@Nullable URI VDC, URI templateId, String name,
|
||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
||||
InstantiateVAppTemplateOptions options, int... portsToOpen) {
|
||||
if (options.getDiskSizeKilobytes() != null) {
|
||||
logger.warn("trmk does not support resizing the primary disk; unsetting disk size");
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
String password = null;
|
||||
VCloudExpressVAppTemplate template = client.getVAppTemplate(templateId);
|
||||
if (template.getDescription().indexOf("Windows") != -1
|
||||
&& options instanceof TerremarkInstantiateVAppTemplateOptions) {
|
||||
&& options instanceof TerremarkInstantiateVAppTemplateOptions) {
|
||||
password = passwordGenerator.get();
|
||||
TerremarkInstantiateVAppTemplateOptions.class.cast(options).getProperties().put("password", password);
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
VCloudExpressVApp vAppResponse = super.start(VDC, templateId, name, options, portsToOpen);
|
||||
if (password != null) {
|
||||
credentialStore.put("node#" + vAppResponse.getHref().toASCIIString(), new Credentials(
|
||||
defaultCredentials.identity, password));
|
||||
defaultCredentials.identity, password));
|
||||
}
|
||||
if (portsToOpen.length > 0)
|
||||
createPublicAddressMappedToPorts(vAppResponse.getHref(), portsToOpen);
|
||||
|
@ -119,41 +120,37 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
InternetService is = null;
|
||||
Protocol protocol;
|
||||
switch (port) {
|
||||
case 22:
|
||||
protocol = Protocol.TCP;
|
||||
break;
|
||||
case 80:
|
||||
case 8080:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 443:
|
||||
protocol = Protocol.HTTPS;
|
||||
break;
|
||||
default:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 22:
|
||||
protocol = Protocol.TCP;
|
||||
break;
|
||||
case 80:
|
||||
case 8080:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
case 443:
|
||||
protocol = Protocol.HTTPS;
|
||||
break;
|
||||
default:
|
||||
protocol = Protocol.HTTP;
|
||||
break;
|
||||
}
|
||||
if (ip == null) {
|
||||
|
||||
Entry<InternetService, PublicIpAddress> entry = internetServiceAndPublicIpAddressSupplier
|
||||
.getNewInternetServiceAndIp(vApp, port, protocol);
|
||||
.getNewInternetServiceAndIp(vApp, port, protocol);
|
||||
is = entry.getKey();
|
||||
ip = entry.getValue();
|
||||
|
||||
} else {
|
||||
logger.debug(">> adding InternetService %s:%s:%d", ip.getAddress(), protocol, port);
|
||||
is = client.addInternetServiceToExistingIp(
|
||||
ip.getId(),
|
||||
vApp.getName() + "-" + port,
|
||||
protocol,
|
||||
port,
|
||||
withDescription(String.format("port %d access to serverId: %s name: %s", port, vApp.getName(),
|
||||
vApp.getName())));
|
||||
is = client.addInternetServiceToExistingIp(ip.getId(), vApp.getName() + "-" + port, protocol, port,
|
||||
withDescription(String.format("port %d access to serverId: %s name: %s", port, vApp.getName(),
|
||||
vApp.getName())));
|
||||
}
|
||||
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getName(), is.getPublicIpAddress().getAddress(),
|
||||
is.getProtocol(), is.getPort());
|
||||
logger.debug("<< created InternetService(%s) %s:%s:%d", is.getName(), is.getPublicIpAddress().getAddress(), is
|
||||
.getProtocol(), is.getPort());
|
||||
logger.debug(">> adding Node %s:%d -> %s:%d", is.getPublicIpAddress().getAddress(), is.getPort(),
|
||||
privateAddress, port);
|
||||
privateAddress, port);
|
||||
Node node = client.addNode(is.getId(), privateAddress, vApp.getName() + "-" + port, port);
|
||||
logger.debug("<< added Node(%s)", node.getName());
|
||||
}
|
||||
|
@ -161,19 +158,20 @@ public class TerremarkVCloudComputeClient extends VCloudExpressComputeClientImpl
|
|||
}
|
||||
|
||||
private Set<PublicIpAddress> deleteInternetServicesAndNodesAssociatedWithVApp(VCloudExpressVApp vApp) {
|
||||
checkNotNull(vApp.getVDC(), "VDC reference missing for vApp(%s)", vApp.getName());
|
||||
Set<PublicIpAddress> ipAddresses = Sets.newHashSet();
|
||||
SERVICE: for (InternetService service : client.getAllInternetServicesInVDC(vApp.getVDC().getHref())) {
|
||||
for (Node node : client.getNodes(service.getId())) {
|
||||
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
|
||||
ipAddresses.add(service.getPublicIpAddress());
|
||||
logger.debug(">> deleting Node(%s) %s:%d -> %s:%d", node.getName(), service.getPublicIpAddress()
|
||||
.getAddress(), service.getPort(), node.getIpAddress(), node.getPort());
|
||||
.getAddress(), service.getPort(), node.getIpAddress(), node.getPort());
|
||||
client.deleteNode(node.getId());
|
||||
logger.debug("<< deleted Node(%s)", node.getName());
|
||||
Set<Node> nodes = client.getNodes(service.getId());
|
||||
if (nodes.size() == 0) {
|
||||
logger.debug(">> deleting InternetService(%s) %s:%d", service.getName(), service.getPublicIpAddress()
|
||||
.getAddress(), service.getPort());
|
||||
.getAddress(), service.getPort());
|
||||
client.deleteInternetService(service.getId());
|
||||
logger.debug("<< deleted InternetService(%s)", service.getName());
|
||||
continue SERVICE;
|
||||
|
|
|
@ -88,14 +88,16 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes
|
|||
|
||||
protected TerremarkVCloudClient tmClient;
|
||||
protected Factory sshFactory;
|
||||
private String publicIp;
|
||||
private InternetService is;
|
||||
private Node node;
|
||||
private VCloudExpressVApp vApp;
|
||||
private RetryablePredicate<IPSocket> socketTester;
|
||||
private RetryablePredicate<URI> successTester;
|
||||
private VCloudExpressVApp clone;
|
||||
private VDC vdc;
|
||||
protected String publicIp;
|
||||
protected InternetService is;
|
||||
protected Node node;
|
||||
protected VCloudExpressVApp vApp;
|
||||
protected RetryablePredicate<IPSocket> socketTester;
|
||||
protected RetryablePredicate<URI> successTester;
|
||||
protected Injector injector;
|
||||
|
||||
protected VCloudExpressVApp clone;
|
||||
protected VDC vdc;
|
||||
public static final String PREFIX = System.getProperty("user.name") + "-terremark";
|
||||
|
||||
@Test
|
||||
|
@ -281,7 +283,7 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes
|
|||
loopAndCheckPass();
|
||||
}
|
||||
|
||||
private void loopAndCheckPass() throws IOException {
|
||||
protected void loopAndCheckPass() throws IOException {
|
||||
for (int i = 0; i < 5; i++) {// retry loop TODO replace with predicate.
|
||||
try {
|
||||
doCheckPass(publicIp);
|
||||
|
@ -373,7 +375,7 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes
|
|||
loopAndCheckPass();
|
||||
}
|
||||
|
||||
private void verifyConfigurationOfVApp(VCloudExpressVApp vApp, String serverName, String expectedOs,
|
||||
protected void verifyConfigurationOfVApp(VCloudExpressVApp vApp, String serverName, String expectedOs,
|
||||
int processorCount, long memory, long hardDisk) {
|
||||
assertEquals(vApp.getName(), serverName);
|
||||
assertEquals(vApp.getOperatingSystemDescription(), expectedOs);
|
||||
|
@ -387,7 +389,7 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes
|
|||
CIMPredicates.resourceTypeIn(ResourceType.DISK_DRIVE)).getVirtualQuantity().longValue());
|
||||
}
|
||||
|
||||
private void doCheckPass(String address) throws IOException {
|
||||
protected void doCheckPass(String address) throws IOException {
|
||||
IPSocket socket = new IPSocket(address, 22);
|
||||
|
||||
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), socket);
|
||||
|
@ -466,7 +468,7 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes
|
|||
setupCredentials();
|
||||
Properties overrides = setupProperties();
|
||||
|
||||
Injector injector = new RestContextFactory().createContextBuilder(provider,
|
||||
injector = new RestContextFactory().createContextBuilder(provider,
|
||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides)
|
||||
.buildInjector();
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ import org.jclouds.vcloud.predicates.TaskSuccess;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.ConfigurationException;
|
||||
|
@ -451,12 +452,14 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
|
|||
checkState(networks.size() > 0, "No networks present in vDC: " + vDC.getName());
|
||||
if (networks.size() == 1)
|
||||
return Iterables.getLast(networks.values()).getHref();
|
||||
String networkName = null;
|
||||
try {
|
||||
String networkName = injector.getInstance(Key.get(String.class, Names
|
||||
.named(PROPERTY_VCLOUD_DEFAULT_NETWORK)));
|
||||
ReferenceType network = networks.get(networkName);
|
||||
checkState(network != null, String.format("network named %s not in %s", networkName, networks.keySet()));
|
||||
networkName = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_VCLOUD_DEFAULT_NETWORK)));
|
||||
ReferenceType network = networks.get(Iterables.find(networks.keySet(), Predicates
|
||||
.containsPattern(networkName)));
|
||||
return network.getHref();
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new IllegalStateException(String.format("network matching [%s] not in %s", networkName, networks.keySet()));
|
||||
} catch (ConfigurationException e) {
|
||||
return findDefaultNetworkForVDC(vDC, networks, injector);
|
||||
}
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
*/
|
||||
package org.jclouds.vcloud.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -41,6 +41,8 @@ import org.jclouds.vcloud.endpoints.Org;
|
|||
import org.jclouds.vcloud.xml.OrgListHandler;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* This parses {@link VCloudSession} from HTTP headers.
|
||||
|
@ -49,7 +51,7 @@ import com.google.common.base.Function;
|
|||
*/
|
||||
@Singleton
|
||||
public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCloudSession> {
|
||||
static final Pattern pattern = Pattern.compile("(vcloud-token=)?([^;]+)(;.*)?");
|
||||
static final Pattern pattern = Pattern.compile("(vcloud-token)=?([^;]+)(;.*)?");
|
||||
|
||||
private final ParseSax.Factory factory;
|
||||
private final Provider<OrgListHandler> orgHandlerProvider;
|
||||
|
@ -61,38 +63,45 @@ public class ParseLoginResponseFromHeaders implements Function<HttpResponse, VCl
|
|||
}
|
||||
|
||||
/**
|
||||
* parses the http response headers to create a new {@link VCloudSession}
|
||||
* object.
|
||||
* parses the http response headers to create a new {@link VCloudSession} object.
|
||||
*/
|
||||
public VCloudSession apply(HttpResponse from) {
|
||||
String cookieHeader = from.getFirstHeaderOrNull("x-vcloud-authorization");
|
||||
if (cookieHeader == null)
|
||||
cookieHeader = from.getFirstHeaderOrNull(HttpHeaders.SET_COOKIE);
|
||||
checkNotNull(cookieHeader, "Header %s or %s must be present", "x-vcloud-authorization", HttpHeaders.SET_COOKIE);
|
||||
|
||||
final Matcher matcher = pattern.matcher(cookieHeader);
|
||||
boolean matchFound = matcher.find();
|
||||
try {
|
||||
if (matchFound) {
|
||||
final Map<String, ReferenceType> org = factory.create(orgHandlerProvider.get()).parse(
|
||||
final String token = parseTokenFromHeaders(from);
|
||||
final Map<String, ReferenceType> org = factory.create(orgHandlerProvider.get()).parse(
|
||||
from.getPayload().getInput());
|
||||
|
||||
return new VCloudSession() {
|
||||
@VCloudToken
|
||||
public String getVCloudToken() {
|
||||
return matcher.group(2);
|
||||
}
|
||||
return new VCloudSession() {
|
||||
@VCloudToken
|
||||
public String getVCloudToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Org
|
||||
public Map<String, ReferenceType> getOrgs() {
|
||||
return org;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@Org
|
||||
public Map<String, ReferenceType> getOrgs() {
|
||||
return org;
|
||||
}
|
||||
};
|
||||
} finally {
|
||||
releasePayload(from);
|
||||
}
|
||||
throw new HttpResponseException("x-vcloud-authorization not found ", null, from);
|
||||
}
|
||||
|
||||
public String parseTokenFromHeaders(HttpResponse from) {
|
||||
String cookieHeader = from.getFirstHeaderOrNull("x-vcloud-authorization");
|
||||
if (cookieHeader != null) {
|
||||
Matcher matcher = pattern.matcher(cookieHeader);
|
||||
return matcher.find() ? matcher.group(2) : cookieHeader;
|
||||
} else {
|
||||
try {
|
||||
cookieHeader = Iterables.find(from.getHeaders().get(HttpHeaders.SET_COOKIE), Predicates.contains(pattern));
|
||||
Matcher matcher = pattern.matcher(cookieHeader);
|
||||
matcher.find();
|
||||
return matcher.group(2);
|
||||
} catch (NoSuchElementException e) {
|
||||
throw new HttpResponseException(String.format("Header %s or %s must be present", "x-vcloud-authorization",
|
||||
HttpHeaders.SET_COOKIE), null, from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,8 +88,9 @@ public class ParseVCloudErrorFromHttpResponse implements HttpErrorHandler {
|
|||
|
||||
switch (response.getStatusCode()) {
|
||||
case 400:
|
||||
if (error != null && error.getMinorErrorCode() != null
|
||||
&& error.getMinorErrorCode() == MinorCode.BUSY_ENTITY)
|
||||
if (error != null
|
||||
&& (error.getMinorErrorCode() != null && error.getMinorErrorCode() == MinorCode.BUSY_ENTITY)
|
||||
|| (error.getMessage() != null && error.getMessage().indexOf("is not running") != -1))
|
||||
exception = new IllegalStateException(message, exception);
|
||||
else
|
||||
exception = new IllegalArgumentException(message, exception);
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import java.net.URI;
|
||||
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.functions.BaseHandlerTest;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
|
@ -54,60 +55,98 @@ public class ParseLoginResponseFromHeadersTest extends BaseHandlerTest {
|
|||
@Test
|
||||
public void testApply() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/"));
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"vcloud-token=9er4d061-4bff-48fa-84b1-5da7166764d2; path=/"));
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "9er4d061-4bff-48fa-84b1-5da7166764d2");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyBlueLock() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0="));
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0="));
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "MUKOJ2HoAfoMmLnHRp4esNb2MtWscCLLhVysnsIsCG0=");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyTerremark() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("Set-Cookie",
|
||||
"vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/"));
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("Set-Cookie",
|
||||
"vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/"));
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "37ce2715-9aba-4f48-8e45-2db8a8da702d");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyTerremarkMultipleCookies() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> builder().put("Set-Cookie",
|
||||
"NSC_ESUO_21654_72.46.239.132_443=fooo;expires=Thu, 02-Jun-2011 17:19:26 GMT;path=/;secure;httponly")
|
||||
.put("Set-Cookie", "vcloud-token=37ce2715-9aba-4f48-8e45-2db8a8da702d; path=/").build());
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "37ce2715-9aba-4f48-8e45-2db8a8da702d");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = HttpResponseException.class)
|
||||
public void testUnmatchedCookieThrowsHttpResponseException() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> builder().put("Set-Cookie",
|
||||
"NSC_ESUO_21654_72.46.239.132_443=fooo;expires=Thu, 02-Jun-2011 17:19:26 GMT;path=/;secure;httponly")
|
||||
.build());
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
parser.apply(response);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = HttpResponseException.class)
|
||||
public void testNoThrowsHttpResponseException() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of());
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
parser.apply(response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApplyVirtacore() {
|
||||
HttpResponse response = new HttpResponse(200, "OK", Payloads.newInputStreamPayload(getClass()
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"vcloud-token=IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48="));
|
||||
.getResourceAsStream("/orglist.xml")), ImmutableMultimap.<String, String> of("x-vcloud-authorization",
|
||||
"vcloud-token=IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48="));
|
||||
response.getPayload().getContentMetadata().setContentType("Content-Type: application/xml; charset=utf-8");
|
||||
response.getPayload().getContentMetadata().setContentLength(307l);
|
||||
|
||||
VCloudSession reply = parser.apply(response);
|
||||
assertEquals(reply.getVCloudToken(), "IPy0w7UGD4lwtdWAK/ZVzfuLK+dztxGRqsOhWqV0i48=");
|
||||
assertEquals(reply.getOrgs(), ImmutableMap.of("adrian@jclouds.org", new ReferenceTypeImpl("adrian@jclouds.org",
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
VCloudMediaType.ORG_XML, URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/org/48"))));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.jclouds.http.HttpErrorHandler;
|
|||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
@ -36,23 +37,32 @@ public class ParseVCloudErrorFromHttpResponseTest extends BaseHttpErrorHandlerTe
|
|||
|
||||
@Test
|
||||
public void testGet404SetsResourceNotFoundException() {
|
||||
assertCodeMakes("GET", URI
|
||||
.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"),
|
||||
404, "", "", ResourceNotFoundException.class);
|
||||
assertCodeMakes("GET", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 404,
|
||||
"", "", ResourceNotFoundException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete404SetsHttpResponseException() {
|
||||
assertCodeMakes("DELETE", URI
|
||||
.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"),
|
||||
assertCodeMakes("DELETE", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"),
|
||||
404, "", "", HttpResponseException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPOSTNotRunningSetsIllegalStateException() {
|
||||
assertCodeMakes(
|
||||
"POST",
|
||||
URI.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-138351019/action/undeploy"),
|
||||
400,
|
||||
"HTTP/1.1 400 Bad Request",
|
||||
VCloudMediaType.ERROR_XML,
|
||||
"<Error xmlns=\"http://www.vmware.com/vcloud/v1\" minorErrorCode=\"BAD_REQUEST\" message=\"The requested operation could not be executed since vApp "adriancolecap-78c" is not running.\" majorErrorCode=\"400\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.vmware.com/vcloud/v1 http://vcenterprise.bluelock.com/api/v1.0/schema/master.xsd\"></Error>\n",
|
||||
IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test401SetsAuthorizationException() {
|
||||
assertCodeMakes("GET", URI
|
||||
.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"),
|
||||
401, "", "", AuthorizationException.class);
|
||||
assertCodeMakes("GET", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 401,
|
||||
"", "", AuthorizationException.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,19 +20,22 @@
|
|||
(ns org.jclouds.compute2
|
||||
"A clojure binding to the jclouds ComputeService.
|
||||
|
||||
Current supported providers are:
|
||||
[aws-ec2, eucualyptus-partnercloud-ec2, elastichosts-lon-b,
|
||||
cloudservers-uk, cloudservers-us, byon, cloudsigma-zrh, stub,
|
||||
trmk-ecloud, trmk-vcloudexpress, vcloud, bluelock, eucalyptus,
|
||||
slicehost, elastichosts-lon-p, elastichosts-sat-p, elastichosts,
|
||||
openhosting-east1, serverlove-z1-man, skalicloud-sdg-my, deltacloud]
|
||||
jclouds supports many compute providers including Amazon EC2 (aws-ec2),
|
||||
Rackspace Cloud Servers (cloudservers-us), GoGrid (gogrid), and BlueLock
|
||||
vCloud (bluelock-vcloud-zone01). There are over a dozen to choose from.
|
||||
|
||||
Current supported providers are available via the following dependency:
|
||||
org.jclouds/jclouds-allcompute
|
||||
|
||||
You can inquire about which providers are loaded via the following:
|
||||
(seq (org.jclouds.providers.Providers/allCompute))
|
||||
|
||||
Here's an example of getting some compute configuration from rackspace:
|
||||
|
||||
(use 'org.jclouds.compute2)
|
||||
(use 'clojure.pprint)
|
||||
|
||||
(def provider \"cloudservers\")
|
||||
(def provider \"cloudservers-us\")
|
||||
(def provider-identity \"username\")
|
||||
(def provider-credential \"password\")
|
||||
|
||||
|
@ -225,7 +228,11 @@ Here's an example of creating and running a small linux node in the group webser
|
|||
|
||||
(defn destroy-nodes-matching
|
||||
"Destroy all the nodes in the fn pred.
|
||||
pred should be a fn of one argument that takes a ComputeMetadata and returns true or false."
|
||||
pred should be a fn of one argument that takes a ComputeMetadata and returns true or false.
|
||||
|
||||
;; destroy all nodes
|
||||
(destroy-nodes-matching compute (constantly true))
|
||||
"
|
||||
([#^ComputeService compute pred]
|
||||
(.destroyNodesMatching compute (to-predicate pred))))
|
||||
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
;
|
||||
(ns org.jclouds.predicate)
|
||||
|
||||
(defprotocol Predicate
|
||||
"Protocol for making a com.google.common.base.Predicate."
|
||||
(defprotocol Coercions
|
||||
"Protocol for coercing between predicate-like things, like
|
||||
Clojure fns and com.google.common.base.Predicate."
|
||||
(to-predicate [p]))
|
||||
|
||||
(extend-protocol Predicate
|
||||
(extend-protocol Coercions
|
||||
clojure.lang.IFn
|
||||
(to-predicate [p]
|
||||
(reify com.google.common.base.Predicate
|
||||
|
|
|
@ -32,13 +32,17 @@ import org.jclouds.compute.options.RunScriptOptions;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.scriptbuilder.InitBuilder;
|
||||
import org.jclouds.scriptbuilder.domain.AppendFile;
|
||||
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
import org.jclouds.scriptbuilder.domain.Statements;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
|
||||
|
@ -47,6 +51,7 @@ import com.google.inject.assistedinject.AssistedInject;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunScriptOnNodeAsInitScriptUsingSsh implements RunScriptOnNode {
|
||||
public static final String PROPERTY_PUSH_INIT_SCRIPT_VIA_SFTP = "jclouds.compute.push-init-script-via-sftp";
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
@ -59,6 +64,14 @@ public class RunScriptOnNodeAsInitScriptUsingSsh implements RunScriptOnNode {
|
|||
|
||||
protected SshClient ssh;
|
||||
|
||||
/**
|
||||
* true to use sftp, false to use ssh. If there's a problem with the sftp configuration, setting
|
||||
* this to false will help.
|
||||
*/
|
||||
@Inject(optional = true)
|
||||
@Named(PROPERTY_PUSH_INIT_SCRIPT_VIA_SFTP)
|
||||
private boolean pushInitViaSftp = true;
|
||||
|
||||
@AssistedInject
|
||||
public RunScriptOnNodeAsInitScriptUsingSsh(Function<NodeMetadata, SshClient> sshFactory,
|
||||
@Assisted NodeMetadata node, @Assisted Statement script, @Assisted RunScriptOptions options) {
|
||||
|
@ -104,7 +117,13 @@ public class RunScriptOnNodeAsInitScriptUsingSsh implements RunScriptOnNode {
|
|||
* ssh client is initialized through this call.
|
||||
*/
|
||||
protected ExecResponse doCall() {
|
||||
ssh.put(name, init.render(OsFamily.UNIX));
|
||||
if (pushInitViaSftp) {
|
||||
ssh.put(name, init.render(OsFamily.UNIX));
|
||||
} else {
|
||||
ssh.exec("rm " + name);
|
||||
ssh.exec(Statements.appendFile(name, Splitter.on('\n').split(init.render(OsFamily.UNIX)),
|
||||
AppendFile.MARKER + "_" + name).render(OsFamily.UNIX));
|
||||
}
|
||||
ssh.exec("chmod 755 " + name);
|
||||
runAction("init");
|
||||
return runAction("start");
|
||||
|
|
|
@ -416,6 +416,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
|
|||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromTemplate(Template template) {
|
||||
location = template.getLocation();
|
||||
fromHardware(template.getHardware());
|
||||
fromImage(template.getImage());
|
||||
options(template.getOptions());
|
||||
|
|
|
@ -561,7 +561,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
protected int nonBlockDuration = 30 * 1000;
|
||||
protected int nonBlockDurationSeconds = 30;
|
||||
|
||||
public void testOptionToNotBlock() throws Exception {
|
||||
String group = this.group + "block";
|
||||
|
@ -577,9 +577,9 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
|
||||
NodeMetadata node = getOnlyElement(nodes);
|
||||
assert node.getState() != NodeState.RUNNING;
|
||||
long duration = System.currentTimeMillis() - time;
|
||||
assert duration < nonBlockDuration : String.format("duration(%d) longer than expected(%d) seconds! ",
|
||||
duration / 1000, nonBlockDuration);
|
||||
long duration = (System.currentTimeMillis() - time) / 1000;
|
||||
assert duration < nonBlockDurationSeconds : String.format("duration(%d) longer than expected(%d) seconds! ",
|
||||
duration, nonBlockDurationSeconds);
|
||||
} finally {
|
||||
client.destroyNodesMatching(inGroup(group));
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.concurrent.TimeoutException;
|
|||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
@ -77,6 +78,35 @@ public abstract class BaseTemplateBuilderLiveTest {
|
|||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
public void testCompareSizes() throws Exception {
|
||||
Hardware defaultSize = context.getComputeService().templateBuilder().build().getHardware();
|
||||
|
||||
Hardware smallest = context.getComputeService().templateBuilder().smallest().build().getHardware();
|
||||
Hardware fastest = context.getComputeService().templateBuilder().fastest().build().getHardware();
|
||||
Hardware biggest = context.getComputeService().templateBuilder().biggest().build().getHardware();
|
||||
|
||||
System.out.printf("smallest %s%n", smallest);
|
||||
System.out.printf("fastest %s%n", fastest);
|
||||
System.out.printf("biggest %s%n", biggest);
|
||||
|
||||
assertEquals(defaultSize, smallest);
|
||||
|
||||
assert getCores(smallest) <= getCores(fastest) : String.format("%s ! <= %s", smallest, fastest);
|
||||
assert getCores(biggest) <= getCores(fastest) : String.format("%s ! <= %s", biggest, fastest);
|
||||
|
||||
assert biggest.getRam() >= fastest.getRam() : String.format("%s ! >= %s", biggest, fastest);
|
||||
assert biggest.getRam() >= smallest.getRam() : String.format("%s ! >= %s", biggest, smallest);
|
||||
|
||||
assert getCores(fastest) >= getCores(biggest) : String.format("%s ! >= %s", fastest, biggest);
|
||||
assert getCores(fastest) >= getCores(smallest) : String.format("%s ! >= %s", fastest, smallest);
|
||||
}
|
||||
|
||||
public void testFromTemplate() {
|
||||
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||
assertEquals(context.getComputeService().templateBuilder().fromTemplate(defaultTemplate).build().toString(),
|
||||
defaultTemplate.toString());
|
||||
}
|
||||
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.date.internal;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class DateUtils {
|
||||
|
||||
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
|
||||
|
||||
public static final Pattern TZ_PATTERN = Pattern.compile("(.*)[+-][0-9][0-9]:?[0-9][0-9]Z?");
|
||||
|
||||
public static String trimNanosToMillis(String toParse) {
|
||||
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
|
||||
return toParse;
|
||||
}
|
||||
|
||||
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
|
||||
|
||||
public static String trimTZ(String toParse) {
|
||||
Matcher matcher = TZ_PATTERN.matcher(toParse);
|
||||
if (matcher.find()) {
|
||||
toParse = matcher.group(1) + 'Z';
|
||||
}
|
||||
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
|
||||
return toParse;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,18 +17,16 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.date.internal;
|
||||
import static org.jclouds.date.internal.DateUtils.trimNanosToMillis;
|
||||
import static org.jclouds.date.internal.DateUtils.trimTZ;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,8 +37,6 @@ import org.jclouds.logging.Logger;
|
|||
*/
|
||||
public class SimpleDateFormatDateService implements DateService {
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
/*
|
||||
* Use default Java Date/SimpleDateFormat classes for date manipulation, but be *very* careful to
|
||||
* guard against the lack of thread safety.
|
||||
|
@ -50,16 +46,16 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
||||
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||
private static final SimpleDateFormat iso8601SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
|
||||
Locale.US);
|
||||
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat(
|
||||
"EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
||||
private static final SimpleDateFormat rfc822SimpleDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
|
||||
Locale.US);
|
||||
|
||||
// @GuardedBy("this")
|
||||
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat(
|
||||
"EEE MMM dd HH:mm:ss '+0000' yyyy", Locale.US);
|
||||
private static final SimpleDateFormat cSimpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss '+0000' yyyy",
|
||||
Locale.US);
|
||||
|
||||
static {
|
||||
iso8601SimpleDateFormat.setTimeZone(new SimpleTimeZone(0, "GMT"));
|
||||
|
@ -138,29 +134,6 @@ public class SimpleDateFormatDateService implements DateService {
|
|||
}
|
||||
}
|
||||
|
||||
public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern
|
||||
.compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]");
|
||||
|
||||
public static final Pattern TZ_PATTERN = Pattern.compile(".*[+-][0-9][0-9]:?[0-9][0-9]");
|
||||
|
||||
private String trimNanosToMillis(String toParse) {
|
||||
if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 3) + 'Z';
|
||||
return toParse;
|
||||
}
|
||||
|
||||
public static final Pattern SECOND_PATTERN = Pattern.compile(".*[0-2][0-9]:00");
|
||||
|
||||
private String trimTZ(String toParse) {
|
||||
if (TZ_PATTERN.matcher(toParse).matches()) {
|
||||
logger.trace("trimming tz from %s", toParse);
|
||||
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
|
||||
}
|
||||
if (toParse.length() == 25 && SECOND_PATTERN.matcher(toParse).matches())
|
||||
toParse = toParse.substring(0, toParse.length() - 6) + 'Z';
|
||||
return toParse;
|
||||
}
|
||||
|
||||
public final Date iso8601SecondsDateParse(String toParse) {
|
||||
toParse = trimTZ(toParse);
|
||||
synchronized (iso8601SecondsSimpleDateFormat) {
|
||||
|
|
|
@ -95,6 +95,18 @@ cloudservers-us.propertiesbuilder=org.jclouds.rackspace.cloudservers.CloudServer
|
|||
bluelock-vcdirector.contextbuilder=org.jclouds.vcloud.bluelock.BluelockVCloudDirectorContextBuilder
|
||||
bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BluelockVCloudDirectorPropertiesBuilder
|
||||
|
||||
bluelock-vcdirector.contextbuilder=org.jclouds.vcloud.bluelock.BluelockVCloudDirectorContextBuilder
|
||||
bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BluelockVCloudDirectorPropertiesBuilder
|
||||
|
||||
bluelock-vcloud-vcenterprise.contextbuilder=org.jclouds.bluelock.vcloud.vcenterprise.BluelockVCloudEnterpriseContextBuilder
|
||||
bluelock-vcloud-vcenterprise.propertiesbuilder=org.jclouds.bluelock.vcloud.vcenterprise.BluelockVCloudEnterprisePropertiesBuilder
|
||||
|
||||
bluelock-vcloud-zone01.contextbuilder=org.jclouds.bluelock.vcloud.zone01.BluelockVCloudZone01ContextBuilder
|
||||
bluelock-vcloud-zone01.propertiesbuilder=org.jclouds.bluelock.vcloud.zone01.BluelockVCloudZone01PropertiesBuilder
|
||||
|
||||
stratogen-vcloud-mycloud.contextbuilder=org.jclouds.stratogen.vcloud.mycloud.StratoGenVCloudMyCloudContextBuilder
|
||||
stratogen-vcloud-mycloud.propertiesbuilder=org.jclouds.stratogen.vcloud.mycloud.StratoGenVCloudMyCloudPropertiesBuilder
|
||||
|
||||
gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder
|
||||
gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ public class DateServiceTest extends PerformanceTest {
|
|||
}
|
||||
|
||||
public DateServiceTest() {
|
||||
// Constant time test values, each TestData item must contain matching times!
|
||||
// Constant time test values, each TestData item must contain matching
|
||||
// times!
|
||||
testData = new TestData[] {
|
||||
new TestData("2009-03-12T02:00:07.000Z", "2009-03-12T02:00:07-04:00", "2009-03-12T02:00:07Z",
|
||||
"Thu, 12 Mar 2009 02:00:07 GMT", "Thu Mar 12 02:00:07 +0000 2009", new Date(1236823207000l)),
|
||||
|
@ -162,6 +163,12 @@ public class DateServiceTest extends PerformanceTest {
|
|||
assertEquals(dateService.rfc822DateFormat(date), "Sat, 26 Sep 2009 23:37:05 GMT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTzWithExtraZ() throws ExecutionException, InterruptedException {
|
||||
assertEquals(dateService.iso8601SecondsDateParse("2011-05-26T06:14:13-04:00").getTime(), 1306390453000l);
|
||||
assertEquals(dateService.iso8601SecondsDateParse("2011-05-26T06:14:13-04:00Z").getTime(), 1306390453000l);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRfc822DateFormatResponseTime() throws ExecutionException, InterruptedException {
|
||||
for (int i = 0; i < LOOP_COUNT; i++)
|
||||
|
|
|
@ -59,15 +59,21 @@ public abstract class BaseHttpErrorHandlerTest {
|
|||
|
||||
protected abstract Class<? extends HttpErrorHandler> getHandlerClass();
|
||||
|
||||
protected void assertCodeMakes(String method, URI uri, int statusCode, String message,
|
||||
protected void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
|
||||
Class<? extends Exception> expected) {
|
||||
assertCodeMakes(method, uri, statusCode, message, null, content, expected);
|
||||
}
|
||||
|
||||
protected void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
|
||||
String content, Class<? extends Exception> expected) {
|
||||
|
||||
HttpErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance(
|
||||
getHandlerClass());
|
||||
HttpErrorHandler function = Guice.createInjector(new SaxParserModule()).getInstance(getHandlerClass());
|
||||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
HttpRequest request = new HttpRequest(method, uri);
|
||||
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newStringPayload(content));
|
||||
if (contentType != null)
|
||||
response.getPayload().getContentMetadata().setContentType(contentType);
|
||||
|
||||
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
|
||||
command.setException(classEq(expected));
|
||||
|
|
|
@ -1,313 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-demos-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-demo-gae-tweetstore</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>JClouds TweetStore for Google App Engine</name>
|
||||
<description>JClouds TweetStore for Google App Engine using Guice for Dependency Injection</description>
|
||||
|
||||
<properties>
|
||||
<!--
|
||||
note you must set the property ${appengine.sdk.root} to a valid
|
||||
extraction of appengine-java-sdk
|
||||
-->
|
||||
<appengine.applicationid>jclouds-tweetstore</appengine.applicationid>
|
||||
<appengine.sdk.version>1.4.2</appengine.sdk.version>
|
||||
<devappserver.address>localhost</devappserver.address>
|
||||
<devappserver.port>8088</devappserver.port>
|
||||
<jclouds.tweetstore.blobstores>cloudfiles-us,aws-s3,azureblob</jclouds.tweetstore.blobstores>
|
||||
<jclouds.tweetstore.container>jclouds-tweetstore</jclouds.tweetstore.container>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
<version>[2.1,)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-s3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>cloudfiles-us</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>azureblob</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-gae</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
<artifactId>displaytag</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Google App Engine API -->
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-1.0-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Needed..??> -->
|
||||
|
||||
<!-- Google App Engine Runtime Dependencies -->
|
||||
<!--dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jta_1.1_spec</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-jpa_3.0_spec</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine.orm</groupId>
|
||||
<artifactId>jdo2-api</artifactId>
|
||||
<version>2.3-eb</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.datanucleus</groupId>
|
||||
<artifactId>datanucleus-core</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine.orm</groupId>
|
||||
<artifactId>datanucleus-appengine</artifactId>
|
||||
<version>1.0.8</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.datanucleus</groupId>
|
||||
<artifactId>datanucleus-jpa</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency-->
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/appengine</directory>
|
||||
<targetPath>WEB-INF/</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>appengine.sdk.root</name>
|
||||
<value>${appengine.sdk.root}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.address</name>
|
||||
<value>${devappserver.address}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.port</name>
|
||||
<value>${devappserver.port}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>warfile</name>
|
||||
<value>${project.build.directory}/${project.artifactId}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>test.twitter.identity</name>
|
||||
<value>${test.twitter.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.credential</name>
|
||||
<value>${test.twitter.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.identity</name>
|
||||
<value>${test.azureblob.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.credential</name>
|
||||
<value>${test.azureblob.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.cloudfiles-us.identity</name>
|
||||
<value>${test.cloudfiles-us.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.cloudfiles-us.credential</name>
|
||||
<value>${test.cloudfiles-us.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.aws-s3.identity</name>
|
||||
<value>${test.aws-s3.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.aws-s3.credential</name>
|
||||
<value>${test.aws-s3.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>appengine.sdk.root</name>
|
||||
<value>${appengine.sdk.root}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.address</name>
|
||||
<value>${devappserver.address}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.port</name>
|
||||
<value>${devappserver.port}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>jclouds.tweetstore.blobstores</name>
|
||||
<value>${jclouds.tweetstore.blobstores}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>jclouds.tweetstore.container</name>
|
||||
<value>${jclouds.tweetstore.container}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>warfile</name>
|
||||
<value>${project.build.directory}/${project.artifactId}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -32,15 +32,13 @@
|
|||
<packaging>pom</packaging>
|
||||
<name>jclouds demos project</name>
|
||||
<modules>
|
||||
<module>gae-tweetstore</module>
|
||||
<module>gae-tweetstore-spring</module>
|
||||
<module>getpath</module>
|
||||
<module>googleappengine</module>
|
||||
<module>perftest</module>
|
||||
<module>runatcloud-tweetstore</module>
|
||||
<module>speedtest-azurequeue</module>
|
||||
<module>speedtest-sqs</module>
|
||||
<module>simpledb</module>
|
||||
<module>tweetstore</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -25,6 +25,8 @@ It should not be regarded as a sample of how to write a web application using Sp
|
|||
however! The original jclouds-demo-gae-tweetstore has been modified in as few places as
|
||||
possible; it has not been rewritten in the style of a Spring MVC application.
|
||||
|
||||
A guide to generating Twitter consumer keys and access tokens is at http://tinyurl.com/2fhebgb
|
||||
|
||||
This sample uses the Google App Engine for Java SDK located at
|
||||
http://code.google.com/p/googleappengine/downloads/list
|
||||
|
||||
|
@ -48,13 +50,15 @@ attempting to run 'mvn -Plive install'
|
|||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<jclouds.aws-s3.identity>YOUR_ACCESS_KEY_ID</jclouds.aws-s3.identity>
|
||||
<jclouds.aws-s3.credential>YOUR_SECRET_KEY</jclouds.aws-s3.credential>
|
||||
<jclouds.cloudfiles-us.identity>YOUR_USER</jclouds.cloudfiles-us.identity>
|
||||
<jclouds.cloudfiles-us.credential>YOUR_HEX_KEY</jclouds.cloudfiles-us.credential>
|
||||
<jclouds.azureblob.identity>YOUR_ACCOUNT</jclouds.azureblob.identity>
|
||||
<jclouds.azureblob.credential>YOUR_BASE64_ENCODED_KEY</jclouds.azureblob.credential>
|
||||
<jclouds.twitter.identity>YOUR_TWITTER_USERNAME</jclouds.twitter.identity>
|
||||
<jclouds.twitter.credential>YOUR_TWITTER_PASSWORD</jclouds.twitter.credential>
|
||||
<test.aws-s3.identity>YOUR_ACCESS_KEY_ID</test.aws-s3.identity>
|
||||
<test.aws-s3.credential>YOUR_SECRET_KEY</test.aws-s3.credential>
|
||||
<test.cloudfiles-us.identity>YOUR_USER</test.cloudfiles-us.identity>
|
||||
<test.cloudfiles-us.credential>YOUR_HEX_KEY</test.cloudfiles-us.credential>
|
||||
<test.azureblob.identity>YOUR_ACCOUNT</test.azureblob.identity>
|
||||
<test.azureblob.credential>YOUR_BASE64_ENCODED_KEY</test.azureblob.credential>
|
||||
<test.twitter.gae-tweetstore-spring.consumer.identity>YOUR_TWITTER_CONSUMER_KEY</test.twitter.gae-tweetstore-spring.consumer.identity>
|
||||
<test.twitter.gae-tweetstore-spring.consumer.credential>YOUR_TWITTER_CONSUMER_SECRET</test.twitter.gae-tweetstore-spring.consumer.credential>
|
||||
<test.twitter.gae-tweetstore-spring.access.identity>YOUR_TWITTER_ACCESSTOKEN</test.twitter.gae-tweetstore-spring.access.identity>
|
||||
<test.twitter.gae-tweetstore-spring.access.credential>YOUR_TWITTER_ACCESSTOKEN_SECRET</test.twitter.gae-tweetstore-spring.access.credential>
|
||||
</properties>
|
||||
</profile>
|
|
@ -24,7 +24,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-demos-project</artifactId>
|
||||
<artifactId>jclouds-demos-tweetstore-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-demo-gae-tweetstore-spring</artifactId>
|
||||
|
@ -41,46 +41,10 @@
|
|||
<appengine.sdk.version>1.4.2</appengine.sdk.version>
|
||||
<devappserver.address>localhost</devappserver.address>
|
||||
<devappserver.port>8088</devappserver.port>
|
||||
<jclouds.tweetstore.blobstores>cloudfiles-us,aws-s3,azureblob</jclouds.tweetstore.blobstores>
|
||||
<jclouds.tweetstore.container>jclouds-tweetstore-spring</jclouds.tweetstore.container>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
<version>[2.1,)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-s3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>cloudfiles-us</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>azureblob</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-gae</artifactId>
|
||||
|
@ -102,42 +66,6 @@
|
|||
<version>2.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
<artifactId>displaytag</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Google App Engine API -->
|
||||
<dependency>
|
||||
|
@ -152,21 +80,9 @@
|
|||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/appengine</directory>
|
||||
<targetPath>WEB-INF/</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
|
@ -219,12 +135,20 @@
|
|||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>test.twitter.identity</name>
|
||||
<value>${test.twitter.identity}</value>
|
||||
<name>test.twitter.consumer.identity</name>
|
||||
<value>${test.twitter.gae-tweetstore-spring.consumer.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.credential</name>
|
||||
<value>${test.twitter.credential}</value>
|
||||
<name>test.twitter.consumer.credential</name>
|
||||
<value>${test.twitter.gae-tweetstore-spring.consumer.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.identity</name>
|
||||
<value>${test.twitter.gae-tweetstore-spring.access.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.credential</name>
|
||||
<value>${test.twitter.gae-tweetstore-spring.access.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.identity</name>
|
||||
|
@ -282,5 +206,22 @@
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.kindleit</groupId>
|
||||
<artifactId>maven-gae-plugin</artifactId>
|
||||
<version>0.8.4</version>
|
||||
<configuration>
|
||||
<serverId>google-appengine</serverId>
|
||||
<sdkDir>${appengine.sdk.root}</sdkDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -1,38 +1,38 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.demo.tweetstore.config;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.jclouds.logging.jdk.JDKLogger;
|
||||
|
||||
/**
|
||||
* Spring config that provides a logger.
|
||||
*
|
||||
* @author Andrew Phillips
|
||||
*/
|
||||
abstract class LoggingConfig {
|
||||
private static final LoggerFactory FACTORY = new JDKLogger.JDKLoggerFactory();
|
||||
protected final Logger logger;
|
||||
|
||||
protected LoggingConfig() {
|
||||
logger = FACTORY.getLogger(this.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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.demo.tweetstore.config;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.logging.Logger.LoggerFactory;
|
||||
import org.jclouds.logging.jdk.JDKLogger;
|
||||
|
||||
/**
|
||||
* Spring config that provides a logger.
|
||||
*
|
||||
* @author Andrew Phillips
|
||||
*/
|
||||
abstract class LoggingConfig {
|
||||
private static final LoggerFactory FACTORY = new JDKLogger.JDKLoggerFactory();
|
||||
protected final Logger logger;
|
||||
|
||||
protected LoggingConfig() {
|
||||
logger = FACTORY.getLogger(this.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -55,7 +55,6 @@ import twitter4j.conf.ConfigurationBuilder;
|
|||
|
||||
import com.google.appengine.api.taskqueue.Queue;
|
||||
import com.google.appengine.api.taskqueue.QueueFactory;
|
||||
import com.google.appengine.api.taskqueue.TaskOptions.Builder;
|
||||
import com.google.appengine.api.taskqueue.TaskOptions.Method;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
|
@ -24,10 +24,11 @@ package org.jclouds.demo.tweetstore.reference;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public interface TweetStoreConstants {
|
||||
public static final String PROPERTY_TWEETSTORE_CONTAINER = "jclouds.tweetstore.container";
|
||||
/**
|
||||
* Note that this has to conform to restrictions of all blobstores. for example, azure doesn't
|
||||
* support periods.
|
||||
*/
|
||||
public static final String SENDER_NAME = "sendername";
|
||||
static final String PROPERTY_TWEETSTORE_BLOBSTORES = "jclouds.tweetstore.blobstores";
|
||||
static final String PROPERTY_TWEETSTORE_CONTAINER = "jclouds.tweetstore.container";
|
||||
/**
|
||||
* Note that this has to conform to restrictions of all blobstores. for
|
||||
* example, azure doesn't support periods.
|
||||
*/
|
||||
static final String SENDER_NAME = "sendername";
|
||||
}
|
|
@ -1,38 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<!-- the usual <context:annotation-config/> can't be used because the
|
||||
CommonAnnotationBeanPostProcessor causes a security exception in GAE when it
|
||||
tries to load javax.annotation.Resource -->
|
||||
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
|
||||
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor" />
|
||||
<bean class="org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor">
|
||||
<property name="initAnnotationType" value="javax.annotation.PostConstruct" />
|
||||
<property name="destroyAnnotationType" value="javax.annotation.PreDestroy" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.jclouds.demo.tweetstore.config.SpringServletConfig" />
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<!-- the usual <context:annotation-config/> can't be used because the
|
||||
CommonAnnotationBeanPostProcessor causes a security exception in GAE when it
|
||||
tries to load javax.annotation.Resource -->
|
||||
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
|
||||
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor" />
|
||||
<bean class="org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor">
|
||||
<property name="initAnnotationType" value="javax.annotation.PostConstruct" />
|
||||
<property name="destroyAnnotationType" value="javax.annotation.PreDestroy" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.jclouds.demo.tweetstore.config.SpringServletConfig" />
|
||||
</beans>
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.demo.tweetstore.integration;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_BLOBSTORES;
|
||||
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -71,14 +72,14 @@ public class TweetStoreLiveTest {
|
|||
private String container;
|
||||
|
||||
private static final Iterable<String> blobstores =
|
||||
Splitter.on(',').split(System.getProperty("jclouds.tweetstore.blobstores",
|
||||
Splitter.on(',').split(System.getProperty(PROPERTY_TWEETSTORE_BLOBSTORES,
|
||||
"cloudfiles-us,aws-s3,azureblob"));
|
||||
private static final Properties props = new Properties();
|
||||
|
||||
@BeforeTest
|
||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
||||
TwitterException {
|
||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER);
|
||||
container = getRequiredSystemProperty(PROPERTY_TWEETSTORE_CONTAINER);
|
||||
|
||||
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER, container);
|
||||
props.setProperty(SpringServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
||||
|
@ -98,10 +99,13 @@ public class TweetStoreLiveTest {
|
|||
contexts.put(provider, factory.createContext(provider, wiring, props));
|
||||
}
|
||||
|
||||
Configuration twitterConf = new ConfigurationBuilder()
|
||||
.setUser(props.getProperty("twitter.identity"))
|
||||
.setPassword(props.getProperty("twitter.credential")).build();
|
||||
Twitter client = new TwitterFactory(twitterConf).getInstance();
|
||||
Configuration conf = new ConfigurationBuilder()
|
||||
.setOAuthConsumerKey(props.getProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY))
|
||||
.setOAuthConsumerSecret(props.getProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET))
|
||||
.setOAuthAccessToken(props.getProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN))
|
||||
.setOAuthAccessTokenSecret(props.getProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET))
|
||||
.build();
|
||||
Twitter client = new TwitterFactory(conf).getInstance();
|
||||
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
||||
|
||||
ResponseList<Status> statuses = client.getMentions();
|
||||
|
@ -135,21 +139,29 @@ public class TweetStoreLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static String getRequiredSystemProperty(String key) {
|
||||
return checkNotNull(System.getProperty(key), key);
|
||||
}
|
||||
|
||||
private void addConfigurationForTwitter(Properties props) {
|
||||
props.setProperty("twitter.identity",
|
||||
checkNotNull(System.getProperty("test.twitter.identity"), "test.twitter.identity"));
|
||||
props.setProperty("twitter.credential",
|
||||
checkNotNull(System.getProperty("test.twitter.credential"), "test.twitter.credential"));
|
||||
}
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET));
|
||||
}
|
||||
|
||||
private void addCredentialsForBlobStores(Properties props) {
|
||||
for (String provider : blobstores) {
|
||||
props.setProperty(provider + ".identity",
|
||||
checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"));
|
||||
props.setProperty(provider + ".credential",
|
||||
checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential"));
|
||||
}
|
||||
}
|
||||
private void addCredentialsForBlobStores(Properties props) {
|
||||
for (String provider : blobstores) {
|
||||
props.setProperty(provider + ".identity",
|
||||
getRequiredSystemProperty("test." + provider + ".identity"));
|
||||
props.setProperty(provider + ".credential",
|
||||
getRequiredSystemProperty("test." + provider + ".credential"));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeTest
|
||||
@Parameters({ "warfile", "devappserver.address", "devappserver.port" })
|
||||
|
@ -208,4 +220,11 @@ public class TweetStoreLiveTest {
|
|||
String string = Strings2.toStringAndClose(i);
|
||||
assert string.indexOf("Tweets in Clouds") >= 0 : string;
|
||||
}
|
||||
|
||||
private static interface TwitterConstants {
|
||||
static final String PROPERTY_TWITTER_CONSUMER_KEY = "twitter.consumer.identity";
|
||||
static final String PROPERTY_TWITTER_CONSUMER_SECRET = "twitter.consumer.credential";
|
||||
static final String PROPERTY_TWITTER_ACCESSTOKEN = "twitter.access.identity";
|
||||
static final String PROPERTY_TWITTER_ACCESSTOKEN_SECRET = "twitter.access.credential";
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@
|
|||
====================================================================
|
||||
====
|
||||
|
||||
A guide to generating Twitter consumer keys and access tokens is at http://tinyurl.com/2fhebgb
|
||||
|
||||
This sample uses the Google App Engine for Java SDK located at
|
||||
http://code.google.com/p/googleappengine/downloads/list
|
||||
|
||||
|
@ -40,13 +42,15 @@ attempting to run 'mvn -Plive install'
|
|||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<jclouds.aws-s3.identity>YOUR_ACCESS_KEY_ID</jclouds.aws-s3.identity>
|
||||
<jclouds.aws-s3.credential>YOUR_SECRET_KEY</jclouds.aws-s3.credential>
|
||||
<jclouds.cloudfiles-us.identity>YOUR_USER</jclouds.cloudfiles-us.identity>
|
||||
<jclouds.cloudfiles-us.credential>YOUR_HEX_KEY</jclouds.cloudfiles-us.credential>
|
||||
<jclouds.azureblob.identity>YOUR_ACCOUNT</jclouds.azureblob.identity>
|
||||
<jclouds.azureblob.credential>YOUR_BASE64_ENCODED_KEY</jclouds.azureblob.credential>
|
||||
<jclouds.twitter.identity>YOUR_TWITTER_USERNAME</jclouds.twitter.identity>
|
||||
<jclouds.twitter.credential>YOUR_TWITTER_PASSWORD</jclouds.twitter.credential>
|
||||
<test.aws-s3.identity>YOUR_ACCESS_KEY_ID</test.aws-s3.identity>
|
||||
<test.aws-s3.credential>YOUR_SECRET_KEY</test.aws-s3.credential>
|
||||
<test.cloudfiles-us.identity>YOUR_USER</test.cloudfiles-us.identity>
|
||||
<test.cloudfiles-us.credential>YOUR_HEX_KEY</test.cloudfiles-us.credential>
|
||||
<test.azureblob.identity>YOUR_ACCOUNT</test.azureblob.identity>
|
||||
<test.azureblob.credential>YOUR_BASE64_ENCODED_KEY</test.azureblob.credential>
|
||||
<test.twitter.gae-tweetstore.consumer.identity>YOUR_TWITTER_CONSUMER_KEY</test.twitter.gae-tweetstore.consumer.identity>
|
||||
<test.twitter.gae-tweetstore.consumer.credential>YOUR_TWITTER_CONSUMER_SECRET</test.twitter.gae-tweetstore.consumer.credential>
|
||||
<test.twitter.gae-tweetstore.access.identity>YOUR_TWITTER_ACCESSTOKEN</test.twitter.gae-tweetstore.access.identity>
|
||||
<test.twitter.gae-tweetstore.access.credential>YOUR_TWITTER_ACCESSTOKEN_SECRET</test.twitter.gae-tweetstore.access.credential>
|
||||
</properties>
|
||||
</profile>
|
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-demos-tweetstore-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-demo-gae-tweetstore</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>JClouds TweetStore for Google App Engine</name>
|
||||
<description>JClouds TweetStore for Google App Engine using Guice for Dependency Injection</description>
|
||||
|
||||
<properties>
|
||||
<!--
|
||||
note you must set the property ${appengine.sdk.root} to a valid
|
||||
extraction of appengine-java-sdk
|
||||
-->
|
||||
<appengine.applicationid>jclouds-tweetstore</appengine.applicationid>
|
||||
<appengine.sdk.version>1.4.2</appengine.sdk.version>
|
||||
<devappserver.address>localhost</devappserver.address>
|
||||
<devappserver.port>8088</devappserver.port>
|
||||
<jclouds.tweetstore.container>jclouds-tweetstore</jclouds.tweetstore.container>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-gae</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Google App Engine API -->
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-api-1.0-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.appengine</groupId>
|
||||
<artifactId>appengine-tools-sdk</artifactId>
|
||||
<version>${appengine.sdk.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>appengine.sdk.root</name>
|
||||
<value>${appengine.sdk.root}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.address</name>
|
||||
<value>${devappserver.address}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.port</name>
|
||||
<value>${devappserver.port}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>warfile</name>
|
||||
<value>${project.build.directory}/${project.artifactId}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>test.twitter.consumer.identity</name>
|
||||
<value>${test.twitter.gae-tweetstore.consumer.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.consumer.credential</name>
|
||||
<value>${test.twitter.gae-tweetstore.consumer.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.identity</name>
|
||||
<value>${test.twitter.gae-tweetstore.access.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.credential</name>
|
||||
<value>${test.twitter.gae-tweetstore.access.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.identity</name>
|
||||
<value>${test.azureblob.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.credential</name>
|
||||
<value>${test.azureblob.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.cloudfiles-us.identity</name>
|
||||
<value>${test.cloudfiles-us.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.cloudfiles-us.credential</name>
|
||||
<value>${test.cloudfiles-us.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.aws-s3.identity</name>
|
||||
<value>${test.aws-s3.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.aws-s3.credential</name>
|
||||
<value>${test.aws-s3.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>appengine.sdk.root</name>
|
||||
<value>${appengine.sdk.root}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.address</name>
|
||||
<value>${devappserver.address}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>devappserver.port</name>
|
||||
<value>${devappserver.port}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>jclouds.tweetstore.blobstores</name>
|
||||
<value>${jclouds.tweetstore.blobstores}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>jclouds.tweetstore.container</name>
|
||||
<value>${jclouds.tweetstore.container}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>warfile</name>
|
||||
<value>${project.build.directory}/${project.artifactId}</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>net.kindleit</groupId>
|
||||
<artifactId>maven-gae-plugin</artifactId>
|
||||
<version>0.8.4</version>
|
||||
<configuration>
|
||||
<serverId>google-appengine</serverId>
|
||||
<sdkDir>${appengine.sdk.root}</sdkDir>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -24,10 +24,11 @@ package org.jclouds.demo.tweetstore.reference;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public interface TweetStoreConstants {
|
||||
public static final String PROPERTY_TWEETSTORE_CONTAINER = "jclouds.tweetstore.container";
|
||||
static final String PROPERTY_TWEETSTORE_BLOBSTORES = "jclouds.tweetstore.blobstores";
|
||||
static final String PROPERTY_TWEETSTORE_CONTAINER = "jclouds.tweetstore.container";
|
||||
/**
|
||||
* Note that this has to conform to restrictions of all blobstores. for example, azure doesn't
|
||||
* support periods.
|
||||
*/
|
||||
public static final String SENDER_NAME = "sendername";
|
||||
static final String SENDER_NAME = "sendername";
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.demo.tweetstore.integration;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_BLOBSTORES;
|
||||
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -70,15 +71,14 @@ public class TweetStoreLiveTest {
|
|||
private Map<String, BlobStoreContext> contexts;
|
||||
private String container;
|
||||
private static final Iterable<String> blobstores =
|
||||
Splitter.on(',').split(System.getProperty("jclouds.tweetstore.blobstores",
|
||||
Splitter.on(',').split(System.getProperty(PROPERTY_TWEETSTORE_BLOBSTORES,
|
||||
"cloudfiles-us,aws-s3,azureblob"));
|
||||
private static final Properties props = new Properties();
|
||||
|
||||
@BeforeTest
|
||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
||||
TwitterException {
|
||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER),
|
||||
PROPERTY_TWEETSTORE_CONTAINER);
|
||||
container = getRequiredSystemProperty(PROPERTY_TWEETSTORE_CONTAINER);
|
||||
|
||||
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER, container);
|
||||
props.setProperty(GuiceServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
||||
|
@ -99,8 +99,11 @@ public class TweetStoreLiveTest {
|
|||
}
|
||||
|
||||
Configuration conf = new ConfigurationBuilder()
|
||||
.setUser(props.getProperty("twitter.identity"))
|
||||
.setPassword(props.getProperty("twitter.credential")).build();
|
||||
.setOAuthConsumerKey(props.getProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY))
|
||||
.setOAuthConsumerSecret(props.getProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET))
|
||||
.setOAuthAccessToken(props.getProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN))
|
||||
.setOAuthAccessTokenSecret(props.getProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET))
|
||||
.build();
|
||||
Twitter client = new TwitterFactory(conf).getInstance();
|
||||
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
||||
|
||||
|
@ -140,6 +143,30 @@ public class TweetStoreLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static String getRequiredSystemProperty(String key) {
|
||||
return checkNotNull(System.getProperty(key), key);
|
||||
}
|
||||
|
||||
private void addConfigurationForTwitter(Properties props) {
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_CONSUMER_KEY));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_CONSUMER_SECRET));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN));
|
||||
props.setProperty(TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET,
|
||||
getRequiredSystemProperty("test." + TwitterConstants.PROPERTY_TWITTER_ACCESSTOKEN_SECRET));
|
||||
}
|
||||
|
||||
private void addCredentialsForBlobStores(Properties props) {
|
||||
for (String provider : blobstores) {
|
||||
props.setProperty(provider + ".identity",
|
||||
getRequiredSystemProperty("test." + provider + ".identity"));
|
||||
props.setProperty(provider + ".credential",
|
||||
getRequiredSystemProperty("test." + provider + ".credential"));
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeTest(dependsOnMethods = "clearAndCreateContainers")
|
||||
@Parameters({ "warfile", "devappserver.address", "devappserver.port" })
|
||||
public void startDevAppServer(final String warfile, final String address, final String port) throws Exception {
|
||||
|
@ -148,22 +175,7 @@ public class TweetStoreLiveTest {
|
|||
server = new GoogleDevServer();
|
||||
server.writePropertiesAndStartServer(address, port, warfile, props);
|
||||
}
|
||||
|
||||
private void addConfigurationForTwitter(Properties props) {
|
||||
props.setProperty("twitter.identity", checkNotNull(System.getProperty("test.twitter.identity"), "test.twitter.identity"));
|
||||
props.setProperty("twitter.credential",
|
||||
checkNotNull(System.getProperty("test.twitter.credential"), "test.twitter.credential"));
|
||||
}
|
||||
|
||||
private void addCredentialsForBlobStores(Properties props) {
|
||||
for (String provider : blobstores) {
|
||||
props.setProperty(provider + ".identity",
|
||||
checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"));
|
||||
props.setProperty(provider + ".credential",
|
||||
checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldPass() throws InterruptedException, IOException {
|
||||
InputStream i = url.openStream();
|
||||
|
@ -213,4 +225,11 @@ public class TweetStoreLiveTest {
|
|||
String string = Strings2.toStringAndClose(i);
|
||||
assert string.indexOf("Tweets in Clouds") >= 0 : string;
|
||||
}
|
||||
|
||||
private static interface TwitterConstants {
|
||||
static final String PROPERTY_TWITTER_CONSUMER_KEY = "twitter.consumer.identity";
|
||||
static final String PROPERTY_TWITTER_CONSUMER_SECRET = "twitter.consumer.credential";
|
||||
static final String PROPERTY_TWITTER_ACCESSTOKEN = "twitter.access.identity";
|
||||
static final String PROPERTY_TWITTER_ACCESSTOKEN_SECRET = "twitter.access.credential";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>jclouds-demos-project</artifactId>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jclouds-demos-tweetstore-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>jclouds TweetStore demos project</name>
|
||||
<modules>
|
||||
<module>gae-tweetstore</module>
|
||||
<module>gae-tweetstore-spring</module>
|
||||
<module>runatcloud-tweetstore</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<remoteResourcesDirectory>target/maven-shared-archive-resources</remoteResourcesDirectory>
|
||||
<jclouds.tweetstore.blobstores>cloudfiles-us,aws-s3,azureblob</jclouds.tweetstore.blobstores>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
<version>[2.2,)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-s3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>cloudfiles-us</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>azureblob</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
<artifactId>displaytag</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<configuration>
|
||||
<!-- prevents the maven-war-plugin from including the resources in WEB-INF/classes -->
|
||||
<attached>false</attached>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.1.1</version>
|
||||
<configuration>
|
||||
<!-- see http://jira.codehaus.org/browse/MWAR-248 -->
|
||||
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/platform</directory>
|
||||
<targetPath>WEB-INF</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${remoteResourcesDirectory}/META-INF</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.2</version>
|
||||
<configuration>
|
||||
<!-- prevents the maven-war-plugin from including the resources in WEB-INF/classes -->
|
||||
<attached>false</attached>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>include-jclouds-properties</id>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resourceBundles>
|
||||
<resourceBundle>org.jclouds:jclouds-properties:${project.version}</resourceBundle>
|
||||
</resourceBundles>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- see http://jira.codehaus.org/browse/MWAR-248 -->
|
||||
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<directory>src/main/platform</directory>
|
||||
<targetPath>WEB-INF</targetPath>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${remoteResourcesDirectory}/META-INF</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${remoteResourcesDirectory}</directory>
|
||||
<targetPath>WEB-INF</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>jclouds.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -17,6 +17,8 @@
|
|||
====================================================================
|
||||
====
|
||||
|
||||
A guide to generating Twitter consumer keys and access tokens is at http://tinyurl.com/2fhebgb
|
||||
|
||||
Please modify your maven settings.xml like below before attempting to run 'mvn -Plive install'
|
||||
|
||||
<profile>
|
||||
|
@ -25,8 +27,8 @@ Please modify your maven settings.xml like below before attempting to run 'mvn -
|
|||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<bees.appid>yourappid</bees.appid>
|
||||
<bees.environment>yourenv</bees.environment>
|
||||
<bees.apikey>yourapikey</bees.apikey>
|
||||
<bees.secret>yoursecret</bees.secret>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
|
@ -36,13 +38,15 @@ Please modify your maven settings.xml like below before attempting to run 'mvn -
|
|||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<jclouds.aws-s3.identity>YOUR_ACCESS_KEY_ID</jclouds.aws-s3.identity>
|
||||
<jclouds.aws-s3.credential>YOUR_SECRET_KEY</jclouds.aws-s3.credential>
|
||||
<jclouds.cloudfiles-us.identity>YOUR_USER</jclouds.cloudfiles-us.identity>
|
||||
<jclouds.cloudfiles-us.credential>YOUR_HEX_KEY</jclouds.cloudfiles-us.credential>
|
||||
<jclouds.azureblob.identity>YOUR_ACCOUNT</jclouds.azureblob.identity>
|
||||
<jclouds.azureblob.credential>YOUR_BASE64_ENCODED_KEY</jclouds.azureblob.credential>
|
||||
<jclouds.twitter.identity>YOUR_TWITTER_USERNAME</jclouds.twitter.identity>
|
||||
<jclouds.twitter.credential>YOUR_TWITTER_PASSWORD</jclouds.twitter.credential>
|
||||
<test.aws-s3.identity>YOUR_ACCESS_KEY_ID</test.aws-s3.identity>
|
||||
<test.aws-s3.credential>YOUR_SECRET_KEY</test.aws-s3.credential>
|
||||
<test.cloudfiles-us.identity>YOUR_USER</test.cloudfiles-us.identity>
|
||||
<test.cloudfiles-us.credential>YOUR_HEX_KEY</test.cloudfiles-us.credential>
|
||||
<test.azureblob.identity>YOUR_ACCOUNT</test.azureblob.identity>
|
||||
<test.azureblob.credential>YOUR_BASE64_ENCODED_KEY</test.azureblob.credential>
|
||||
<test.twitter.runatcloud-tweetstore.consumer.identity>YOUR_TWITTER_CONSUMER_KEY</test.twitter.runatcloud-tweetstore.consumer.identity>
|
||||
<test.twitter.runatcloud-tweetstore.consumer.credential>YOUR_TWITTER_CONSUMER_SECRET</test.twitter.runatcloud-tweetstore.consumer.credential>
|
||||
<test.twitter.runatcloud-tweetstore.access.identity>YOUR_TWITTER_ACCESSTOKEN</test.twitter.runatcloud-tweetstore.access.identity>
|
||||
<test.twitter.runatcloud-tweetstore.access.credential>YOUR_TWITTER_ACCESSTOKEN_SECRET</test.twitter.runatcloud-tweetstore.access.credential>
|
||||
</properties>
|
||||
</profile>
|
|
@ -22,7 +22,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-demos-project</artifactId>
|
||||
<artifactId>jclouds-demos-tweetstore-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>jclouds-demo-runatcloud-tweetstore</artifactId>
|
||||
|
@ -31,91 +31,19 @@
|
|||
<description>jclouds TweetStore for CloudBees' RUN@cloud using Guice for Dependency Injection</description>
|
||||
|
||||
<properties>
|
||||
<bees.appid>tweetstore</bees.appid>
|
||||
<bees.environment>run</bees.environment>
|
||||
<bees.address>localhost</bees.address>
|
||||
<bees.port>8088</bees.port>
|
||||
<jclouds.tweetstore.blobstores>cloudfiles-us,aws-s3,azureblob</jclouds.tweetstore.blobstores>
|
||||
<jclouds.tweetstore.container>jclouds-tweetstore-runatcloud</jclouds.tweetstore.container>
|
||||
<bees.appid>jclouds/tweetstore</bees.appid>
|
||||
<bees.environment>run</bees.environment>
|
||||
<bees.address>localhost</bees.address>
|
||||
<bees.port>8088</bees.port>
|
||||
<jclouds.tweetstore.container>jclouds-tweetstore-runatcloud</jclouds.tweetstore.container>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.twitter4j</groupId>
|
||||
<artifactId>twitter4j-core</artifactId>
|
||||
<version>[2.1,)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>aws-s3</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>cloudfiles-us</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.provider</groupId>
|
||||
<artifactId>azureblob</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>displaytag</groupId>
|
||||
<artifactId>displaytag</artifactId>
|
||||
<version>1.2</version>
|
||||
<scope>runtime</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>jstl</artifactId>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>standard</artifactId>
|
||||
<groupId>taglibs</groupId>
|
||||
<version>1.1.2</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- RUN@cloud API -->
|
||||
<dependency>
|
||||
|
@ -126,21 +54,7 @@
|
|||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>bees-plugins-snapshots</id>
|
||||
<url>http://repository-cloudbees.forge.cloudbees.com/public-snapshot/</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
|
@ -178,13 +92,8 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.cloudbees</groupId>
|
||||
<artifactId>bees-maven-plugin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
|
@ -203,12 +112,20 @@
|
|||
<configuration>
|
||||
<systemProperties>
|
||||
<property>
|
||||
<name>test.twitter.identity</name>
|
||||
<value>${test.twitter.identity}</value>
|
||||
<name>test.twitter.consumer.identity</name>
|
||||
<value>${test.twitter.runatcloud-tweetstore.consumer.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.credential</name>
|
||||
<value>${test.twitter.credential}</value>
|
||||
<name>test.twitter.consumer.credential</name>
|
||||
<value>${test.twitter.runatcloud-tweetstore.consumer.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.identity</name>
|
||||
<value>${test.twitter.runatcloud-tweetstore.access.identity}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.twitter.access.credential</name>
|
||||
<value>${test.twitter.runatcloud-tweetstore.access.credential}</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>test.azureblob.identity</name>
|
||||
|
@ -270,5 +187,35 @@
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>bees-plugins-snapshots</id>
|
||||
<url>http://repository-cloudbees.forge.cloudbees.com/public-snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.cloudbees</groupId>
|
||||
<artifactId>bees-maven-plugin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<environment>${bees.environment}</environment>
|
||||
<apikey>${bees.apikey}</apikey>
|
||||
<secret>${bees.secret}</secret>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue