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/06/07 20:39:02 UTC

[2/2] jclouds-labs git commit: Network Security Group API

Network Security Group 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/016f6e0c
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/016f6e0c
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/016f6e0c

Branch: refs/heads/master
Commit: 016f6e0cc79e6f26ef9f9e2cdc099391db5d9e0d
Parents: 7e55ad7
Author: Jim Spring <jm...@gmail.com>
Authored: Mon Jun 6 08:12:58 2016 -0700
Committer: Ignasi Barrera <na...@apache.org>
Committed: Tue Jun 7 22:25:16 2016 +0200

----------------------------------------------------------------------
 .../azurecompute/arm/AzureComputeApi.java       |  20 +-
 .../arm/domain/NetworkSecurityGroup.java        |  54 +++++
 .../domain/NetworkSecurityGroupProperties.java  |  85 ++++++++
 .../arm/domain/NetworkSecurityRule.java         |  46 ++++
 .../domain/NetworkSecurityRuleProperties.java   | 143 ++++++++++++
 .../arm/features/NetworkSecurityGroupApi.java   |  85 ++++++++
 .../arm/features/NetworkSecurityRuleApi.java    |  94 ++++++++
 .../NetworkSecurityGroupApiLiveTest.java        | 152 +++++++++++++
 .../NetworkSecurityGroupApiMockTest.java        | 165 ++++++++++++++
 .../NetworkSecurityRuleApiLiveTest.java         | 217 +++++++++++++++++++
 .../NetworkSecurityRuleApiMockTest.java         | 206 ++++++++++++++++++
 .../resources/networksecuritygroupcreate.json   | 125 +++++++++++
 .../test/resources/networksecuritygroupget.json | 125 +++++++++++
 .../resources/networksecuritygrouplist.json     | 127 +++++++++++
 .../resources/networksecurityrulecreate.json    |  17 ++
 .../test/resources/networksecurityruleget.json  |  17 ++
 .../networksecurityrulegetdefault.json          |  17 ++
 .../test/resources/networksecurityrulelist.json |  35 +++
 .../networksecurityrulelistdefault.json         |  99 +++++++++
 19 files changed, 1828 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
index 4e10089..c39022e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
@@ -29,6 +29,8 @@ import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
 import org.jclouds.azurecompute.arm.features.VMSizeApi;
 import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
+import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
 import org.jclouds.rest.annotations.Delegate;
 
 import com.google.inject.Provides;
@@ -137,7 +139,23 @@ public interface AzureComputeApi extends Closeable {
    @Delegate
    DeploymentApi getDeploymentApi(@PathParam("resourcegroup") String resourceGroup);
 
+   /**
+    * The NetworkSecurityGroup API includes operations for managing network security groups within your subscription.
+    *
+    * @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt163615.aspx">docs</a>
+    */
+   @Delegate
+   NetworkSecurityGroupApi getNetworkSecurityGroupApi(@PathParam("resourcegroup") String resourcegroup);
+ 
+   /**
+    * The NetworkSecurityRule API includes operations for managing network security rules within a network security group.
+    *
+    * @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt163580.aspx">docs</a>
+    */
+   @Delegate
+   NetworkSecurityRuleApi getNetworkSecurityRuleApi(@PathParam("resourcegroup") String resourcegroup,
+                                                    @PathParam("networksecuritygroup") String networksecuritygroup);
+
    @Provides
    DeploymentTemplateBuilder.Factory deploymentTemplateFactory();
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroup.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroup.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroup.java
new file mode 100644
index 0000000..ebe842e
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroup.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.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+import java.util.Map;
+
+@AutoValue
+public abstract class NetworkSecurityGroup {
+   @Nullable
+   public abstract String name();
+
+   @Nullable
+   public abstract String location();
+
+   @Nullable
+   public abstract Map<String, String> tags();
+
+   @Nullable
+   public abstract NetworkSecurityGroupProperties properties();
+
+   @Nullable
+   public abstract String etag();
+
+   @SerializedNames({"name", "location", "tags", "properties", "etag"})
+   public static NetworkSecurityGroup create(final String name,
+                                             final String location,
+                                             final Map<String, String> tags,
+                                             final NetworkSecurityGroupProperties properties,
+                                             final String etag) {
+      return new AutoValue_NetworkSecurityGroup(name, location,
+                                                (tags == null) ? null : ImmutableMap.copyOf(tags),
+                                                properties, etag);
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroupProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroupProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroupProperties.java
new file mode 100644
index 0000000..f81ab0f
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityGroupProperties.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+@AutoValue
+public abstract class NetworkSecurityGroupProperties {
+
+   @Nullable
+   public abstract List<NetworkSecurityRule> securityRules();
+
+   @Nullable
+   public abstract List<NetworkSecurityRule> defaultSecurityRules();
+
+   @Nullable
+   public abstract List<NetworkInterfaceCard> networkInterfaces();
+
+   @Nullable
+   public abstract List<Subnet> subnets();
+
+   @Nullable
+   public abstract String resourceGuid();
+
+   @Nullable
+   public abstract String provisioningState();
+
+   @SerializedNames({"securityRules", "defaultSecurityRules", "networkInterfaces", "subnets", "resourceGuid", "provisioningState"})
+   public static NetworkSecurityGroupProperties create(final List<NetworkSecurityRule> securityRules,
+                                          final List<NetworkSecurityRule> defaultSecurityRules,
+                                          final List<NetworkInterfaceCard> networkInterfaces,
+                                          final List<Subnet> subnets,
+                                          final String resourceGuid,
+                                          final String provisioningState) {
+      return builder()
+              .securityRules((securityRules == null) ? null : ImmutableList.copyOf(securityRules))
+              .defaultSecurityRules((defaultSecurityRules == null) ? null : ImmutableList.copyOf(defaultSecurityRules))
+              .networkInterfaces((networkInterfaces == null) ? null : ImmutableList.copyOf(networkInterfaces))
+              .subnets((subnets == null) ? null : ImmutableList.copyOf(subnets))
+              .resourceGuid(resourceGuid)
+              .provisioningState(provisioningState)
+              .build();
+   }
+
+   public static Builder builder() {
+      return new AutoValue_NetworkSecurityGroupProperties.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder securityRules(List<NetworkSecurityRule> securityRules);
+
+      public abstract Builder defaultSecurityRules(List<NetworkSecurityRule> securityRules);
+
+      public abstract Builder networkInterfaces(List<NetworkInterfaceCard> networkInterfaces);
+
+      public abstract Builder subnets(List<Subnet> subnets);
+
+      public abstract Builder resourceGuid(String resourceGuid);
+
+      public abstract Builder provisioningState(String provisioningState);
+
+      public abstract NetworkSecurityGroupProperties build();
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRule.java
new file mode 100644
index 0000000..857a568
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRule.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class NetworkSecurityRule {
+
+   @Nullable
+   public abstract String name();
+
+   @Nullable
+   public abstract String id();
+
+   @Nullable
+   public abstract String etag();
+
+   @Nullable
+   public abstract NetworkSecurityRuleProperties properties();
+
+   @SerializedNames({"name", "id", "etag", "properties"})
+   public static NetworkSecurityRule create(final String name,
+                                            final String id,
+                                            final String etag,
+                                            final NetworkSecurityRuleProperties properties) {
+      return new AutoValue_NetworkSecurityRule(name, id, etag, properties);
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRuleProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRuleProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRuleProperties.java
new file mode 100644
index 0000000..0710503
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkSecurityRuleProperties.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+@AutoValue
+public abstract class NetworkSecurityRuleProperties {
+   public enum Protocol {
+      // * is an allowed value, will handle in
+      Tcp("Tcp"),
+      Udp("Udp"),
+      All("*"),
+      UNRECOGNIZED("Unrecognized");
+
+      private final String label;
+
+      private Protocol(String label) { this.label = label; }
+
+      public static Protocol fromValue(final String text) {
+         if ("*".equals(text)) {
+            return All;
+         } else {
+            return (Protocol) GetEnumValue.fromValueOrDefault(text, Protocol.UNRECOGNIZED);
+         }
+      }
+
+      @Override
+      public String toString() {
+         return label;
+      }
+   }
+
+   public enum Access {
+      Allow,
+      Deny,
+      UNRECOGNIZED;
+
+      public static Access fromValue(final String text) {
+         return (Access) GetEnumValue.fromValueOrDefault(text, Access.UNRECOGNIZED);
+      }
+   }
+
+   public enum Direction {
+      Inbound,
+      Outbound,
+      UNRECOGNIZED;
+
+      public static Direction fromValue(final String text) {
+         return (Direction) GetEnumValue.fromValueOrDefault(text, Direction.UNRECOGNIZED);
+      }
+   }
+
+   @Nullable
+   public abstract String description();
+
+   public abstract Protocol protocol();
+
+   @Nullable
+   public abstract String sourcePortRange();
+
+   @Nullable
+   public abstract String destinationPortRange();
+
+   public abstract String sourceAddressPrefix();
+
+   public abstract String destinationAddressPrefix();
+
+   public abstract Access access();
+
+   @Nullable
+   public abstract Integer priority();
+
+   public abstract Direction direction();
+
+   @SerializedNames({"description", "protocol", "sourcePortRange", "destinationPortRange", "sourceAddressPrefix", "destinationAddressPrefix", "access", "priority", "direction"})
+   public static NetworkSecurityRuleProperties create(final String description,
+                                                      final Protocol protocol,
+                                                      final String sourcePortRange,
+                                                      final String destinationPortRange,
+                                                      final String sourceAddressPrefix,
+                                                      final String destinationAddressPrefix,
+                                                      final Access access,
+                                                      final Integer priority,
+                                                      final Direction direction) {
+      return builder()
+              .description(description)
+              .protocol(protocol)
+              .sourcePortRange(sourcePortRange)
+              .destinationPortRange(destinationPortRange)
+              .sourceAddressPrefix(sourceAddressPrefix)
+              .destinationAddressPrefix(destinationAddressPrefix)
+              .access(access)
+              .priority(priority)
+              .direction(direction)
+              .build();
+   }
+
+   public static Builder builder() {
+      return new AutoValue_NetworkSecurityRuleProperties.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder description(String description);
+
+      public abstract Builder protocol(Protocol protocol);
+
+      public abstract Builder sourcePortRange(String sourcePortRange);
+
+      public abstract Builder destinationPortRange(String destinationPortRange);
+
+      public abstract Builder sourceAddressPrefix(String sourceAddressPrefix);
+
+      public abstract Builder destinationAddressPrefix(String sourceAddressPrefix);
+
+      public abstract Builder access(Access access);
+
+      public abstract Builder priority(Integer priority);
+
+      public abstract Builder direction(Direction direction);
+
+      public abstract NetworkSecurityRuleProperties build();
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
new file mode 100644
index 0000000..e6b310d
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApi.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
+import org.jclouds.azurecompute.arm.functions.URIParser;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+import javax.inject.Named;
+import javax.ws.rs.Produces;
+import javax.ws.rs.Path;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups")
+
+@QueryParams(keys = "api-version", values = "2016-03-30")
+@RequestFilters(OAuthFilter.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface NetworkSecurityGroupApi {
+
+   @Named("networksecuritygroup:list")
+   @GET
+   @SelectJson("value")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<NetworkSecurityGroup> list();
+
+   @Named("networksecuritygroup:delete")
+   @Path("/{networksecuritygroupname}")
+   @DELETE
+   @ResponseParser(URIParser.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   URI delete(@PathParam("networksecuritygroupname") String nsgName);
+
+   @Named("networksecuritygroup:createOrUpdate")
+   @Path("/{networksecuritygroupname}")
+   @PUT
+   @MapBinder(BindToJsonPayload.class)
+   @Produces(MediaType.APPLICATION_JSON)
+   NetworkSecurityGroup createOrUpdate(@PathParam("networksecuritygroupname") String nsgName,
+                                       @PayloadParam("location") String location,
+                                       @Nullable @PayloadParam("tags") Map<String, String> tags,
+                                       @PayloadParam("properties")NetworkSecurityGroupProperties properties);
+
+   @Named("networksecuritygroup:get")
+   @Path("/{networksecuritygroupname}")
+   @GET
+   @Fallback(NullOnNotFoundOr404.class)
+   NetworkSecurityGroup get(@PathParam("networksecuritygroupname") String nsgName);
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
new file mode 100644
index 0000000..2edd3df
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApi.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+import org.jclouds.azurecompute.arm.functions.URIParser;
+import org.jclouds.oauth.v2.filters.OAuthFilter;
+
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+import javax.inject.Named;
+import javax.ws.rs.Produces;
+import javax.ws.rs.Path;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.PUT;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+import java.util.List;
+import java.net.URI;
+
+@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups/{networksecuritygroup}")
+
+@QueryParams(keys = "api-version", values = "2016-03-30")
+@RequestFilters(OAuthFilter.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface NetworkSecurityRuleApi {
+   @Named("networksecurityrule:createOrUpdate")
+   @Path("/securityRules/{networksecurityrulename}")
+   @PUT
+   @MapBinder(BindToJsonPayload.class)
+   @Produces(MediaType.APPLICATION_JSON)
+   NetworkSecurityRule createOrUpdate(@PathParam("networksecurityrulename") String ruleName,
+                                      @PayloadParam("properties") NetworkSecurityRuleProperties properties);
+
+   @Named("networksecurityrule:getDefaultRule")
+   @Path("/defaultSecurityRules/{networksecurityrulename}")
+   @GET
+   @Fallback(NullOnNotFoundOr404.class)
+   NetworkSecurityRule getDefaultRule(@PathParam("networksecurityrulename") String ruleName);
+
+   @Named("networksecurityrule:get")
+   @Path("/securityRules/{networksecurityrulename}")
+   @GET
+   @Fallback(NullOnNotFoundOr404.class)
+   NetworkSecurityRule get(@PathParam("networksecurityrulename") String ruleName);
+
+   @Named("networksecurityrule:delete")
+   @Path("/securityRules/{networksecurityrulename}")
+   @DELETE
+   @ResponseParser(URIParser.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   URI delete(@PathParam("networksecurityrulename") String ruleName);
+
+   @Named("networksecuritygroup:list")
+   @Path("/securityRules")
+   @GET
+   @SelectJson("value")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<NetworkSecurityRule> list();
+
+   @Named("networksecuritygroup:listDefaultRules")
+   @Path("/defaultSecurityRules")
+   @GET
+   @SelectJson("value")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<NetworkSecurityRule> listDefaultRules();
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiLiveTest.java
new file mode 100644
index 0000000..095c0e2
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiLiveTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import com.google.common.base.Predicate;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Access;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Direction;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Protocol;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
+
+import org.jclouds.util.Predicates2;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.net.URI;
+
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
+
+@Test(groups = "live", singleThreaded = true)
+public class NetworkSecurityGroupApiLiveTest extends BaseAzureComputeApiLiveTest {
+
+   private String resourcegroup;
+   private static String DEFAULT_NSG_NAME = "testNetworkSecurityGroup";
+
+   private NetworkSecurityGroup createGroup() {
+      NetworkSecurityRule rule = NetworkSecurityRule.create("denyallout", null, null,
+                     NetworkSecurityRuleProperties.builder()
+                                       .description("deny all out")
+                                       .protocol(Protocol.Tcp)
+                                       .sourcePortRange("*")
+                                       .destinationPortRange("*")
+                                       .sourceAddressPrefix("*")
+                                       .destinationAddressPrefix("*")
+                                       .access(Access.Deny)
+                                       .priority(4095)
+                                       .direction(Direction.Outbound)
+                                       .build());
+      ArrayList<NetworkSecurityRule> ruleList = new ArrayList<NetworkSecurityRule>();
+      ruleList.add(rule);
+      NetworkSecurityGroup nsg = NetworkSecurityGroup.create("samplensg", "westus", null,
+                                                             NetworkSecurityGroupProperties.builder()
+                                                                                       .securityRules(ruleList)
+                                                                                       .build(),
+                                                             null);
+      return nsg;
+   }
+
+   @BeforeClass
+   @Override
+   public void setup() {
+      super.setup();
+      resourcegroup = getResourceGroupName();
+   }
+
+   @Test(groups = "live")
+   public void deleteNetworkSecurityGroupDoesNotExist() {
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      URI uri = nsgApi.delete(DEFAULT_NSG_NAME);
+      assertNull(uri);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "deleteNetworkSecurityGroupDoesNotExist")
+   public void createNetworkSecurityGroup() {
+      final NetworkSecurityGroup nsg = createGroup();
+      assertNotNull(nsg);
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      NetworkSecurityGroup result = nsgApi.createOrUpdate(DEFAULT_NSG_NAME,
+                                                  nsg.location(),
+                                                  nsg.tags(),
+                                                  nsg.properties());
+      assertNotNull(result);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityGroup")
+   public void listNetworkSecurityGroups() {
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      List<NetworkSecurityGroup> result = nsgApi.list();
+
+      // verify we have something
+      assertNotNull(result);
+      assertEquals(result.size(), 1);
+
+      // check that the nework security group matches the one we originally passed in
+      NetworkSecurityGroup original = createGroup();
+      NetworkSecurityGroup nsg = result.get(0);
+      assertEquals(original.name(), nsg.name());
+      assertEquals(original.location(), nsg.location());
+      assertEquals(original.tags(), nsg.tags());
+
+      // check the network security rule in the group
+      assertEquals(nsg.properties().securityRules().size(), 1);
+      NetworkSecurityRule originalRule = original.properties().securityRules().get(0);
+      NetworkSecurityRule nsgRule = nsg.properties().securityRules().get(0);
+      assertEquals(originalRule.name(), nsgRule.name());
+      assertTrue(originalRule.properties().equals(nsgRule.properties()));
+   }
+
+   @Test(groups = "live", dependsOnMethods = {"listNetworkSecurityGroups", "getNetworkSecurityGroup"}, alwaysRun = true)
+   public void deleteNetworkSecurityGroup() {
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      URI uri = nsgApi.delete(DEFAULT_NSG_NAME);
+      if (uri != null) {
+         assertTrue(uri.toString().contains("api-version"));
+         assertTrue(uri.toString().contains("operationresults"));
+
+         boolean jobDone = Predicates2.retry(new Predicate<URI>() {
+            @Override
+            public boolean apply(URI uri) {
+               return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
+            }
+         }, 60 * 2 * 1000 /* 2 minute timeout */).apply(uri);
+         assertTrue(jobDone, "delete operation did not complete in the configured timeout");
+      }
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityGroup")
+   public void getNetworkSecurityGroup() {
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      NetworkSecurityGroup nsg = nsgApi.get(DEFAULT_NSG_NAME);
+      assertNotNull(nsg);
+      assertNotNull(nsg.etag());
+      assertEquals(nsg.name(), DEFAULT_NSG_NAME);
+   }
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiMockTest.java
new file mode 100644
index 0000000..adefd95
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityGroupApiMockTest.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import com.google.gson.Gson;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Protocol;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.google.common.collect.Iterables.isEmpty;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+@Test(groups = "unit", testName = "NetworkSecurityGroupApiMockTest", singleThreaded = true)
+public class NetworkSecurityGroupApiMockTest extends BaseAzureComputeApiMockTest {
+   private final String subscriptionid = "SUBSCRIPTIONID";
+   private final String resourcegroup = "myresourcegroup";
+   private final String apiVersion = "api-version=2016-03-30";
+   private static String DEFAULT_NSG_NAME = "testNetworkSecurityGroup";
+
+   private NetworkSecurityGroup createGroup() {
+      NetworkSecurityRule rule = NetworkSecurityRule.create("denyallout", null, null,
+              NetworkSecurityRuleProperties.builder()
+                      .description("deny all out")
+                      .protocol(Protocol.Tcp)
+                      .sourcePortRange("*")
+                      .destinationPortRange("*")
+                      .sourceAddressPrefix("*")
+                      .destinationAddressPrefix("*")
+                      .access(NetworkSecurityRuleProperties.Access.Deny)
+                      .priority(4095)
+                      .direction(NetworkSecurityRuleProperties.Direction.Outbound)
+                      .build());
+      ArrayList<NetworkSecurityRule> ruleList = new ArrayList<NetworkSecurityRule>();
+      ruleList.add(rule);
+      NetworkSecurityGroup nsg = NetworkSecurityGroup.create("samplensg", "westus", null,
+              NetworkSecurityGroupProperties.builder()
+                      .securityRules(ruleList)
+                      .build(),
+              null);
+      return nsg;
+   }
+
+   public void createNetworkSecurityGroup() throws InterruptedException {
+      NetworkSecurityGroup nsg = createGroup();
+
+      server.enqueue(jsonResponse("/networksecuritygroupcreate.json").setResponseCode(200));
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      String json = String.format("{\"location\":\"%s\",\"properties\":%s}", "westus", new Gson().toJson(nsg.properties()));
+      NetworkSecurityGroup result = nsgApi.createOrUpdate(DEFAULT_NSG_NAME, "westus", null, nsg.properties());
+      assertSent(server, "PUT", path, json);
+
+      assertEquals(result.name(), DEFAULT_NSG_NAME);
+      assertEquals(result.location(), "westus");
+      assertEquals(result.properties().securityRules().size(), 1);
+      assertEquals(result.properties().securityRules().get(0).properties().protocol(), Protocol.Tcp);
+   }
+
+   public void getNetworkSecurityGroup() throws InterruptedException {
+      NetworkSecurityGroup nsg = createGroup();
+
+      server.enqueue(jsonResponse("/networksecuritygroupget.json").setResponseCode(200));
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      NetworkSecurityGroup result = nsgApi.get(DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      assertSent(server, "GET", path);
+
+      assertEquals(result.name(), DEFAULT_NSG_NAME);
+      assertEquals(result.location(), "westus");
+      assertEquals(result.properties().securityRules().size(), 1);
+      assertEquals(result.properties().securityRules().get(0).properties().protocol(), Protocol.Tcp);
+   }
+
+   public void getNetworkSecurityGroupReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      NetworkSecurityGroup result = nsgApi.get(DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      assertSent(server, "GET", path);
+
+      assertNull(result);
+   }
+
+   public void listNetworkSecurityGroups() throws InterruptedException {
+      server.enqueue(jsonResponse("/networksecuritygrouplist.json").setResponseCode(200));
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      List<NetworkSecurityGroup> result = nsgApi.list();
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups?%s", subscriptionid, resourcegroup, apiVersion);
+      assertSent(server, "GET", path);
+
+      assertNotNull(result);
+      assertTrue(result.size() > 0);
+   }
+
+   public void listNetworkSecurityGroupsReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      List<NetworkSecurityGroup> result = nsgApi.list();
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups?%s", subscriptionid, resourcegroup, apiVersion);
+      assertSent(server, "GET", path);
+
+      assertTrue(isEmpty(result));
+   }
+
+   public void deleteNetworkSecurityGroup() throws InterruptedException {
+      server.enqueue(response202WithHeader());
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      URI uri = nsgApi.delete(DEFAULT_NSG_NAME);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertNotNull(uri);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      assertSent(server, "DELETE", path);
+
+      assertTrue(uri.toString().contains("api-version"));
+      assertTrue(uri.toString().contains("operationresults"));
+   }
+
+   public void deleteNetworkSecurityGroupDoesNotExist() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      URI uri = nsgApi.delete(DEFAULT_NSG_NAME);
+      assertNull(uri);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      assertSent(server, "DELETE", path);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiLiveTest.java
new file mode 100644
index 0000000..fbcd2b4
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiLiveTest.java
@@ -0,0 +1,217 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Access;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Direction;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Protocol;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
+
+import org.jclouds.util.Predicates2;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+@Test(groups = "live", singleThreaded = true)
+public class NetworkSecurityRuleApiLiveTest extends BaseAzureComputeApiLiveTest {
+
+   private String resourcegroup;
+   private static String DEFAULT_NSG_NAME = "testNetworkSecurityGroup";
+   private static String UNKNOWN_RULE_NAME = "ruledoesntexist";
+
+   private NetworkSecurityGroup createGroup() {
+      NetworkSecurityRule rule = NetworkSecurityRule.create("denyallout", null, null,
+              NetworkSecurityRuleProperties.builder()
+                      .description("deny all out")
+                      .protocol(Protocol.Tcp)
+                      .sourcePortRange("*")
+                      .destinationPortRange("*")
+                      .sourceAddressPrefix("*")
+                      .destinationAddressPrefix("*")
+                      .access(Access.Deny)
+                      .priority(4095)
+                      .direction(Direction.Outbound)
+                      .build());
+      ArrayList<NetworkSecurityRule> ruleList = new ArrayList<NetworkSecurityRule>();
+      ruleList.add(rule);
+      NetworkSecurityGroup nsg = NetworkSecurityGroup.create("samplensg", "westus", null,
+              NetworkSecurityGroupProperties.builder()
+                      .securityRules(ruleList)
+                      .build(),
+              null);
+      return nsg;
+   }
+
+   private NetworkSecurityRule createRule() {
+      NetworkSecurityRule rule = NetworkSecurityRule.create("allowalludpin", null, null,
+              NetworkSecurityRuleProperties.builder()
+                        .description("allow all udp in")
+                        .protocol(Protocol.Udp)
+                        .sourcePortRange("*")
+                        .destinationPortRange("*")
+                        .sourceAddressPrefix("*")
+                        .destinationAddressPrefix("*")
+                        .access(Access.Allow)
+                        .priority(4094)
+                        .direction(Direction.Inbound)
+                        .build());
+      return rule;
+   }
+
+   @BeforeClass
+   @Override
+   public void setup() {
+      super.setup();
+      resourcegroup = getResourceGroupName();
+
+      // a network security group is needed
+      final NetworkSecurityGroup nsg = createGroup();
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      NetworkSecurityGroup result = nsgApi.createOrUpdate(DEFAULT_NSG_NAME,
+              nsg.location(),
+              nsg.tags(),
+              nsg.properties());
+   }
+
+   @AfterClass(alwaysRun = true)
+   @Override
+   public void tearDown() {
+      // remove the security group we created
+      final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
+      URI uri = nsgApi.delete(DEFAULT_NSG_NAME);
+      if (uri != null) {
+         boolean jobDone = Predicates2.retry(new Predicate<URI>() {
+            @Override
+            public boolean apply(URI uri) {
+               return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
+            }
+         }, 60 * 2 * 1000 /* 2 minute timeout */).apply(uri);
+      }
+
+      super.tearDown();
+   }
+
+   @Test(groups = "live")
+   public void deleteNetworkSecurityRuleDoesNotExist() {
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      URI uri = ruleApi.delete(UNKNOWN_RULE_NAME);
+      assertNull(uri);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "deleteNetworkSecurityRuleDoesNotExist")
+   public void createNetworkSecurityRule() {
+      final NetworkSecurityRule rule = createRule();
+      assertNotNull(rule);
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      NetworkSecurityRule result = ruleApi.createOrUpdate(rule.name(), rule.properties());
+      assertNotNull(result);
+      assertEquals(result.name(), rule.name());
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityRule")
+   public void getNetworkSecurityRule() {
+      final NetworkSecurityRule rule = createRule();
+      assertNotNull(rule);
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      NetworkSecurityRule result = ruleApi.get(rule.name());
+      assertNotNull(result);
+      assertNotNull(result.etag());
+      assertEquals(result.name(), rule.name());
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityRule")
+   public void getNetworkSecurityDefaultRule() {
+      String defaultRuleName = "AllowVnetInBound";
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      NetworkSecurityRule result = ruleApi.getDefaultRule(defaultRuleName);
+
+      assertNotNull(result);
+      assertNotNull(result.etag());
+      assertEquals(result.name(), defaultRuleName);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityRule")
+   public void listNetworkSecurityRules() {
+      final NetworkSecurityRule rule = createRule();
+      assertNotNull(rule);
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      List<NetworkSecurityRule> result = ruleApi.list();
+
+      assertNotNull(result);
+      assertEquals(result.size(), 2);
+
+      boolean rulePresent = Iterables.any(result, new Predicate<NetworkSecurityRule>() {
+         public boolean apply(NetworkSecurityRule input) {
+            return input.name().equals(rule.name());
+         }
+      });
+
+      assertTrue(rulePresent);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "createNetworkSecurityRule")
+   public void listDefaultSecurityRules() {
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      List<NetworkSecurityRule> result = ruleApi.listDefaultRules();
+
+      assertNotNull(result);
+      assertTrue(result.size() > 0);
+   }
+
+   @Test(groups = "live", dependsOnMethods = {"listNetworkSecurityRules", "listDefaultSecurityRules", "getNetworkSecurityRule"}, alwaysRun = true)
+   public void deleteNetworkSecurityRule() {
+      final NetworkSecurityRule rule = createRule();
+      assertNotNull(rule);
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      URI uri = ruleApi.delete(rule.name());
+      if (uri != null) {
+         assertTrue(uri.toString().contains("api-version"));
+         assertTrue(uri.toString().contains("operationresults"));
+
+         boolean jobDone = Predicates2.retry(new Predicate<URI>() {
+            @Override
+            public boolean apply(URI uri) {
+               return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
+            }
+         }, 60 * 2 * 1000 /* 2 minute timeout */).apply(uri);
+         assertTrue(jobDone, "delete operation did not complete in the configured timeout");
+      }
+   }
+
+}
+

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiMockTest.java
new file mode 100644
index 0000000..1ca4284
--- /dev/null
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkSecurityRuleApiMockTest.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.features;
+
+import com.google.gson.Gson;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties.Protocol;
+import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.util.List;
+
+import static com.google.common.collect.Iterables.isEmpty;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNotNull;
+
+
+@Test(groups = "unit", testName = "NetworkSecurityRuleApiMockTest", singleThreaded = true)
+public class NetworkSecurityRuleApiMockTest extends BaseAzureComputeApiMockTest {
+   private final String subscriptionid = "SUBSCRIPTIONID";
+   private final String resourcegroup = "myresourcegroup";
+   private final String apiVersion = "api-version=2016-03-30";
+   private static String DEFAULT_NSG_NAME = "testNetworkSecurityGroup";
+
+   private NetworkSecurityRule createRule() {
+      NetworkSecurityRule rule = NetworkSecurityRule.create("allowalludpin", null, null,
+              NetworkSecurityRuleProperties.builder()
+                      .description("allow all udp in")
+                      .protocol(Protocol.Udp)
+                      .sourcePortRange("*")
+                      .destinationPortRange("*")
+                      .sourceAddressPrefix("*")
+                      .destinationAddressPrefix("*")
+                      .access(NetworkSecurityRuleProperties.Access.Allow)
+                      .priority(4094)
+                      .direction(NetworkSecurityRuleProperties.Direction.Inbound)
+                      .build());
+      return rule;
+   }
+
+   public void createNetworkSecurityRule() throws InterruptedException {
+      NetworkSecurityRule rule = createRule();
+
+      server.enqueue(jsonResponse("/networksecurityrulecreate.json").setResponseCode(200));
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, rule.name(), apiVersion);
+      NetworkSecurityRule result = ruleApi.createOrUpdate(rule.name(), rule.properties());
+      String json = String.format("{\"properties\":%s}", new Gson().toJson(rule.properties()));
+
+      assertSent(server, "PUT", path, json);
+
+      assertNotNull(result);
+      assertEquals(result.name(), rule.name());
+   }
+
+   public void getNetworkSecurityRule() throws InterruptedException {
+      NetworkSecurityRule rule = createRule();
+
+      server.enqueue(jsonResponse("/networksecurityruleget.json").setResponseCode(200));
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, rule.name(), apiVersion);
+      NetworkSecurityRule result = ruleApi.get(rule.name());
+      assertSent(server, "GET", path);
+
+      assertEquals(result.name(), rule.name());
+   }
+
+   public void getNetworkSecurityRuleReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      String missingRuleName = "ruleismissing";
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, missingRuleName, apiVersion);
+      NetworkSecurityRule result = ruleApi.get(missingRuleName);
+      assertSent(server, "GET", path);
+
+      assertNull(result);
+   }
+
+   public void getNetworkSecurityDefaultRule() throws InterruptedException {
+      server.enqueue(jsonResponse("/networksecurityrulegetdefault.json").setResponseCode(200));
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      String ruleName = "AllowVnetInBound";
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/defaultSecurityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, ruleName, apiVersion);
+      NetworkSecurityRule result = ruleApi.getDefaultRule(ruleName);
+      assertSent(server, "GET", path);
+
+      assertNotNull(result);
+      assertEquals(result.name(), ruleName);
+   }
+
+   public void getNetworkSecurityDefaultRuleReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      String missingRuleName = "ruleismissing";
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/defaultSecurityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, missingRuleName, apiVersion);
+      NetworkSecurityRule result = ruleApi.getDefaultRule(missingRuleName);
+      assertSent(server, "GET", path);
+
+      assertNull(result);
+   }
+
+   public void listNetworkSecurityRules() throws InterruptedException {
+      server.enqueue(jsonResponse("/networksecurityrulelist.json").setResponseCode(200));
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      List<NetworkSecurityRule> result = ruleApi.list();
+      assertSent(server, "GET", path);
+
+      assertNotNull(result);
+      assertTrue(result.size() > 0);
+   }
+
+   public void listNetworkSecurityRulesReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      List<NetworkSecurityRule> result = ruleApi.list();
+      assertSent(server, "GET", path);
+
+      assertTrue(isEmpty(result));
+   }
+
+   public void listNetworkSecurityDefaultRules() throws InterruptedException {
+      server.enqueue(jsonResponse("/networksecurityrulelistdefault.json").setResponseCode(200));
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/defaultSecurityRules?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      List<NetworkSecurityRule> result = ruleApi.listDefaultRules();
+      assertSent(server, "GET", path);
+
+      assertNotNull(result);
+      assertTrue(result.size() > 0);
+   }
+
+   public void listNetworkSecurityDefaultRulesReturns404() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/defaultSecurityRules?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, apiVersion);
+      List<NetworkSecurityRule> result = ruleApi.listDefaultRules();
+      assertSent(server, "GET", path);
+
+      assertTrue(isEmpty(result));
+   }
+
+   public void deleteNetworkSecurityRule() throws InterruptedException {
+      server.enqueue(response202WithHeader());
+
+      NetworkSecurityRule rule = createRule();
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      URI uri = ruleApi.delete(rule.name());
+
+      assertEquals(server.getRequestCount(), 1);
+      assertNotNull(uri);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, rule.name(), apiVersion);
+      assertSent(server, "DELETE", path);
+
+      assertTrue(uri.toString().contains("api-version"));
+      assertTrue(uri.toString().contains("operationresults"));
+   }
+
+   public void deleteNetworkSecurityRuleDoesNotExist() throws InterruptedException {
+      server.enqueue(response404());
+
+      final NetworkSecurityRuleApi ruleApi = api.getNetworkSecurityRuleApi(resourcegroup, DEFAULT_NSG_NAME);
+      String dummyname = "dummyrulename";
+      URI uri = ruleApi.delete(dummyname);
+      assertNull(uri);
+
+      String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkSecurityGroups/%s/securityRules/%s?%s", subscriptionid, resourcegroup, DEFAULT_NSG_NAME, dummyname, apiVersion);
+      assertSent(server, "DELETE", path);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecuritygroupcreate.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecuritygroupcreate.json b/azurecompute-arm/src/test/resources/networksecuritygroupcreate.json
new file mode 100644
index 0000000..b416bcc
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecuritygroupcreate.json
@@ -0,0 +1,125 @@
+{
+  "name": "testNetworkSecurityGroup",
+  "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup",
+  "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+  "type": "Microsoft.Network/networkSecurityGroups",
+  "location": "westus",
+  "properties": {
+    "provisioningState": "Updating",
+    "resourceGuid": "028cb30d-f97f-4dbe-9fea-705da1f383ca",
+    "securityRules": [{
+      "name": "denyallout",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/denyallout",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "deny all out",
+        "protocol": "Tcp",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 4095,
+        "direction": "Outbound"
+      }
+    }],
+    "defaultSecurityRules": [{
+      "name": "AllowVnetInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetInBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Allow inbound traffic from all VMs in VNET",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "VirtualNetwork",
+        "destinationAddressPrefix": "VirtualNetwork",
+        "access": "Allow",
+        "priority": 65000,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "AllowAzureLoadBalancerInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowAzureLoadBalancerInBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Allow inbound traffic from azure load balancer",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "AzureLoadBalancer",
+        "destinationAddressPrefix": "*",
+        "access": "Allow",
+        "priority": 65001,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "DenyAllInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllInBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Deny all inbound traffic",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 65500,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "AllowVnetOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetOutBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Allow outbound traffic from all VMs to all VMs in VNET",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "VirtualNetwork",
+        "destinationAddressPrefix": "VirtualNetwork",
+        "access": "Allow",
+        "priority": 65000,
+        "direction": "Outbound"
+      }
+    }, {
+      "name": "AllowInternetOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowInternetOutBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Allow outbound traffic from all VMs to Internet",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "Internet",
+        "access": "Allow",
+        "priority": 65001,
+        "direction": "Outbound"
+      }
+    }, {
+      "name": "DenyAllOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllOutBound",
+      "etag": "W/\"1883271c-c55b-4f5b-a95a-b7415833e0ae\"",
+      "properties": {
+        "provisioningState": "Updating",
+        "description": "Deny all outbound traffic",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 65500,
+        "direction": "Outbound"
+      }
+    }]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecuritygroupget.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecuritygroupget.json b/azurecompute-arm/src/test/resources/networksecuritygroupget.json
new file mode 100644
index 0000000..17a2680
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecuritygroupget.json
@@ -0,0 +1,125 @@
+{
+  "name": "testNetworkSecurityGroup",
+  "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup",
+  "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+  "type": "Microsoft.Network/networkSecurityGroups",
+  "location": "westus",
+  "properties": {
+    "provisioningState": "Succeeded",
+    "resourceGuid": "028cb30d-f97f-4dbe-9fea-705da1f383ca",
+    "securityRules": [{
+      "name": "denyallout",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/denyallout",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "deny all out",
+        "protocol": "Tcp",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 4095,
+        "direction": "Outbound"
+      }
+    }],
+    "defaultSecurityRules": [{
+      "name": "AllowVnetInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetInBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Allow inbound traffic from all VMs in VNET",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "VirtualNetwork",
+        "destinationAddressPrefix": "VirtualNetwork",
+        "access": "Allow",
+        "priority": 65000,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "AllowAzureLoadBalancerInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowAzureLoadBalancerInBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Allow inbound traffic from azure load balancer",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "AzureLoadBalancer",
+        "destinationAddressPrefix": "*",
+        "access": "Allow",
+        "priority": 65001,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "DenyAllInBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllInBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Deny all inbound traffic",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 65500,
+        "direction": "Inbound"
+      }
+    }, {
+      "name": "AllowVnetOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetOutBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Allow outbound traffic from all VMs to all VMs in VNET",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "VirtualNetwork",
+        "destinationAddressPrefix": "VirtualNetwork",
+        "access": "Allow",
+        "priority": 65000,
+        "direction": "Outbound"
+      }
+    }, {
+      "name": "AllowInternetOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowInternetOutBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Allow outbound traffic from all VMs to Internet",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "Internet",
+        "access": "Allow",
+        "priority": 65001,
+        "direction": "Outbound"
+      }
+    }, {
+      "name": "DenyAllOutBound",
+      "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllOutBound",
+      "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+      "properties": {
+        "provisioningState": "Succeeded",
+        "description": "Deny all outbound traffic",
+        "protocol": "*",
+        "sourcePortRange": "*",
+        "destinationPortRange": "*",
+        "sourceAddressPrefix": "*",
+        "destinationAddressPrefix": "*",
+        "access": "Deny",
+        "priority": 65500,
+        "direction": "Outbound"
+      }
+    }]
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecuritygrouplist.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecuritygrouplist.json b/azurecompute-arm/src/test/resources/networksecuritygrouplist.json
new file mode 100644
index 0000000..7beebb0
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecuritygrouplist.json
@@ -0,0 +1,127 @@
+{
+  "value": [{
+    "name": "testNetworkSecurityGroup",
+    "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup",
+    "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+    "type": "Microsoft.Network/networkSecurityGroups",
+    "location": "westus",
+    "properties": {
+      "provisioningState": "Succeeded",
+      "resourceGuid": "028cb30d-f97f-4dbe-9fea-705da1f383ca",
+      "securityRules": [{
+        "name": "denyallout",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/denyallout",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "deny all out",
+          "protocol": "Tcp",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "*",
+          "destinationAddressPrefix": "*",
+          "access": "Deny",
+          "priority": 4095,
+          "direction": "Outbound"
+        }
+      }],
+      "defaultSecurityRules": [{
+        "name": "AllowVnetInBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetInBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Allow inbound traffic from all VMs in VNET",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "VirtualNetwork",
+          "destinationAddressPrefix": "VirtualNetwork",
+          "access": "Allow",
+          "priority": 65000,
+          "direction": "Inbound"
+        }
+      }, {
+        "name": "AllowAzureLoadBalancerInBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowAzureLoadBalancerInBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Allow inbound traffic from azure load balancer",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "AzureLoadBalancer",
+          "destinationAddressPrefix": "*",
+          "access": "Allow",
+          "priority": 65001,
+          "direction": "Inbound"
+        }
+      }, {
+        "name": "DenyAllInBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllInBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Deny all inbound traffic",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "*",
+          "destinationAddressPrefix": "*",
+          "access": "Deny",
+          "priority": 65500,
+          "direction": "Inbound"
+        }
+      }, {
+        "name": "AllowVnetOutBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetOutBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Allow outbound traffic from all VMs to all VMs in VNET",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "VirtualNetwork",
+          "destinationAddressPrefix": "VirtualNetwork",
+          "access": "Allow",
+          "priority": 65000,
+          "direction": "Outbound"
+        }
+      }, {
+        "name": "AllowInternetOutBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowInternetOutBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Allow outbound traffic from all VMs to Internet",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "*",
+          "destinationAddressPrefix": "Internet",
+          "access": "Allow",
+          "priority": 65001,
+          "direction": "Outbound"
+        }
+      }, {
+        "name": "DenyAllOutBound",
+        "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims947groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/DenyAllOutBound",
+        "etag": "W/\"14e288e4-5d9b-48cf-89c4-b532b59d71de\"",
+        "properties": {
+          "provisioningState": "Succeeded",
+          "description": "Deny all outbound traffic",
+          "protocol": "*",
+          "sourcePortRange": "*",
+          "destinationPortRange": "*",
+          "sourceAddressPrefix": "*",
+          "destinationAddressPrefix": "*",
+          "access": "Deny",
+          "priority": 65500,
+          "direction": "Outbound"
+        }
+      }]
+    }
+  }]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecurityrulecreate.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecurityrulecreate.json b/azurecompute-arm/src/test/resources/networksecurityrulecreate.json
new file mode 100644
index 0000000..c09bf08
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecurityrulecreate.json
@@ -0,0 +1,17 @@
+{
+  "name": "allowalludpin",
+  "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims859groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/allowalludpin",
+  "etag": "W/\"d9b6cda9-3873-445d-bc70-cd9c13f87ba7\"",
+  "properties": {
+    "provisioningState": "Updating",
+    "description": "allow all udp in",
+    "protocol": "Udp",
+    "sourcePortRange": "*",
+    "destinationPortRange": "*",
+    "sourceAddressPrefix": "*",
+    "destinationAddressPrefix": "*",
+    "access": "Allow",
+    "priority": 4094,
+    "direction": "Inbound"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecurityruleget.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecurityruleget.json b/azurecompute-arm/src/test/resources/networksecurityruleget.json
new file mode 100644
index 0000000..c09bf08
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecurityruleget.json
@@ -0,0 +1,17 @@
+{
+  "name": "allowalludpin",
+  "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims859groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/allowalludpin",
+  "etag": "W/\"d9b6cda9-3873-445d-bc70-cd9c13f87ba7\"",
+  "properties": {
+    "provisioningState": "Updating",
+    "description": "allow all udp in",
+    "protocol": "Udp",
+    "sourcePortRange": "*",
+    "destinationPortRange": "*",
+    "sourceAddressPrefix": "*",
+    "destinationAddressPrefix": "*",
+    "access": "Allow",
+    "priority": 4094,
+    "direction": "Inbound"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecurityrulegetdefault.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecurityrulegetdefault.json b/azurecompute-arm/src/test/resources/networksecurityrulegetdefault.json
new file mode 100644
index 0000000..3330985
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecurityrulegetdefault.json
@@ -0,0 +1,17 @@
+{
+  "name": "AllowVnetInBound",
+  "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims741groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/defaultSecurityRules/AllowVnetInBound",
+  "etag": "W/\"23efab91-398a-4984-a9a7-281af38f6538\"",
+  "properties": {
+    "provisioningState": "Succeeded",
+    "description": "Allow inbound traffic from all VMs in VNET",
+    "protocol": "*",
+    "sourcePortRange": "*",
+    "destinationPortRange": "*",
+    "sourceAddressPrefix": "VirtualNetwork",
+    "destinationAddressPrefix": "VirtualNetwork",
+    "access": "Allow",
+    "priority": 65000,
+    "direction": "Inbound"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/016f6e0c/azurecompute-arm/src/test/resources/networksecurityrulelist.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/networksecurityrulelist.json b/azurecompute-arm/src/test/resources/networksecurityrulelist.json
new file mode 100644
index 0000000..d48fe32
--- /dev/null
+++ b/azurecompute-arm/src/test/resources/networksecurityrulelist.json
@@ -0,0 +1,35 @@
+{
+  "value": [{
+    "name": "denyallout",
+    "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims859groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/denyallout",
+    "etag": "W/\"409ae6c7-fbe1-4bc4-aadb-c1d8330844d2\"",
+    "properties": {
+      "provisioningState": "Succeeded",
+      "description": "deny all out",
+      "protocol": "Tcp",
+      "sourcePortRange": "*",
+      "destinationPortRange": "*",
+      "sourceAddressPrefix": "*",
+      "destinationAddressPrefix": "*",
+      "access": "Deny",
+      "priority": 4095,
+      "direction": "Outbound"
+    }
+  }, {
+    "name": "allowalludpin",
+    "id": "/subscriptions/e43b3d9c-f839-48a8-b0fb-691aee6f1e4d/resourceGroups/jims859groupjclouds/providers/Microsoft.Network/networkSecurityGroups/testNetworkSecurityGroup/securityRules/allowalludpin",
+    "etag": "W/\"409ae6c7-fbe1-4bc4-aadb-c1d8330844d2\"",
+    "properties": {
+      "provisioningState": "Succeeded",
+      "description": "allow all udp in",
+      "protocol": "Udp",
+      "sourcePortRange": "*",
+      "destinationPortRange": "*",
+      "sourceAddressPrefix": "*",
+      "destinationAddressPrefix": "*",
+      "access": "Allow",
+      "priority": 4094,
+      "direction": "Inbound"
+    }
+  }]
+}
\ No newline at end of file