Merge "Adding support for listing, getting, and creating floating ip addresses Fixed minor documentation typos."

This commit is contained in:
Jenkins
2014-08-12 19:40:51 +00:00
committed by Gerrit Code Review
23 changed files with 1198 additions and 13 deletions

View File

@@ -0,0 +1,186 @@
// /* ============================================================================
// Copyright 2014 Hewlett Packard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================ */
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenStack.Compute;
using OpenStack.Network;
namespace OpenStack.Test.Network
{
[TestClass]
public class FloatingIpPayloadConverterTests
{
internal string CreateFloatingIpJsonFixtrue(string id, string ipAddress, FloatingIpStatus status)
{
var payloadFixture = @"{{
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
""status"": ""{1}"",
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
""fixed_ip_address"": ""10.0.0.2"",
""floating_ip_address"": ""{2}"",
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
""id"": ""{0}""
}}";
return string.Format(payloadFixture, id, status, ipAddress);
}
[TestMethod]
public void CanParseValidFloatingIpsJsonPayloadWithMultipleIps()
{
var validMultipleIpJsonFixture = @"{{ ""floatingips"": [ {0} ] }}";
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
var secondIp = CreateFloatingIpJsonFixtrue("54321", "172.0.0.2", FloatingIpStatus.Down);
var validMultipleIpsJson = string.Format(validMultipleIpJsonFixture,
string.Join(",", new List<string>() { firstIp, secondIp }));
var converter = new FloatingIpPayloadConverter();
var floatingIps = converter.ConvertFloatingIps(validMultipleIpsJson).ToList();
Assert.AreEqual(2, floatingIps.Count());
var ip1 =
floatingIps.First(o => string.Equals(o.Id, "12345", StringComparison.InvariantCultureIgnoreCase));
var ip2 =
floatingIps.First(o => string.Equals(o.Id, "54321", StringComparison.InvariantCultureIgnoreCase));
Assert.IsNotNull(ip1);
Assert.IsNotNull(ip2);
Assert.AreEqual("12345", ip1.Id);
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
Assert.AreEqual("54321", ip2.Id);
Assert.AreEqual("172.0.0.2", ip2.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Down, ip2.Status);
}
[TestMethod]
public void CanConvertValidFloatingIpsJsonPayloadWithSingleNetwork()
{
var validSingleIpJsonPayload = @"{{ ""floatingips"": [ {0} ] }}";
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
var validSingleIpPayload = string.Format(validSingleIpJsonPayload,
string.Join(",", new List<string>() { firstIp }));
var converter = new FloatingIpPayloadConverter();
var floatingIps = converter.ConvertFloatingIps(validSingleIpPayload).ToList();
Assert.AreEqual(1, floatingIps.Count());
var ip1 =
floatingIps.First(o => string.Equals(o.Id, "12345", StringComparison.InvariantCultureIgnoreCase));
Assert.IsNotNull(ip1);
Assert.AreEqual("12345", ip1.Id);
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
}
[TestMethod]
public void CanParseValidFloatingIpsPayloadWithEmptyJsonArray()
{
var emptyJsonArray = @"{ ""floatingips"": [ ] }";
var converter = new FloatingIpPayloadConverter();
var networks = converter.ConvertFloatingIps(emptyJsonArray).ToList();
Assert.AreEqual(0, networks.Count());
}
[TestMethod]
public void CanParseAnEmptyFloatingIpsPayload()
{
var payload = string.Empty;
var converter = new FloatingIpPayloadConverter();
var networks = converter.ConvertFloatingIps(payload).ToList();
Assert.AreEqual(0, networks.Count());
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void CannotParseANullFloatingIpsPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.ConvertFloatingIps(null);
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void CannotParseInvalidFloatingIpsJsonPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.ConvertFloatingIps("[ { \"SomeAtrib\" }]");
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void CannotParseInvalidFloatingIpsPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.ConvertFloatingIps("NOT JSON");
}
[TestMethod]
public void CanConvertValidFloatingIpJsonPayload()
{
var validSingleIpJsonPayload = @"{{ ""floatingip"": {0} }}";
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
var validSingleIpPayload = string.Format(validSingleIpJsonPayload,
string.Join(",", new List<string>() { firstIp }));
var converter = new FloatingIpPayloadConverter();
var ip1 = converter.Convert(validSingleIpPayload);
Assert.IsNotNull(ip1);
Assert.AreEqual("12345", ip1.Id);
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void CannotParseANullFloatingIpPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.Convert(null);
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void CannotParseInvalidFloatingIpJsonPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.Convert("[ { \"SomeAtrib\" }]");
}
[TestMethod]
[ExpectedException(typeof(FormatException))]
public void CannotParseInvalidFloatingIpPayload()
{
var converter = new FloatingIpPayloadConverter();
converter.Convert("NOT JSON");
}
}
}

View File

@@ -15,6 +15,7 @@
// ============================================================================ */
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -34,9 +35,12 @@ namespace OpenStack.Test.Network
{
internal ICollection<OpenStack.Network.Network> Networks { get; private set; }
internal ICollection<FloatingIp> FloatingIps { get; private set; }
public NetworkRestSimulator() : base()
{
this.Networks = new List<OpenStack.Network.Network>();
this.FloatingIps = new List<OpenStack.Network.FloatingIp>();
}
public NetworkRestSimulator(CancellationToken token)
@@ -46,12 +50,14 @@ namespace OpenStack.Test.Network
protected override IHttpResponseAbstraction HandleGet()
{
if (this.Uri.Segments.Count() >= 4)
if (this.Uri.Segments.Count() >= 3)
{
switch (this.Uri.Segments[3].TrimEnd('/').ToLower())
switch (this.Uri.Segments[2].TrimEnd('/').ToLower())
{
case "networks":
return HandleGetNetworks();
case "floatingips":
return HandleGetFloatingIps();
}
}
throw new NotImplementedException();
@@ -62,9 +68,9 @@ namespace OpenStack.Test.Network
Stream networkContent;
switch (this.Uri.Segments.Count())
{
case 4:
case 3:
//no flavor id given, list all flavors
networkContent = TestHelper.CreateStream(GenerateNetworksPayload(this.Networks));
networkContent = TestHelper.CreateStream(GenerateCollectionPayload(this.Networks, this.GenerateNetworkPayload, "networks"));
break;
default:
//Unknown Uri format
@@ -74,11 +80,66 @@ namespace OpenStack.Test.Network
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), networkContent);
}
internal IHttpResponseAbstraction HandleGetFloatingIps()
{
Stream floatingIpContent;
switch (this.Uri.Segments.Count())
{
case 3:
floatingIpContent = TestHelper.CreateStream(GenerateCollectionPayload(this.FloatingIps, this.GenerateFloatingIpPayload, "floatingips"));
break;
case 4:
var floatId = this.Uri.Segments[3].TrimEnd('/').ToLower();
return HandleGetFloatingIp(floatId);
default:
//Unknown Uri format
throw new NotImplementedException();
}
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatingIpContent);
}
internal IHttpResponseAbstraction HandleGetFloatingIp(string floatingIpId)
{
var payloadFixture = @"{{
""floatingip"": {0}
}}";
var floatIp = this.FloatingIps.FirstOrDefault(ip => ip.Id == floatingIpId);
if (floatIp == null)
{
return TestHelper.CreateResponse(HttpStatusCode.NotFound);
}
var floatIpContent = string.Format(payloadFixture, GenerateFloatingIpPayload(floatIp)).ConvertToStream();
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatIpContent);
}
protected override IHttpResponseAbstraction HandlePost()
{
if (this.Uri.Segments.Count() >= 3)
{
switch (this.Uri.Segments[2].TrimEnd('/').ToLower())
{
case "floatingips":
return HandleCreateFloatingIp();
}
}
throw new NotImplementedException();
}
internal IHttpResponseAbstraction HandleCreateFloatingIp()
{
var payloadFixture = @"{{
""floatingip"": {0}
}}";
var ip = new FloatingIp(Guid.NewGuid().ToString(), "172.0.0." +(this.FloatingIps.Count +1), FloatingIpStatus.Active);
this.FloatingIps.Add(ip);
var floatIpContent = string.Format(payloadFixture, GenerateFloatingIpPayload(ip)).ConvertToStream();
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatIpContent);
}
protected override IHttpResponseAbstraction HandlePut()
{
throw new NotImplementedException();
@@ -99,19 +160,20 @@ namespace OpenStack.Test.Network
throw new NotImplementedException();
}
private string GenerateNetworksPayload(IEnumerable<OpenStack.Network.Network> networks)
private string GenerateCollectionPayload<T>(IEnumerable<T> collection, Func<T, string> genFunc,
string collectionName)
{
var payload = new StringBuilder();
payload.Append("{{ \"networks\": [");
payload.Append(string.Format("{{ \"{0}\": [", collectionName));
var first = true;
foreach (var item in networks)
foreach (var item in collection)
{
if (!first)
{
payload.Append(",");
}
payload.Append(GenerateNetworkPayload(item));
payload.Append(genFunc(item));
first = false;
}
payload.Append("] }");
@@ -134,6 +196,21 @@ namespace OpenStack.Test.Network
}}";
return string.Format(payloadFixture, network.Name, network.Id, network.Status.ToString().ToUpper());
}
private string GenerateFloatingIpPayload(FloatingIp floatingIp)
{
var payloadFixture = @"{{
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
""status"": ""{1}"",
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
""fixed_ip_address"": ""10.0.0.2"",
""floating_ip_address"": ""{2}"",
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
""id"": ""{0}""
}}";
return string.Format(payloadFixture, floatingIp.Id, floatingIp.Status.ToString().ToUpper(), floatingIp.FloatingIpAddress);
}
}
public class NetworkRestSimulatorFactory : IHttpAbstractionClientFactory

View File

@@ -68,7 +68,7 @@ namespace OpenStack.Test.Network
}
[TestMethod]
public async Task CanGetFlavors()
public async Task CanGetNetworks()
{
var ntw1 = new OpenStack.Network.Network("12345","MyNetwork", NetworkStatus.Active);
var ntw2 = new OpenStack.Network.Network("54321", "NetworkMy", NetworkStatus.Down);
@@ -85,5 +85,82 @@ namespace OpenStack.Test.Network
Assert.AreEqual(ntw1, respNetworks[0]);
Assert.AreEqual(ntw2, respNetworks[1]);
}
[TestMethod]
public async Task CanGetFloatingIps()
{
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
var ip2 = new OpenStack.Network.FloatingIp("54321", "172.0.0.2", FloatingIpStatus.Down);
var ips = new List<OpenStack.Network.FloatingIp>() { ip1, ip2 };
this.ServicePocoClient.GetFloatingIpsDelegate = () => Task.Factory.StartNew(() => (IEnumerable<OpenStack.Network.FloatingIp>)ips);
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
var resp = await client.GetFloatingIps();
Assert.IsNotNull(resp);
var respIps = resp.ToList();
Assert.AreEqual(2, respIps.Count());
Assert.AreEqual(ip1, respIps[0]);
Assert.AreEqual(ip2, respIps[1]);
}
[TestMethod]
public async Task CanGetFloatingIp()
{
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
this.ServicePocoClient.GetFloatingIpDelegate = (ip) => Task.Factory.StartNew(() => ip1);
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
var resp = await client.GetFloatingIp("12345");
Assert.IsNotNull(resp);
Assert.AreEqual(ip1, resp);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task GetFloatingIpWithNullFloatingIpIdThrows()
{
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
await client.GetFloatingIp(null);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task GetFloatingIpWithEmptyFloatingIpIdThrows()
{
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
await client.GetFloatingIp(string.Empty);
}
[TestMethod]
public async Task CanCreateFloatingIp()
{
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
this.ServicePocoClient.CreateFloatingIpDelegate = (ip) => Task.Factory.StartNew(() => ip1);
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
var resp = await client.CreateFloatingIp("12345");
Assert.IsNotNull(resp);
Assert.AreEqual(ip1, resp);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public async Task CreateFloatingIpWithNullNetworkIdThrows()
{
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
await client.CreateFloatingIp(null);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public async Task CreateFloatingIpWithEmptyNetworkIdThrows()
{
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
await client.CreateFloatingIp(string.Empty);
}
}
}

View File

@@ -142,5 +142,184 @@ namespace OpenStack.Test.Network
}
#endregion
#region Get Floating IPs Tests
[TestMethod]
public async Task CanGetFloatingIpsWithOkResponse()
{
var payload = @"{
""floatingips"": [
{
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
""status"": ""ACTIVE"",
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
""fixed_ip_address"": ""10.0.0.2"",
""floating_ip_address"": ""172.0.0.1"",
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
""id"": ""12345""
}
]
}";
var content = TestHelper.CreateStream(payload);
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
var result = await client.GetFloatingIps();
Assert.IsNotNull(result);
var floatingIps = result.ToList();
Assert.AreEqual(1, floatingIps.Count());
var floatingIp = floatingIps.First();
Assert.AreEqual("12345", floatingIp.Id);
Assert.AreEqual("172.0.0.1", floatingIp.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, floatingIp.Status);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenGettingFloatingIpsAndNotAuthed()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIps();
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenGettingFloatingIpsAndServerError()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIps();
}
#endregion
#region Get Floating IP Tests
[TestMethod]
public async Task CanGetFloatingIpWithOkResponse()
{
var payload = @"{
""floatingip"":
{
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
""status"": ""ACTIVE"",
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
""fixed_ip_address"": ""10.0.0.2"",
""floating_ip_address"": ""172.0.0.1"",
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
""id"": ""12345""
}
}";
var content = TestHelper.CreateStream(payload);
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
var result = await client.GetFloatingIp("12345");
Assert.IsNotNull(result);
Assert.AreEqual("12345", result.Id);
Assert.AreEqual("172.0.0.1", result.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, result.Status);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenGettingFloatingIpAndNotAuthed()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIp("12345");
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenGettingFloatingIpAndServerError()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIp("12345");
}
#endregion
#region Create Floating IP Tests
[TestMethod]
public async Task CanCreateFloatingIpWithOkResponse()
{
var payload = @"{
""floatingip"":
{
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
""status"": ""ACTIVE"",
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
""fixed_ip_address"": ""10.0.0.2"",
""floating_ip_address"": ""172.0.0.1"",
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
""id"": ""12345""
}
}";
var content = TestHelper.CreateStream(payload);
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
var result = await client.CreateFloatingIp("12345");
Assert.IsNotNull(result);
Assert.AreEqual("12345", result.Id);
Assert.AreEqual("172.0.0.1", result.FloatingIpAddress);
Assert.AreEqual(FloatingIpStatus.Active, result.Status);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenCreatingFloatingIpAndNotAuthed()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CreateFloatingIp("12345");
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task ExceptionthrownWhenCreatingFloatingIpAndServerError()
{
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
await client.CreateFloatingIp("12345");
}
#endregion
}
}

View File

@@ -36,7 +36,7 @@ namespace OpenStack.Test.Network
{
internal NetworkRestSimulator simulator;
internal string authId = "12345";
internal Uri endpoint = new Uri("http://testnetworkendpoint.com/v2/1234567890");
internal Uri endpoint = new Uri("http://testnetworkendpoint.com");
internal IServiceLocator ServiceLocator;
[TestInitialize]
@@ -91,7 +91,7 @@ namespace OpenStack.Test.Network
await client.GetNetworks();
Assert.AreEqual(string.Format("{0}/networks", endpoint), this.simulator.Uri.ToString());
Assert.AreEqual(string.Format("{0}/networks", endpoint +"v2.0"), this.simulator.Uri.ToString());
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
}
@@ -112,5 +112,154 @@ namespace OpenStack.Test.Network
}
#endregion
#region Get FloatingIps Tests
[TestMethod]
public async Task GetFloatingIpsIncludesAuthHeader()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIps();
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
}
[TestMethod]
public async Task GetFloatingIpsFormsCorrectUrlAndMethod()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIps();
Assert.AreEqual(string.Format("{0}/floatingips", endpoint + "v2.0"), this.simulator.Uri.ToString());
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
}
[TestMethod]
public async Task CanGetFloatingIps()
{
this.simulator.FloatingIps.Add(new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active));
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
var resp = await client.GetFloatingIps();
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
var respContent = TestHelper.GetStringFromStream(resp.Content);
Assert.IsTrue(respContent.Length > 0);
}
#endregion
#region Get FloatingIp Tests
[TestMethod]
public async Task GetFloatingIpIncludesAuthHeader()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.GetNetworks();
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
}
[TestMethod]
public async Task GetFloatingIpFormsCorrectUrlAndMethod()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.GetFloatingIp("12345");
Assert.AreEqual(string.Format("{0}/floatingips/12345", endpoint + "v2.0"), this.simulator.Uri.ToString());
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
}
[TestMethod]
public async Task CanGetFloatinIp()
{
this.simulator.FloatingIps.Add(new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active));
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
var resp = await client.GetFloatingIp("12345");
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
var respContent = TestHelper.GetStringFromStream(resp.Content);
Assert.IsTrue(respContent.Length > 0);
}
#endregion
#region Create FloatingIp Tests
[TestMethod]
public async Task CreateFloatingIpIncludesAuthHeader()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.CreateFloatingIp("12345");
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
}
[TestMethod]
public async Task CreateFloatingIpFormsCorrectUrlAndMethod()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
await client.CreateFloatingIp("12345");
Assert.AreEqual(string.Format("{0}/floatingips", endpoint + "v2.0"), this.simulator.Uri.ToString());
Assert.AreEqual(HttpMethod.Post, this.simulator.Method);
}
[TestMethod]
public async Task CanCreateFloatinIp()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
var resp = await client.CreateFloatingIp("12345");
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
var respContent = TestHelper.GetStringFromStream(resp.Content);
Assert.IsTrue(respContent.Length > 0);
}
[TestMethod]
public async Task CreateFloatinIpFormCorrectBody()
{
var client =
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
var resp = await client.CreateFloatingIp("12345");
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
this.simulator.Content.Position = 0;
var body = TestHelper.GetStringFromStream(this.simulator.Content);
var ipObj = JObject.Parse(body);
Assert.IsNotNull(ipObj);
Assert.IsNotNull(ipObj["floatingip"]);
Assert.IsNotNull(ipObj["floatingip"]["floating_network_id"]);
Assert.AreEqual("12345", (string)ipObj["floatingip"]["floating_network_id"]);
}
#endregion
}
}

View File

@@ -26,11 +26,31 @@ namespace OpenStack.Test.Network
{
public Func<Task<IEnumerable<OpenStack.Network.Network>>> GetNetworksDelegate { get; set; }
public Func<Task<IEnumerable<OpenStack.Network.FloatingIp>>> GetFloatingIpsDelegate { get; set; }
public Func<string, Task<OpenStack.Network.FloatingIp>> GetFloatingIpDelegate { get; set; }
public Func<string, Task<OpenStack.Network.FloatingIp>> CreateFloatingIpDelegate { get; set; }
public async Task<IEnumerable<OpenStack.Network.Network>> GetNetworks()
{
return await this.GetNetworksDelegate();
}
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
{
return await GetFloatingIpsDelegate();
}
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
{
return await GetFloatingIpDelegate(floatingIpId);
}
public async Task<FloatingIp> CreateFloatingIp(string networkId)
{
return await CreateFloatingIpDelegate(networkId);
}
}
public class TestNetworkServicePocoClientFactory : INetworkServicePocoClientFactory

View File

@@ -35,6 +35,21 @@ namespace OpenStack.Test.Network
{
return Task.Factory.StartNew(() => Responses.Dequeue());
}
public Task<IHttpResponseAbstraction> GetFloatingIps()
{
return Task.Factory.StartNew(() => Responses.Dequeue());
}
public Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId)
{
return Task.Factory.StartNew(() => Responses.Dequeue());
}
public Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId)
{
return Task.Factory.StartNew(() => Responses.Dequeue());
}
}
public class TestNetworkServiceRestClientFactory : INetworkServiceRestClientFactory

View File

@@ -83,6 +83,7 @@
<Compile Include="Identity\OpenStackServiceCatalogTests.cs" />
<Compile Include="Identity\IdentityServiceClientDefinitionTests.cs" />
<Compile Include="Identity\OpenStackRegionResolverTests.cs" />
<Compile Include="Network\FloatingIpPayloadConverterTests.cs" />
<Compile Include="Network\NetworkServiceClientTests.cs" />
<Compile Include="Network\NetworkServicePocoClientTests.cs" />
<Compile Include="Network\NetworkPayloadConverterTests.cs" />

View File

@@ -63,7 +63,7 @@ namespace OpenStack.Common
/// <returns>A complete request Uri.</returns>
internal Uri CreateRequestUri(Uri endpoint, params string[] values)
{
var temp = new List<string> { endpoint.AbsoluteUri };
var temp = new List<string> { endpoint.AbsoluteUri.TrimEnd('/') };
temp.AddRange(values);
return new Uri(string.Join("/", temp.ToArray()));
}

View File

@@ -0,0 +1,52 @@
// /* ============================================================================
// Copyright 2014 Hewlett Packard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================ */
namespace OpenStack.Network
{
/// <summary>
/// Represents a Floating IP address on the remote OpenStack instance.
/// </summary>
public class FloatingIp
{
/// <summary>
/// Gets the id of the FloatingIp.
/// </summary>
public string Id { get; internal set; }
/// <summary>
/// Gets the status of the FloatingIp.
/// </summary>
public FloatingIpStatus Status { get; internal set; }
/// <summary>
/// Gets the floating ip address of the FloatingIp.
/// </summary>
public string FloatingIpAddress { get; internal set; }
/// <summary>
/// Create a new instance of the FloatingIp class.
/// </summary>
/// <param name="id">The Id of the floating ip.</param>
/// <param name="FloatingIpAddress">The floating ip address of the floating ip.</param>
/// <param name="status">The status of the floating ip.</param>
internal FloatingIp(string id, string FloatingIpAddress, FloatingIpStatus status)
{
this.Id = id;
this.FloatingIpAddress = FloatingIpAddress;
this.Status = status;
}
}
}

View File

@@ -0,0 +1,122 @@
// /* ============================================================================
// Copyright 2014 Hewlett Packard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================ */
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using OpenStack.Common;
using System.Linq;
namespace OpenStack.Network
{
using System;
/// <inheritdoc/>
internal class FloatingIpPayloadConverter : IFloatingIpPayloadConverter
{
/// <inheritdoc/>
public FloatingIp Convert(string payload)
{
payload.AssertIsNotNullOrEmpty("payload", "A null or empty floating ip payload cannot be converted.");
try
{
var token = JToken.Parse(payload);
return ConvertFloatingIp(token["floatingip"]);
}
catch (FormatException)
{
throw;
}
catch (Exception ex)
{
throw new FormatException(
string.Format("Floating IP payload could not be parsed. Payload: '{0}'", payload), ex);
}
}
/// <summary>
/// Converts a json token into a FloatingIp object.
/// </summary>
/// <param name="floatingIpToken">The json Token to convert.</param>
/// <returns>A FloatingIp object.</returns>
internal FloatingIp ConvertFloatingIp(JToken floatingIpToken)
{
var floatingIpAddress = string.Empty;
var id = string.Empty;
var status = string.Empty;
try
{
floatingIpAddress = (string)floatingIpToken["floating_ip_address"];
id = (string)floatingIpToken["id"];
status = (string) floatingIpToken["status"];
if (string.IsNullOrEmpty(floatingIpAddress) || string.IsNullOrEmpty(id) || string.IsNullOrEmpty(status))
{
throw new FormatException();
}
return new FloatingIp(id, floatingIpAddress, status.GetFloatingIpStatus());
}
catch (Exception ex)
{
var msg = "Floating IP payload could not be parsed.";
if (!string.IsNullOrEmpty(id) && floatingIpToken != null)
{
msg = string.Format(
"Floating IP with Id '{0}' payload could not be parsed. Payload: '{1}'", id, floatingIpToken);
}
else if (floatingIpToken != null)
{
msg = string.Format("Floating IP payload could not be parsed. Payload: '{0}'", floatingIpToken);
}
throw new FormatException(msg, ex);
}
}
/// <inheritdoc/>
public IEnumerable<FloatingIp> ConvertFloatingIps(string payload)
{
payload.AssertIsNotNull("payload", "A null floating IPs payload cannot be converted.");
var floatingIps = new List<FloatingIp>();
if (String.IsNullOrEmpty(payload))
{
return floatingIps;
}
try
{
var payloadToken = JToken.Parse(payload);
var floatingIpArray = payloadToken["floatingips"];
floatingIps.AddRange(floatingIpArray.Select(ConvertFloatingIp));
}
catch (FormatException)
{
throw;
}
catch (Exception ex)
{
throw new FormatException(
string.Format("Floating IPs payload could not be parsed. Payload: '{0}'", payload), ex);
}
return floatingIps;
}
}
}

View File

@@ -0,0 +1,67 @@
// /* ============================================================================
// Copyright 2014 Hewlett Packard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================ */
using OpenStack.Common;
namespace OpenStack.Network
{
/// <summary>
/// Represents the states that a Floating IP can be in.
/// </summary>
public enum FloatingIpStatus
{
/// <summary>
/// The Floating IP is active and available.
/// </summary>
Active,
/// <summary>
/// The Floating IP is down and unavailable.
/// </summary>
Down,
/// <summary>
/// The Floating IP is in an unknown state.
/// </summary>
Unknown
}
/// <summary>
/// Static class for holding FloatingIpStatus related extention methods.
/// </summary>
public static class FloatingIpStatusExtentions
{
/// <summary>
/// Creates a FloatingIpStatus enum from a string.
/// </summary>
/// <param name="input">The input string.</param>
/// <returns>A FloatingIpStatus enum.</returns>
public static FloatingIpStatus GetFloatingIpStatus(this string input)
{
input.AssertIsNotNullOrEmpty("input", "Cannot get Floating IP status with null or empty value.");
switch (input.ToLowerInvariant())
{
case "active":
return FloatingIpStatus.Active;
case "down":
return FloatingIpStatus.Down;
default:
return FloatingIpStatus.Unknown;
}
}
}
}

View File

@@ -0,0 +1,40 @@
// /* ============================================================================
// Copyright 2014 Hewlett Packard
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ============================================================================ */
using System.Collections.Generic;
namespace OpenStack.Network
{
/// <summary>
/// Converter that can be used to convert an HTTP payload into a FloatingIp Poco object.
/// </summary>
public interface IFloatingIpPayloadConverter
{
/// <summary>
/// Converts an HTTP payload into a FloatingIp object.
/// </summary>
/// <param name="payload">The HTTP payload to convert. </param>
/// <returns>A FloatingIp object.</returns>
FloatingIp Convert(string payload);
/// <summary>
/// Converts an HTTP payload into a list of FloatingIp objects.
/// </summary>
/// <param name="payload">The HTTP payload to convert.</param>
/// <returns>An enumerable list of FloatingIp objects.</returns>
IEnumerable<FloatingIp> ConvertFloatingIps(string payload);
}
}

View File

@@ -29,5 +29,25 @@ namespace OpenStack.Network
/// </summary>
/// <returns>An enumerable list of networks.</returns>
Task<IEnumerable<Network>> GetNetworks();
/// <summary>
/// Gets a list of Floating IPs from the remote OpenStack instance.
/// </summary>
/// <returns>An enumerable list of floating ips.</returns>
Task<IEnumerable<FloatingIp>> GetFloatingIps();
/// <summary>
/// Gets the details of a Floating IP from the remote OpenStack instance.
/// </summary>
/// <param name="floatingIpId">The id of the target floating ip.</param>
/// <returns>A FloatingIp object.</returns>
Task<FloatingIp> GetFloatingIp(string floatingIpId);
/// <summary>
/// Creates a Floating IP on the remote OpenStack instance.
/// </summary>
/// <param name="networkId">The network id to use when creating the new ip address.</param>
/// <returns>A FloatingIp object.</returns>
Task<FloatingIp> CreateFloatingIp(string networkId);
}
}

View File

@@ -29,5 +29,25 @@ namespace OpenStack.Network
/// </summary>
/// <returns>An enumerable list of networks.</returns>
Task<IEnumerable<Network>> GetNetworks();
/// <summary>
/// Gets a list of Floating IPs from the remote OpenStack instance.
/// </summary>
/// <returns>An enumerable list of floating ips.</returns>
Task<IEnumerable<FloatingIp>> GetFloatingIps();
/// <summary>
/// Gets the details of a Floating IP from the remote OpenStack instance.
/// </summary>
/// <param name="floatingIpId">The id of the target floating ip.</param>
/// <returns>A FloatingIp object.</returns>
Task<FloatingIp> GetFloatingIp(string floatingIpId);
/// <summary>
/// Creates a Floating IP on the remote OpenStack instance.
/// </summary>
/// <param name="networkId">The network id to use when creating the new ip address.</param>
/// <returns>A FloatingIp object.</returns>
Task<FloatingIp> CreateFloatingIp(string networkId);
}
}

View File

@@ -29,5 +29,25 @@ namespace OpenStack.Network
/// </summary>
/// <returns>An HTTP response from the remote server.</returns>
Task<IHttpResponseAbstraction> GetNetworks();
/// <summary>
/// Gets a list of Floating IPs from the remote OpenStack instance.
/// </summary>
/// <returns>An HTTP response from the remote server.</returns>
Task<IHttpResponseAbstraction> GetFloatingIps();
/// <summary>
/// Gets the details of a Floating IP from the remote OpenStack instance.
/// </summary>
/// <param name="floatingIpId">The id of the target floating ip.</param>
/// <returns>An HTTP response from the remote server.</returns>
Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId);
/// <summary>
/// Creates a Floating IP on the remote OpenStack instance.
/// </summary>
/// <param name="networkId">The network id to use when creating the new ip address.</param>
/// <returns>An HTTP response from the remote server.</returns>
Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId);
}
}

View File

@@ -37,7 +37,7 @@ namespace OpenStack.Network
public NetworkStatus Status { get; internal set; }
/// <summary>
/// Create a new instance of the ComputeItem class.
/// Create a new instance of the Network class.
/// </summary>
/// <param name="id">The Id of the network.</param>
/// <param name="name">The name of the network.</param>

View File

@@ -53,6 +53,31 @@ namespace OpenStack.Network
return await client.GetNetworks();
}
/// <inheritdoc/>
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
{
var client = this.GetPocoClient();
return await client.GetFloatingIps();
}
/// <inheritdoc/>
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
{
floatingIpId.AssertIsNotNullOrEmpty("floatingIpId", "Cannot get a floating ip with a null or empty id.");
var client = this.GetPocoClient();
return await client.GetFloatingIp(floatingIpId);
}
/// <inheritdoc/>
public async Task<FloatingIp> CreateFloatingIp(string networkId)
{
networkId.AssertIsNotNullOrEmpty("networkId", "Cannot create a floating ip with a null or empty network id.");
var client = this.GetPocoClient();
return await client.CreateFloatingIp(networkId);
}
/// <summary>
/// Gets a client to interact with the remote OpenStack instance.
/// </summary>

View File

@@ -59,6 +59,57 @@ namespace OpenStack.Network
return networks;
}
/// <inheritdoc/>
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
{
var client = this.GetRestClient();
var resp = await client.GetFloatingIps();
if (resp.StatusCode != HttpStatusCode.OK)
{
throw new InvalidOperationException(string.Format("Failed to get floating ips. The remote server returned the following status code: '{0}'.", resp.StatusCode));
}
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
var floatingIps = converter.ConvertFloatingIps(await resp.ReadContentAsStringAsync());
return floatingIps;
}
/// <inheritdoc/>
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
{
var client = this.GetRestClient();
var resp = await client.GetFloatingIp(floatingIpId);
if (resp.StatusCode != HttpStatusCode.OK)
{
throw new InvalidOperationException(string.Format("Failed to get floating ip. The remote server returned the following status code: '{0}'.", resp.StatusCode));
}
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
var floatingIp = converter.Convert(await resp.ReadContentAsStringAsync());
return floatingIp;
}
/// <inheritdoc/>
public async Task<FloatingIp> CreateFloatingIp(string networkId)
{
var client = this.GetRestClient();
var resp = await client.CreateFloatingIp(networkId);
if (resp.StatusCode != HttpStatusCode.OK)
{
throw new InvalidOperationException(string.Format("Failed to create floating ip. The remote server returned the following status code: '{0}'.", resp.StatusCode));
}
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
var floatingIp = converter.Convert(await resp.ReadContentAsStringAsync());
return floatingIp;
}
/// <summary>
/// Gets a client that can be used to connect to the REST endpoints of an OpenStack network service.
/// </summary>

View File

@@ -14,8 +14,10 @@
// limitations under the License.
// ============================================================================ */
using System.Dynamic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using OpenStack.Common;
using OpenStack.Common.Http;
using OpenStack.Common.ServiceLocation;
@@ -26,6 +28,7 @@ namespace OpenStack.Network
internal class NetworkServiceRestClient : OpenStackServiceRestClientBase, INetworkServiceRestClient
{
internal const string NetworksUrlMoniker = "networks";
internal const string FloatingIpsUrlMoniker = "floatingips";
internal const string NetworkVersionMoniker = "v2.0";
/// <summary>
@@ -47,5 +50,49 @@ namespace OpenStack.Network
return await client.SendAsync();
}
/// <inheritdoc/>
public async Task<IHttpResponseAbstraction> GetFloatingIps()
{
var client = this.GetHttpClient(this.Context);
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker);
client.Method = HttpMethod.Get;
return await client.SendAsync();
}
/// <inheritdoc/>
public async Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId)
{
floatingIpId.AssertIsNotNullOrEmpty("floatingIpId", "Cannot get a floating ip with a null or empty id.");
var client = this.GetHttpClient(this.Context);
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker, floatingIpId);
client.Method = HttpMethod.Get;
return await client.SendAsync();
}
/// <inheritdoc/>
public async Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId)
{
var client = this.GetHttpClient(this.Context);
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker);
client.Method = HttpMethod.Post;
client.ContentType = "application/json";
dynamic body = new ExpandoObject();
dynamic networkIdProp = new ExpandoObject();
networkIdProp.floating_network_id = networkId;
body.floatingip = networkIdProp;
string requestBody = JToken.FromObject(body).ToString();
client.Content = requestBody.ConvertToStream();
return await client.SendAsync();
}
}
}

View File

@@ -111,9 +111,12 @@
<Compile Include="IOpenStackServiceClient.cs" />
<Compile Include="IOpenStackServiceClientDefinition.cs" />
<Compile Include="IOpenStackServiceClientManager.cs" />
<Compile Include="Network\FloatingIp.cs" />
<Compile Include="Network\IFloatingIpPayloadConverter.cs" />
<Compile Include="Network\INetworkServiceClient.cs" />
<Compile Include="Network\INetworkServicePocoClient.cs" />
<Compile Include="Network\INetworkServicePocoClientFactory.cs" />
<Compile Include="Network\FloatingIpPayloadConverter.cs" />
<Compile Include="Network\NetworkPayloadConverter.cs" />
<Compile Include="Network\INetworkPayloadConverter.cs" />
<Compile Include="Network\INetworkServiceRestClient.cs" />
@@ -125,6 +128,7 @@
<Compile Include="Network\NetworkServicePocoClientFactory.cs" />
<Compile Include="Network\NetworkServiceRestClient.cs" />
<Compile Include="Network\NetworkServiceRestClientFactory.cs" />
<Compile Include="Network\FloatingIpStatus.cs" />
<Compile Include="Network\NetworkStatus.cs" />
<Compile Include="OpenStackClient.cs" />
<Compile Include="OpenStackClientFactory.cs" />

View File

@@ -63,6 +63,7 @@ namespace OpenStack
manager.RegisterServiceInstance(typeof(IOpenStackServiceEndpointPayloadConverter), new OpenStackServiceEndpointPayloadConverter());
manager.RegisterServiceInstance(typeof(IComputeFlavorPayloadConverter), new ComputeFlavorPayloadConverter());
manager.RegisterServiceInstance(typeof(INetworkPayloadConverter), new NetworkPayloadConverter());
manager.RegisterServiceInstance(typeof(IFloatingIpPayloadConverter), new FloatingIpPayloadConverter());
manager.RegisterServiceInstance(typeof(IComputeImagePayloadConverter), new ComputeImagePayloadConverter());
manager.RegisterServiceInstance(typeof(IComputeItemMetadataPayloadConverter), new ComputeItemMetadataPayloadConverter());
manager.RegisterServiceInstance(typeof(IComputeServerPayloadConverter), new ComputeServerPayloadConverter());

View File

@@ -277,6 +277,18 @@
<Compile Include="..\OpenStack\IOpenStackServiceClientManager.cs">
<Link>IOpenStackServiceClientManager.cs</Link>
</Compile>
<Compile Include="..\OpenStack\Network\FloatingIp.cs">
<Link>Network\FloatingIp.cs</Link>
</Compile>
<Compile Include="..\OpenStack\Network\FloatingIpPayloadConverter.cs">
<Link>Network\FloatingIpPayloadConverter.cs</Link>
</Compile>
<Compile Include="..\OpenStack\Network\FloatingIpStatus.cs">
<Link>Network\FloatingIpStatus.cs</Link>
</Compile>
<Compile Include="..\OpenStack\Network\IFloatingIpPayloadConverter.cs">
<Link>Network\IFloatingIpPayloadConverter.cs</Link>
</Compile>
<Compile Include="..\OpenStack\Network\INetworkPayloadConverter.cs">
<Link>Network\INetworkPayloadConverter.cs</Link>
</Compile>