updated to latest deltacloud 0.3.0 release

This commit is contained in:
Adrian Cole 2011-04-01 20:27:54 -07:00
parent 72768c206d
commit 4f7a58b498
29 changed files with 575 additions and 383 deletions

View File

@ -7,6 +7,7 @@ To install deltacloud, do the following:
* OS/X and jruby * OS/X and jruby
# use homebrew or equiv to install jruby # use homebrew or equiv to install jruby
* brew install jruby * brew install jruby
* note testing took place w/ 1.6.0
# install and configure openssl to avoid "certificate verify failed" errors # install and configure openssl to avoid "certificate verify failed" errors
# install and link openssl # install and link openssl
* brew install openssl * brew install openssl
@ -24,7 +25,9 @@ To install deltacloud, do the following:
* jruby -ropen-uri -e 'p open("https://encrypted.google.com")' * jruby -ropen-uri -e 'p open("https://encrypted.google.com")'
* should see something like #<StringIO:0x5330cb4b> * should see something like #<StringIO:0x5330cb4b>
# install specific version of rack that doesn't conflict with deltacloud # install specific version of rack that doesn't conflict with deltacloud
* jruby -S gem --version 1.1.0 install rack * jruby -S gem install rack --version 1.1.0
# install net-ssh
* jruby -S gem install net-ssh
# install deltacloud core # install deltacloud core
* jruby -S gem install deltacloud-core * jruby -S gem install deltacloud-core
@ -40,12 +43,15 @@ Here are some notes about specific cloud providers
# install fog gem # install fog gem
* jruby -S gem install fog * jruby -S gem install fog
* rackspace * rackspace
# install cloudfiles gem # install cloudfiles, cloudservers gem
* jruby -S gem install cloudservers
* jruby -S gem install cloudfiles * jruby -S gem install cloudfiles
* ec2 * ec2
# install amazon-ec2 gem * using jruby --1.8, 'gem install aws' will fail with ArrayIndexOutOfBoundsException per http://jira.codehaus.org/browse/JRUBY-5581
* jruby -S gem install amazon-ec2 * using jruby --1.9, 'gem install aws' works, but running './server/bin/deltacloudd -i ec2' fails per http://jira.codehaus.org/browse/JRUBY-5529
# install i18n, aws gem
* jruby -S gem install i18n
* jruby -S gem install aws
Local Development of Delta Local Development of Delta
* jruby -S gem install rack-test cucumber * jruby -S gem install rack-test cucumber

View File

@ -37,9 +37,9 @@ import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Image; import org.jclouds.deltacloud.domain.Image;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.functions.ReturnVoidOnRedirectedDelete; import org.jclouds.deltacloud.functions.ReturnVoidOnRedirectedDelete;
import org.jclouds.deltacloud.options.CreateInstanceOptions; import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.deltacloud.xml.DeltacloudCollectionsHandler; import org.jclouds.deltacloud.xml.DeltacloudCollectionsHandler;
@ -93,7 +93,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(InstanceStates.class) @Endpoint(InstanceStates.class)
@ExceptionParser(ReturnEmptyMultimapOnNotFoundOr404.class) @ExceptionParser(ReturnEmptyMultimapOnNotFoundOr404.class)
@XMLResponseParser(InstanceStatesHandler.class) @XMLResponseParser(InstanceStatesHandler.class)
ListenableFuture<? extends Multimap<InstanceState, ? extends Transition>> getInstanceStates(); ListenableFuture<? extends Multimap<State, ? extends Transition>> getInstanceStates();
/** /**
* @see DeltacloudClient#listRealms * @see DeltacloudClient#listRealms

View File

@ -28,9 +28,9 @@ import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Image; import org.jclouds.deltacloud.domain.Image;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.deltacloud.options.CreateInstanceOptions; import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -58,7 +58,7 @@ public interface DeltacloudClient {
* *
* @return The possible states of an instance, and how to traverse between them * @return The possible states of an instance, and how to traverse between them
*/ */
Multimap<InstanceState, ? extends Transition> getInstanceStates(); Multimap<State, ? extends Transition> getInstanceStates();
/** /**
* The realms collection will return a set of all realms available to the current user. * The realms collection will return a set of all realms available to the current user.

View File

@ -1,3 +1,28 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
/** /**
* *
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
@ -17,8 +42,6 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
@ -44,7 +67,7 @@ public interface HardwareProperty {
*/ */
UNRECOGNIZED; UNRECOGNIZED;
public static Kind fromValue(String kind) { public static HardwareProperty.Kind fromValue(String kind) {
try { try {
return valueOf(checkNotNull(kind, "kind").toUpperCase()); return valueOf(checkNotNull(kind, "kind").toUpperCase());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -57,7 +80,7 @@ public interface HardwareProperty {
* *
* @return describes the values to chose from. * @return describes the values to chose from.
*/ */
Kind getKind(); HardwareProperty.Kind getKind();
/** /**
* *
@ -76,4 +99,4 @@ public interface HardwareProperty {
* @return the actual value of the property. It depends on the specified unit: 1024, 2 on x86_64 * @return the actual value of the property. It depends on the specified unit: 1024, 2 on x86_64
*/ */
Object getValue(); Object getValue();
} }

View File

@ -38,6 +38,83 @@ import com.google.common.collect.ImmutableSet;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Instance { public class Instance {
public static interface Authentication {
}
public static enum State {
/**
* initial state, before instance is created.
*/
START,
/**
* the instance is in the process of being launched
*/
PENDING,
/**
* the instance launched (although the boot process might not be completed)
*/
RUNNING,
/**
* the instance is shutting down
*/
SHUTTING_DOWN,
/**
* the instance is stopped
*/
STOPPED,
/**
* the instance is terminated
*/
FINISH,
/**
* state returned as something besides the above.
*/
UNRECOGNIZED;
public static State fromValue(String state) {
try {
return valueOf(checkNotNull(state, "state").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
public static enum Action {
CREATE,
RUN,
REBOOT,
START,
STOP,
DESTROY,
UNRECOGNIZED;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static Action fromValue(String action) {
try {
return valueOf(checkNotNull(action, "action").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
private final URI href; private final URI href;
private final String id; private final String id;
private final String ownerId; private final String ownerId;
@ -46,14 +123,16 @@ public class Instance {
private final URI image; private final URI image;
private final URI hardwareProfile; private final URI hardwareProfile;
private final URI realm; private final URI realm;
private final InstanceState state; private final State state;
private final Map<InstanceAction, HttpRequest> actions; private final Map<Action, HttpRequest> actions;
@Nullable
private final Authentication authentication;
private final Set<String> publicAddresses; private final Set<String> publicAddresses;
private final Set<String> privateAddresses; private final Set<String> privateAddresses;
public Instance(URI href, String id, String ownerId, @Nullable String name, URI image, URI hardwareProfile, public Instance(URI href, String id, String ownerId, @Nullable String name, URI image, URI hardwareProfile,
URI realm, InstanceState state, Map<InstanceAction, HttpRequest> actions, Set<String> publicAddresses, URI realm, State state, Map<Action, HttpRequest> actions, @Nullable Authentication authentication,
Set<String> privateAddresses) { Set<String> publicAddresses, Set<String> privateAddresses) {
this.href = checkNotNull(href, "href"); this.href = checkNotNull(href, "href");
this.id = checkNotNull(id, "id"); this.id = checkNotNull(id, "id");
this.ownerId = checkNotNull(ownerId, "ownerId"); this.ownerId = checkNotNull(ownerId, "ownerId");
@ -63,6 +142,7 @@ public class Instance {
this.realm = checkNotNull(realm, "realm"); this.realm = checkNotNull(realm, "realm");
this.state = checkNotNull(state, "state"); this.state = checkNotNull(state, "state");
this.actions = ImmutableMap.copyOf(checkNotNull(actions, "actions")); this.actions = ImmutableMap.copyOf(checkNotNull(actions, "actions"));
this.authentication = authentication;
this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses")); this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses"));
this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses")); this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses"));
} }
@ -128,7 +208,7 @@ public class Instance {
* *
* @return indicator of the instance's current state * @return indicator of the instance's current state
*/ */
public InstanceState getState() { public State getState() {
return state; return state;
} }
@ -137,10 +217,19 @@ public class Instance {
* @return valid actions for the instance, along with the URL which may be used to perform the * @return valid actions for the instance, along with the URL which may be used to perform the
* action * action
*/ */
public Map<InstanceAction, HttpRequest> getActions() { public Map<Action, HttpRequest> getActions() {
return actions; return actions;
} }
/**
*
* @return authentication of the instance or null
*/
@Nullable
public Authentication getAuthentication() {
return authentication;
}
/** /**
* *
* @return publicly routable IP addresses or names for the instance * @return publicly routable IP addresses or names for the instance
@ -161,16 +250,7 @@ public class Instance {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((actions == null) ? 0 : actions.hashCode());
result = prime * result + ((hardwareProfile == null) ? 0 : hardwareProfile.hashCode());
result = prime * result + ((href == null) ? 0 : href.hashCode()); result = prime * result + ((href == null) ? 0 : href.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
result = prime * result + ((realm == null) ? 0 : realm.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
return result; return result;
} }
@ -183,61 +263,21 @@ public class Instance {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
Instance other = (Instance) obj; Instance other = (Instance) obj;
if (actions == null) {
if (other.actions != null)
return false;
} else if (!actions.equals(other.actions))
return false;
if (hardwareProfile == null) {
if (other.hardwareProfile != null)
return false;
} else if (!hardwareProfile.equals(other.hardwareProfile))
return false;
if (href == null) { if (href == null) {
if (other.href != null) if (other.href != null)
return false; return false;
} else if (!href.equals(other.href)) } else if (!href.equals(other.href))
return false; return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (privateAddresses == null) {
if (other.privateAddresses != null)
return false;
} else if (!privateAddresses.equals(other.privateAddresses))
return false;
if (publicAddresses == null) {
if (other.publicAddresses != null)
return false;
} else if (!publicAddresses.equals(other.publicAddresses))
return false;
if (realm == null) {
if (other.realm != null)
return false;
} else if (!realm.equals(other.realm))
return false;
if (state != other.state)
return false;
return true; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "[href=" + href + ", id=" + id + ", name=" + name + ", image=" + image + ", hardwareProfile=" return String
+ hardwareProfile + ", realm=" + realm + ", state=" + state + ", actions=" + actions + ", publicAddresses=" .format(
+ publicAddresses + ", privateAddresses=" + privateAddresses + "]"; "[id=%s, href=%s, image=%s, name=%s, state=%s, realm=%s, ownerId=%s, hardwareProfile=%s, actions=%s, authentication=%s, privateAddresses=%s, publicAddresses=%s]",
id, href, image, name, state, realm, ownerId, hardwareProfile, actions, authentication,
privateAddresses, publicAddresses);
} }
} }

View File

@ -1,61 +0,0 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* Indicator of the instance's current action
*
* @author Adrian Cole
*
*/
public enum InstanceAction {
CREATE,
REBOOT,
START,
STOP,
DESTROY,
UNRECOGNIZED;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static InstanceAction fromValue(String action) {
try {
return valueOf(checkNotNull(action, "action").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -1,68 +0,0 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* Indicator of the instance's current state
*
* @author Adrian Cole
*
*/
public enum InstanceState {
/**
* initial state, before instance is created.
*/
START,
/**
* the instance is in the process of being launched
*/
PENDING,
/**
* the instance launched (although the boot process might not be completed)
*/
RUNNING,
/**
* the instance is shutting down
*/
SHUTTING_DOWN,
/**
* the instance is stopped
*/
STOPPED,
/**
* the instance is terminated
*/
FINISH,
/**
* state returned as something besides the above.
*/
UNRECOGNIZED;
public static InstanceState fromValue(String state) {
try {
return valueOf(checkNotNull(state, "state").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -0,0 +1,79 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
/**
*
* @author Adrian Cole
*/
public class KeyAuthentication implements Instance.Authentication, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = 7669076186483470376L;
private final String keyName;
public KeyAuthentication(String keyName) {
this.keyName = checkNotNull(keyName, "keyName");
}
public String getKeyName() {
return keyName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
KeyAuthentication other = (KeyAuthentication) obj;
if (keyName == null) {
if (other.keyName != null)
return false;
} else if (!keyName.equals(other.keyName))
return false;
return true;
}
@Override
public String toString() {
return String.format("[keyName=%s]", keyName);
}
}

View File

@ -0,0 +1,81 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.Serializable;
import org.jclouds.domain.Credentials;
/**
*
* @author Adrian Cole
*/
public class PasswordAuthentication implements Instance.Authentication, Serializable {
/** The serialVersionUID */
private static final long serialVersionUID = 7669076186483470376L;
private final Credentials login;
public PasswordAuthentication(Credentials login) {
this.login = checkNotNull(login, "login");
}
public Credentials getLoginCredentials() {
return login;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((login == null) ? 0 : login.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PasswordAuthentication other = (PasswordAuthentication) obj;
if (login == null) {
if (other.login != null)
return false;
} else if (!login.equals(other.login))
return false;
return true;
}
@Override
public String toString() {
return String.format("[login=%s]", login);
}
}

View File

@ -36,14 +36,39 @@ import javax.annotation.Nullable;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Realm { public class Realm {
public enum State {
/**
* the realm is available
*/
AVAILABLE,
/**
* the realm is unavailable
*/
UNAVAILABLE,
/**
* state returned as something besides the above.
*/
UNRECOGNIZED;
public static State fromValue(String state) {
try {
return valueOf(checkNotNull(state, "state"));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
private final URI href; private final URI href;
private final String id; private final String id;
@Nullable @Nullable
private final String limit; private final String limit;
private final String name; private final String name;
private final RealmState state; private final State state;
public Realm(URI href, String id, String name, @Nullable String limit, RealmState state) { public Realm(URI href, String id, String name, @Nullable String limit, State state) {
this.href = checkNotNull(href, "href"); this.href = checkNotNull(href, "href");
this.id = checkNotNull(id, "id"); this.id = checkNotNull(id, "id");
this.name = checkNotNull(name, "name"); this.name = checkNotNull(name, "name");
@ -90,7 +115,7 @@ public class Realm {
* *
* @return indicator of the realm's current state * @return indicator of the realm's current state
*/ */
public RealmState getState() { public State getState() {
return state; return state;
} }

View File

@ -1,55 +0,0 @@
/**
*
* 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.
* ====================================================================
*/
package org.jclouds.deltacloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* Indicator of the realm's current state
*
* @author Adrian Cole
*
*/
public enum RealmState {
/**
* the realm is available
*/
AVAILABLE,
/**
* the realm is unavailable
*/
UNAVAILABLE,
/**
* state returned as something besides the above.
*/
UNRECOGNIZED;
public static RealmState fromValue(String state) {
try {
return valueOf(checkNotNull(state, "state"));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}

View File

@ -24,5 +24,5 @@ package org.jclouds.deltacloud.domain;
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface Transition { public interface Transition {
InstanceState getTo(); Instance.State getTo();
} }

View File

@ -26,13 +26,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class TransitionAutomatically implements Transition { public class TransitionAutomatically implements Transition {
private final InstanceState to; private final Instance.State to;
public TransitionAutomatically(InstanceState to) { public TransitionAutomatically(Instance.State to) {
this.to = checkNotNull(to, "to"); this.to = checkNotNull(to, "to");
} }
public InstanceState getTo() { public Instance.State getTo() {
return to; return to;
} }

View File

@ -26,19 +26,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class TransitionOnAction implements Transition { public class TransitionOnAction implements Transition {
private final InstanceAction action; private final Instance.Action action;
private final InstanceState to; private final Instance.State to;
public TransitionOnAction(InstanceAction action, InstanceState to) { public TransitionOnAction(Instance.Action action, Instance.State to) {
this.to = checkNotNull(to, "to"); this.to = checkNotNull(to, "to");
this.action = checkNotNull(action, "action"); this.action = checkNotNull(action, "action");
} }
public InstanceState getTo() { public Instance.State getTo() {
return to; return to;
} }
public InstanceAction getAction() { public Instance.Action getAction() {
return action; return action;
} }

View File

@ -30,8 +30,8 @@ import org.jclouds.deltacloud.domain.EnumHardwareProperty;
import org.jclouds.deltacloud.domain.FixedHardwareProperty; import org.jclouds.deltacloud.domain.FixedHardwareProperty;
import org.jclouds.deltacloud.domain.HardwareParameter; import org.jclouds.deltacloud.domain.HardwareParameter;
import org.jclouds.deltacloud.domain.HardwareProperty; import org.jclouds.deltacloud.domain.HardwareProperty;
import org.jclouds.deltacloud.domain.HardwareProperty.Kind;
import org.jclouds.deltacloud.domain.RangeHardwareProperty; import org.jclouds.deltacloud.domain.RangeHardwareProperty;
import org.jclouds.deltacloud.domain.HardwareProperty.Kind;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils; import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;

View File

@ -19,6 +19,8 @@
package org.jclouds.deltacloud.xml; package org.jclouds.deltacloud.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -26,8 +28,10 @@ import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceAction; import org.jclouds.deltacloud.domain.KeyAuthentication;
import org.jclouds.deltacloud.domain.InstanceState; import org.jclouds.deltacloud.domain.PasswordAuthentication;
import org.jclouds.deltacloud.domain.Instance.Authentication;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -54,8 +58,8 @@ public class InstanceHandler extends ParseSax.HandlerWithResult<Instance> {
private URI image; private URI image;
private URI hardwareProfile; private URI hardwareProfile;
private URI realm; private URI realm;
private InstanceState state; private Instance.State state;
private Map<InstanceAction, HttpRequest> actions = Maps.newLinkedHashMap(); private Map<Instance.Action, HttpRequest> actions = Maps.newLinkedHashMap();
private Set<String> publicAddresses = Sets.newLinkedHashSet(); private Set<String> publicAddresses = Sets.newLinkedHashSet();
private Set<String> privateAddresses = Sets.newLinkedHashSet(); private Set<String> privateAddresses = Sets.newLinkedHashSet();
@ -64,6 +68,10 @@ public class InstanceHandler extends ParseSax.HandlerWithResult<Instance> {
private Instance instance; private Instance instance;
private Credentials.Builder<Credentials> credentialsBuilder = new Credentials.Builder<Credentials>();
private String keyName;
private Authentication authentication;
public Instance getResult() { public Instance getResult() {
return instance; return instance;
} }
@ -83,10 +91,10 @@ public class InstanceHandler extends ParseSax.HandlerWithResult<Instance> {
this.id = attributes.get("id"); this.id = attributes.get("id");
} else if (qName.equals("link")) { } else if (qName.equals("link")) {
try { try {
InstanceAction action = InstanceAction.fromValue(attributes.get("rel")); Instance.Action action = Instance.Action.fromValue(attributes.get("rel"));
if (action != InstanceAction.UNRECOGNIZED) { if (action != Instance.Action.UNRECOGNIZED) {
HttpRequest request = new HttpRequest(attributes.get("method").toUpperCase(), URI.create(attributes HttpRequest request = new HttpRequest(attributes.get("method").toUpperCase(), URI.create(attributes
.get("href"))); .get("href")));
actions.put(action, request); actions.put(action, request);
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
@ -112,19 +120,35 @@ public class InstanceHandler extends ParseSax.HandlerWithResult<Instance> {
inPrivateAddresses = false; inPrivateAddresses = false;
} }
if (qName.equalsIgnoreCase("owner_id")) { if (qName.equalsIgnoreCase("owner_id")) {
this.ownerId = currentText.toString().trim(); this.ownerId = currentOrNull(currentText);
} else if (qName.equalsIgnoreCase("name")) { } else if (qName.equalsIgnoreCase("name")) {
this.name = currentText.toString().trim(); this.name = currentOrNull(currentText);
} else if (qName.equalsIgnoreCase("keyname")) {
this.keyName = currentOrNull(currentText);
} else if (qName.equalsIgnoreCase("username")) {
this.credentialsBuilder.identity(currentOrNull(currentText));
} else if (qName.equalsIgnoreCase("password")) {
this.credentialsBuilder.credential(currentOrNull(currentText));
} else if (qName.equalsIgnoreCase("authentication")) {
if (keyName != null) {
this.authentication = new KeyAuthentication(keyName);
} else {
Credentials creds = credentialsBuilder.build();
if (creds.identity != null)
this.authentication = new PasswordAuthentication(creds);
}
this.keyName = null;
this.credentialsBuilder = new Credentials.Builder<Credentials>();
} else if (qName.equalsIgnoreCase("state")) { } else if (qName.equalsIgnoreCase("state")) {
this.state = InstanceState.fromValue(currentText.toString().trim()); this.state = Instance.State.fromValue(currentOrNull(currentText));
} else if (qName.equalsIgnoreCase("address")) { } else if (qName.equalsIgnoreCase("address")) {
if (inPublicAddresses) if (inPublicAddresses)
this.publicAddresses.add(currentText.toString().trim()); this.publicAddresses.add(currentOrNull(currentText));
else if (inPrivateAddresses) else if (inPrivateAddresses)
this.privateAddresses.add(currentText.toString().trim()); this.privateAddresses.add(currentOrNull(currentText));
} else if (qName.equalsIgnoreCase("instance")) { } else if (qName.equalsIgnoreCase("instance")) {
this.instance = new Instance(href, id, ownerId, name, image, hardwareProfile, realm, state, actions, this.instance = new Instance(href, id, ownerId, name, image, hardwareProfile, realm, state, actions,
publicAddresses, privateAddresses); authentication, publicAddresses, privateAddresses);
this.href = null; this.href = null;
this.id = null; this.id = null;
this.ownerId = null; this.ownerId = null;
@ -133,6 +157,7 @@ public class InstanceHandler extends ParseSax.HandlerWithResult<Instance> {
this.hardwareProfile = null; this.hardwareProfile = null;
this.realm = null; this.realm = null;
this.state = null; this.state = null;
this.authentication = null;
this.actions = Maps.newLinkedHashMap(); this.actions = Maps.newLinkedHashMap();
this.publicAddresses = Sets.newLinkedHashSet(); this.publicAddresses = Sets.newLinkedHashSet();
this.privateAddresses = Sets.newLinkedHashSet(); this.privateAddresses = Sets.newLinkedHashSet();

View File

@ -23,11 +23,11 @@ import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.jclouds.deltacloud.domain.InstanceAction;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.TransitionAutomatically; import org.jclouds.deltacloud.domain.TransitionAutomatically;
import org.jclouds.deltacloud.domain.TransitionOnAction; import org.jclouds.deltacloud.domain.TransitionOnAction;
import org.jclouds.deltacloud.domain.Instance.Action;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.util.SaxUtils; import org.jclouds.util.SaxUtils;
@ -40,15 +40,15 @@ import com.google.common.collect.Multimap;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
public class InstanceStatesHandler extends ParseSax.HandlerWithResult<Multimap<InstanceState, ? extends Transition>> { public class InstanceStatesHandler extends ParseSax.HandlerWithResult<Multimap<State, ? extends Transition>> {
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private Multimap<InstanceState, Transition> states = LinkedHashMultimap.create(); private Multimap<State, Transition> states = LinkedHashMultimap.create();
private InstanceState state; private State state;
public Multimap<InstanceState, ? extends Transition> getResult() { public Multimap<State, ? extends Transition> getResult() {
return states; return states;
} }
@ -66,16 +66,16 @@ public class InstanceStatesHandler extends ParseSax.HandlerWithResult<Multimap<I
} }
} }
InstanceState instanceStateWarningOnUnrecognized(String input) { State instanceStateWarningOnUnrecognized(String input) {
InstanceState state = InstanceState.fromValue(input); State state = State.fromValue(input);
if (state == InstanceState.UNRECOGNIZED) if (state == State.UNRECOGNIZED)
logger.warn("unrecognized state: %s", input); logger.warn("unrecognized state: %s", input);
return state; return state;
} }
InstanceAction instanceActionWarningOnUnrecognized(String input) { Action instanceActionWarningOnUnrecognized(String input) {
InstanceAction action = InstanceAction.fromValue(input); Action action = Action.fromValue(input);
if (action == InstanceAction.UNRECOGNIZED) if (action == Action.UNRECOGNIZED)
logger.warn("unrecognized action: %s", input); logger.warn("unrecognized action: %s", input);
return action; return action;
} }

View File

@ -23,7 +23,7 @@ import java.net.URI;
import java.util.Map; import java.util.Map;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.RealmState; import org.jclouds.deltacloud.domain.Realm.State;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils; import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -39,7 +39,7 @@ public class RealmHandler extends ParseSax.HandlerWithResult<Realm> {
private String id; private String id;
private String name; private String name;
private String limit; private String limit;
private RealmState state; private State state;
private Realm realm; private Realm realm;
@ -65,7 +65,7 @@ public class RealmHandler extends ParseSax.HandlerWithResult<Realm> {
} else if (qName.equalsIgnoreCase("name")) { } else if (qName.equalsIgnoreCase("name")) {
this.name = currentText.toString().trim(); this.name = currentText.toString().trim();
} else if (qName.equalsIgnoreCase("state")) { } else if (qName.equalsIgnoreCase("state")) {
this.state = RealmState.fromValue(currentText.toString().trim()); this.state = State.fromValue(currentText.toString().trim());
} else if (qName.equalsIgnoreCase("realm")) { } else if (qName.equalsIgnoreCase("realm")) {
this.realm = new Realm(href, id, name, limit, state); this.realm = new Realm(href, id, name, limit, state);
this.href = null; this.href = null;

View File

@ -234,7 +234,7 @@ public class DeltacloudAsyncClientTest extends RestClientTest<DeltacloudAsyncCli
public void testCreateInstance() throws SecurityException, NoSuchMethodException, IOException { public void testCreateInstance() throws SecurityException, NoSuchMethodException, IOException {
Method method = DeltacloudAsyncClient.class.getMethod("createInstance", String.class, Method method = DeltacloudAsyncClient.class.getMethod("createInstance", String.class,
CreateInstanceOptions[].class); CreateInstanceOptions[].class);
GeneratedHttpRequest<DeltacloudAsyncClient> httpRequest = processor.createRequest(method, "imageId-1"); GeneratedHttpRequest<DeltacloudAsyncClient> httpRequest = processor.createRequest(method, "imageId-1");
assertRequestLineEquals(httpRequest, "POST http://localhost:3001/api/instances HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST http://localhost:3001/api/instances HTTP/1.1");
@ -251,9 +251,9 @@ public class DeltacloudAsyncClientTest extends RestClientTest<DeltacloudAsyncCli
public void testCreateInstanceWithOptions() throws SecurityException, NoSuchMethodException, IOException { public void testCreateInstanceWithOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = DeltacloudAsyncClient.class.getMethod("createInstance", String.class, Method method = DeltacloudAsyncClient.class.getMethod("createInstance", String.class,
CreateInstanceOptions[].class); CreateInstanceOptions[].class);
GeneratedHttpRequest<DeltacloudAsyncClient> httpRequest = processor.createRequest(method, "imageId-1", GeneratedHttpRequest<DeltacloudAsyncClient> httpRequest = processor.createRequest(method, "imageId-1",
CreateInstanceOptions.Builder.named("foo")); CreateInstanceOptions.Builder.named("foo"));
assertRequestLineEquals(httpRequest, "POST http://localhost:3001/api/instances HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST http://localhost:3001/api/instances HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/xml\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/xml\n");
@ -269,8 +269,8 @@ public class DeltacloudAsyncClientTest extends RestClientTest<DeltacloudAsyncCli
public void testPerformAction() throws IOException, SecurityException, NoSuchMethodException { public void testPerformAction() throws IOException, SecurityException, NoSuchMethodException {
Method method = DeltacloudAsyncClient.class.getMethod("performAction", HttpRequest.class); Method method = DeltacloudAsyncClient.class.getMethod("performAction", HttpRequest.class);
HttpRequest request = processor.createRequest(method, HttpRequest request = processor.createRequest(method, HttpRequest.builder().method("POST").endpoint(
HttpRequest.builder().method("POST").endpoint(URI.create("https://delta/instance1/reboot")).build()); URI.create("https://delta/instance1/reboot")).build());
assertRequestLineEquals(request, "POST https://delta/instance1/reboot HTTP/1.1"); assertRequestLineEquals(request, "POST https://delta/instance1/reboot HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/xml\n");

View File

@ -25,9 +25,8 @@ import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.deltacloud.domain.Image;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceAction;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.options.CreateInstanceOptions; import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -37,6 +36,7 @@ import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.inject.Guice; import com.google.inject.Guice;
@ -54,8 +54,14 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
public void testCreateInstance() throws Exception { public void testCreateInstance() throws Exception {
Logger.getAnonymousLogger().info("starting instance"); Logger.getAnonymousLogger().info("starting instance");
instance = client.createInstance(Iterables.get(client.listImages(), 0).getId(), instance = client.createInstance(Iterables.find(client.listImages(), new Predicate<Image>() {
CreateInstanceOptions.Builder.named(prefix));
@Override
public boolean apply(Image input) {
return input.getDescription().toLowerCase().indexOf("fedora") != -1;
}
}).getId(), CreateInstanceOptions.Builder.named(prefix));
instance = client.getInstance(instance.getHref()); instance = client.getInstance(instance.getHref());
checkStartedInstance(); checkStartedInstance();
@ -71,7 +77,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
protected void checkStartedInstance() { protected void checkStartedInstance() {
System.out.println(new Gson().toJson(instance)); System.out.println(new Gson().toJson(instance));
assertEquals(instance.getName(), prefix); assertEquals(instance.getName(), prefix);
assertEquals(instance.getState(), InstanceState.RUNNING); assertEquals(instance.getState(), Instance.State.RUNNING);
} }
@Test(dependsOnMethods = "testCreateInstance") @Test(dependsOnMethods = "testCreateInstance")
@ -88,37 +94,37 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
return null; return null;
} }
public HttpRequest refreshInstanceAndGetAction(InstanceAction action) { public HttpRequest refreshInstanceAndGetAction(Instance.Action action) {
return client.getInstance(instance.getHref()).getActions().get(action); return client.getInstance(instance.getHref()).getActions().get(action);
} }
@Test(dependsOnMethods = "testConnectivity") @Test(dependsOnMethods = "testConnectivity")
public void testLifeCycle() throws Exception { public void testLifeCycle() {
client.performAction(refreshInstanceAndGetAction(InstanceAction.STOP)); client.performAction(refreshInstanceAndGetAction(Instance.Action.STOP));
assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.STOPPED); assertEquals(client.getInstance(instance.getHref()).getState(), Instance.State.STOPPED);
client.performAction(refreshInstanceAndGetAction(InstanceAction.START)); client.performAction(refreshInstanceAndGetAction(Instance.Action.START));
assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.RUNNING); assertEquals(client.getInstance(instance.getHref()).getState(), Instance.State.RUNNING);
client.performAction(refreshInstanceAndGetAction(InstanceAction.REBOOT)); client.performAction(refreshInstanceAndGetAction(Instance.Action.REBOOT));
assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.RUNNING); assertEquals(client.getInstance(instance.getHref()).getState(), Instance.State.RUNNING);
} }
@Test(dependsOnMethods = "testLifeCycle") @Test(dependsOnMethods = "testLifeCycle")
public void testDestroyInstance() throws Exception { public void testDestroyInstance() {
try { try {
client.performAction(refreshInstanceAndGetAction(InstanceAction.STOP)); client.performAction(refreshInstanceAndGetAction(Instance.Action.STOP));
assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.STOPPED); assertEquals(client.getInstance(instance.getHref()).getState(), Instance.State.STOPPED);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
} }
client.performAction(refreshInstanceAndGetAction(InstanceAction.DESTROY)); client.performAction(refreshInstanceAndGetAction(Instance.Action.DESTROY));
assertEquals(client.getInstance(instance.getHref()), null); assertEquals(client.getInstance(instance.getHref()), null);
} }
protected void doConnectViaSsh(Instance instance, Credentials creds) throws IOException { protected void doConnectViaSsh(Instance instance, Credentials creds) throws IOException {
SshClient ssh = Guice.createInjector(new JschSshClientModule()).getInstance(SshClient.Factory.class) SshClient ssh = Guice.createInjector(new JschSshClientModule()).getInstance(SshClient.Factory.class).create(
.create(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22), creds); new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
try { try {
ssh.connect(); ssh.connect();
ExecResponse hello = ssh.exec("echo hello"); ExecResponse hello = ssh.exec("echo hello");
@ -137,7 +143,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
protected void tearDown() { protected void tearDown() {
try { try {
testDestroyInstance(); testDestroyInstance();
} catch (Exception e) { } catch (NullPointerException e) {
// no need to check null or anything as we swallow all // no need to check null or anything as we swallow all
} }
super.tearDown(); super.tearDown();

View File

@ -32,7 +32,6 @@ import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Image; import org.jclouds.deltacloud.domain.Image;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -57,7 +56,7 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName ="ReadOnlyDeltacloudClientLiveTest") @Test(groups = "live", sequential = true, testName = "ReadOnlyDeltacloudClientLiveTest")
public class ReadOnlyDeltacloudClientLiveTest { public class ReadOnlyDeltacloudClientLiveTest {
protected DeltacloudClient client; protected DeltacloudClient client;
@ -96,7 +95,7 @@ public class ReadOnlyDeltacloudClientLiveTest {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()), context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
overrides); overrides);
client = context.getApi(); client = context.getApi();
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS);
@ -110,20 +109,20 @@ public class ReadOnlyDeltacloudClientLiveTest {
@Test @Test
public void testGetInstanceStatesCanGoFromStartToFinish() throws Exception { public void testGetInstanceStatesCanGoFromStartToFinish() throws Exception {
Multimap<InstanceState, ? extends Transition> states = client.getInstanceStates(); Multimap<Instance.State, ? extends Transition> states = client.getInstanceStates();
assertNotNull(states); assertNotNull(states);
Iterable<Transition> toFinishFromStart = findChainTo(InstanceState.FINISH, InstanceState.START, states); Iterable<Transition> toFinishFromStart = findChainTo(Instance.State.FINISH, Instance.State.START, states);
assert Iterables.size(toFinishFromStart) > 0 : toFinishFromStart; assert Iterables.size(toFinishFromStart) > 0 : toFinishFromStart;
Iterable<Transition> toRunningFromStart = findChainTo(InstanceState.RUNNING, InstanceState.START, states); Iterable<Transition> toRunningFromStart = findChainTo(Instance.State.RUNNING, Instance.State.START, states);
assert Iterables.size(toRunningFromStart) > 0 : toRunningFromStart; assert Iterables.size(toRunningFromStart) > 0 : toRunningFromStart;
Iterable<Transition> toFinishFromRunning = findChainTo(InstanceState.FINISH, InstanceState.RUNNING, states); Iterable<Transition> toFinishFromRunning = findChainTo(Instance.State.FINISH, Instance.State.RUNNING, states);
assert Iterables.size(toFinishFromRunning) > 0 : toFinishFromRunning; assert Iterables.size(toFinishFromRunning) > 0 : toFinishFromRunning;
assertEquals(ImmutableList.copyOf(Iterables.concat(toRunningFromStart, toFinishFromRunning)), assertEquals(ImmutableList.copyOf(Iterables.concat(toRunningFromStart, toFinishFromRunning)), ImmutableList
ImmutableList.copyOf(toFinishFromStart)); .copyOf(toFinishFromStart));
} }
Iterable<Transition> findChainTo(InstanceState desired, InstanceState currentState, Iterable<Transition> findChainTo(Instance.State desired, Instance.State currentState,
Multimap<InstanceState, ? extends Transition> states) { Multimap<Instance.State, ? extends Transition> states) {
for (Transition transition : states.get(currentState)) { for (Transition transition : states.get(currentState)) {
if (currentState.ordinal() >= transition.getTo().ordinal()) if (currentState.ordinal() >= transition.getTo().ordinal())
continue; continue;

View File

@ -25,8 +25,10 @@ import java.io.InputStream;
import java.net.URI; import java.net.URI;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceAction; import org.jclouds.deltacloud.domain.KeyAuthentication;
import org.jclouds.deltacloud.domain.InstanceState; import org.jclouds.deltacloud.domain.PasswordAuthentication;
import org.jclouds.deltacloud.domain.Instance.Authentication;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.http.functions.config.SaxParserModule;
@ -48,7 +50,7 @@ public class InstanceHandlerTest {
static ParseSax<Instance> createParser() { static ParseSax<Instance> createParser() {
Injector injector = Guice.createInjector(new SaxParserModule()); Injector injector = Guice.createInjector(new SaxParserModule());
ParseSax<Instance> parser = injector.getInstance(ParseSax.Factory.class).create( ParseSax<Instance> parser = injector.getInstance(ParseSax.Factory.class).create(
injector.getInstance(InstanceHandler.class)); injector.getInstance(InstanceHandler.class));
return parser; return parser;
} }
@ -61,17 +63,37 @@ public class InstanceHandlerTest {
return createParser().parse(is); return createParser().parse(is);
} }
public void test() { public void testWithNoAuthentication() {
Instance expects = new Instance(URI.create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", Instance expects = instanceWithAuthentication(null);
"larry", "Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"), assertEquals(parseInstance("/test_get_instance.xml").toString(), expects.toString());
URI.create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"), }
URI.create("http://fancycloudprovider.com/api/realms/us"), InstanceState.RUNNING, ImmutableMap.of(
InstanceAction.REBOOT, public void testWithPasswordAuthentication() {
new HttpRequest("POST", URI.create("http://fancycloudprovider.com/api/instances/inst1/reboot")), Instance expects = instanceWithAuthentication(new PasswordAuthentication(new Credentials("root", "FOO")));
InstanceAction.STOP, assertEquals(parseInstance("/test_get_instance_pw.xml").toString(), expects.toString());
new HttpRequest("POST", URI.create("http://fancycloudprovider.com/api/instances/inst1/stop"))), }
ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet.of("inst1.larry.internal"));
assertEquals(parseInstance(), expects); public void testWithKeyAuthentication() {
Instance expects = instanceWithAuthentication(new KeyAuthentication("keyname"));
assertEquals(parseInstance("/test_get_instance_key.xml").toString(), expects.toString());
}
public void testWithKeyAuthenticationBlank() {
Instance expects = instanceWithAuthentication(null);
assertEquals(parseInstance("/test_get_instance_nokey.xml").toString(), expects.toString());
}
private Instance instanceWithAuthentication(Authentication authentication) {
return new Instance(URI.create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", "larry",
"Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"), URI
.create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"), URI
.create("http://fancycloudprovider.com/api/realms/us"), Instance.State.RUNNING, ImmutableMap
.of(Instance.Action.REBOOT, new HttpRequest("POST", URI
.create("http://fancycloudprovider.com/api/instances/inst1/reboot")),
Instance.Action.STOP, new HttpRequest("POST", URI
.create("http://fancycloudprovider.com/api/instances/inst1/stop"))),
authentication, ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet
.of("inst1.larry.internal"));
} }
} }

View File

@ -23,11 +23,11 @@ import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import org.jclouds.deltacloud.domain.InstanceAction;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.deltacloud.domain.Transition; import org.jclouds.deltacloud.domain.Transition;
import org.jclouds.deltacloud.domain.TransitionAutomatically; import org.jclouds.deltacloud.domain.TransitionAutomatically;
import org.jclouds.deltacloud.domain.TransitionOnAction; import org.jclouds.deltacloud.domain.TransitionOnAction;
import org.jclouds.deltacloud.domain.Instance.Action;
import org.jclouds.deltacloud.domain.Instance.State;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -35,26 +35,25 @@ import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
/** /**
* Tests behavior of {@code InstanceStatesHandler} * Tests behavior of {@code StatesHandler}
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "InstanceStatesHandlerTest") @Test(groups = "unit", testName = "StatesHandlerTest")
public class InstanceStatesHandlerTest extends BaseHandlerTest { public class InstanceStatesHandlerTest extends BaseHandlerTest {
public void test() { public void test() {
InputStream is = getClass().getResourceAsStream("/test_get_states.xml"); InputStream is = getClass().getResourceAsStream("/test_get_states.xml");
Multimap<InstanceState, ? extends Transition> expects = ImmutableMultimap Multimap<State, ? extends Transition> expects = ImmutableMultimap.<State, Transition> builder().put(State.START,
.<InstanceState, Transition> builder() new TransitionOnAction(Action.CREATE, State.PENDING)).put(State.PENDING,
.put(InstanceState.START, new TransitionOnAction(InstanceAction.CREATE, InstanceState.PENDING)) new TransitionAutomatically(State.RUNNING))
.put(InstanceState.PENDING, new TransitionAutomatically(InstanceState.RUNNING)) .putAll(State.RUNNING, new TransitionOnAction(Action.REBOOT, State.RUNNING),
.putAll(InstanceState.RUNNING, new TransitionOnAction(InstanceAction.REBOOT, InstanceState.RUNNING), new TransitionOnAction(Action.STOP, State.STOPPED)).putAll(State.STOPPED,
new TransitionOnAction(InstanceAction.STOP, InstanceState.STOPPED)) new TransitionOnAction(Action.START, State.RUNNING),
.putAll(InstanceState.STOPPED, new TransitionOnAction(InstanceAction.START, InstanceState.RUNNING), new TransitionOnAction(Action.DESTROY, State.FINISH)).build();
new TransitionOnAction(InstanceAction.DESTROY, InstanceState.FINISH)).build(); assertEquals(factory.create(injector.getInstance(InstanceStatesHandler.class)).parse(is).entries(), expects
assertEquals(factory.create(injector.getInstance(InstanceStatesHandler.class)).parse(is).entries(), .entries());
expects.entries());
} }
} }

View File

@ -26,8 +26,6 @@ import java.net.URI;
import java.util.Set; import java.util.Set;
import org.jclouds.deltacloud.domain.Instance; import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.domain.InstanceAction;
import org.jclouds.deltacloud.domain.InstanceState;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -48,15 +46,15 @@ public class InstancesHandlerTest extends BaseHandlerTest {
public void test() { public void test() {
InputStream is = getClass().getResourceAsStream("/test_list_instances.xml"); InputStream is = getClass().getResourceAsStream("/test_list_instances.xml");
Set<? extends Instance> expects = ImmutableSet.of(new Instance(URI Set<? extends Instance> expects = ImmutableSet.of(new Instance(URI
.create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", "larry", .create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", "larry",
"Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"), URI "Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"), URI
.create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"), URI .create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"), URI
.create("http://fancycloudprovider.com/api/realms/us"), InstanceState.RUNNING, ImmutableMap.of( .create("http://fancycloudprovider.com/api/realms/us"), Instance.State.RUNNING, ImmutableMap
InstanceAction.REBOOT, .of(Instance.Action.REBOOT, new HttpRequest("POST", URI
new HttpRequest("POST", URI.create("http://fancycloudprovider.com/api/instances/inst1/reboot")), .create("http://fancycloudprovider.com/api/instances/inst1/reboot")),
InstanceAction.STOP, Instance.Action.STOP, new HttpRequest("POST", URI
new HttpRequest("POST", URI.create("http://fancycloudprovider.com/api/instances/inst1/stop"))), .create("http://fancycloudprovider.com/api/instances/inst1/stop"))), null,
ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet.of("inst1.larry.internal"))); ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet.of("inst1.larry.internal")));
assertEquals(factory.create(injector.getInstance(InstancesHandler.class)).parse(is), expects); assertEquals(factory.create(injector.getInstance(InstancesHandler.class)).parse(is).toString(), expects.toString());
} }
} }

View File

@ -25,7 +25,6 @@ import java.io.InputStream;
import java.net.URI; import java.net.URI;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.RealmState;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.http.functions.config.SaxParserModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -44,7 +43,7 @@ public class RealmHandlerTest {
static ParseSax<Realm> createParser() { static ParseSax<Realm> createParser() {
Injector injector = Guice.createInjector(new SaxParserModule()); Injector injector = Guice.createInjector(new SaxParserModule());
ParseSax<Realm> parser = injector.getInstance(ParseSax.Factory.class).create( ParseSax<Realm> parser = injector.getInstance(ParseSax.Factory.class).create(
injector.getInstance(RealmHandler.class)); injector.getInstance(RealmHandler.class));
return parser; return parser;
} }
@ -59,7 +58,7 @@ public class RealmHandlerTest {
public void test() { public void test() {
Realm expects = new Realm(URI.create("http://fancycloudprovider.com/api/realms/us"), "us", "United States", null, Realm expects = new Realm(URI.create("http://fancycloudprovider.com/api/realms/us"), "us", "United States", null,
RealmState.AVAILABLE); Realm.State.AVAILABLE);
assertEquals(parseRealm(), expects); assertEquals(parseRealm(), expects);
} }

View File

@ -26,7 +26,6 @@ import java.net.URI;
import java.util.Set; import java.util.Set;
import org.jclouds.deltacloud.domain.Realm; import org.jclouds.deltacloud.domain.Realm;
import org.jclouds.deltacloud.domain.RealmState;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -44,10 +43,10 @@ public class RealmsHandlerTest extends BaseHandlerTest {
@Test @Test
public void test() { public void test() {
InputStream is = getClass().getResourceAsStream("/test_list_realms.xml"); InputStream is = getClass().getResourceAsStream("/test_list_realms.xml");
Set<? extends Realm> expects = ImmutableSet.of( Set<? extends Realm> expects = ImmutableSet.of(new Realm(URI
new Realm(URI.create("http://fancycloudprovider.com/api/realms/us"), "us", "United States", null, .create("http://fancycloudprovider.com/api/realms/us"), "us", "United States", null,
RealmState.AVAILABLE), new Realm(URI.create("http://fancycloudprovider.com/api/realms/eu"), "eu", Realm.State.AVAILABLE), new Realm(URI.create("http://fancycloudprovider.com/api/realms/eu"), "eu",
"Europe", null, RealmState.AVAILABLE)); "Europe", null, Realm.State.AVAILABLE));
assertEquals(factory.create(injector.getInstance(RealmsHandler.class)).parse(is), expects); assertEquals(factory.create(injector.getInstance(RealmsHandler.class)).parse(is), expects);
} }
} }

View File

@ -0,0 +1,24 @@
<?xml version='1.0' encoding='utf-8' ?>
<instance href="http://fancycloudprovider.com/api/instances/inst1" id='inst1'>
<owner_id>larry</owner_id>
<name>Production JBoss Instance</name>
<image href="http://fancycloudprovider.com/api/images/img3"/>
<hardware_profile href="http://fancycloudprovider.com/api/hardware_profiles/m1-small"/>
<realm href="http://fancycloudprovider.com/api/realms/us"/>
<state>RUNNING</state>
<actions>
<link rel="reboot" href="http://fancycloudprovider.com/api/instances/inst1/reboot" method="post" />
<link rel="stop" href="http://fancycloudprovider.com/api/instances/inst1/stop" method="post" />
</actions>
<public_addresses>
<address>inst1.larry.fancycloudprovider.com</address>
</public_addresses>
<private_addresses>
<address>inst1.larry.internal</address>
</private_addresses>
<authentication type='key'>
<keyname>keyname</keyname>
</authentication>
</instance>

View File

@ -0,0 +1,24 @@
<?xml version='1.0' encoding='utf-8' ?>
<instance href="http://fancycloudprovider.com/api/instances/inst1" id='inst1'>
<owner_id>larry</owner_id>
<name>Production JBoss Instance</name>
<image href="http://fancycloudprovider.com/api/images/img3"/>
<hardware_profile href="http://fancycloudprovider.com/api/hardware_profiles/m1-small"/>
<realm href="http://fancycloudprovider.com/api/realms/us"/>
<state>RUNNING</state>
<actions>
<link rel="reboot" href="http://fancycloudprovider.com/api/instances/inst1/reboot" method="post" />
<link rel="stop" href="http://fancycloudprovider.com/api/instances/inst1/stop" method="post" />
</actions>
<public_addresses>
<address>inst1.larry.fancycloudprovider.com</address>
</public_addresses>
<private_addresses>
<address>inst1.larry.internal</address>
</private_addresses>
<authentication type='key'>
<keyname></keyname>
</authentication>
</instance>

View File

@ -0,0 +1,27 @@
<?xml version='1.0' encoding='utf-8' ?>
<instance href="http://fancycloudprovider.com/api/instances/inst1" id='inst1'>
<owner_id>larry</owner_id>
<name>Production JBoss Instance</name>
<image href="http://fancycloudprovider.com/api/images/img3"/>
<hardware_profile href="http://fancycloudprovider.com/api/hardware_profiles/m1-small"/>
<realm href="http://fancycloudprovider.com/api/realms/us"/>
<state>RUNNING</state>
<actions>
<link rel="reboot" href="http://fancycloudprovider.com/api/instances/inst1/reboot" method="post" />
<link rel="stop" href="http://fancycloudprovider.com/api/instances/inst1/stop" method="post" />
</actions>
<public_addresses>
<address>inst1.larry.fancycloudprovider.com</address>
</public_addresses>
<private_addresses>
<address>inst1.larry.internal</address>
</private_addresses>
<authentication type='password'>
<login>
<username>root</username>
<password>FOO</password>
</login>
</authentication>
</instance>