Skip to content

Commit

Permalink
Enhance Initialization and Resilience with Multiple Node URLs for Imp…
Browse files Browse the repository at this point in the history
…roved Failover Handling (#8)
  • Loading branch information
lausannel authored Jul 9, 2024
1 parent 1d5ab6c commit 58cf1db
Show file tree
Hide file tree
Showing 107 changed files with 13,238 additions and 6,805 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

# Apache IoTDB Client for C#

[![E2E Tests](https://github.com/apache/iotdb-client-csharp/actions/workflows/e2e.yml/badge.svg)](https://github.com/apache/iotdb-client-csharp/actions/workflows/e2e.yml)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
## Overview

This is the C# client of Apache IoTDB.
Expand All @@ -41,7 +43,8 @@ We have prepared Nuget Package for C# users. Users can directly install the clie
dotnet add package Apache.IoTDB
```

Note that the `Apache.IoTDB` package only supports versions greater than `.net framework 4.6.1`.
> [!NOTE]
> The `Apache.IoTDB` package only supports versions greater than `.net framework 4.6.1`.
## Prerequisites

Expand All @@ -65,7 +68,7 @@ NLog >= 4.7.9

### OS

* Linux, Macos or other unix-like OS
* Linux, MacOS or other unix-like OS
* Windows+bash(WSL, cygwin, Git Bash)

### Command Line Tools
Expand Down
8 changes: 5 additions & 3 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
[English](./README.md) | [中文](./README_ZH.md)

# Apache IoTDB C#语言客户端

[![E2E Tests](https://github.com/apache/iotdb-client-csharp/actions/workflows/e2e.yml/badge.svg)](https://github.com/apache/iotdb-client-csharp/actions/workflows/e2e.yml)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
## 概览

本仓库是Apache IoTDB的C#语言客户端,与其他语言支持相同语义的用户接口。
Expand All @@ -38,8 +39,9 @@ Apache IoTDB Github: https://github.com/apache/iotdb
```sh
dotnet add package Apache.IoTDB
```
> [!NOTE]
> 请注意,`Apache.IoTDB`这个包仅支持大于`.net framework 4.6.1`的版本。
请注意,`Apache.IoTDB`这个包仅支持大于`.net framework 4.6.1`的版本。
## 环境准备

.NET SDK Version >= 5.0
Expand All @@ -62,7 +64,7 @@ NLog >= 4.7.9

### 操作系统

* Linux、Macos或其他类unix系统
* Linux、MacOS或其他类unix系统
* Windows+bash(WSL、cygwin、Git Bash)

### 命令行工具
Expand Down
Empty file removed courgette.log
Empty file.
18 changes: 10 additions & 8 deletions samples/Apache.IoTDB.Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
using System;
using System.Threading.Tasks;

namespace Apache.IoTDB.Samples
{
public static class Program
namespace Apache.IoTDB.Samples
{
public static class Program
{
public static async Task Main(string[] args)
{
var sessionPoolTest = new SessionPoolTest("iotdb");
await sessionPoolTest.Test() ;
{
var utilsTest = new UtilsTest();
utilsTest.TestParseEndPoint();
var sessionPoolTest = new SessionPoolTest("iotdb");
await sessionPoolTest.Test();
}

public static void OpenDebugMode(this SessionPool session)
Expand All @@ -20,6 +22,6 @@ public static void OpenDebugMode(this SessionPool session)
builder.AddConsole();
builder.AddNLog();
});
}
}
}
}
}
53 changes: 53 additions & 0 deletions samples/Apache.IoTDB.Samples/SessionPoolTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Apache.IoTDB.DataStructure;
using ConsoleTableExt;
using System.Net.Sockets;
using System.Diagnostics;

namespace Apache.IoTDB.Samples
{
Expand All @@ -15,6 +16,7 @@ public partial class SessionPoolTest
public int port = 6667;
public string user = "root";
public string passwd = "root";
public List<string> node_urls = new();
public int fetch_size = 500;
public int processed_size = 4;
public bool debug = false;
Expand All @@ -36,10 +38,17 @@ public partial class SessionPoolTest
public SessionPoolTest(string _host = "localhost")
{
host = _host;
node_urls.Add(host + ":" + port);
}

public async Task Test()
{
await TestOpenWithNodeUrls();

await TestOpenWith2NodeUrls();

await TestOpenWithNodeUrlsAndInsertOneRecord();

await TestInsertOneRecord();

await TestInsertAlignedRecord();
Expand Down Expand Up @@ -112,6 +121,50 @@ public async Task Test()

await TestNonSqlBy_ADO();
}
public async Task TestOpenWithNodeUrls()
{
var session_pool = new SessionPool(node_urls, 8);
await session_pool.Open(false);
Debug.Assert(session_pool.IsOpen());
if (debug) session_pool.OpenDebugMode();
await session_pool.Close();
Console.WriteLine("TestOpenWithNodeUrls Passed!");
}
public async Task TestOpenWith2NodeUrls()
{
var session_pool = new SessionPool(new List<string>() { host + ":" + port, host + ":" + (port + 1) }, 8);
await session_pool.Open(false);
Debug.Assert(session_pool.IsOpen());
if (debug) session_pool.OpenDebugMode();
await session_pool.Close();

session_pool = new SessionPool(new List<string>() { host + ":" + (port + 1), host + ":" + port }, 8);
await session_pool.Open(false);
Debug.Assert(session_pool.IsOpen());
if (debug) session_pool.OpenDebugMode();
await session_pool.Close();
Console.WriteLine("TestOpenWith2NodeUrls Passed!");
}
public async Task TestOpenWithNodeUrlsAndInsertOneRecord()
{
var session_pool = new SessionPool(node_urls, 8);
await session_pool.Open(false);
if (debug) session_pool.OpenDebugMode();
await session_pool.DeleteStorageGroupAsync(test_group_name);
var status = await session_pool.CreateTimeSeries(
string.Format("{0}.{1}.{2}", test_group_name, test_device, test_measurements[0]),
TSDataType.TEXT, TSEncoding.PLAIN, Compressor.SNAPPY);
status = await session_pool.CreateTimeSeries(
string.Format("{0}.{1}.{2}", test_group_name, test_device, test_measurements[1]),
TSDataType.TEXT, TSEncoding.PLAIN, Compressor.SNAPPY);
status = await session_pool.CreateTimeSeries(
string.Format("{0}.{1}.{2}", test_group_name, test_device, test_measurements[2]),
TSDataType.TEXT, TSEncoding.PLAIN, Compressor.SNAPPY);
var rowRecord = new RowRecord(1668404120807, new() { "1111111", "22222", "333333" }, new() { test_measurements[0], test_measurements[1], test_measurements[2] });
status = await session_pool.InsertRecordsAsync(new List<string>() { string.Format("{0}.{1}", test_group_name, test_device) }, new List<RowRecord>() { rowRecord });
Debug.Assert(status == 0);
Console.WriteLine("TestOpenWithNodeUrlsAndInsertOneRecord Passed!");
}
public async Task TestInsertOneRecord()
{
var session_pool = new SessionPool(host, port, 1);
Expand Down
62 changes: 62 additions & 0 deletions samples/Apache.IoTDB.Samples/UtilsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Diagnostics;

namespace Apache.IoTDB.Samples
{
public class UtilsTest
{
private Utils _utilFunctions = new Utils();
public void Test()
{
TestParseEndPoint();
}

public void TestParseEndPoint()
{
TestIPv4Address();
TestIPv6Address();
TestInvalidInputs();
}

private void TestIPv4Address()
{
string correctEndpointIPv4 = "192.168.1.1:8080";
var endpoint = _utilFunctions.ParseTEndPointIpv4AndIpv6Url(correctEndpointIPv4);
Debug.Assert(endpoint.Ip == "192.168.1.1", "IPv4 address mismatch.");
Debug.Assert(endpoint.Port == 8080, "IPv4 port mismatch.");
Console.WriteLine("TestIPv4Address passed.");
}

private void TestIPv6Address()
{
string correctEndpointIPv6 = "[2001:db8:85a3::8a2e:370:7334]:443";
var endpoint = _utilFunctions.ParseTEndPointIpv4AndIpv6Url(correctEndpointIPv6);
Debug.Assert(endpoint.Ip == "2001:db8:85a3::8a2e:370:7334", "IPv6 address mismatch.");
Debug.Assert(endpoint.Port == 443, "IPv6 port mismatch.");
Console.WriteLine("TestIPv6Address passed.");
}

private void TestInvalidInputs()
{
string noPort = "192.168.1.1";
var endpointNoPort = _utilFunctions.ParseTEndPointIpv4AndIpv6Url(noPort);
Debug.Assert(string.IsNullOrEmpty(endpointNoPort.Ip) && endpointNoPort.Port == 0, "Failed to handle missing port.");

string emptyInput = "";
var endpointEmpty = _utilFunctions.ParseTEndPointIpv4AndIpv6Url(emptyInput);
Debug.Assert(string.IsNullOrEmpty(endpointEmpty.Ip) && endpointEmpty.Port == 0, "Failed to handle empty input.");

string invalidFormat = "192.168.1.1:port";
try
{
var endpointInvalid = _utilFunctions.ParseTEndPointIpv4AndIpv6Url(invalidFormat);
Debug.Fail("Should have thrown an exception due to invalid port.");
}
catch (FormatException)
{
// Expected exception
}
Console.WriteLine("TestInvalidInputs passed.");
}
}
}
29 changes: 18 additions & 11 deletions src/Apache.IoTDB/Apache.IoTDB.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net5.0;net6.0;netstandard2.1;netstandard2.0;net461</TargetFrameworks>
<LangVersion>latest</LangVersion>
<PropertyGroup>
<TargetFrameworks>net5.0;net6.0;netstandard2.1;netstandard2.0;net461</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Authors>eedalong, lausannel, MysticBoy, Aiemu, HTHou</Authors>
<Company>LiuLin Lab</Company>
<PackageDescription>C# client for Apache IoTDB</PackageDescription>
<PackageProjectUrl>https://github.com/apache/iotdb-client-csharp</PackageProjectUrl>
<RepositoryUrl>https://github.com/apache/iotdb-client-csharp</RepositoryUrl>

</PropertyGroup>

<ItemGroup>
<PackageReference Include="ApacheThrift" Version="0.14.1" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net461' or '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="IndexRange" Version="1.0.2" />
</ItemGroup>
</PropertyGroup>

</Project>
<ItemGroup>
<PackageReference Include="ApacheThrift" Version="0.14.1" />
</ItemGroup>
<ItemGroup
Condition="'$(TargetFramework)' == 'net461' or '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="IndexRange" Version="1.0.2" />
</ItemGroup>

</Project>
4 changes: 3 additions & 1 deletion src/Apache.IoTDB/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ public class Client
public long SessionId { get; }
public long StatementId { get; }
public TFramedTransport Transport { get; }
public TEndPoint EndPoint { get; }

public Client(IClientRPCService.Client client, long sessionId, long statementId, TFramedTransport transport)
public Client(IClientRPCService.Client client, long sessionId, long statementId, TFramedTransport transport, TEndPoint endpoint)
{
ServiceClient = client;
SessionId = sessionId;
StatementId = statementId;
Transport = transport;
EndPoint = endpoint;
}
}
}
Loading

0 comments on commit 58cf1db

Please sign in to comment.