mirror of https://github.com/apache/jclouds.git
Merge pull request #1288 from jclouds/dynect-zones
add session management filter and read-only zone support to dynect
This commit is contained in:
commit
adf9cd5802
|
@ -19,6 +19,7 @@
|
|||
package org.jclouds.dynect.v3;
|
||||
|
||||
import org.jclouds.dynect.v3.features.SessionApi;
|
||||
import org.jclouds.dynect.v3.features.ZoneApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
|
||||
/**
|
||||
|
@ -37,4 +38,10 @@ public interface DynECTApi {
|
|||
*/
|
||||
@Delegate
|
||||
SessionApi getSessionApi();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Zone features.
|
||||
*/
|
||||
@Delegate
|
||||
ZoneApi getZoneApi();
|
||||
}
|
|
@ -23,6 +23,7 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
|||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.jclouds.dynect.v3.features.SessionAsyncApi;
|
||||
import org.jclouds.dynect.v3.features.ZoneAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.Headers;
|
||||
|
||||
|
@ -44,4 +45,10 @@ public interface DynECTAsyncApi {
|
|||
*/
|
||||
@Delegate
|
||||
SessionAsyncApi getSessionApi();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Zone features.
|
||||
*/
|
||||
@Delegate
|
||||
ZoneAsyncApi getZoneApi();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.dynect.v3;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_MAX_REDIRECTS;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -49,6 +51,8 @@ public class DynECTProviderMetadata extends BaseProviderMetadata {
|
|||
|
||||
public static Properties defaultProperties() {
|
||||
Properties properties = new Properties();
|
||||
// job polling occurs via redirect loop
|
||||
properties.setProperty(PROPERTY_MAX_REDIRECTS, "20");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,19 @@
|
|||
*/
|
||||
package org.jclouds.dynect.v3.config;
|
||||
|
||||
import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.dynect.v3.DynECTApi;
|
||||
import org.jclouds.dynect.v3.DynECTAsyncApi;
|
||||
import org.jclouds.dynect.v3.features.SessionApi;
|
||||
import org.jclouds.dynect.v3.features.SessionAsyncApi;
|
||||
import org.jclouds.dynect.v3.features.ZoneApi;
|
||||
import org.jclouds.dynect.v3.features.ZoneAsyncApi;
|
||||
import org.jclouds.dynect.v3.filters.SessionManager;
|
||||
import org.jclouds.http.HttpRetryHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
|
@ -39,9 +46,24 @@ public class DynECTRestClientModule extends RestClientModule<DynECTApi, DynECTAs
|
|||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(SessionApi.class, SessionAsyncApi.class)
|
||||
.build();
|
||||
.put(ZoneApi.class, ZoneAsyncApi.class).build();
|
||||
|
||||
public DynECTRestClientModule() {
|
||||
super(DELEGATE_MAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindRetryHandlers() {
|
||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(SessionManager.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
// binding explicitly ensures singleton despite multiple linked bindings
|
||||
bind(SessionManager.class);
|
||||
super.configure();
|
||||
// Bind apis that are used directly vs via DynECTApi
|
||||
bindHttpApi(binder(), SessionApi.class, SessionAsyncApi.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.domain;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public final class Zone {
|
||||
|
||||
private final String name;
|
||||
@Named("zone_type")
|
||||
private final Type type;
|
||||
private final int serial;
|
||||
@Named("serial_style")
|
||||
private final SerialStyle serialStyle;
|
||||
|
||||
public static enum Type {
|
||||
PRIMARY, SECONDARY;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
|
||||
}
|
||||
|
||||
public static Type fromValue(String type) {
|
||||
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static enum SerialStyle {
|
||||
/**
|
||||
* Serials are incremented by 1 on every change
|
||||
*/
|
||||
INCREMENT,
|
||||
/**
|
||||
* Serials will be the UNIX timestamp at the time of the publish
|
||||
*/
|
||||
EPOCH,
|
||||
/**
|
||||
* Serials will be in the form of YYYYMMDDxx where xx is incremented by
|
||||
* one for each change during that particular day
|
||||
*/
|
||||
DAY,
|
||||
/**
|
||||
* Serials will be in the form of YYMMDDHHMM
|
||||
*/
|
||||
MINUTE,
|
||||
|
||||
UNRECOGNIZED;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase();
|
||||
}
|
||||
|
||||
public static SerialStyle fromValue(String serialStyle) {
|
||||
try {
|
||||
return valueOf(checkNotNull(serialStyle, "serialStyle").toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ConstructorProperties({ "zone", "zone_type", "serial", "serial_style" })
|
||||
private Zone(String name, Type type, int serial, SerialStyle serialStyle) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.type = checkNotNull(type, "type for %s", name);
|
||||
this.serial = checkNotNull(serial, "serial for %s", name);
|
||||
this.serialStyle = checkNotNull(serialStyle, "serialStyle for %s", serialStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the requested zone
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique string that identifies the request to create the hosted zone.
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* The current serial number of the zone
|
||||
*/
|
||||
public int getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* The style of the zone's serial
|
||||
*/
|
||||
public SerialStyle getSerialStyle() {
|
||||
return serialStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
Zone that = Zone.class.cast(obj);
|
||||
return equal(this.name, that.name) && equal(this.type, that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).omitNullValues().add("name", name).add("type", type).add("serial", serial)
|
||||
.add("serialStyle", serialStyle).toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().from(this);
|
||||
}
|
||||
|
||||
public final static class Builder {
|
||||
private String name;
|
||||
private Type type;
|
||||
private int serial;
|
||||
private SerialStyle serialStyle;
|
||||
|
||||
/**
|
||||
* @see Zone#getName()
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getType()
|
||||
*/
|
||||
public Builder type(Type type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getSerial()
|
||||
*/
|
||||
public Builder serial(int serial) {
|
||||
this.serial = serial;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getSerialStyle()
|
||||
*/
|
||||
public Builder serialStyle(SerialStyle serialStyle) {
|
||||
this.serialStyle = serialStyle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Zone build() {
|
||||
return new Zone(name, type, serial, serialStyle);
|
||||
}
|
||||
|
||||
public Builder from(Zone in) {
|
||||
return this.name(in.name).type(in.type).serial(in.serial).serialStyle(in.serialStyle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.features;
|
||||
|
||||
import org.jclouds.dynect.v3.domain.Zone;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* @see ZoneAsyncApi
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface ZoneApi {
|
||||
/**
|
||||
* Lists all zone ids.
|
||||
*/
|
||||
FluentIterable<String> list();
|
||||
|
||||
/**
|
||||
* Retrieves information about the specified zone, including its nameserver
|
||||
* configuration
|
||||
*
|
||||
* @param name
|
||||
* name of the zone to get information about. ex
|
||||
* {@code Z1PA6795UKMFR9}
|
||||
* @return null if not found
|
||||
*/
|
||||
@Nullable
|
||||
Zone get(String name);
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.features;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.dynect.v3.domain.Zone;
|
||||
import org.jclouds.dynect.v3.filters.SessionManager;
|
||||
import org.jclouds.dynect.v3.functions.ExtractNames;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.Headers;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
/**
|
||||
*
|
||||
* @see ZoneApi
|
||||
* @see <a
|
||||
* href="https://manage.dynect.net/help/docs/api2/rest/resources/Zone.html">doc</a>
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
// required for all calls
|
||||
@Produces(APPLICATION_JSON)
|
||||
@Headers(keys = "API-Version", values = "{jclouds.api-version}")
|
||||
@Path("/Zone")
|
||||
@RequestFilters(SessionManager.class)
|
||||
public interface ZoneAsyncApi {
|
||||
|
||||
/**
|
||||
* @see ZoneApi#list
|
||||
*/
|
||||
@Named("GET:ZoneList")
|
||||
@GET
|
||||
@SelectJson("data")
|
||||
@Transform(ExtractNames.class)
|
||||
ListenableFuture<FluentIterable<String>> list();
|
||||
|
||||
/**
|
||||
* @see ZoneApi#isValid
|
||||
*/
|
||||
@Named("GET:Zone")
|
||||
@GET
|
||||
@Path("/{name}")
|
||||
@SelectJson("data")
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Zone> get(@PathParam("name") String name);
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.filters;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.dynect.v3.domain.Session;
|
||||
import org.jclouds.dynect.v3.domain.SessionCredentials;
|
||||
import org.jclouds.dynect.v3.features.SessionApi;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequest.Builder;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
/**
|
||||
*
|
||||
* This class manages session interactions, including grabbing latest from the
|
||||
* cache, and invalidating upon 401 If the credentials supplied in the
|
||||
* authentication header are invalid, or if the token has expired, the server
|
||||
* returns HTTP response code 401. After the token expires, you must log in
|
||||
* again to obtain a new token.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public final class SessionManager extends BackoffLimitedRetryHandler implements HttpRequestFilter {
|
||||
|
||||
@Resource
|
||||
private Logger logger = Logger.NULL;
|
||||
|
||||
private final Supplier<Credentials> creds;
|
||||
private final SessionApi sessionApi;
|
||||
private final LoadingCache<Credentials, Session> sessionCache;
|
||||
|
||||
@Inject
|
||||
SessionManager(@Provider Supplier<Credentials> creds, SessionApi sessionApi) {
|
||||
this(creds, buildCache(sessionApi), sessionApi);
|
||||
}
|
||||
|
||||
SessionManager(@Provider Supplier<Credentials> creds, LoadingCache<Credentials, Session> sessionCache,
|
||||
SessionApi sessionApi) {
|
||||
this.creds = creds;
|
||||
this.sessionCache = sessionCache;
|
||||
this.sessionApi = sessionApi;
|
||||
}
|
||||
|
||||
static LoadingCache<Credentials, Session> buildCache(final SessionApi sessionApi) {
|
||||
return CacheBuilder.newBuilder().build(new CacheLoader<Credentials, Session>() {
|
||||
public Session load(Credentials key) {
|
||||
return sessionApi.login(convert(key));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static SessionCredentials convert(Credentials key) {
|
||||
if (key instanceof SessionCredentials)
|
||||
return SessionCredentials.class.cast(key);
|
||||
return SessionCredentials.builder().customerName(key.identity.substring(0, key.identity.indexOf(':')))
|
||||
.userName(key.identity.substring(key.identity.indexOf(':') + 1)).password(key.credential).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
Session session = sessionCache.getUnchecked(creds.get());
|
||||
Builder<?> builder = request.toBuilder();
|
||||
builder.replaceHeader("Auth-Token", session.getToken());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||
boolean retry = false; // default
|
||||
try {
|
||||
if (response.getStatusCode() == 401) {
|
||||
closeClientButKeepContentStream(response);
|
||||
logger.debug("invalidating session");
|
||||
sessionCache.invalidateAll();
|
||||
retry = super.shouldRetryRequest(command, response);
|
||||
}
|
||||
return retry;
|
||||
} finally {
|
||||
releasePayload(response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* it is important that we close any sessions on close to help the server not
|
||||
* become overloaded.
|
||||
*/
|
||||
@PreDestroy
|
||||
public void logoutOnClose() {
|
||||
for (Session s : sessionCache.asMap().values()) {
|
||||
try {
|
||||
sessionApi.logout(s.getToken());
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "error logging out session %s", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
|
||||
/**
|
||||
* Zones come back encoded in REST paths, such as
|
||||
* {@code /REST/Zone/jclouds.org/}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public final class ExtractNames implements Function<FluentIterable<String>, FluentIterable<String>> {
|
||||
public FluentIterable<String> apply(FluentIterable<String> in) {
|
||||
return in.transform(ExtractNameInPath.INSTANCE);
|
||||
}
|
||||
|
||||
static enum ExtractNameInPath implements Function<String, String> {
|
||||
INSTANCE;
|
||||
|
||||
final int position = "/REST/Zone/".length();
|
||||
|
||||
public String apply(String in) {
|
||||
return in.substring(position, in.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.loaders;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.dynect.v3.domain.Session;
|
||||
import org.jclouds.dynect.v3.domain.SessionCredentials;
|
||||
import org.jclouds.dynect.v3.features.SessionApi;
|
||||
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
||||
@Singleton
|
||||
public class LoginUserInOrgWithPassword extends CacheLoader<SessionCredentials, Session> {
|
||||
private final SessionApi api;
|
||||
|
||||
@Inject
|
||||
LoginUserInOrgWithPassword(SessionApi api) {
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Session load(SessionCredentials input) {
|
||||
return api.login(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "loginUserInOrgWithPassword()";
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ import static org.testng.Assert.assertTrue;
|
|||
import org.jclouds.dynect.v3.DynECTApi;
|
||||
import org.jclouds.dynect.v3.domain.SessionCredentials;
|
||||
import org.jclouds.dynect.v3.internal.BaseDynECTApiExpectTest;
|
||||
import org.jclouds.dynect.v3.parse.ParseSessionTest;
|
||||
import org.jclouds.dynect.v3.parse.CreateSessionResponseTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -37,24 +37,13 @@ import org.testng.annotations.Test;
|
|||
@Test(groups = "unit", testName = "SessionApiExpectTest")
|
||||
public class SessionApiExpectTest extends BaseDynECTApiExpectTest {
|
||||
|
||||
private String authToken = "FFFFFFFFFF";
|
||||
|
||||
HttpRequest create = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://api2.dynect.net/REST/Session")
|
||||
.addHeader("API-Version", "3.3.7")
|
||||
.payload(payloadFromStringWithContentType("{\"customer_name\":\"jclouds\",\"user_name\":\"joe\",\"password\":\"letmein\"}",APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse createResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/create_session.json", APPLICATION_JSON)).build();
|
||||
|
||||
public void testCreateWhenResponseIs2xx() {
|
||||
DynECTApi apiCreatesSession = requestSendsResponse(create, createResponse);
|
||||
DynECTApi apiCreatesSession = requestSendsResponse(createSession, createSessionResponse);
|
||||
assertEquals(apiCreatesSession.getSessionApi().login(SessionCredentials.builder()
|
||||
.customerName("jclouds")
|
||||
.userName("joe")
|
||||
.password("letmein").build()).toString(),
|
||||
new ParseSessionTest().expected().toString());
|
||||
new CreateSessionResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
HttpRequest isValid = HttpRequest.builder().method("GET")
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.features;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import org.jclouds.dynect.v3.DynECTApi;
|
||||
import org.jclouds.dynect.v3.internal.BaseDynECTApiExpectTest;
|
||||
import org.jclouds.dynect.v3.parse.GetZoneResponseTest;
|
||||
import org.jclouds.dynect.v3.parse.ListZonesResponseTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ZoneApiExpectTest")
|
||||
public class ZoneApiExpectTest extends BaseDynECTApiExpectTest {
|
||||
|
||||
HttpRequest get = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://api2.dynect.net/REST/Zone/jclouds.org")
|
||||
.addHeader("API-Version", "3.3.7")
|
||||
.addHeader("Auth-Token", authToken)
|
||||
.payload(emptyJsonPayload())
|
||||
.build();
|
||||
|
||||
HttpResponse getResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/get_zone.json", APPLICATION_JSON)).build();
|
||||
|
||||
public void testGetWhenResponseIs2xx() {
|
||||
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, get, getResponse);
|
||||
assertEquals(success.getZoneApi().get("jclouds.org").toString(),
|
||||
new GetZoneResponseTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testGetWhenResponseError2401() {
|
||||
DynECTApi fail = requestsSendResponses(createSession, createSessionResponse, get, notFound);
|
||||
assertNull(fail.getZoneApi().get("jclouds.org"));
|
||||
}
|
||||
|
||||
HttpRequest list = HttpRequest.builder().method("GET")
|
||||
.endpoint("https://api2.dynect.net/REST/Zone")
|
||||
.addHeader("API-Version", "3.3.7")
|
||||
.addHeader("Auth-Token", authToken)
|
||||
.payload(emptyJsonPayload())
|
||||
.build();
|
||||
|
||||
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/list_zones.json", APPLICATION_JSON)).build();
|
||||
|
||||
public void testListWhenResponseIs2xx() {
|
||||
DynECTApi success = requestsSendResponses(createSession, createSessionResponse, list, listResponse);
|
||||
assertEquals(success.getZoneApi().list().toString(),
|
||||
new ListZonesResponseTest().expected().toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, String 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.dynect.v3.features;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.util.logging.Logger.getAnonymousLogger;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
import org.jclouds.dynect.v3.domain.Zone;
|
||||
import org.jclouds.dynect.v3.internal.BaseDynECTApiLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", testName = "ZoneApiLiveTest")
|
||||
public class ZoneApiLiveTest extends BaseDynECTApiLiveTest {
|
||||
|
||||
private void checkZone(Zone zone) {
|
||||
checkNotNull(zone.getName(), "Name cannot be null for a Zone: %s", zone);
|
||||
checkNotNull(zone.getSerial(), "Serial cannot be null for a Zone: %s", zone);
|
||||
}
|
||||
|
||||
@Test
|
||||
protected void testListAndGetZones() {
|
||||
ImmutableList<String> zones = api().list().toList();
|
||||
getAnonymousLogger().info("zones: " + zones.size());
|
||||
|
||||
for (String zoneName : zones) {
|
||||
Zone zone = api().get(zoneName);
|
||||
checkNotNull(zone, "zone was null for Zone: %s", zoneName);
|
||||
checkZone(zone);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetZoneWhenNotFound() {
|
||||
assertNull(api().get("AAAAAAAAAAAAAAAA"));
|
||||
}
|
||||
|
||||
protected ZoneApi api() {
|
||||
return context.getApi().getZoneApi();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.filters;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.dynect.v3.domain.Session;
|
||||
import org.jclouds.dynect.v3.domain.SessionCredentials;
|
||||
import org.jclouds.dynect.v3.features.SessionApi;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "SessionManagerTest")
|
||||
public class SessionManagerTest {
|
||||
SessionCredentials creds = SessionCredentials.builder().customerName("customer").userName("robbie")
|
||||
.password("password").build();
|
||||
Session session = Session.forTokenAndVersion("token", "version");
|
||||
|
||||
public void testAlreadySessionCredentials() {
|
||||
assertSame(SessionManager.convert(creds), creds);
|
||||
}
|
||||
|
||||
public void testConvertCredentialsParsesCustomer() {
|
||||
assertEquals(SessionManager.convert(new Credentials("customer:robbie", "password")), creds);
|
||||
}
|
||||
|
||||
public void testCacheLoadLogsIn() {
|
||||
SessionApi sessionApi = createMock(SessionApi.class);
|
||||
expect(sessionApi.login(creds)).andReturn(session);
|
||||
replay(sessionApi);
|
||||
|
||||
assertSame(SessionManager.buildCache(sessionApi).apply(creds), session);
|
||||
|
||||
verify(sessionApi);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void test401ShouldInvalidateSessionAndRetry() {
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
Supplier<Credentials> creds = createMock(Supplier.class);
|
||||
LoadingCache<Credentials, Session> sessionCache = createMock(LoadingCache.class);
|
||||
SessionApi sessionApi = createMock(SessionApi.class);
|
||||
|
||||
sessionCache.invalidateAll();
|
||||
expectLastCall();
|
||||
expect(command.incrementFailureCount()).andReturn(1);
|
||||
expect(command.isReplayable()).andReturn(true);
|
||||
expect(command.getFailureCount()).andReturn(1).atLeastOnce();
|
||||
|
||||
replay(creds, sessionCache, sessionApi, command);
|
||||
|
||||
HttpResponse response = HttpResponse.builder().statusCode(401).build();
|
||||
|
||||
SessionManager retry = new SessionManager(creds, sessionCache, sessionApi);
|
||||
|
||||
assertTrue(retry.shouldRetryRequest(command, response));
|
||||
|
||||
verify(creds, sessionCache, sessionApi, command);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void test403ShouldNotInvalidateSessionOrRetry() {
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
Supplier<Credentials> creds = createMock(Supplier.class);
|
||||
LoadingCache<Credentials, Session> sessionCache = createMock(LoadingCache.class);
|
||||
SessionApi sessionApi = createMock(SessionApi.class);
|
||||
|
||||
replay(creds, sessionCache, sessionApi, command);
|
||||
|
||||
HttpResponse response = HttpResponse.builder().statusCode(403).build();
|
||||
|
||||
SessionManager retry = new SessionManager(creds, sessionCache, sessionApi);
|
||||
|
||||
assertFalse(retry.shouldRetryRequest(command, response));
|
||||
|
||||
verify(creds, sessionCache, sessionApi, command);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.dynect.v3.functions.ExtractNames.ExtractNameInPath;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ExtractNamesTest {
|
||||
ExtractNames fn = new ExtractNames();
|
||||
|
||||
public void testExtractNameInPath() {
|
||||
assertEquals(ExtractNameInPath.INSTANCE.apply("/REST/Zone/jclouds.org/"), "jclouds.org");
|
||||
}
|
||||
|
||||
public void testExtractNames() {
|
||||
assertEquals(fn.apply(FluentIterable.from(ImmutableSet.of("/REST/Zone/jclouds.org/"))).toSet(),
|
||||
ImmutableSet.of("jclouds.org"));
|
||||
}
|
||||
}
|
|
@ -18,12 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.dynect.v3.internal;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import org.jclouds.dynect.v3.DynECTApi;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
|
||||
/**
|
||||
* Base class for writing DynECT Expect tests
|
||||
|
@ -32,14 +27,4 @@ import org.jclouds.io.Payloads;
|
|||
*/
|
||||
public class BaseDynECTApiExpectTest extends BaseDynECTExpectTest<DynECTApi> {
|
||||
|
||||
public static Payload emptyJsonPayload() {
|
||||
Payload p = Payloads.newByteArrayPayload(new byte[] {});
|
||||
p.getContentMetadata().setContentType(APPLICATION_JSON);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
|
||||
return HttpRequestComparisonType.JSON;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.dynect.v3.internal;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.rest.internal.BaseRestApiExpectTest;
|
||||
|
||||
/**
|
||||
|
@ -28,5 +34,31 @@ import org.jclouds.rest.internal.BaseRestApiExpectTest;
|
|||
public class BaseDynECTExpectTest<T> extends BaseRestApiExpectTest<T> {
|
||||
public BaseDynECTExpectTest() {
|
||||
provider = "dynect";
|
||||
identity = "jclouds:joe";
|
||||
credential = "letmein";
|
||||
}
|
||||
|
||||
public static Payload emptyJsonPayload() {
|
||||
Payload p = Payloads.newByteArrayPayload(new byte[] {});
|
||||
p.getContentMetadata().setContentType(APPLICATION_JSON);
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
|
||||
return HttpRequestComparisonType.JSON;
|
||||
}
|
||||
|
||||
protected String authToken = "FFFFFFFFFF";
|
||||
|
||||
protected HttpRequest createSession = HttpRequest.builder().method("POST")
|
||||
.endpoint("https://api2.dynect.net/REST/Session")
|
||||
.addHeader("API-Version", "3.3.7")
|
||||
.payload(payloadFromStringWithContentType("{\"customer_name\":\"jclouds\",\"user_name\":\"joe\",\"password\":\"letmein\"}",APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
protected HttpResponse createSessionResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResourceWithContentType("/create_session.json", APPLICATION_JSON)).build();
|
||||
|
||||
protected HttpResponse notFound = HttpResponse.builder().statusCode(404).build();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.testng.annotations.Test;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseSessionTest extends BaseDynECTParseTest<Session> {
|
||||
public class CreateSessionResponseTest extends BaseDynECTParseTest<Session> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.parse;
|
||||
|
||||
import static org.jclouds.dynect.v3.domain.Zone.SerialStyle.INCREMENT;
|
||||
import static org.jclouds.dynect.v3.domain.Zone.Type.PRIMARY;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.dynect.v3.domain.Zone;
|
||||
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class GetZoneResponseTest extends BaseDynECTParseTest<Zone> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/get_zone.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("data")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Zone expected() {
|
||||
return Zone.builder().type(PRIMARY).serialStyle(INCREMENT).serial(5).name("jclouds.org").build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.dynect.v3.parse;
|
||||
|
||||
import static com.google.common.base.Functions.compose;
|
||||
|
||||
import org.jclouds.dynect.v3.functions.ExtractNames;
|
||||
import org.jclouds.dynect.v3.internal.BaseDynECTParseTest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ListZonesResponseTest extends BaseDynECTParseTest<FluentIterable<String>> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/list_zones.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SelectJson("data")
|
||||
public FluentIterable<String> expected() {
|
||||
return FluentIterable.from(ImmutableSet.of("0.0.0.0.d.6.e.0.0.a.2.ip6.arpa", "126.12.44.in-addr.arpa", "jclouds.org"));
|
||||
}
|
||||
|
||||
// TODO: currently our parsing of annotations on expected() ignores @Transform
|
||||
@Override
|
||||
protected Function<HttpResponse, FluentIterable<String>> parser(Injector i) {
|
||||
return compose(new ExtractNames(), super.parser(i));
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"status": "success", "data": {"zone_type": "Primary", "serial_style": "increment", "serial": 5, "zone": "jclouds.org"}, "job_id": 260737493, "msgs": [{"INFO": "get: Your zone, jclouds.org", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}
|
|
@ -0,0 +1 @@
|
|||
{"status": "success", "data": ["/REST/Zone/0.0.0.0.d.6.e.0.0.a.2.ip6.arpa/", "/REST/Zone/126.12.44.in-addr.arpa/", "/REST/Zone/jclouds.org/"], "job_id": 260657587, "msgs": [{"INFO": "get: Your 3 zones", "SOURCE": "BLL", "ERR_CD": null, "LVL": "INFO"}]}
|
Loading…
Reference in New Issue