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:
Dmitri Babaev 2011-06-03 03:50:47 +04:00
commit e1f0cdcfa5
280 changed files with 6415 additions and 1346 deletions

View File

@ -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

View File

@ -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>

View File

@ -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")

View File

@ -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))))))

View File

@ -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
*/

View File

@ -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() + "]";
}
}

View File

@ -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());
}
}

View File

@ -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)) {

View File

@ -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,

View File

@ -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) {

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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());

View File

@ -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) {

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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";

View File

@ -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",

View File

@ -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;

View File

@ -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();

View File

@ -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);
}

View File

@ -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);
}
}
}
}

View File

@ -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);

View File

@ -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"))));
}
}

View File

@ -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 &quot;adriancolecap-78c&quot; 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

View File

@ -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))))

View File

@ -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

View File

@ -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");

View File

@ -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());

View File

@ -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));
}

View File

@ -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");

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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

View File

@ -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++)

View File

@ -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));

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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());
}
}

View File

@ -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;

View File

@ -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";
}

View File

@ -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>

View File

@ -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";
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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";
}

View File

@ -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";
}
}

207
demos/tweetstore/pom.xml Normal file
View File

@ -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>

View File

@ -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>

View File

@ -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