Implemented Volume API
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/9a8b346c Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/9a8b346c Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/9a8b346c Branch: refs/heads/master Commit: 9a8b346cafd9e332b0e532f1341e739d0388a347 Parents: 7b3c878 Author: mirza-spc <[email protected]> Authored: Mon Feb 22 14:10:00 2016 +0100 Committer: Reijhanniel Jearl Campos <[email protected]> Committed: Tue Feb 23 20:22:56 2016 +0800 ---------------------------------------------------------------------- profitbricks-rest/pom.xml | 7 + .../profitbricks/rest/ProfitBricksApi.java | 8 + .../binder/server/AttachCdromRequestBinder.java | 4 + .../server/AttachVolumeRequestBinder.java | 6 +- .../server/CreateServerRequestBinder.java | 3 + .../server/UpdateServerRequestBinder.java | 4 + .../volume/CreateSnapshotRequestBinder.java | 73 +++++++ .../volume/CreateVolumeRequestBinder.java | 81 ++++++++ .../volume/RestoreSnapshotRequestBinder.java | 72 +++++++ .../volume/UpdateVolumeRequestBinder.java | 70 +++++++ .../profitbricks/rest/domain/Provisionable.java | 25 +++ .../profitbricks/rest/domain/Server.java | 4 +- .../profitbricks/rest/domain/Snapshot.java | 91 ++++++++ .../profitbricks/rest/domain/Volume.java | 176 +++++++++++++++- .../profitbricks/rest/features/ServerApi.java | 3 +- .../profitbricks/rest/features/SnapshotApi.java | 53 +++++ .../profitbricks/rest/features/VolumeApi.java | 101 ++++++++- .../profitbricks/rest/ids/VolumeRef.java | 31 +++ .../profitbricks/rest/util/MacAddresses.java | 29 +++ .../profitbricks/rest/util/Passwords.java | 64 ++++++ .../server/AttachCdromRequestBinderTest.java | 63 ++++++ .../server/AttachVolumeRequestBinderTest.java | 63 ++++++ .../server/CreateServerRequestBinderTest.java | 72 +++++++ .../server/UpdateServerRequestBinderTest.java | 66 ++++++ .../volume/CreateSnapshotRequestBinderTest.java | 63 ++++++ .../volume/CreateVolumeRequestBinderTest.java | 73 +++++++ .../RestoreSnapshotRequestBinderTest.java | 54 +++++ .../volume/UpdateVolumeRequestBinderTest.java | 63 ++++++ .../rest/features/DataCenterApiMockTest.java | 32 --- .../rest/features/ServerApiLiveTest.java | 61 +++++- .../rest/features/ServerApiMockTest.java | 39 +--- .../rest/features/VolumeApiLiveTest.java | 175 ++++++++++++++++ .../rest/features/VolumeApiMockTest.java | 154 ++++++++++++++ .../internal/BaseProfitBricksApiMockTest.java | 12 +- .../rest/internal/BaseProfitBricksLiveTest.java | 37 +++- .../rest/util/MacAddressesTest.java | 45 ++++ .../profitbricks/rest/util/ParseIdTest.java | 49 +++++ .../profitbricks/rest/util/PasswordsTest.java | 53 +++++ .../src/test/resources/volume/get.json | 33 +++ .../src/test/resources/volume/list.json | 205 +++++++++++++++++++ .../src/test/resources/volume/snapshot.json | 30 +++ 41 files changed, 2259 insertions(+), 88 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/pom.xml ---------------------------------------------------------------------- diff --git a/profitbricks-rest/pom.xml b/profitbricks-rest/pom.xml index d676d88..7c04c2f 100644 --- a/profitbricks-rest/pom.xml +++ b/profitbricks-rest/pom.xml @@ -65,6 +65,13 @@ <artifactId>jclouds-okhttp</artifactId> <version>${jclouds.version}</version> </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.5-SNAPSHOT</version> + <scope>test</scope> + <type>jar</type> + </dependency> <!-- Test dependencies --> <dependency> <groupId>org.apache.jclouds</groupId> http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ProfitBricksApi.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ProfitBricksApi.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ProfitBricksApi.java index 977fbc7..44d4c0d 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ProfitBricksApi.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ProfitBricksApi.java @@ -21,6 +21,8 @@ import com.google.common.annotations.Beta; import java.io.Closeable; import org.apache.jclouds.profitbricks.rest.features.DataCenterApi; import org.apache.jclouds.profitbricks.rest.features.ServerApi; +import org.apache.jclouds.profitbricks.rest.features.SnapshotApi; +import org.apache.jclouds.profitbricks.rest.features.VolumeApi; import org.jclouds.rest.annotations.Delegate; @Beta @@ -31,5 +33,11 @@ public interface ProfitBricksApi extends Closeable { @Delegate ServerApi serverApi(); + + @Delegate + VolumeApi volumeApi(); + + @Delegate + SnapshotApi snapshotApi(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinder.java index 49faee2..efc1195 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinder.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinder.java @@ -44,6 +44,10 @@ public class AttachCdromRequestBinder extends BaseProfitBricksRequestBinder<Serv protected String createPayload(Server.Request.AttachCdromPayload payload) { checkNotNull(payload, "payload"); + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.serverId(), "serverId"); + checkNotNull(payload.imageId(), "imageId"); dataCenterId = payload.dataCenterId(); serverId = payload.serverId(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinder.java index f843d34..0ffebaa 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinder.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinder.java @@ -44,11 +44,15 @@ public class AttachVolumeRequestBinder extends BaseProfitBricksRequestBinder<Ser protected String createPayload(Server.Request.AttachVolumePayload payload) { checkNotNull(payload, "payload"); + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.serverId(), "serverId"); + checkNotNull(payload.volumeId(), "volumeId"); dataCenterId = payload.dataCenterId(); serverId = payload.serverId(); - requestBuilder.put("id", payload.imageId()); + requestBuilder.put("id", payload.volumeId()); return jsonBinder.toJson(requestBuilder); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinder.java index aaa07c1..bac058d 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinder.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinder.java @@ -16,6 +16,7 @@ */ package org.apache.jclouds.profitbricks.rest.binder.server; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.inject.Inject; import java.util.HashMap; import java.util.Map; @@ -40,6 +41,8 @@ public class CreateServerRequestBinder extends BaseProfitBricksRequestBinder<Ser @Override protected String createPayload(Server.Request.CreatePayload payload) { + checkNotNull(payload.dataCenterId(), "dataCenterId"); + dataCenterId = payload.dataCenterId(); Map<String, Object> properties = new HashMap<String, Object>(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinder.java index 9d7eda9..3c00111 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinder.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinder.java @@ -16,6 +16,7 @@ */ package org.apache.jclouds.profitbricks.rest.binder.server; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.inject.Inject; import java.util.HashMap; import java.util.Map; @@ -41,6 +42,9 @@ public class UpdateServerRequestBinder extends BaseProfitBricksRequestBinder<Ser @Override protected String createPayload(Server.Request.UpdatePayload payload) { + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.id(), "serverId"); + dataCenterId = payload.dataCenterId(); serverId = payload.id(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinder.java new file mode 100644 index 0000000..d18d69e --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinder.java @@ -0,0 +1,73 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import javax.ws.rs.core.MediaType; +import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpRequest.Builder; + +public class CreateSnapshotRequestBinder extends BaseProfitBricksRequestBinder<Volume.Request.CreateSnapshotPayload> { + + protected final Multimap<String, String> requestBuilder; + private String dataCenterId; + private String volumeId; + + CreateSnapshotRequestBinder() { + super("snapshot"); + this.requestBuilder = HashMultimap.create(); + } + + @Override + protected String createPayload(Volume.Request.CreateSnapshotPayload payload) { + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.volumeId(), "volumeId"); + + dataCenterId = payload.dataCenterId(); + volumeId = payload.volumeId(); + + if (payload.name() != null) + requestBuilder.put("name", payload.name()); + + if (payload.description() != null) + requestBuilder.put("description", payload.description()); + + return ""; + } + + @Override + protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) { + + fromRequest = super.createRequest(fromRequest, payload); + + Builder<?> reqBuilder = fromRequest.toBuilder(); + + reqBuilder.addFormParams(requestBuilder); + reqBuilder.replacePath(String.format("/rest/datacenters/%s/volumes/%s/create-snapshot", dataCenterId, volumeId)); + + R req = (R) reqBuilder.build(); + req.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + return req; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinder.java new file mode 100644 index 0000000..76e4a3b --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinder.java @@ -0,0 +1,81 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import static com.google.common.base.Preconditions.checkNotNull; +import com.google.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; + +public class CreateVolumeRequestBinder extends BaseProfitBricksRequestBinder<Volume.Request.CreatePayload> { + + protected final Map<String, Object> requestBuilder; + final Json jsonBinder; + + private String dataCenterId; + + @Inject + CreateVolumeRequestBinder(Json jsonBinder) { + super("volume"); + this.jsonBinder = jsonBinder; + this.requestBuilder = new HashMap<String, Object>(); + } + + @Override + protected String createPayload(Volume.Request.CreatePayload payload) { + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + + dataCenterId = payload.dataCenterId(); + + Map<String, Object> properties = new HashMap<String, Object>(); + + properties.put("size", payload.size()); + + if (payload.name() != null) + properties.put("name", payload.name()); + + if (payload.bus() != null) + properties.put("bus", payload.bus()); + + if (payload.type() != null) + properties.put("type", payload.type()); + + if (payload.imagePassword() != null) + properties.put("imagePassword", payload.imagePassword()); + + if (payload.image() != null) + properties.put("image", payload.image()); + else if (payload.licenceType() != null) + properties.put("licenceType", payload.licenceType()); + + requestBuilder.put("properties", properties); + + return jsonBinder.toJson(requestBuilder); + } + + @Override + protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) { + R request = (R) fromRequest.toBuilder().replacePath(String.format("/rest/datacenters/%s/volumes", dataCenterId)).build(); + return super.createRequest(request, payload); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinder.java new file mode 100644 index 0000000..ff08240 --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinder.java @@ -0,0 +1,72 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import javax.ws.rs.core.MediaType; +import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; + +public class RestoreSnapshotRequestBinder extends BaseProfitBricksRequestBinder<Volume.Request.RestoreSnapshotPayload> { + + protected final Multimap<String, String> requestBuilder; + + private String dataCenterId; + private String volumeId; + private String snapshotId; + + RestoreSnapshotRequestBinder() { + super("snapshot"); + this.requestBuilder = HashMultimap.create(); + } + + @Override + protected String createPayload(Volume.Request.RestoreSnapshotPayload payload) { + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.volumeId(), "volumeId"); + checkNotNull(payload.snapshotId(), "snapshotId"); + + dataCenterId = payload.dataCenterId(); + volumeId = payload.volumeId(); + snapshotId = payload.snapshotId(); + + requestBuilder.put("snapshotId", payload.snapshotId()); + + return ""; + } + + @Override + protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) { + + fromRequest = super.createRequest(fromRequest, payload); + + HttpRequest.Builder<?> reqBuilder = fromRequest.toBuilder(); + + reqBuilder.addFormParams(requestBuilder); + reqBuilder.replacePath(String.format("/rest/datacenters/%s/volumes/%s/restore-snapshot", dataCenterId, volumeId)); + + R req = (R) reqBuilder.build(); + req.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + return req; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinder.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinder.java new file mode 100644 index 0000000..51d8027 --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinder.java @@ -0,0 +1,70 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import static com.google.common.base.Preconditions.checkNotNull; +import com.google.inject.Inject; +import java.util.HashMap; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; + +public class UpdateVolumeRequestBinder extends BaseProfitBricksRequestBinder<Volume.Request.UpdatePayload> { + + protected final Map<String, Object> requestBuilder; + final Json jsonBinder; + + private String dataCenterId; + private String volumeId; + + @Inject + UpdateVolumeRequestBinder(Json jsonBinder) { + super("volume"); + this.jsonBinder = jsonBinder; + this.requestBuilder = new HashMap<String, Object>(); + } + + @Override + protected String createPayload(Volume.Request.UpdatePayload payload) { + + checkNotNull(payload.dataCenterId(), "dataCenterId"); + checkNotNull(payload.id(), "volumeId"); + + dataCenterId = payload.dataCenterId(); + volumeId = payload.id(); + + if (payload.name() != null) + requestBuilder.put("name", payload.name()); + + if (payload.size() != null) + requestBuilder.put("size", payload.size()); + + if (payload.bus() != null) + requestBuilder.put("bus", payload.bus()); + + return jsonBinder.toJson(requestBuilder); + } + + @Override + protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) { + R request = (R) fromRequest.toBuilder().replacePath(String.format("/rest/datacenters/%s/volumes/%s", dataCenterId, volumeId)).build(); + return super.createRequest(request, payload); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Provisionable.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Provisionable.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Provisionable.java new file mode 100644 index 0000000..9e813d2 --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Provisionable.java @@ -0,0 +1,25 @@ +/* + * 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.apache.jclouds.profitbricks.rest.domain; + +/** + * Marker interface for {@link org.jclouds.profitbricks.domain.Image} and + * {@link org.jclouds.profitbricks.domain.Snapshot} + */ +public interface Provisionable { + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Server.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Server.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Server.java index d832ea0..f574777 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Server.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Server.java @@ -259,14 +259,14 @@ public abstract class Server { @AutoValue public abstract static class AttachVolumePayload { - public abstract String imageId(); + public abstract String volumeId(); public abstract String dataCenterId(); public abstract String serverId(); @AutoValue.Builder public abstract static class Builder { - public abstract Builder imageId(String imageId); + public abstract Builder volumeId(String volumeId); public abstract Builder dataCenterId(String dataCenterId); public abstract Builder serverId(String serverId); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Snapshot.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Snapshot.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Snapshot.java new file mode 100644 index 0000000..793cede --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Snapshot.java @@ -0,0 +1,91 @@ +/* + * 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.apache.jclouds.profitbricks.rest.domain; + +import com.google.auto.value.AutoValue; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +@AutoValue +public abstract class Snapshot { + + public abstract String id(); + + public abstract String type(); + + public abstract String href(); + + @Nullable + public abstract Metadata metadata(); + + @Nullable + public abstract Properties properties(); + + @SerializedNames({"id", "type", "href", "metadata", "properties"}) + public static Snapshot create(String id, String type, String href, Metadata metadata, Properties properties) { + return new AutoValue_Snapshot(id, type, href, metadata, properties); + } + + @AutoValue + public abstract static class Properties { + + @Nullable + public abstract String name(); + + @Nullable + public abstract String description(); + + @Nullable + public abstract Integer size(); + + @Nullable + public abstract LicenceType licenceType(); + + public abstract Location location(); + + public abstract boolean cpuHotPlug(); + + public abstract boolean cpuHotUnplug(); + + public abstract boolean ramHotPlug(); + + public abstract boolean ramHotUnplug(); + + public abstract boolean nicHotPlug(); + + public abstract boolean nicHotUnplug(); + + public abstract boolean discVirtioHotPlug(); + + public abstract boolean discVirtioHotUnplug(); + + public abstract boolean discScsiHotPlug(); + + public abstract boolean discScsiHotUnplug(); + + @SerializedNames({"name", "description", "size", "licenceType", "location", "cpuHotPlug", "cpuHotUnplug", "ramHotPlug", "ramHotUnplug", "nicHotPlug", "nicHotUnplug", "discVirtioHotPlug", "discVirtioHotUnplug", "discScsiHotPlug", "discScsiHotUnplug"}) + public static Snapshot.Properties create(String name, String description, Integer size, LicenceType licenceType, Location location, + boolean cpuHotPlug, boolean cpuHotUnplug, boolean ramHotPlug, boolean ramHotUnplug, boolean nicHotPlug, boolean nicHotUnplug, boolean discVirtioHotPlug, + boolean discVirtioHotUnplug, boolean discScsiHotPlug, boolean discScsiHotUnplug) { + + return new AutoValue_Snapshot_Properties(name, description, size, licenceType, location, cpuHotPlug, cpuHotUnplug, ramHotPlug, ramHotUnplug, nicHotPlug, nicHotUnplug, discVirtioHotPlug, discVirtioHotUnplug, discScsiHotPlug, discScsiHotUnplug); + + + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Volume.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Volume.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Volume.java index b978294..0608f3d 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Volume.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/Volume.java @@ -18,13 +18,18 @@ package org.apache.jclouds.profitbricks.rest.domain; import com.google.auto.value.AutoValue; import com.google.common.base.Enums; +import org.apache.jclouds.profitbricks.rest.util.Passwords; import org.jclouds.javax.annotation.Nullable; import org.jclouds.json.SerializedNames; +import static com.google.common.base.Preconditions.checkArgument; @AutoValue public abstract class Volume { public abstract String id(); + + @Nullable + public abstract String dataCenterId(); public abstract String type(); @@ -36,9 +41,9 @@ public abstract class Volume { @Nullable public abstract Properties properties(); - @SerializedNames({"id", "type", "href", "metadata", "properties"}) - public static Volume create(String id, String type, String href, Metadata metadata, Properties properties) { - return new AutoValue_Volume(id, type, href, metadata, properties); + @SerializedNames({"id", "dataCenterId", "type", "href", "metadata", "properties"}) + public static Volume create(String id, String dataCenterId, String type, String href, Metadata metadata, Properties properties) { + return new AutoValue_Volume(id, dataCenterId, type, href, metadata, properties); } @AutoValue @@ -53,8 +58,10 @@ public abstract class Volume { } } + @Nullable public abstract String name(); + @Nullable public abstract String type(); public abstract float size(); @@ -65,6 +72,7 @@ public abstract class Volume { @Nullable public abstract String imagePassword(); + @Nullable public abstract BusType bus(); public abstract LicenceType licenceType(); @@ -102,4 +110,166 @@ public abstract class Volume { } } + + public static final class Request { + + public static CreatePayload.Builder creatingBuilder() { + return new AutoValue_Volume_Request_CreatePayload.Builder(); + } + + public static UpdatePayload.Builder updatingBuilder() { + return new AutoValue_Volume_Request_UpdatePayload.Builder(); + } + + public static CreateSnapshotPayload.Builder createSnapshotBuilder() { + return new AutoValue_Volume_Request_CreateSnapshotPayload.Builder(); + } + + public static RestoreSnapshotPayload.Builder restoreSnapshotBuilder() { + return new AutoValue_Volume_Request_RestoreSnapshotPayload.Builder(); + } + + @AutoValue + public abstract static class CreatePayload { + + @Nullable + public abstract String name(); + + @Nullable + public abstract String type(); + + public abstract int size(); + + @Nullable + public abstract String image(); + + @Nullable + public abstract String imagePassword(); + + @Nullable + public abstract Properties.BusType bus(); + + @Nullable + public abstract LicenceType licenceType(); + + public abstract String dataCenterId(); + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder name(String name); + public abstract Builder type(String type); + public abstract Builder size(int size); + public abstract Builder image(String image); + public abstract Builder imagePassword(String imagePassword); + public abstract Builder bus(Properties.BusType bus); + public abstract Builder licenceType(LicenceType licenceType); + public abstract Builder dataCenterId(String dataCenterId); + + abstract CreatePayload autoBuild(); + + public CreatePayload build() { + CreatePayload payload = autoBuild(); + + if (payload.imagePassword() != null) + checkArgument(Passwords.isValidPassword(payload.imagePassword()), "Password's format is not valid"); + + checkArgument( + payload.image() != null || payload.licenceType() != null, + "Either image or licenceType need to be present" + ); + + return payload; + } + } + + } + + @AutoValue + public abstract static class UpdatePayload { + + @Nullable + public abstract String name(); + + @Nullable + public abstract Integer size(); + + @Nullable + public abstract Properties.BusType bus(); + + public abstract String dataCenterId(); + public abstract String id(); + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder name(String name); + public abstract Builder size(Integer size); + public abstract Builder bus(Properties.BusType bus); + public abstract Builder dataCenterId(String dataCenterId); + public abstract Builder id(String id); + + abstract UpdatePayload autoBuild(); + + public UpdatePayload build() { + return autoBuild(); + } + } + } + + @AutoValue + public abstract static class CreateSnapshotPayload { + + @Nullable + public abstract String name(); + + @Nullable + public abstract String description(); + + public abstract String dataCenterId(); + public abstract String volumeId(); + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder name(String name); + public abstract Builder description(String description); + public abstract Builder dataCenterId(String dataCenterId); + public abstract Builder volumeId(String volumeId); + + abstract CreateSnapshotPayload autoBuild(); + + public CreateSnapshotPayload build() { + return autoBuild(); + } + } + + } + + @AutoValue + public abstract static class RestoreSnapshotPayload { + + public abstract String snapshotId(); + public abstract String dataCenterId(); + public abstract String volumeId(); + + @AutoValue.Builder + public abstract static class Builder { + + public abstract Builder snapshotId(String snapshotId); + public abstract Builder dataCenterId(String dataCenterId); + public abstract Builder volumeId(String volumeId); + + abstract RestoreSnapshotPayload autoBuild(); + + public RestoreSnapshotPayload build() { + return autoBuild(); + } + } + + } + + } + + } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/ServerApi.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/ServerApi.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/ServerApi.java index fa1718c..faedf6c 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/ServerApi.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/ServerApi.java @@ -182,8 +182,7 @@ public interface ServerApi extends Closeable { @Override public <V> V apply(InputStream stream, Type type) throws IOException { try { - return (V) json.fromJson(this.parseService.parseId(Strings2.toStringAndClose(stream), "datacenters", "dataCenterId"), type - ); + return (V) json.fromJson(this.parseService.parseId(Strings2.toStringAndClose(stream), "datacenters", "dataCenterId"), type); } finally { if (stream != null) stream.close(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/SnapshotApi.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/SnapshotApi.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/SnapshotApi.java new file mode 100644 index 0000000..f1d4815 --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/SnapshotApi.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jclouds.profitbricks.rest.features; + +import com.google.inject.Inject; +import com.google.inject.TypeLiteral; +import java.io.Closeable; +import javax.inject.Named; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import org.apache.jclouds.profitbricks.rest.domain.Snapshot; +import org.jclouds.Fallbacks; +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.json.Json; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; + +@Path("/snapshots") +@RequestFilters(BasicAuthentication.class) +public interface SnapshotApi extends Closeable { + + @Named("snapshot:get") + @GET + @Path("/{id}") + @ResponseParser(SnapshotApi.SnapshotParser.class) + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + Snapshot getSnapshot(@PathParam("id") String id); + + + static final class SnapshotParser extends ParseJson<Snapshot> { + @Inject SnapshotParser(Json json) { + super(json, TypeLiteral.get(Snapshot.class)); + } + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/VolumeApi.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/VolumeApi.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/VolumeApi.java index 028a648..4f03478 100644 --- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/VolumeApi.java +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/VolumeApi.java @@ -19,20 +19,117 @@ package org.apache.jclouds.profitbricks.rest.features; import com.google.inject.Inject; import com.google.inject.TypeLiteral; import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.List; +import javax.inject.Named; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import org.apache.jclouds.profitbricks.rest.binder.volume.CreateSnapshotRequestBinder; +import org.apache.jclouds.profitbricks.rest.binder.volume.CreateVolumeRequestBinder; +import org.apache.jclouds.profitbricks.rest.binder.volume.RestoreSnapshotRequestBinder; +import org.apache.jclouds.profitbricks.rest.binder.volume.UpdateVolumeRequestBinder; +import org.apache.jclouds.profitbricks.rest.domain.Snapshot; import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.apache.jclouds.profitbricks.rest.domain.options.DepthOptions; +import org.apache.jclouds.profitbricks.rest.util.ParseId; +import org.jclouds.Fallbacks; +import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.functions.ParseJson; import org.jclouds.json.Json; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.PATCH; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SelectJson; +import org.jclouds.util.Strings2; -@Path("/volumes") +@Path("/datacenters/{dataCenterId}/volumes") @RequestFilters(BasicAuthentication.class) public interface VolumeApi extends Closeable { + @Named("volume:list") + @GET + @SelectJson("items") + @Fallback(EmptyListOnNotFoundOr404.class) + List<Volume> getList(@PathParam("dataCenterId") String dataCenterId); + + @Named("volume:list") + @GET + @SelectJson("items") + @Fallback(EmptyListOnNotFoundOr404.class) + List<Volume> getList(@PathParam("dataCenterId") String dataCenterId, DepthOptions options); + + @Named("volume:get") + @GET + @Path("/{volumeId}") + @ResponseParser(VolumeApi.VolumeParser.class) + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + Volume getVolume(@PathParam("dataCenterId") String dataCenterId, @PathParam("volumeId") String volumeId); + + @Named("volume:get") + @GET + @Path("/{volumeId}") + @ResponseParser(VolumeApi.VolumeParser.class) + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + Volume getVolume(@PathParam("dataCenterId") String dataCenterId, @PathParam("volumeId") String volumeId, DepthOptions options); + + @Named("volume:create") + @POST + @MapBinder(CreateVolumeRequestBinder.class) + @ResponseParser(VolumeApi.VolumeParser.class) + Volume createVolume(@PayloadParam("volume") Volume.Request.CreatePayload payload); + + @Named("volume:update") + @PATCH + @Path("/{volumeId}") + @MapBinder(UpdateVolumeRequestBinder.class) + @ResponseParser(VolumeApi.VolumeParser.class) + @Produces("application/vnd.profitbricks.partial-properties+json") + Volume updateVolume(@PayloadParam("volume") Volume.Request.UpdatePayload payload); + + @Named("volume:delete") + @DELETE + @Path("/{volumeId}") + @Fallback(Fallbacks.VoidOnNotFoundOr404.class) + void deleteVolume(@PathParam("dataCenterId") String dataCenterId, @PathParam("volumeId") String volumeId); + + @Named("volume:snapshot:create") + @POST + @MapBinder(CreateSnapshotRequestBinder.class) + @ResponseParser(SnapshotApi.SnapshotParser.class) + Snapshot createSnapshot(@PayloadParam("snapshot") Volume.Request.CreateSnapshotPayload payload); + + @Named("volume:snapshot:restore") + @POST + @MapBinder(RestoreSnapshotRequestBinder.class) + void restoreSnapshot(@PayloadParam("snapshot") Volume.Request.RestoreSnapshotPayload payload); + static final class VolumeParser extends ParseJson<Volume> { - @Inject VolumeParser(Json json) { + + final ParseId parseService; + + @Inject VolumeParser(Json json, ParseId parseId) { super(json, TypeLiteral.get(Volume.class)); + this.parseService = parseId; + } + + @Override + public <V> V apply(InputStream stream, Type type) throws IOException { + try { + return (V) json.fromJson(this.parseService.parseId(Strings2.toStringAndClose(stream), "datacenters", "dataCenterId"), type); + } finally { + if (stream != null) + stream.close(); + } } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ids/VolumeRef.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ids/VolumeRef.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ids/VolumeRef.java new file mode 100644 index 0000000..a60d57a --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/ids/VolumeRef.java @@ -0,0 +1,31 @@ +/* + * 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.apache.jclouds.profitbricks.rest.ids; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class VolumeRef { + + public abstract String dataCenterId(); + public abstract String volumeId(); + + public static VolumeRef create(String dataCenterId, String volumeId) { + return new AutoValue_VolumeRef(dataCenterId, volumeId); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/MacAddresses.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/MacAddresses.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/MacAddresses.java new file mode 100644 index 0000000..a27a9ce --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/MacAddresses.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jclouds.profitbricks.rest.util; + +import java.util.regex.Pattern; + +public class MacAddresses { + + private static final String MAC_ADDR_FORMAT = "^([0-9a-f]{2}[:]){5}([0-9a-f]{2})$"; + private static final Pattern MAC_ADDR_PATTERN = Pattern.compile(MAC_ADDR_FORMAT); + + public static boolean isMacAddress(String in) { + return MAC_ADDR_PATTERN.matcher(in).matches(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/Passwords.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/Passwords.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/Passwords.java new file mode 100644 index 0000000..b6e5a85 --- /dev/null +++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/util/Passwords.java @@ -0,0 +1,64 @@ +/* + * 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.apache.jclouds.profitbricks.rest.util; + +import java.util.Random; +import java.util.regex.Pattern; + +import com.google.common.collect.ImmutableSet; + +public class Passwords { + + private static final Random random = new Random(); + + private static final int MIN_CHAR = 8; + private static final int MAX_CHAR = 50; + private static final String PASSWORD_FORMAT = String.format( + "[a-zA-Z0-9][^iIloOwWyYzZ10]{%d,%d}", MIN_CHAR - 1, MAX_CHAR); + private static final Pattern PASSWORD_PATTERN = Pattern.compile(PASSWORD_FORMAT); + + private static final ImmutableSet<Character> INVALID_CHARS = ImmutableSet.<Character>of( + 'i', 'I', 'l', 'o', 'O', 'w', 'W', 'y', 'Y', 'z', 'Z', '1', '0'); + + public static boolean isValidPassword(String password) { + return PASSWORD_PATTERN.matcher(password).matches(); + } + + public static String generate() { + int count = random.nextInt(MAX_CHAR - MIN_CHAR) + MIN_CHAR; + + final char[] buffer = new char[count]; + + final int start = 'A'; + final int end = 'z'; + final int gap = end - start + 1; + + while (count-- != 0) { + char ch = (char) (random.nextInt(gap) + start); + if ((isBetween(ch, start, 'Z') || isBetween(ch, 'a', end)) + && !INVALID_CHARS.contains(ch)) + buffer[count] = ch; + else + count++; + } + return new String(buffer); + } + + private static boolean isBetween(char ch, int start, int end) { + return ch >= start && ch <= end; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinderTest.java new file mode 100644 index 0000000..b0af74f --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachCdromRequestBinderTest.java @@ -0,0 +1,63 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.server; + +import com.google.common.reflect.TypeToken; +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.domain.Server; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "AttachCdromRequestBinderTest") +public class AttachCdromRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + AttachCdromRequestBinder binder = injector.getInstance(AttachCdromRequestBinder.class); + + Server.Request.AttachCdromPayload payload = Server.Request.attachCdromBuilder() + .dataCenterId("datacenter-id") + .serverId("server-id") + .imageId("image-id") + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("PATCH").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/servers/server-id/cdroms"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + String expectedJson = json.toJson(json.fromJson(expectedPayload, new TypeToken<Map<String, Object>>(){}.getType())); + + assertEquals(actual, expectedJson); + } + + private final String expectedPayload = "{\"id\":\"image-id\"}"; +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinderTest.java new file mode 100644 index 0000000..590da6d --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/AttachVolumeRequestBinderTest.java @@ -0,0 +1,63 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.server; + +import com.google.common.reflect.TypeToken; +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.domain.Server; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "AttachVolumeRequestBinderTest") +public class AttachVolumeRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + AttachVolumeRequestBinder binder = injector.getInstance(AttachVolumeRequestBinder.class); + + Server.Request.AttachVolumePayload payload = Server.Request.attachVolumeBuilder() + .dataCenterId("datacenter-id") + .serverId("server-id") + .volumeId("volume-id") + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("POST").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/servers/server-id/volumes"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + String expectedJson = json.toJson(json.fromJson(expectedPayload, new TypeToken<Map<String, Object>>(){}.getType())); + + assertEquals(actual, expectedJson); + } + + private final String expectedPayload = "{\"id\":\"volume-id\"}"; +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinderTest.java new file mode 100644 index 0000000..da0ee30 --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/CreateServerRequestBinderTest.java @@ -0,0 +1,72 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.server; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.HashMap; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.domain.Server; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "CreateServerRequestBinderTest") +public class CreateServerRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + CreateServerRequestBinder binder = injector.getInstance(CreateServerRequestBinder.class); + + Server.Request.CreatePayload payload = Server.Request.creatingBuilder() + .dataCenterId("datacenter-id") + .name("jclouds-node") + .cores(4) + .ram(4 * 1024) + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("POST").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/servers"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + + Map<String, Object> properties = new HashMap<String, Object>(); + + properties.put("cores", 4); + properties.put("name", "jclouds-node"); + properties.put("ram", 4 * 1024); + + HashMap<String, Object> expectedPayload = new HashMap<String, Object>(); + + expectedPayload.put("properties", properties); + + assertEquals(actual, json.toJson(expectedPayload)); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinderTest.java new file mode 100644 index 0000000..e1c8102 --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/server/UpdateServerRequestBinderTest.java @@ -0,0 +1,66 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.server; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.HashMap; +import org.apache.jclouds.profitbricks.rest.domain.Server; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "UpdateServerRequestBinderTest") +public class UpdateServerRequestBinderTest { + + @Test + public void testCreatePayload() { + Injector injector = Guice.createInjector(new GsonModule()); + UpdateServerRequestBinder binder = injector.getInstance(UpdateServerRequestBinder.class); + + Server.Request.UpdatePayload payload = Server.Request.updatingBuilder() + .id("server-id") + .cores(8) + .ram(8 * 1024) + .name("apache-node") + .dataCenterId("datacenter-id") + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("PATCH").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/servers/server-id"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + + HashMap<String, Object> expectedPayload = new HashMap<String, Object>(); + expectedPayload.put("cores", 8); + expectedPayload.put("name", "apache-node"); + expectedPayload.put("ram", 8192); + + assertEquals(actual, json.toJson(expectedPayload)); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinderTest.java new file mode 100644 index 0000000..2c1566f --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateSnapshotRequestBinderTest.java @@ -0,0 +1,63 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.inject.Guice; +import com.google.inject.Injector; +import javax.ws.rs.core.MediaType; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.io.payloads.UrlEncodedFormPayload; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "CreateSnapshotRequestBinderTest") +public class CreateSnapshotRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + CreateSnapshotRequestBinder binder = injector.getInstance(CreateSnapshotRequestBinder.class); + + Volume.Request.CreateSnapshotPayload payload = Volume.Request.createSnapshotBuilder() + .dataCenterId("datacenter-id") + .volumeId("volume-id") + .name("test-snapshot") + .description("snapshot desc...") + .build(); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("POST").endpoint("http://test.com").build(), + binder.createPayload(payload) + ); + + Multimap<String, String> expectedPayload = HashMultimap.create(); + + expectedPayload.put("name", "test-snapshot"); + expectedPayload.put("description", "snapshot desc..."); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/volumes/volume-id/create-snapshot"); + assertEquals(request.getPayload().getContentMetadata().getContentType(), MediaType.APPLICATION_FORM_URLENCODED); + assertEquals(request.getPayload().getRawContent(), "&" + (new UrlEncodedFormPayload(expectedPayload)).getRawContent()); + + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinderTest.java new file mode 100644 index 0000000..f49ab75 --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/CreateVolumeRequestBinderTest.java @@ -0,0 +1,73 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.HashMap; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.domain.LicenceType; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "CreateVolumeRequestBinderTest") +public class CreateVolumeRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + CreateVolumeRequestBinder binder = injector.getInstance(CreateVolumeRequestBinder.class); + + Volume.Request.CreatePayload payload = Volume.Request.creatingBuilder() + .dataCenterId("datacenter-id") + .name("jclouds-volume") + .size(3) + .licenceType(LicenceType.LINUX) + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("POST").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/volumes"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + + Map<String, Object> properties = new HashMap<String, Object>(); + + properties.put("size", 3); + properties.put("licenceType", "LINUX"); + properties.put("name", "jclouds-volume"); + + HashMap<String, Object> expectedPayload = new HashMap<String, Object>(); + + expectedPayload.put("properties", properties); + + assertEquals(actual, json.toJson(expectedPayload)); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinderTest.java new file mode 100644 index 0000000..f19daa4 --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/RestoreSnapshotRequestBinderTest.java @@ -0,0 +1,54 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import javax.ws.rs.core.MediaType; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "RestoreSnapshotRequestBinderTest") +public class RestoreSnapshotRequestBinderTest { + + @Test + public void testRestorePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + RestoreSnapshotRequestBinder binder = injector.getInstance(RestoreSnapshotRequestBinder.class); + + Volume.Request.RestoreSnapshotPayload payload = Volume.Request.restoreSnapshotBuilder() + .dataCenterId("datacenter-id") + .volumeId("volume-id") + .snapshotId("snapshot-id") + .build(); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("POST").endpoint("http://test.com").build(), + binder.createPayload(payload) + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/volumes/volume-id/restore-snapshot"); + assertEquals(request.getPayload().getContentMetadata().getContentType(), MediaType.APPLICATION_FORM_URLENCODED); + assertEquals(request.getPayload().getRawContent(), "&snapshotId=snapshot-id"); + + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinderTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinderTest.java new file mode 100644 index 0000000..f0e6694 --- /dev/null +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/volume/UpdateVolumeRequestBinderTest.java @@ -0,0 +1,63 @@ +/* + * 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.apache.jclouds.profitbricks.rest.binder.volume; + +import com.google.common.reflect.TypeToken; +import com.google.inject.Guice; +import com.google.inject.Injector; +import java.util.Map; +import org.apache.jclouds.profitbricks.rest.domain.Volume; +import org.jclouds.http.HttpRequest; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "UpdateVolumeRequestBinderTest") +public class UpdateVolumeRequestBinderTest { + + @Test + public void testCreatePayload() { + + Injector injector = Guice.createInjector(new GsonModule()); + UpdateVolumeRequestBinder binder = injector.getInstance(UpdateVolumeRequestBinder.class); + + Volume.Request.UpdatePayload payload = Volume.Request.updatingBuilder() + .dataCenterId("datacenter-id") + .id("volume-id") + .name("apache-volume") + .build(); + + String actual = binder.createPayload(payload); + + HttpRequest request = binder.createRequest( + HttpRequest.builder().method("PATCH").endpoint("http://test.com").build(), + actual + ); + + assertEquals(request.getEndpoint().getPath(), "/rest/datacenters/datacenter-id/volumes/volume-id"); + assertNotNull(actual, "Binder returned null payload"); + + Json json = injector.getInstance(Json.class); + String expectedJson = json.toJson(json.fromJson(expectedPayload, new TypeToken<Map<String, Object>>(){}.getType())); + + assertEquals(actual, expectedJson); + } + + private final String expectedPayload = "{\"name\":\"apache-volume\"}"; +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/DataCenterApiMockTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/DataCenterApiMockTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/DataCenterApiMockTest.java index 022eb92..f4d2e11 100644 --- a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/DataCenterApiMockTest.java +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/DataCenterApiMockTest.java @@ -24,8 +24,6 @@ import org.apache.jclouds.profitbricks.rest.domain.options.DepthOptions; import org.apache.jclouds.profitbricks.rest.internal.BaseProfitBricksApiMockTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; import org.testng.annotations.Test; @Test(groups = "unit", testName = "DataCenterApiMockTest", singleThreaded = true) @@ -46,15 +44,6 @@ public class DataCenterApiMockTest extends BaseProfitBricksApiMockTest { assertEquals(server.getRequestCount(), 1); assertSent(server, "GET", "/datacenters"); } - - @Test - public void testGetListWith404() throws InterruptedException { - server.enqueue(response404()); - List<DataCenter> list = dataCenterApi().list(new DepthOptions().depth(1)); - assertTrue(list.isEmpty()); - assertEquals(server.getRequestCount(), 1); - assertSent(server, "GET", "/datacenters?depth=1"); - } @Test public void testGetDataCenter() throws InterruptedException { @@ -73,17 +62,6 @@ public class DataCenterApiMockTest extends BaseProfitBricksApiMockTest { assertSent(server, "GET", "/datacenters/some-id"); } - public void testGetDataCenterWith404() throws InterruptedException { - server.enqueue(response404()); - - DataCenter dataCenter = dataCenterApi().getDataCenter("some-id"); - - assertNull(dataCenter); - - assertEquals(server.getRequestCount(), 1); - assertSent(server, "GET", "/datacenters/some-id"); - } - @Test public void testCreate() throws InterruptedException { server.enqueue( @@ -123,16 +101,6 @@ public class DataCenterApiMockTest extends BaseProfitBricksApiMockTest { } @Test - public void testDeleteWith404() throws InterruptedException { - server.enqueue(response404()); - - dataCenterApi().delete("some-id"); - - assertEquals(server.getRequestCount(), 1); - assertSent(server, "DELETE", "/datacenters/some-id"); - } - - @Test public void testDepth() throws InterruptedException { for (int i = 1; i <= 5; ++i) { http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9a8b346c/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/ServerApiLiveTest.java ---------------------------------------------------------------------- diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/ServerApiLiveTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/ServerApiLiveTest.java index cb0a6b4..949588b 100644 --- a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/ServerApiLiveTest.java +++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/ServerApiLiveTest.java @@ -24,6 +24,7 @@ import org.apache.jclouds.profitbricks.rest.domain.Server; import org.apache.jclouds.profitbricks.rest.domain.State; import org.apache.jclouds.profitbricks.rest.domain.Volume; import org.apache.jclouds.profitbricks.rest.ids.ServerRef; +import org.apache.jclouds.profitbricks.rest.ids.VolumeRef; import org.apache.jclouds.profitbricks.rest.internal.BaseProfitBricksLiveTest; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -142,8 +143,41 @@ public class ServerApiLiveTest extends BaseProfitBricksLiveTest { List<Volume> volumes = serverApi().listAttachedVolumes(testServer.dataCenterId(), testServer.id()); assertTrue(volumes.isEmpty()); } - + @Test(dependsOnMethods = "testListVolumes") + public void testAttachVolume() { + + Volume volume = createVolume(dataCenter); + + assertVolumeAvailable(VolumeRef.create(dataCenter.id(), volume.id())); + + attachedVolume = serverApi().attachVolume( + Server.Request.attachVolumeBuilder() + .dataCenterId(testServer.dataCenterId()) + .serverId(testServer.id()) + .volumeId(volume.id()) + .build() + ); + + assertVolumeAttached(testServer, volume.id()); + + List<Volume> volumes = serverApi().listAttachedVolumes(testServer.dataCenterId(), testServer.id()); + assertEquals(volumes.size(), 1); + } + + @Test(dependsOnMethods = "testAttachVolume") + public void testGetVolume() { + Volume volume = serverApi().getVolume(testServer.dataCenterId(), testServer.id(), attachedVolume.id()); + assertEquals(volume.id(), attachedVolume.id()); + } + + @Test(dependsOnMethods = "testGetVolume") + public void testDetachVolume() { + serverApi().detachVolume(testServer.dataCenterId(), testServer.id(), attachedVolume.id()); + assertVolumeDetached(testServer, attachedVolume.id()); + } + + @Test(dependsOnMethods = "testDetachVolume") public void testListCdroms() { List<Image> images = serverApi().listAttachedCdroms(testServer.dataCenterId(), testServer.id()); assertTrue(images.isEmpty()); @@ -211,5 +245,30 @@ public class ServerApiLiveTest extends BaseProfitBricksLiveTest { } }, complexId(server.dataCenterId(), server.id(), cdRomId)); } + + private void assertVolumeAttached(Server server, String volumeId) { + assertRandom(new Predicate<String>() { + @Override + public boolean apply(String args) { + String[] params = args.split(","); + Volume volume = serverApi().getVolume(params[0], params[1], params[2]); + + if (volume == null || volume.metadata() == null) + return false; + + return volume.metadata().state() == State.AVAILABLE; + } + }, complexId(server.dataCenterId(), server.id(), volumeId)); + } + + private void assertVolumeDetached(Server server, String volumeId) { + assertRandom(new Predicate<String>() { + @Override + public boolean apply(String args) { + String[] params = args.split(","); + return serverApi().getVolume(params[0], params[1], params[2]) == null; + } + }, complexId(server.dataCenterId(), server.id(), volumeId)); + } }
