Skip to content

Commit 95018f5

Browse files
Merge branch 'master' of https://github.com/easymorph/server-sdk
2 parents c04aed6 + 23b3936 commit 95018f5

File tree

64 files changed

+3119
-870
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3119
-870
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## EasyMorph Sever .NET SDK
1+
## EasyMorph Server .NET SDK
22

33
This library allows you to interact with EasyMorph Server from a .NET application.
44

src/Client/DataTransferUtility.cs

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
using Morph.Server.Sdk.Model;
2+
using System;
3+
using System.IO;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace Morph.Server.Sdk.Client
8+
{
9+
/// <summary>
10+
/// Transfer file from/to server to/from local file
11+
/// </summary>
12+
public class DataTransferUtility : IDataTransferUtility
13+
{
14+
private int BufferSize { get; set; } = 81920;
15+
private readonly IMorphServerApiClient _morphServerApiClient;
16+
private readonly ApiSession _apiSession;
17+
18+
public DataTransferUtility(IMorphServerApiClient morphServerApiClient, ApiSession apiSession)
19+
{
20+
this._morphServerApiClient = morphServerApiClient ?? throw new ArgumentNullException(nameof(morphServerApiClient));
21+
this._apiSession = apiSession ?? throw new ArgumentNullException(nameof(apiSession));
22+
}
23+
24+
public async Task SpaceUploadFileAsync(string localFilePath, string serverFolder, CancellationToken cancellationToken, bool overwriteExistingFile = false)
25+
{
26+
if (!File.Exists(localFilePath))
27+
{
28+
throw new FileNotFoundException(string.Format("File '{0}' not found", localFilePath));
29+
}
30+
var fileSize = new FileInfo(localFilePath).Length;
31+
var fileName = Path.GetFileName(localFilePath);
32+
using (var fsSource = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))
33+
{
34+
var request = new SpaceUploadDataStreamRequest
35+
{
36+
DataStream = fsSource,
37+
FileName = fileName,
38+
FileSize = fileSize,
39+
OverwriteExistingFile = overwriteExistingFile,
40+
ServerFolder = serverFolder
41+
};
42+
await _morphServerApiClient.SpaceUploadDataStreamAsync(_apiSession, request, cancellationToken);
43+
return;
44+
}
45+
}
46+
47+
48+
49+
50+
public async Task SpaceDownloadFileIntoFileAsync(string remoteFilePath, string targetLocalFilePath, CancellationToken cancellationToken, bool overwriteExistingFile = false)
51+
{
52+
if (remoteFilePath == null)
53+
{
54+
throw new ArgumentNullException(nameof(remoteFilePath));
55+
}
56+
57+
if (targetLocalFilePath == null)
58+
{
59+
throw new ArgumentNullException(nameof(targetLocalFilePath));
60+
}
61+
62+
63+
var localFolder = Path.GetDirectoryName(targetLocalFilePath);
64+
var tempFile = Path.Combine(localFolder, Guid.NewGuid().ToString("D") + ".emtmp");
65+
66+
if (!overwriteExistingFile && File.Exists(targetLocalFilePath))
67+
{
68+
throw new Exception($"Destination file '{targetLocalFilePath}' already exists.");
69+
}
70+
71+
72+
try
73+
{
74+
using (Stream tempFileStream = File.Open(tempFile, FileMode.Create))
75+
{
76+
using (var serverStreamingData = await _morphServerApiClient.SpaceOpenStreamingDataAsync(_apiSession, remoteFilePath, cancellationToken))
77+
{
78+
await serverStreamingData.Stream.CopyToAsync(tempFileStream, BufferSize, cancellationToken);
79+
}
80+
}
81+
82+
if (File.Exists(targetLocalFilePath))
83+
{
84+
File.Delete(targetLocalFilePath);
85+
}
86+
File.Move(tempFile, targetLocalFilePath);
87+
88+
}
89+
finally
90+
{
91+
//drop file
92+
if (tempFile != null && File.Exists(tempFile))
93+
{
94+
File.Delete(tempFile);
95+
}
96+
97+
}
98+
}
99+
100+
public async Task SpaceDownloadFileIntoFolderAsync(string remoteFilePath, string targetLocalFolder, CancellationToken cancellationToken, bool overwriteExistingFile = false)
101+
{
102+
if (remoteFilePath == null)
103+
{
104+
throw new ArgumentNullException(nameof(remoteFilePath));
105+
}
106+
107+
if (targetLocalFolder == null)
108+
{
109+
throw new ArgumentNullException(nameof(targetLocalFolder));
110+
}
111+
112+
string destFileName = null;
113+
var tempFile = Path.Combine(targetLocalFolder, Guid.NewGuid().ToString("D") + ".emtmp");
114+
try
115+
{
116+
using (Stream tempFileStream = File.Open(tempFile, FileMode.Create))
117+
{
118+
119+
using (var serverStreamingData = await _morphServerApiClient.SpaceOpenStreamingDataAsync(_apiSession, remoteFilePath, cancellationToken))
120+
{
121+
destFileName = Path.Combine(targetLocalFolder, serverStreamingData.FileName);
122+
123+
if (!overwriteExistingFile && File.Exists(destFileName))
124+
{
125+
throw new Exception($"Destination file '{destFileName}' already exists.");
126+
}
127+
128+
await serverStreamingData.Stream.CopyToAsync(tempFileStream, BufferSize, cancellationToken);
129+
}
130+
}
131+
132+
if (File.Exists(destFileName))
133+
{
134+
File.Delete(destFileName);
135+
}
136+
File.Move(tempFile, destFileName);
137+
138+
}
139+
finally
140+
{
141+
//drop file
142+
if (tempFile != null && File.Exists(tempFile))
143+
{
144+
File.Delete(tempFile);
145+
}
146+
147+
}
148+
149+
}
150+
151+
public async Task SpaceUploadFileAsync(string localFilePath, string serverFolder, string destFileName, CancellationToken cancellationToken, bool overwriteExistingFile = false)
152+
{
153+
if (!File.Exists(localFilePath))
154+
{
155+
throw new FileNotFoundException(string.Format("File '{0}' not found", localFilePath));
156+
}
157+
var fileSize = new FileInfo(localFilePath).Length;
158+
159+
using (var fsSource = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))
160+
{
161+
var request = new SpaceUploadDataStreamRequest
162+
{
163+
DataStream = fsSource,
164+
FileName = destFileName,
165+
FileSize = fileSize,
166+
OverwriteExistingFile = overwriteExistingFile,
167+
ServerFolder = serverFolder
168+
};
169+
await _morphServerApiClient.SpaceUploadDataStreamAsync(_apiSession, request, cancellationToken);
170+
return;
171+
}
172+
}
173+
}
174+
175+
}
176+
177+

src/Client/IDataTransferUtility.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
4+
namespace Morph.Server.Sdk.Client
5+
{
6+
public interface IDataTransferUtility
7+
{
8+
Task SpaceUploadFileAsync(string localFilePath, string serverFolder, CancellationToken cancellationToken, bool overwriteExistingFile = false);
9+
Task SpaceUploadFileAsync(string localFilePath, string serverFolder, string destFileName, CancellationToken cancellationToken, bool overwriteExistingFile = false);
10+
Task SpaceDownloadFileIntoFileAsync(string remoteFilePath, string targetLocalFilePath, CancellationToken cancellationToken, bool overwriteExistingFile = false);
11+
Task SpaceDownloadFileIntoFolderAsync(string remoteFilePath, string targetLocalFolder, CancellationToken cancellationToken, bool overwriteExistingFile = false);
12+
}
13+
14+
}

src/Client/ILowLevelApiClient.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using Morph.Server.Sdk.Dto;
2+
using Morph.Server.Sdk.Model;
3+
using System;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Morph.Server.Sdk.Dto.Commands;
7+
using System.Collections.Generic;
8+
using Morph.Server.Sdk.Model.InternalModels;
9+
using Morph.Server.Sdk.Events;
10+
11+
namespace Morph.Server.Sdk.Client
12+
{
13+
internal interface ILowLevelApiClient: IDisposable
14+
{
15+
IRestClient RestClient { get; }
16+
17+
// TASKS
18+
Task<ApiResult<TaskStatusDto>> GetTaskStatusAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
19+
Task<ApiResult<SpaceTasksListDto>> GetTasksListAsync(ApiSession apiSession, CancellationToken cancellationToken);
20+
Task<ApiResult<SpaceTaskDto>> GetTaskAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
21+
Task<ApiResult<SpaceTaskDto>> TaskChangeModeAsync(ApiSession apiSession, Guid taskId, SpaceTaskChangeModeRequestDto requestDto, CancellationToken cancellationToken);
22+
23+
// RUN-STOP Task
24+
Task<ApiResult<RunningTaskStatusDto>> GetRunningTaskStatusAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
25+
Task<ApiResult<RunningTaskStatusDto>> StartTaskAsync(ApiSession apiSession, Guid taskId, TaskStartRequestDto taskStartRequestDto, CancellationToken cancellationToken);
26+
Task<ApiResult<NoContentResult>> StopTaskAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
27+
28+
// Tasks validation
29+
Task<ApiResult<ValidateTasksResponseDto>> ValidateTasksAsync(ApiSession apiSession, ValidateTasksRequestDto validateTasksRequestDto, CancellationToken cancellationToken);
30+
31+
32+
// Auth and sessions
33+
Task<ApiResult<NoContentResult>> AuthLogoutAsync(ApiSession apiSession, CancellationToken cancellationToken);
34+
Task<ApiResult<LoginResponseDto>> AuthLoginPasswordAsync(LoginRequestDto loginRequestDto, CancellationToken cancellationToken);
35+
Task<ApiResult<GenerateNonceResponseDto>> AuthGenerateNonce(CancellationToken cancellationToken);
36+
37+
38+
39+
// Server interaction
40+
Task<ApiResult<ServerStatusDto>> ServerGetStatusAsync(CancellationToken cancellationToken);
41+
42+
43+
// spaces
44+
45+
Task<ApiResult<SpacesEnumerationDto>> SpacesGetListAsync(CancellationToken cancellationToken);
46+
Task<ApiResult<SpacesLookupResponseDto>> SpacesLookupAsync(SpacesLookupRequestDto requestDto, CancellationToken cancellationToken);
47+
Task<ApiResult<SpaceStatusDto>> SpacesGetSpaceStatusAsync(ApiSession apiSession, string spaceName, CancellationToken cancellationToken);
48+
49+
// WEB FILES
50+
Task<ApiResult<SpaceBrowsingResponseDto>> WebFilesBrowseSpaceAsync(ApiSession apiSession, string folderPath, CancellationToken cancellationToken);
51+
Task<ApiResult<bool>> WebFileExistsAsync(ApiSession apiSession, string serverFilePath, CancellationToken cancellationToken);
52+
Task<ApiResult<NoContentResult>> WebFilesDeleteFileAsync(ApiSession apiSession, string serverFilePath, CancellationToken cancellationToken);
53+
Task<ApiResult<FetchFileStreamData>> WebFilesDownloadFileAsync(ApiSession apiSession, string serverFilePath, Action<FileTransferProgressEventArgs> onReceiveProgress, CancellationToken cancellationToken);
54+
Task<ApiResult<NoContentResult>> WebFilesPutFileStreamAsync(ApiSession apiSession, string serverFolder, SendFileStreamData sendFileStreamData, Action<FileTransferProgressEventArgs> onSendProgress, CancellationToken cancellationToken);
55+
Task<ApiResult<NoContentResult>> WebFilesPostFileStreamAsync(ApiSession apiSession, string serverFolder, SendFileStreamData sendFileStreamData, Action<FileTransferProgressEventArgs> onSendProgress, CancellationToken cancellationToken);
56+
57+
Task<ApiResult<ServerPushStreaming>> WebFilesOpenContiniousPostStreamAsync(ApiSession apiSession, string serverFolder, string fileName, CancellationToken cancellationToken);
58+
Task<ApiResult<ServerPushStreaming>> WebFilesOpenContiniousPutStreamAsync(ApiSession apiSession, string serverFolder, string fileName, CancellationToken cancellationToken);
59+
60+
}
61+
}
62+
63+
64+

src/Client/IMorphServerApiClient.cs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Net.Http;
5+
using System.Net.Security;
6+
using System.Security.Cryptography.X509Certificates;
47
using System.Threading;
58
using System.Threading.Tasks;
69
using Morph.Server.Sdk.Events;
@@ -9,29 +12,51 @@
912

1013
namespace Morph.Server.Sdk.Client
1114
{
12-
public interface IMorphServerApiClient
15+
16+
public interface IHasConfig
1317
{
14-
event EventHandler<FileEventArgs> FileProgress;
18+
IClientConfiguration Config { get; }
19+
}
1520

16-
Task<SpaceBrowsingInfo> BrowseSpaceAsync(ApiSession apiSession, string folderPath, CancellationToken cancellationToken);
21+
internal interface ICanCloseSession: IHasConfig, IDisposable
22+
{
1723
Task CloseSessionAsync(ApiSession apiSession, CancellationToken cancellationToken);
18-
Task DeleteFileAsync(ApiSession apiSession, string serverFolder, string fileName, CancellationToken cancellationToken);
19-
Task DownloadFileAsync(ApiSession apiSession, string remoteFilePath, Func<DownloadFileInfo, bool> handleFile, Stream streamToWriteTo, CancellationToken cancellationToken);
20-
Task<DownloadFileInfo> DownloadFileAsync(ApiSession apiSession, string remoteFilePath, Stream streamToWriteTo, CancellationToken cancellationToken);
21-
Task<bool> FileExistsAsync(ApiSession apiSession, string serverFolder, string fileName, CancellationToken cancellationToken);
24+
25+
}
26+
27+
public interface IMorphServerApiClient: IHasConfig, IDisposable
28+
{
29+
event EventHandler<FileTransferProgressEventArgs> OnDataDownloadProgress;
30+
event EventHandler<FileTransferProgressEventArgs> OnDataUploadProgress;
31+
32+
33+
2234
Task<ServerStatus> GetServerStatusAsync(CancellationToken cancellationToken);
2335
Task<Model.TaskStatus> GetTaskStatusAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
2436
Task<ApiSession> OpenSessionAsync(OpenSessionRequest openSessionRequest, CancellationToken cancellationToken);
2537

26-
Task<RunningTaskStatus> StartTaskAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken, IEnumerable<TaskParameterBase> taskParameters = null);
38+
Task<RunningTaskStatus> StartTaskAsync(ApiSession apiSession, StartTaskRequest startTaskRequest, CancellationToken cancellationToken);
2739
Task StopTaskAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
28-
Task UploadFileAsync(ApiSession apiSession, Stream inputStream, string fileName, long fileSize, string destFolderPath, CancellationToken cancellationToken, bool overwriteFileifExists = false);
29-
Task UploadFileAsync(ApiSession apiSession, string localFilePath, string destFolderPath, string destFileName, CancellationToken cancellationToken, bool overwriteFileifExists = false);
30-
Task UploadFileAsync(ApiSession apiSession, string localFilePath, string destFolderPath, CancellationToken cancellationToken, bool overwriteFileifExists = false);
40+
41+
42+
Task<SpaceTask> TaskChangeModeAsync(ApiSession apiSession, Guid taskId, TaskChangeModeRequest taskChangeModeRequest, CancellationToken cancellationToken);
3143
Task<ValidateTasksResult> ValidateTasksAsync(ApiSession apiSession, string projectPath, CancellationToken cancellationToken);
3244
Task<SpacesEnumerationList> GetSpacesListAsync(CancellationToken cancellationToken);
45+
Task<SpacesLookupResponse> SpacesLookupAsync(SpacesLookupRequest request, CancellationToken cancellationToken);
46+
3347
Task<SpaceStatus> GetSpaceStatusAsync(ApiSession apiSession, CancellationToken cancellationToken);
3448
Task<SpaceTasksList> GetTasksListAsync(ApiSession apiSession, CancellationToken cancellationToken);
3549
Task<SpaceTask> GetTaskAsync(ApiSession apiSession, Guid taskId, CancellationToken cancellationToken);
50+
51+
Task<SpaceBrowsingInfo> SpaceBrowseAsync(ApiSession apiSession, string folderPath, CancellationToken cancellationToken);
52+
Task SpaceDeleteFileAsync(ApiSession apiSession, string remoteFilePath, CancellationToken cancellationToken);
53+
Task<bool> SpaceFileExistsAsync(ApiSession apiSession, string remoteFilePath, CancellationToken cancellationToken);
54+
55+
Task<ServerStreamingData> SpaceOpenStreamingDataAsync(ApiSession apiSession, string remoteFilePath, CancellationToken cancellationToken);
56+
Task<Stream> SpaceOpenDataStreamAsync(ApiSession apiSession, string remoteFilePath, CancellationToken cancellationToken);
57+
58+
Task SpaceUploadDataStreamAsync(ApiSession apiSession, SpaceUploadDataStreamRequest spaceUploadFileRequest, CancellationToken cancellationToken);
59+
Task<ContiniousStreamingConnection> SpaceUploadContiniousStreamingAsync(ApiSession apiSession, SpaceUploadContiniousStreamRequest continiousStreamRequest, CancellationToken cancellationToken);
60+
3661
}
3762
}

src/Client/IRestClient.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using System.Collections.Specialized;
6+
using Morph.Server.Sdk.Model.InternalModels;
7+
using Morph.Server.Sdk.Events;
8+
using Morph.Server.Sdk.Model;
9+
10+
namespace Morph.Server.Sdk.Client
11+
{
12+
public interface IRestClient : IDisposable
13+
{
14+
HttpClient HttpClient { get; set; }
15+
Task<ApiResult<TResult>> GetAsync<TResult>(string url, NameValueCollection urlParameters, HeadersCollection headersCollection, CancellationToken cancellationToken)
16+
where TResult : new();
17+
Task<ApiResult<TResult>> HeadAsync<TResult>(string url, NameValueCollection urlParameters, HeadersCollection headersCollection, CancellationToken cancellationToken)
18+
where TResult : new();
19+
Task<ApiResult<TResult>> PostAsync<TModel, TResult>(string url, TModel model, NameValueCollection urlParameters, HeadersCollection headersCollection, CancellationToken cancellationToken)
20+
where TResult : new();
21+
Task<ApiResult<TResult>> PutAsync<TModel, TResult>(string url, TModel model, NameValueCollection urlParameters, HeadersCollection headersCollection, CancellationToken cancellationToken)
22+
where TResult : new();
23+
Task<ApiResult<TResult>> DeleteAsync<TResult>(string url, NameValueCollection urlParameters, HeadersCollection headersCollection, CancellationToken cancellationToken)
24+
where TResult : new();
25+
Task<ApiResult<TResult>> PutFileStreamAsync<TResult>(string url, SendFileStreamData sendFileStreamData, NameValueCollection urlParameters, HeadersCollection headersCollection, Action<FileTransferProgressEventArgs> onSendProgress, CancellationToken cancellationToken)
26+
where TResult : new();
27+
Task<ApiResult<TResult>> PostFileStreamAsync<TResult>(string url, SendFileStreamData sendFileStreamData, NameValueCollection urlParameters, HeadersCollection headersCollection, Action<FileTransferProgressEventArgs> onSendProgress, CancellationToken cancellationToken)
28+
where TResult : new();
29+
30+
Task<ApiResult<FetchFileStreamData>> RetrieveFileGetAsync(string url, NameValueCollection urlParameters, HeadersCollection headersCollection, Action<FileTransferProgressEventArgs> onReceiveProgress, CancellationToken cancellationToken);
31+
32+
33+
Task<ApiResult<ServerPushStreaming>> PushContiniousStreamingDataAsync<TResult>(
34+
HttpMethod httpMethod, string path, ContiniousStreamingRequest startContiniousStreamingRequest, NameValueCollection urlParameters, HeadersCollection headersCollection,
35+
CancellationToken cancellationToken)
36+
where TResult : new();
37+
38+
39+
}
40+
41+
42+
43+
}

0 commit comments

Comments
 (0)