You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/04/19 17:06:27 UTC

[1/2] jclouds-labs git commit: Profitbricks REST - Firewall API

Repository: jclouds-labs
Updated Branches:
  refs/heads/master b82378c2b -> 44ddd688f


Profitbricks REST - Firewall 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/5b757ee4
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/5b757ee4
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/5b757ee4

Branch: refs/heads/master
Commit: 5b757ee412a802448dcad120389661b65ae7d43c
Parents: b82378c
Author: mirza-spc <mi...@stackpointcloud.com>
Authored: Thu Apr 7 10:10:13 2016 +0200
Committer: Ignasi Barrera <na...@apache.org>
Committed: Tue Apr 19 17:00:34 2016 +0200

----------------------------------------------------------------------
 .../profitbricks/rest/ProfitBricksApi.java      |   4 +
 .../binder/BaseProfitBricksRequestBinder.java   |   5 +
 .../CreateFirewallRuleRequestBinder.java        |  76 +++++++
 .../UpdateFirewallRuleRequestBinder.java        |  73 +++++++
 .../rest/binder/lan/CreateLanRequestBinder.java |   4 +
 .../rest/binder/lan/UpdateLanRequestBinder.java |   5 +
 .../profitbricks/rest/domain/FirewallRule.java  | 143 ++++++++++++-
 .../profitbricks/rest/features/FirewallApi.java | 130 ++++++++++++
 .../CreateFirewallRuleRequestBinderTest.java    |  71 +++++++
 .../UpdateFirewallRuleRequestBinderTest.java    |  63 ++++++
 .../rest/features/FirewallApiLiveTest.java      | 177 ++++++++++++++++
 .../rest/features/FirewallApiMockTest.java      | 207 +++++++++++++++++++
 .../rest/features/NicApiLiveTest.java           |  17 +-
 .../rest/internal/BaseProfitBricksLiveTest.java |  15 ++
 .../src/test/resources/firewall/get.json        |  24 +++
 .../src/test/resources/firewall/list.json       |  31 +++
 16 files changed, 1025 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/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 881a087..a97dd02 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
@@ -20,6 +20,7 @@ package org.apache.jclouds.profitbricks.rest;
 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.FirewallApi;
 import org.apache.jclouds.profitbricks.rest.features.ImageApi;
 import org.apache.jclouds.profitbricks.rest.features.LanApi;
 import org.apache.jclouds.profitbricks.rest.features.NicApi;
@@ -51,5 +52,8 @@ public interface ProfitBricksApi extends Closeable {
    
    @Delegate
    LanApi lanApi();
+   
+   @Delegate
+   FirewallApi firewallApi();
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/BaseProfitBricksRequestBinder.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/BaseProfitBricksRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/BaseProfitBricksRequestBinder.java
index 3c8753c..d0f4a05 100644
--- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/BaseProfitBricksRequestBinder.java
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/BaseProfitBricksRequestBinder.java
@@ -86,4 +86,9 @@ public abstract class BaseProfitBricksRequestBinder<T> implements MapBinder {
       
       return request;
    }
+   
+   protected void putIfPresent(Map<String, Object> list, String key, Object value) {
+      if (value != null)
+         list.put(key, value);
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinder.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinder.java
new file mode 100644
index 0000000..c62ed6a
--- /dev/null
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinder.java
@@ -0,0 +1,76 @@
+/*
+ * 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.firewall;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import org.jclouds.location.Provider;
+
+public class CreateFirewallRuleRequestBinder extends BaseProfitBricksRequestBinder<FirewallRule.Request.CreatePayload> {
+
+   private String dataCenterId;
+   private String serverId;
+   private String nicId;
+
+   @Inject
+   CreateFirewallRuleRequestBinder(Json jsonBinder,  @Provider Supplier<URI> endpointSupplier) {
+      super("firewallRule", jsonBinder, endpointSupplier);
+   }
+
+   @Override
+   protected String createPayload(FirewallRule.Request.CreatePayload payload) {
+            
+      checkNotNull(payload, "payload");
+      checkNotNull(payload.dataCenterId(), "dataCenterId");
+      checkNotNull(payload.serverId(), "serverId");
+      checkNotNull(payload.nicId(), "nicId");      
+      
+      dataCenterId = payload.dataCenterId();
+      serverId = payload.serverId();
+      nicId = payload.nicId();
+      
+      Map<String, Object> properties = new HashMap<String, Object>();
+      
+      properties.put("protocol",  payload.protocol());
+      
+      putIfPresent(properties, "name", payload.name());
+      putIfPresent(properties, "sourceMac", payload.sourceMac());
+      putIfPresent(properties, "sourceIp", payload.sourceIp());
+      putIfPresent(properties, "targetIp", payload.targetIp());
+      putIfPresent(properties, "icmpCode", payload.icmpCode());
+      putIfPresent(properties, "portRangeStart", payload.portRangeStart());
+      putIfPresent(properties, "portRangeEnd", payload.portRangeEnd());
+            
+      requestBuilder.put("properties", properties);
+      
+      return jsonBinder.toJson(requestBuilder);
+   }
+
+   @Override
+   protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) {
+      return super.createRequest(genRequest(String.format("datacenters/%s/servers/%s/nics/%s/firewallrules", dataCenterId, serverId, nicId), fromRequest), payload);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinder.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinder.java
new file mode 100644
index 0000000..69b7266
--- /dev/null
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinder.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.firewall;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+import java.net.URI;
+import org.apache.jclouds.profitbricks.rest.binder.BaseProfitBricksRequestBinder;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import org.jclouds.location.Provider;
+
+public class UpdateFirewallRuleRequestBinder extends BaseProfitBricksRequestBinder<FirewallRule.Request.UpdatePayload> {
+
+   private String dataCenterId;
+   private String serverId;
+   private String nicId;
+   private String id;
+
+   @Inject
+   UpdateFirewallRuleRequestBinder(Json jsonBinder,  @Provider Supplier<URI> endpointSupplier) {
+      super("firewallRule", jsonBinder, endpointSupplier);
+   }
+
+   @Override
+   protected String createPayload(FirewallRule.Request.UpdatePayload payload) {
+
+      checkNotNull(payload, "payload");
+      checkNotNull(payload.dataCenterId(), "dataCenterId");
+      checkNotNull(payload.serverId(), "serverId");
+      checkNotNull(payload.nicId(), "nicId");
+      checkNotNull(payload.id(), "id");
+      
+      dataCenterId = payload.dataCenterId();
+      serverId = payload.serverId();
+      nicId = payload.nicId();
+      id = payload.id();
+      
+      putIfPresent(requestBuilder, "name", payload.name());
+      putIfPresent(requestBuilder, "sourceMac", payload.sourceMac());
+      putIfPresent(requestBuilder, "sourceIp", payload.sourceIp());
+      putIfPresent(requestBuilder, "targetIp", payload.targetIp());
+      putIfPresent(requestBuilder, "icmpCode", payload.icmpCode());
+      putIfPresent(requestBuilder, "icmpType", payload.icmpType());
+      putIfPresent(requestBuilder, "portRangeStart", payload.portRangeStart());
+      putIfPresent(requestBuilder, "portRangeEnd", payload.portRangeEnd());
+      
+      return jsonBinder.toJson(requestBuilder);
+   }
+
+   @Override
+   protected <R extends HttpRequest> R createRequest(R fromRequest, String payload) {
+      return super.createRequest(genRequest(String.format("datacenters/%s/servers/%s/nics/%s/firewallrules/%s", dataCenterId, serverId, nicId, id), fromRequest), payload);
+   }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/CreateLanRequestBinder.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/CreateLanRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/CreateLanRequestBinder.java
index 2c0cfbe..a4fdb3a 100644
--- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/CreateLanRequestBinder.java
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/CreateLanRequestBinder.java
@@ -16,6 +16,7 @@
  */
 package org.apache.jclouds.profitbricks.rest.binder.lan;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.base.Supplier;
 import com.google.inject.Inject;
 import java.net.URI;
@@ -39,6 +40,9 @@ public class CreateLanRequestBinder extends BaseProfitBricksRequestBinder<Lan.Re
    @Override
    protected String createPayload(Lan.Request.CreatePayload payload) {
 
+      checkNotNull(payload, "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/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/UpdateLanRequestBinder.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/UpdateLanRequestBinder.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/UpdateLanRequestBinder.java
index 1614f30..8298852 100644
--- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/UpdateLanRequestBinder.java
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/binder/lan/UpdateLanRequestBinder.java
@@ -16,6 +16,7 @@
  */
 package org.apache.jclouds.profitbricks.rest.binder.lan;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.base.Supplier;
 import com.google.inject.Inject;
 import java.net.URI;
@@ -38,6 +39,10 @@ public class UpdateLanRequestBinder extends BaseProfitBricksRequestBinder<Lan.Re
    @Override
    protected String createPayload(Lan.Request.UpdatePayload payload) {
 
+      checkNotNull(payload, "payload");
+      checkNotNull(payload.dataCenterId(), "dataCenterId");
+      checkNotNull(payload.id(), "id");
+      
       dataCenterId = payload.dataCenterId();
       lanId = payload.id();
       

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/FirewallRule.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/FirewallRule.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/FirewallRule.java
index 5ecf217..2a0ac1d 100644
--- a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/FirewallRule.java
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/domain/FirewallRule.java
@@ -25,13 +25,24 @@ import org.jclouds.json.SerializedNames;
 public abstract class FirewallRule {
 
     public abstract String id();
+    
+    @Nullable
+    public abstract String dataCenterId();
+    
+    @Nullable
+    public abstract String serverId();
+    
+    @Nullable
+    public abstract String nicId();
 
     public abstract String type();
 
     public abstract String href();
 
+    @Nullable
     public abstract Metadata metadata();
 
+    @Nullable
     public abstract Properties properties();
 
     public enum Protocol {
@@ -45,9 +56,9 @@ public abstract class FirewallRule {
         }
     }   
 
-    @SerializedNames({"id", "type", "href", "metadata", "properties"})
-    public static FirewallRule create(String id, String type, String href, Metadata metadata, Properties properties) {
-        return new AutoValue_FirewallRule(id, type, href, metadata, properties);
+    @SerializedNames({"id", "dataCenterId", "serverId", "nicId", "type", "href", "metadata", "properties"})
+    public static FirewallRule create(String id, String dataCenterId, String serverId, String nicId, String type, String href, Metadata metadata, Properties properties) {
+        return new AutoValue_FirewallRule(id, dataCenterId, serverId, nicId, type, href, metadata, properties);
     }
 
     @AutoValue
@@ -73,7 +84,6 @@ public abstract class FirewallRule {
         public abstract String icmpType();
 
         public abstract int portRangeStart();
-
         public abstract int portRangeEnd();
 
         @SerializedNames({"name", "protocol", "sourceMac", "sourceIp", "targetIp", "icmpCode", "icmpType", "portRangeStart", "portRangeEnd"})
@@ -81,4 +91,129 @@ public abstract class FirewallRule {
             return new AutoValue_FirewallRule_Properties(name, protocol, sourceMac, sourceIp, targetIp, icmpCode, icmpType, portRangeStart, portRangeEnd);
         }
     }
+    
+   public static final class Request {
+
+      public static CreatePayload.Builder creatingBuilder() {
+         return new AutoValue_FirewallRule_Request_CreatePayload.Builder();
+      }
+
+      public static UpdatePayload.Builder updatingBuilder() {
+         return new AutoValue_FirewallRule_Request_UpdatePayload.Builder();
+      }
+
+      @AutoValue
+      public abstract static class CreatePayload {
+
+         @Nullable
+         public abstract String name();
+
+         public abstract Protocol protocol();
+
+         @Nullable
+         public abstract String sourceMac();
+
+         @Nullable
+         public abstract String sourceIp();
+
+         @Nullable
+         public abstract String targetIp();
+
+         @Nullable
+         public abstract String icmpCode();
+
+         @Nullable
+         public abstract String icmpType();
+
+         @Nullable
+         public abstract Integer portRangeStart();
+
+         @Nullable
+         public abstract Integer portRangeEnd();
+
+         public abstract String dataCenterId();
+         public abstract String serverId();
+         public abstract String nicId();
+
+         @AutoValue.Builder
+         public abstract static class Builder {
+
+            public abstract Builder name(String name);
+            public abstract Builder protocol(Protocol protocol);
+            public abstract Builder sourceMac(String sourceMac);
+            public abstract Builder sourceIp(String sourceIp);
+            public abstract Builder targetIp(String targetIp);
+            public abstract Builder icmpCode(String icmpCode);
+            public abstract Builder icmpType(String icmpType);
+            public abstract Builder portRangeStart(Integer portRangeStart);
+            public abstract Builder portRangeEnd(Integer portRangeEnd);
+            public abstract Builder dataCenterId(String dataCenterId);
+            public abstract Builder serverId(String serverId);
+            public abstract Builder nicId(String nicId);
+           
+            abstract CreatePayload autoBuild();
+
+            public CreatePayload build() {
+               return autoBuild();
+            }
+         }
+      }
+
+      @AutoValue
+      public abstract static class UpdatePayload {
+
+         @Nullable
+         public abstract String name();
+
+         @Nullable
+         public abstract String sourceMac();
+
+         @Nullable
+         public abstract String sourceIp();
+
+         @Nullable
+         public abstract String targetIp();
+
+         @Nullable
+         public abstract String icmpCode();
+
+         @Nullable
+         public abstract String icmpType();
+
+         @Nullable
+         public abstract Integer portRangeStart();
+
+         @Nullable
+         public abstract Integer portRangeEnd();
+
+         public abstract String dataCenterId();
+         public abstract String serverId();
+         public abstract String nicId();
+         public abstract String id();
+
+         @AutoValue.Builder
+         public abstract static class Builder {
+            public abstract Builder name(String name);
+            public abstract Builder sourceMac(String sourceMac);
+            public abstract Builder sourceIp(String sourceIp);
+            public abstract Builder targetIp(String targetIp);
+            public abstract Builder icmpCode(String icmpCode);
+            public abstract Builder icmpType(String icmpType);
+            public abstract Builder portRangeStart(Integer portRangeStart);
+            public abstract Builder portRangeEnd(Integer portRangeEnd);
+            public abstract Builder dataCenterId(String dataCenterId);
+            public abstract Builder serverId(String serverId);
+            public abstract Builder nicId(String nicId);
+            public abstract Builder id(String id);
+           
+            abstract UpdatePayload autoBuild();
+
+            public UpdatePayload build() {
+               return autoBuild();
+            }
+         }
+      }
+      
+   }
+   
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/FirewallApi.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/FirewallApi.java b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/FirewallApi.java
new file mode 100644
index 0000000..984c6f7
--- /dev/null
+++ b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/features/FirewallApi.java
@@ -0,0 +1,130 @@
+/*
+ * 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 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.firewall.CreateFirewallRuleRequestBinder;
+import org.apache.jclouds.profitbricks.rest.binder.firewall.UpdateFirewallRuleRequestBinder;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+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("/datacenters/{dataCenterId}/servers/{serverId}/nics/{nicId}/firewallrules")
+@RequestFilters(BasicAuthentication.class)
+public interface FirewallApi extends Closeable {
+   
+   @Named("firewallRule:list")
+   @GET
+   @SelectJson("items")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<FirewallRule> list(@PathParam("dataCenterId") String dataCenterId, @PathParam("serverId") String serverId, @PathParam("nicId") String nicId);
+
+   @Named("firewallRule:list")
+   @GET
+   @SelectJson("items")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<FirewallRule> list(@PathParam("dataCenterId") String dataCenterId, @PathParam("serverId") String serverId, @PathParam("nicId") String nicId, DepthOptions options);
+   
+   @Named("firewallRule:get")
+   @GET   
+   @Path("/{firewallRuleId}")
+   @ResponseParser(FirewallApi.FirewallRuleParser.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   FirewallRule get(@PathParam("dataCenterId") String dataCenterId, @PathParam("serverId") String serverId, @PathParam("nicId") String nicId, @PathParam("firewallRuleId") String firewallRuleId);
+
+   @Named("firewallRule:get")
+   @GET   
+   @Path("/{firewallRuleId}")
+   @ResponseParser(FirewallApi.FirewallRuleParser.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   FirewallRule get(@PathParam("dataCenterId") String dataCenterId, @PathParam("serverId") String serverId, @PathParam("nicId") String nicId, @PathParam("firewallRuleId") String firewallRuleId, DepthOptions options);
+   
+   @Named("firewallRule:create")
+   @POST
+   @MapBinder(CreateFirewallRuleRequestBinder.class)
+   @ResponseParser(FirewallApi.FirewallRuleParser.class)
+   FirewallRule create(@PayloadParam("firewallRule") FirewallRule.Request.CreatePayload payload);
+   
+   @Named("firewallRule:update")
+   @PATCH
+   @MapBinder(UpdateFirewallRuleRequestBinder.class)
+   @ResponseParser(FirewallApi.FirewallRuleParser.class)
+   @Produces("application/vnd.profitbricks.partial-properties+json")
+   FirewallRule update(@PayloadParam("firewallRule") FirewallRule.Request.UpdatePayload payload);
+   
+   @Named("firewallRule:delete")
+   @DELETE
+   @Path("/{firewallRuleId}")
+   @Fallback(Fallbacks.VoidOnNotFoundOr404.class)
+   void delete(@PathParam("dataCenterId") String dataCenterId, @PathParam("serverId") String serverId, @PathParam("nicId") String nicId, @PathParam("firewallRuleId") String firewallRuleId);
+   
+   static final class FirewallRuleParser extends ParseJson<FirewallRule> {
+      
+      private final ParseId parseService;
+            
+      @Inject FirewallRuleParser(Json json, ParseId parseId) {
+         super(json, TypeLiteral.get(FirewallRule.class));
+         this.parseService = parseId;
+      }
+      
+      @Override      
+      public <V> V apply(InputStream stream, Type type) throws IOException {
+         try {
+            return (V) json.fromJson(
+               this.parseService.parseId(
+                  this.parseService.parseId(
+                     this.parseService.parseId(Strings2.toStringAndClose(stream), "datacenters", "dataCenterId"),
+                     "servers", "serverId"
+                  ),
+                  "nics", "nicId"
+               )
+            , type);
+         } finally {
+            if (stream != null)
+               stream.close();
+         }
+      }
+      
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinderTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinderTest.java
new file mode 100644
index 0000000..ce74db1
--- /dev/null
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/CreateFirewallRuleRequestBinderTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.firewall;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.jclouds.profitbricks.rest.binder.BinderTestBase;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "CreateFirewallRuleRequestBinderTest")
+public class CreateFirewallRuleRequestBinderTest extends BinderTestBase {
+   
+   @Test
+   public void testUpdatePayload() {
+            
+      CreateFirewallRuleRequestBinder binder = injector.getInstance(CreateFirewallRuleRequestBinder.class);
+      
+      FirewallRule.Request.CreatePayload payload = FirewallRule.Request.creatingBuilder()
+         .dataCenterId("datacenter-id")
+         .serverId("server-id")
+         .nicId("nic-id")
+         .name("jclouds-firewall")
+         .protocol(FirewallRule.Protocol.TCP)
+         .portRangeStart(1)
+         .portRangeEnd(600)
+         .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/v2/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules");
+      assertNotNull(actual, "Binder returned null payload");
+      
+      Json json = injector.getInstance(Json.class);
+      
+      Map<String, Object> properties = new HashMap<String, Object>();
+      properties.put("name", "jclouds-firewall");
+      properties.put("protocol", FirewallRule.Protocol.TCP);
+      properties.put("portRangeStart", 1);
+      properties.put("portRangeEnd", 600);
+      
+      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/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinderTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinderTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinderTest.java
new file mode 100644
index 0000000..49c0646
--- /dev/null
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/binder/firewall/UpdateFirewallRuleRequestBinderTest.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.firewall;
+
+import java.util.HashMap;
+import org.apache.jclouds.profitbricks.rest.binder.BinderTestBase;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "UpdateFirewallRuleRequestBinderTest")
+public class UpdateFirewallRuleRequestBinderTest extends BinderTestBase {
+   
+   @Test
+   public void testUpdatePayload() {
+            
+      UpdateFirewallRuleRequestBinder binder = injector.getInstance(UpdateFirewallRuleRequestBinder.class);
+      
+      FirewallRule.Request.UpdatePayload payload = FirewallRule.Request.updatingBuilder()
+         .dataCenterId("datacenter-id")
+         .serverId("server-id")
+         .nicId("nic-id")
+         .id("id")
+         .name("apache-firewall")
+         .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/v2/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/id");
+      assertNotNull(actual, "Binder returned null payload");
+      
+      Json json = injector.getInstance(Json.class);
+      
+      HashMap<String, Object> expectedPayload = new HashMap<String, Object>();
+      
+      expectedPayload.put("name", "apache-firewall");
+      
+      assertEquals(actual, json.toJson(expectedPayload));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiLiveTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiLiveTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiLiveTest.java
new file mode 100644
index 0000000..30912ca
--- /dev/null
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiLiveTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import java.util.List;
+import org.apache.jclouds.profitbricks.rest.domain.DataCenter;
+import org.apache.jclouds.profitbricks.rest.domain.State;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.apache.jclouds.profitbricks.rest.domain.Nic;
+import org.apache.jclouds.profitbricks.rest.domain.Server;
+import org.apache.jclouds.profitbricks.rest.ids.ServerRef;
+import org.apache.jclouds.profitbricks.rest.internal.BaseProfitBricksLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "live", testName = "FirewallApiLiveTest")
+public class FirewallApiLiveTest extends BaseProfitBricksLiveTest {
+   
+   private DataCenter dataCenter;
+   private Server testServer;
+   private Nic testNic;
+   private FirewallRule testFirewallRule;
+  
+   @BeforeClass
+   public void setupTest() {
+      dataCenter = createDataCenter();
+      assertDataCenterAvailable(dataCenter);
+            
+      testServer = api.serverApi().createServer(
+         Server.Request.creatingBuilder()
+            .dataCenterId(dataCenter.id())
+            .name("jclouds-node")
+            .cores(1)
+            .ram(1024)
+            .build());
+      
+      assertNodeAvailable(ServerRef.create(dataCenter.id(), testServer.id()));
+            
+      testNic = nicApi().create(
+              Nic.Request.creatingBuilder()
+              .dataCenterId(dataCenter.id())
+              .serverId(testServer.id())
+              .name("jclouds-nic")
+              .lan(1)
+              .build());
+
+      assertNicAvailable(testNic);
+   }
+   
+   @AfterClass(alwaysRun = true)
+   public void teardownTest() {
+      if (dataCenter != null)
+         deleteDataCenter(dataCenter.id());
+   }
+     
+   @Test
+   public void testCreateFirewallRule() {
+      assertNotNull(dataCenter);
+            
+      testFirewallRule = firewallApi().create(
+              FirewallRule.Request.creatingBuilder()
+              .dataCenterId(dataCenter.id())
+              .serverId(testServer.id())
+              .nicId(testNic.id())
+              .name("jclouds-firewall")
+              .protocol(FirewallRule.Protocol.TCP)
+              .portRangeStart(1)
+              .portRangeEnd(600)
+              .build());
+
+      assertNotNull(testFirewallRule);
+      assertEquals(testFirewallRule.properties().name(), "jclouds-firewall");
+      assertFirewallRuleAvailable(testFirewallRule);
+   }
+   
+
+   @Test(dependsOnMethods = "testCreateFirewallRule")
+   public void testGetFirewallRule() {
+      FirewallRule firewallRule = firewallApi().get(dataCenter.id(), testServer.id(), testNic.id(), testFirewallRule.id());
+
+      assertNotNull(firewallRule);
+      assertEquals(firewallRule.id(), testFirewallRule.id());
+   }
+
+   @Test(dependsOnMethods = "testCreateFirewallRule")
+   public void testListRules() {
+      List<FirewallRule> firewalls = firewallApi().list(dataCenter.id(), testServer.id(), testNic.id());
+
+      assertNotNull(firewalls);
+      assertFalse(firewalls.isEmpty());
+      assertTrue(Iterables.any(firewalls, new Predicate<FirewallRule>() {
+         @Override public boolean apply(FirewallRule input) {
+            return input.id().equals(testFirewallRule.id());
+         }
+      }));
+   }
+   
+   @Test(dependsOnMethods = "testCreateFirewallRule")
+   public void testUpdateFirewallRule() {
+      assertDataCenterAvailable(dataCenter);
+      
+      firewallApi().update(FirewallRule.Request.updatingBuilder()
+              .dataCenterId(testFirewallRule.dataCenterId())
+              .serverId(testServer.id())
+              .nicId(testNic.id())
+              .id(testFirewallRule.id())
+              .name("apache-firewall")
+              .build());
+
+      assertFirewallRuleAvailable(testFirewallRule);
+      
+      FirewallRule firewallRule = firewallApi().get(dataCenter.id(), testServer.id(), testNic.id(), testFirewallRule.id());
+      
+      assertEquals(firewallRule.properties().name(), "apache-firewall");
+   }
+   
+
+   @Test(dependsOnMethods = "testUpdateFirewallRule")
+   public void testDeleteFirewallRule() {
+      firewallApi().delete(testFirewallRule.dataCenterId(), testServer.id(), testNic.id(), testFirewallRule.id());
+      assertFirewallRuleRemoved(testFirewallRule);
+   } 
+   
+   private void assertFirewallRuleAvailable(FirewallRule firewallRule) {
+      assertPredicate(new Predicate<FirewallRule>() {
+         @Override
+         public boolean apply(FirewallRule testRule) {
+            FirewallRule firewallRule = firewallApi().get(testRule.dataCenterId(), testRule.serverId(), testRule.nicId(), testRule.id());
+            
+            if (firewallRule == null || firewallRule.metadata() == null)
+               return false;
+            
+            return firewallRule.metadata().state() == State.AVAILABLE;
+         }
+      }, firewallRule);
+   }
+   
+   private void assertFirewallRuleRemoved(FirewallRule firewallRule) {
+      assertPredicate(new Predicate<FirewallRule>() {
+         @Override
+         public boolean apply(FirewallRule testRule) {
+            return firewallApi().get(testRule.dataCenterId(), testRule.serverId(), testRule.nicId(), testRule.id()) == null;
+         }
+      }, firewallRule);
+   }
+     
+   private FirewallApi firewallApi() {
+      return api.firewallApi();
+   }   
+           
+   private NicApi nicApi() {
+      return api.nicApi();
+   }
+   
+   
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiMockTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiMockTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiMockTest.java
new file mode 100644
index 0000000..4f80679
--- /dev/null
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/FirewallApiMockTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.squareup.okhttp.mockwebserver.MockResponse;
+import java.util.List;
+import org.apache.jclouds.profitbricks.rest.domain.FirewallRule;
+import org.apache.jclouds.profitbricks.rest.domain.options.DepthOptions;
+import org.apache.jclouds.profitbricks.rest.internal.BaseProfitBricksApiMockTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "FirewallApiMockTest", singleThreaded = true)
+public class FirewallApiMockTest extends BaseProfitBricksApiMockTest {
+   
+   @Test
+   public void testGeRuleList() throws InterruptedException {
+      server.enqueue(
+         new MockResponse().setBody(stringFromResource("/firewall/list.json"))
+      );
+      
+      List<FirewallRule> list = firewallApi().list("datacenter-id", "server-id", "nic-id");
+      
+      assertNotNull(list);
+      assertEquals(list.size(), 1);
+      assertEquals(list.get(0).properties().name(), "apache-firewall");
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules");
+   }
+   
+   @Test
+   public void testGeRuleListWithDepth() throws InterruptedException {
+      server.enqueue(
+         new MockResponse().setBody(stringFromResource("/firewall/list.json"))
+      );
+      
+      List<FirewallRule> list = firewallApi().list("datacenter-id", "server-id", "nic-id", new DepthOptions().depth(3));
+      
+      assertNotNull(list);
+      assertEquals(list.size(), 1);
+      assertEquals(list.get(0).properties().name(), "apache-firewall");
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules?depth=3");
+   }
+
+   @Test
+   public void testGetRuleListWith404() throws InterruptedException {
+      server.enqueue(response404());
+      List<FirewallRule> list = firewallApi().list("datacenter-id", "server-id", "nic-id");
+      assertTrue(list.isEmpty());
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules");
+   }
+   
+   @Test
+   public void testGetRuleListWith404AndDepth() throws InterruptedException {
+      server.enqueue(response404());
+      List<FirewallRule> list = firewallApi().list("datacenter-id", "server-id", "nic-id", new DepthOptions().depth(1));
+      assertTrue(list.isEmpty());
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules?depth=1");
+   }
+    
+   @Test
+   public void testGetFirewallRule() throws InterruptedException {
+      MockResponse response = new MockResponse();
+      response.setBody(stringFromResource("/firewall/get.json"));
+      response.setHeader("Content-Type", "application/vnd.profitbricks.resource+json");
+      
+      server.enqueue(response);
+      
+      FirewallRule firewallRule = firewallApi().get("datacenter-id", "server-id", "nic-id", "some-id");
+      
+      assertNotNull(firewallRule);
+      assertEquals(firewallRule.properties().name(), "apache-firewall");
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id");
+   }
+   
+   public void testGetFirewallRuleWithDepth() throws InterruptedException {
+      MockResponse response = new MockResponse();
+      response.setBody(stringFromResource("/firewall/get.json"));
+      response.setHeader("Content-Type", "application/vnd.profitbricks.resource+json");
+      
+      server.enqueue(response);
+      
+      FirewallRule firewallRule = firewallApi().get("datacenter-id", "server-id", "nic-id", "some-id", new DepthOptions().depth(3));
+      
+      assertNotNull(firewallRule);
+      assertEquals(firewallRule.properties().name(), "apache-firewall");
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id?depth=3");
+   }
+   
+   public void testGetFirewallRuleWith404() throws InterruptedException {
+      server.enqueue(response404());
+
+      FirewallRule firewallRule = firewallApi().get("datacenter-id", "server-id", "nic-id", "some-id");
+      
+      assertEquals(firewallRule, null);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id");
+   }
+   
+   public void testGetFirewallRuleWith404AndDepth() throws InterruptedException {
+      server.enqueue(response404());
+
+      FirewallRule firewallRule = firewallApi().get("datacenter-id", "server-id", "nic-id", "some-id", new DepthOptions().depth(2));
+      
+      assertEquals(firewallRule, null);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id?depth=2");
+   }
+   
+   @Test
+   public void testCreateRule() throws InterruptedException {
+      server.enqueue(
+         new MockResponse().setBody(stringFromResource("/firewall/get.json"))
+      );
+      
+      FirewallRule firewallRule = firewallApi().create(
+              FirewallRule.Request.creatingBuilder()
+              .dataCenterId("datacenter-id")
+              .serverId("server-id")
+              .nicId("nic-id")
+              .name("jclouds-firewall")
+              .protocol(FirewallRule.Protocol.TCP)
+              .portRangeStart(20)
+              .portRangeEnd(80)
+              .build());
+
+      assertNotNull(firewallRule);
+      assertNotNull(firewallRule.id());
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules", 
+              "{\"properties\": {\"name\": \"jclouds-firewall\", \"protocol\": \"TCP\", \"portRangeStart\": 20, \"portRangeEnd\": 80}}"
+      );
+   }
+   
+   @Test
+   public void testUpdateRule() throws InterruptedException {
+      server.enqueue(
+         new MockResponse().setBody(stringFromResource("/firewall/get.json"))
+      );
+      
+      api.firewallApi().update(
+              FirewallRule.Request.updatingBuilder()
+              .id("some-id")
+              .dataCenterId("datacenter-id")
+              .serverId("server-id")
+              .nicId("nic-id")
+              .name("apache-firewall")
+              .build());
+            
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PATCH", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id", "{\"name\": \"apache-firewall\"}");
+   }
+   
+   @Test
+   public void testDeleteRule() throws InterruptedException {
+      server.enqueue(
+         new MockResponse().setBody("")
+      );
+      
+      firewallApi().delete("datacenter-id", "server-id", "nic-id", "some-id");
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id");
+   }
+   
+   @Test
+   public void testDeleteRuleWith404() throws InterruptedException {
+      server.enqueue(response404());
+
+      firewallApi().delete("datacenter-id", "server-id", "nic-id", "some-id");
+      
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/datacenters/datacenter-id/servers/server-id/nics/nic-id/firewallrules/some-id");
+   }
+           
+   private FirewallApi firewallApi() {
+      return api.firewallApi();
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/NicApiLiveTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/NicApiLiveTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/NicApiLiveTest.java
index b2f4860..ceb9ab3 100644
--- a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/NicApiLiveTest.java
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/NicApiLiveTest.java
@@ -19,7 +19,6 @@ package org.apache.jclouds.profitbricks.rest.features;
 import com.google.common.base.Predicate;
 import java.util.List;
 import org.apache.jclouds.profitbricks.rest.domain.DataCenter;
-import org.apache.jclouds.profitbricks.rest.domain.State;
 import org.apache.jclouds.profitbricks.rest.domain.Nic;
 import org.apache.jclouds.profitbricks.rest.domain.Server;
 import org.apache.jclouds.profitbricks.rest.ids.ServerRef;
@@ -120,21 +119,7 @@ public class NicApiLiveTest extends BaseProfitBricksLiveTest {
       nicApi().delete(testNic.dataCenterId(), testServer.id(), testNic.id());
       assertNicRemoved(testNic);
    } 
-   
-   private void assertNicAvailable(Nic nic) {
-      assertPredicate(new Predicate<Nic>() {
-         @Override
-         public boolean apply(Nic testNic) {
-            Nic nic = nicApi().get(testNic.dataCenterId(), testNic.serverId(), testNic.id());
-            
-            if (nic == null || nic.metadata() == null)
-               return false;
-            
-            return nic.metadata().state() == State.AVAILABLE;
-         }
-      }, nic);
-   }
-   
+      
    private void assertNicRemoved(Nic nic) {
       assertPredicate(new Predicate<Nic>() {
          @Override

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/internal/BaseProfitBricksLiveTest.java
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/internal/BaseProfitBricksLiveTest.java b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/internal/BaseProfitBricksLiveTest.java
index 79b7f92..74dde47 100644
--- a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/internal/BaseProfitBricksLiveTest.java
+++ b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/internal/BaseProfitBricksLiveTest.java
@@ -33,6 +33,7 @@ import static org.apache.jclouds.profitbricks.rest.config.ProfitBricksComputePro
 import org.apache.jclouds.profitbricks.rest.domain.DataCenter;
 import org.apache.jclouds.profitbricks.rest.domain.LicenceType;
 import org.apache.jclouds.profitbricks.rest.domain.Location;
+import org.apache.jclouds.profitbricks.rest.domain.Nic;
 import org.apache.jclouds.profitbricks.rest.domain.Server;
 import org.apache.jclouds.profitbricks.rest.domain.State;
 import org.apache.jclouds.profitbricks.rest.domain.Volume;
@@ -157,6 +158,20 @@ public class BaseProfitBricksLiveTest extends BaseApiLiveTest<ProfitBricksApi> {
               String.format("Volume %s wasn't available in the configured timeout", volumeRef.volumeId()));
    }
    
+   protected void assertNicAvailable(Nic nic) {
+      assertPredicate(new Predicate<Nic>() {
+         @Override
+         public boolean apply(Nic testNic) {
+            Nic nic = api.nicApi().get(testNic.dataCenterId(), testNic.serverId(), testNic.id());
+            
+            if (nic == null || nic.metadata() == null)
+               return false;
+            
+            return nic.metadata().state() == State.AVAILABLE;
+         }
+      }, nic);
+   }
+   
    protected DataCenter createDataCenter() {
       return api.dataCenterApi().create("test-data-center", "example description", TestLocation.value());
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/resources/firewall/get.json
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/resources/firewall/get.json b/profitbricks-rest/src/test/resources/firewall/get.json
new file mode 100644
index 0000000..51efd70
--- /dev/null
+++ b/profitbricks-rest/src/test/resources/firewall/get.json
@@ -0,0 +1,24 @@
+{
+  "id": "e6389079-3dc7-4041-9c97-dfb56ee49925",
+  "type": "firewall-rule",
+  "href": "https://api.profitbricks.com/rest/datacenters/f38043f0-331d-49e7-b2b8-8319b11d3869/servers/158b2fb1-e8d6-4a87-8244-fd4ad36bb5a2/nics/751dec13-b89f-44ff-a1f8-fa6916a98075/firewallrules/e6389079-3dc7-4041-9c97-dfb56ee49925",
+  "metadata": {
+    "createdDate": "2015-12-30T07:45:50Z",
+    "createdBy": "mirza@stackpointcloud.com",
+    "etag": "9790223e2920abfecde0d3a72acf962f",
+    "lastModifiedDate": "2015-12-30T07:46:01Z",
+    "lastModifiedBy": "mirza@stackpointcloud.com",
+    "state": "AVAILABLE"
+  },
+  "properties": {
+    "name": "apache-firewall",
+    "protocol": "TCP",
+    "sourceMac": null,
+    "sourceIp": null,
+    "targetIp": null,
+    "icmpCode": null,
+    "icmpType": null,
+    "portRangeStart": 1,
+    "portRangeEnd": 600
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/5b757ee4/profitbricks-rest/src/test/resources/firewall/list.json
----------------------------------------------------------------------
diff --git a/profitbricks-rest/src/test/resources/firewall/list.json b/profitbricks-rest/src/test/resources/firewall/list.json
new file mode 100644
index 0000000..b0bf323
--- /dev/null
+++ b/profitbricks-rest/src/test/resources/firewall/list.json
@@ -0,0 +1,31 @@
+{
+  "id": "751dec13-b89f-44ff-a1f8-fa6916a98075/firewallrules",
+  "type": "collection",
+  "href": "https://api.profitbricks.com/rest/datacenters/f38043f0-331d-49e7-b2b8-8319b11d3869/servers/158b2fb1-e8d6-4a87-8244-fd4ad36bb5a2/nics/751dec13-b89f-44ff-a1f8-fa6916a98075/firewallrules",
+  "items": [
+    {
+      "id": "e6389079-3dc7-4041-9c97-dfb56ee49925",
+      "type": "firewall-rule",
+      "href": "https://api.profitbricks.com/rest/datacenters/f38043f0-331d-49e7-b2b8-8319b11d3869/servers/158b2fb1-e8d6-4a87-8244-fd4ad36bb5a2/nics/751dec13-b89f-44ff-a1f8-fa6916a98075/firewallrules/e6389079-3dc7-4041-9c97-dfb56ee49925",
+      "metadata": {
+        "createdDate": "2015-12-30T07:45:50Z",
+        "createdBy": "mirza@stackpointcloud.com",
+        "etag": "9790223e2920abfecde0d3a72acf962f",
+        "lastModifiedDate": "2015-12-30T07:46:01Z",
+        "lastModifiedBy": "mirza@stackpointcloud.com",
+        "state": "AVAILABLE"
+      },
+      "properties": {
+        "name": "apache-firewall",
+        "protocol": "TCP",
+        "sourceMac": null,
+        "sourceIp": null,
+        "targetIp": null,
+        "icmpCode": null,
+        "icmpType": null,
+        "portRangeStart": 1,
+        "portRangeEnd": 600
+      }
+    }
+  ]
+}
\ No newline at end of file


[2/2] jclouds-labs git commit: Make DockerTemplateOptions values null safe

Posted by na...@apache.org.
Make DockerTemplateOptions values null safe


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/44ddd688
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/44ddd688
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/44ddd688

Branch: refs/heads/master
Commit: 44ddd688f8d5b1cb8c4fac37eca3da7ce7f00359
Parents: 5b757ee
Author: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Authored: Thu Apr 14 21:05:34 2016 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Tue Apr 19 17:01:18 2016 +0200

----------------------------------------------------------------------
 .../compute/options/DockerTemplateOptions.java  | 22 ++++++++++----------
 .../jclouds/docker/internal/NullSafeCopies.java |  8 +++++++
 2 files changed, 19 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/44ddd688/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java
----------------------------------------------------------------------
diff --git a/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java b/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java
index bff0d9c..8a42253 100644
--- a/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java
+++ b/docker/src/main/java/org/jclouds/docker/compute/options/DockerTemplateOptions.java
@@ -83,15 +83,15 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable
    private static final String NO_IMAGE = "jclouds-placeholder-for-image";
 
    protected List<String> dns = ImmutableList.of();
-   protected String hostname;
-   protected Integer memory;
-   protected Integer cpuShares;
-   protected List<String> entrypoint = ImmutableList.of();
-   protected List<String> commands = ImmutableList.of();
+   @Nullable protected String hostname;
+   @Nullable protected Integer memory;
+   @Nullable protected Integer cpuShares;
+   @Nullable List<String> entrypoint;
+   @Nullable List<String> commands;
    protected Map<String, String> volumes = ImmutableMap.of();
-   protected List<String> env = ImmutableList.of();
+   @Nullable protected List<String> env;
    protected Map<Integer, Integer> portBindings = ImmutableMap.of();
-   protected String networkMode;
+   @Nullable protected String networkMode;
    protected Map<String, String> extraHosts = ImmutableMap.of();
    protected List<String> volumesFrom = ImmutableList.of();
    protected boolean privileged;
@@ -189,12 +189,12 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable
    }
 
    public DockerTemplateOptions dns(Iterable<String> dns) {
-      this.dns = NullSafeCopies.copyWithNullOf(dns);
+      this.dns = NullSafeCopies.copyOf(dns);
       return this;
    }
 
    public DockerTemplateOptions dns(String...dns) {
-      this.dns = NullSafeCopies.copyWithNullOf(dns);
+      this.dns = NullSafeCopies.copyOf(dns);
       return this;
    }
 
@@ -278,7 +278,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable
     * @param extraHosts the map of host names to IP addresses
     */
    public DockerTemplateOptions extraHosts(Map<String, String> extraHosts) {
-      this.extraHosts = NullSafeCopies.copyWithNullOf(extraHosts);
+      this.extraHosts = NullSafeCopies.copyOf(extraHosts);
       return this;
    }
 
@@ -288,7 +288,7 @@ public class DockerTemplateOptions extends TemplateOptions implements Cloneable
     * @param volumesFrom the list of container names
     */
    public DockerTemplateOptions volumesFrom(Iterable<String> volumesFrom) {
-      this.volumesFrom = NullSafeCopies.copyWithNullOf(volumesFrom);
+      this.volumesFrom = NullSafeCopies.copyOf(volumesFrom);
       return this;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/44ddd688/docker/src/main/java/org/jclouds/docker/internal/NullSafeCopies.java
----------------------------------------------------------------------
diff --git a/docker/src/main/java/org/jclouds/docker/internal/NullSafeCopies.java b/docker/src/main/java/org/jclouds/docker/internal/NullSafeCopies.java
index b6e190c..f3d9eb8 100644
--- a/docker/src/main/java/org/jclouds/docker/internal/NullSafeCopies.java
+++ b/docker/src/main/java/org/jclouds/docker/internal/NullSafeCopies.java
@@ -34,6 +34,14 @@ public class NullSafeCopies {
       return list != null ? ImmutableList.copyOf(list) : ImmutableList.<E> of();
    }
 
+   public static <E> List<E> copyOf(@Nullable Iterable<E> list) {
+      return list != null ? ImmutableList.copyOf(list) : ImmutableList.<E> of();
+   }
+
+   public static <E> List<E> copyOf(@Nullable E[] array) {
+      return array != null ? ImmutableList.copyOf(array) : ImmutableList.<E> of();
+   }
+
    /**
     * Copies given List with keeping null value if provided.
     *