Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions QS.Cloud.Client/Clients/DataBaseManagementCloudClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Grpc.Core;
using QS.Cloud.Core;
using QS.Project.Versioning;
using System.Threading;

namespace QS.Cloud.Client.Clients {
public class DataBaseManagementCloudClient : CloudClientByBasicAuth {
private IApplicationInfo applicationInfo { get; set; }
public DataBaseManagementCloudClient(IBasicAuthInfoProvider basicAuthInfoProvider)
: base(basicAuthInfoProvider, "core.cloud.qsolution.ru", 443)
{
this.applicationInfo = applicationInfo;
}

public CreateDataBaseResponse CreateDataBase(string dbName, string dbTitle, IApplicationInfo applicationInfo) {
var client = new DataBaseManagement.DataBaseManagementClient(Channel);
var request = new CreateDataBaseRequest { Name = dbName, Title = dbTitle, ProductId = applicationInfo.ProductCode };
return client.CreateDataBase(request, headers);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,42 @@
using System.Linq;
using System.Reflection;
using System;
using System.Threading;
using QS.Cloud.Client.Clients;
using QS.DBScripts.Controllers;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace QS.Cloud.Client
namespace QS.Cloud.Client.DataBase
{
public class QSCloudProvider : IDbProvider {
public string ConnectionString { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

public bool IsConnected => throw new NotImplementedException();
public int BaseId { get; private set; }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не согласен, с решением, по сути ты смешиваешь зачем то 2 различные функциональности, вход в саму админку сервера и вход в базу. Просто в моем представлении у IDbProvider не может быть базы в принцепе. Или я не понял задумки.

public BasicAuthInfoProvider AuthInfo { get; private set; }

public bool IsConnected { get; private set; }

public bool IsAdmin { get; protected set; }

#region Параметры подключени
public string Account { get; private set; }


#endregion
public string UserName { get; private set; }

private CloudFeaturesClient featuresClient;
public bool CanCreateDatabase => dbClient.CanConnect;

private LoginManagementCloudClient loginClient;
private SessionManagementCloudClient sessionClient;
private UserManagementCloudClient userClient;
private DataBaseManagementCloudClient dbClient;


public QSCloudProvider(IList<ConnectionParameterValue> parameters, string password = null) {
Account = parameters.First(p => p.Name == "Account").Value;
UserName = parameters.First(p => p.Name == "Login").Value;
BasicAuthInfoProvider authInfo = new BasicAuthInfoProvider($@"{Account}\{UserName}", password);
AuthInfo = new BasicAuthInfoProvider($@"{Account}\{UserName}", password);

loginClient = new LoginManagementCloudClient(authInfo);
loginClient = new LoginManagementCloudClient(AuthInfo);
dbClient = new DataBaseManagementCloudClient(AuthInfo);
}

public bool AddUser(string username, string password)
Expand All @@ -49,9 +56,12 @@ public bool ChangePassword(string username, string oldPassword, string newPasswo
throw new NotImplementedException();
}

public bool CreateDatabase(string databaseName)
public bool CreateDatabase(string databaseName, string title, IServiceProvider services)
{
throw new NotImplementedException();
IApplicationInfo applicationInfo = services.GetService<IApplicationInfo>();
CreateDataBaseResponse response = dbClient.CreateDataBase(databaseName, title, applicationInfo);
BaseId = response.BaseId;
return true;
}

public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
using Microsoft.Extensions.DependencyInjection;
using QS.DbManagement;
using QS.DBScripts;
using QS.DBScripts.Controllers;
using QS.DBScripts.Models;
using QS.Utilities.Extensions;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using QS.Utilities.Extensions;

namespace QS.Cloud.Client {
namespace QS.Cloud.Client.DataBase {
public class QsCloudConnectionTypeBase : ConnectionTypeBase {

public QsCloudConnectionTypeBase() {
Title = "QS: Облако";
ConnectionTypeName = "QSCloud";

Parameters.Add(new ConnectionParameter("Account","Организация"));
Parameters.Add(new ConnectionParameter("Login","Пользователь"));

IconBytes = Assembly.GetExecutingAssembly().GetResourceByteArray("QS.Cloud.Client.Icons.qscloud.ico");
}

Expand All @@ -21,7 +26,21 @@ public override bool CanConnect(IEnumerable<ConnectionParameterValue> parameters
parameters.Any(p => p.Name == "Login" && !string.IsNullOrEmpty(p.Value));
}

public override IDbProvider CreateProvider(IList<ConnectionParameterValue> parameters, string password = null)
=> new QSCloudProvider(parameters, password);
public override IDbProvider CreateProvider(IList<ConnectionParameterValue> parameters, string password = null) {
return new QSCloudProvider(parameters, password);
}

public override IDbCreatorModel CreatorFactory(CreatorFactoryArgs args) {
var provider = (QSCloudProvider)args.Provider;
var scripts = args.ServiceProvider.GetRequiredService<IDbScriptsConfiguration>();
var creator = new QsCloudDbCreator(
provider.BaseId,
provider.AuthInfo,
scripts,
args.Progress,
args.Interaction,
args.CancellationToken);
return creator;
}
}
}
86 changes: 86 additions & 0 deletions QS.Cloud.Client/DataBase/QsCloudDbCreator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using QS.Cloud.Core;
using QS.DBScripts;
using QS.DBScripts.Controllers;
using QS.DBScripts.Models;
using QS.Dialog;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace QS.Cloud.Client.DataBase
{
public class QsCloudDbCreator : IDbCreatorModel
{
static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

private readonly int baseId;

private readonly IProgressBarDisplayable progress;
private readonly IDbCreatorInteraction interaction;
private readonly IDbScriptsConfiguration configuration;
private readonly CancellationToken cancellationToken;

private LoginManagementCloudClient loginClient;

public QsCloudDbCreator(
int baseId,
BasicAuthInfoProvider AuthInfo,
IDbScriptsConfiguration configuration,
IProgressBarDisplayable progress,
IDbCreatorInteraction interaction,
CancellationToken cancellationToken)
{
this.baseId = baseId;

loginClient = new LoginManagementCloudClient(AuthInfo);

this.configuration = configuration ?? throw new ArgumentNullException(nameof(progress));
this.progress = progress ?? throw new ArgumentNullException(nameof(progress));
this.interaction = interaction ?? throw new ArgumentNullException(nameof(interaction));
this.cancellationToken = cancellationToken;
}


public async Task<bool> RunCreationAsync(string dbName, string dbTitle) {
try {
StartSessionResponse session = loginClient.StartSession(baseId);

if(!session.Success) {
await interaction.ReportErrorAsync("Ошибка в создании сесии", "Запрос в облако");
throw new InvalidOperationException("Ошибка в создании сесии");
}
else if(!session.IsAdmin) {
await interaction.ReportErrorAsync("Вы не имеете прав Администратора", "Запрос в облако");
}

var infoProvider = new SessionInfoProvider(sessionId: session.SessionId);
var sessionLife = new AliveCloudClient(infoProvider);
sessionLife.NewMessage += (mes) => {
progress.Update("Сессия: " + mes + " в статусе " + sessionLife.LastStatus.ToString());
};
sessionLife.KeepAlive();

var creator = new MySqlDbCreateModel(session.Db.Server, session.Db.Port, session.Db.Login, session.Db.Password, configuration, progress, interaction, cancellationToken);
creator.FillBaseGuid = false;
bool success = await creator.RunCreationAsync(session.Db.BaseName, dbTitle);

sessionLife.Dispose();

return success;
}
catch(OperationCanceledException) {
logger.Info("Создание базы в облаке отменено пользователем.");
return false;
}
catch(Exception ex) {
logger.Error(ex, "Ошибка при создании базы в облаке.");
await interaction.ReportErrorAsync(ex.Message, null);
throw;
}
finally {
if(progress.IsStarted)
progress.Close();
}
}
}
}
38 changes: 38 additions & 0 deletions QS.Cloud.Client/DataBase/QsCloudScriptsConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using QS.DBScripts;
using QS.DBScripts.Models;
using QS.Updater.DB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace QS.Cloud.Client.DataBase {
public class QsCloudScriptsConfiguration : IDbScriptsConfiguration {
private string ResourceName = "QS.Cloud.Client.Scripts.new_empty.sql";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как в библиотеках может быть такой ресурс?
это задается внешним проектом.

public bool HasCreationScript() {
return Assembly.GetAssembly(typeof(QsCloudScriptsConfiguration))
.GetReferencedAssemblies().Select(x => x.FullName)
.Contains(ResourceName);
}

public CreationScript MakeCreationScript() {
return new CreationScript(
Assembly.GetAssembly(typeof(QsCloudScriptsConfiguration)),
ResourceName,
new Version(1, 7)
);
}

public UpdateConfiguration MakeUpdateConfiguration() {
var configuration = new UpdateConfiguration();

configuration.AddUpdate(
new Version(1, 7),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То же самое, что это вообще может делать в библиотеках?

new Version(1, 7, 1),
"QS.Cloud.Client.Scripts.1.7.sql");

return configuration;
}
}
}
19 changes: 19 additions & 0 deletions QS.Cloud.Client/Protos/DataBaseManagement.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
syntax = "proto3";

package QS.Cloud.Core;

service DataBaseManagement{
// Создать пустую базу
rpc CreateDataBase (CreateDataBaseRequest) returns (CreateDataBaseResponse);
}

message CreateDataBaseRequest{
string name = 1;
string title = 2;
uint32 product_id = 3;
}

message CreateDataBaseResponse{
int32 base_id = 1;
string base_guid = 2;
}
10 changes: 9 additions & 1 deletion QS.Cloud.Client/QS.Cloud.Client.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand All @@ -15,18 +15,26 @@
<PackageReference Include="NLog" Version="6.1.1" />
</ItemGroup>

<ItemGroup>
<None Remove="Scripts\*.sql" />
<EmbeddedResource Include="Scripts\*.sql" />
</ItemGroup>

<ItemGroup>
<None Remove="Protos\BaseManagement.proto" />
<None Remove="Protos\CloudFeatures.proto" />
<None Remove="Protos\LoginManagement.proto" />
<None Remove="Protos\SessionManagement.proto" />
<None Remove="Protos\UserControl.proto" />
<None Remove="Protos\UserManagement.proto" />
<None Remove="Protos\DataBaseManagement.proto" />
<ProjectReference Include="..\QS.DbManagement\QS.DbManagement.csproj" />
<ProjectReference Include="..\QS.Project.Abstract\QS.Project.Abstract.csproj" />
<ProjectReference Include="..\QS.Updater.Core\QS.Updater.Core.csproj" />
<Protobuf Include="Protos\CloudFeatures.proto" />
<Protobuf Include="Protos\LoginManagement.proto" />
<Protobuf Include="Protos\SessionManagement.proto" />
<Protobuf Include="Protos\DataBaseManagement.proto" />
<Protobuf Include="Protos\UserManagement.proto" />
</ItemGroup>

Expand Down
Loading