Skip to content

Commit

Permalink
feat(): Terminate other Customer Environment Versions (#23)
Browse files Browse the repository at this point in the history
* added helper methods for terminating customer environment versions and waiting for them

* support for terminating other customer versions when creating a new version

* version bump 1.1.7

* revert version in package.json

* fix help messages

* fix setter access

* resolve pr suggestions

* Added fixs for PR review and updated version to 1.3.0

Co-authored-by: Vítor Moreira <[email protected]>
  • Loading branch information
vitorpmoreira and Vítor Moreira authored Jan 7, 2022
1 parent 441cad3 commit a44322a
Show file tree
Hide file tree
Showing 17 changed files with 516 additions and 35 deletions.
25 changes: 13 additions & 12 deletions src/Common/CmfPortalSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public abstract class CmfPortalSession : ISession
public LogLevel LogLevel { get; protected set; } = LogLevel.Information;

public IConfiguration Configuration { get; set; }
public string AccessToken { get; set; }

public string AccessToken { get; private set; }

private string Token
{
Expand Down Expand Up @@ -52,8 +53,8 @@ private string Token
token = value;
LogDebug("Login Access Token saved");
}
}

}

public void ConfigureSession(string token = null)
{
// make sure that empty/whitespace values are set as null
Expand Down Expand Up @@ -91,17 +92,17 @@ protected void ConfigureLBOs(string token)
UseSsl = bool.Parse(Configuration["ClientConfiguration:UseSsl"]),
SecurityAccessToken = token,
SecurityPortalBaseAddress = new Uri(Configuration["ClientConfiguration:SecurityPortalBaseAddress"])
};
};
clientConfiguration.TokenProviderUpdated += (object sender, IAuthProvider authProvider) =>
{
// save access token in the session
if (token == null)
{
Token = authProvider.RefreshToken;
}

{
// save access token in the session
if (token == null)
{
Token = authProvider.RefreshToken;
}

AccessToken = authProvider.AccessToken;
};
};


return clientConfiguration;
Expand Down
203 changes: 201 additions & 2 deletions src/Common/CustomerPortalClient.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
using Cmf.Foundation.BusinessOrchestration.ApplicationSettingManagement.InputObjects;
using Cmf.CustomerPortal.BusinessObjects;
using Cmf.Foundation.BusinessObjects;
using Cmf.Foundation.BusinessObjects.QueryObject;
using Cmf.Foundation.BusinessOrchestration.ApplicationSettingManagement.InputObjects;
using Cmf.Foundation.BusinessOrchestration.GenericServiceManagement.InputObjects;
using Cmf.Foundation.BusinessOrchestration.QueryManagement.InputObjects;
using Cmf.Foundation.Common.Base;
using Cmf.LightBusinessObjects.Infrastructure;
using Cmf.MessageBus.Client;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace Cmf.CustomerPortal.Sdk.Common
{
Expand All @@ -22,6 +34,80 @@ public CustomerPortalClient(ISession session)
_session = session;
}

#region Private Methods

private static DataSet NgpDataSetToDataSet(NgpDataSet ngpDataSet)
{
DataSet ds = new DataSet();

if (ngpDataSet == null || (string.IsNullOrWhiteSpace(ngpDataSet.XMLSchema) && string.IsNullOrWhiteSpace(ngpDataSet.DataXML)))
{
return ds;
}

//Insert schema
using (TextReader a = new StringReader(ngpDataSet.XMLSchema))
using (XmlReader readerS = new XmlTextReader(a))
{
ds.ReadXmlSchema(readerS);
}

//Insert data
byte[] byteArray = Encoding.UTF8.GetBytes(ngpDataSet.DataXML);
using (MemoryStream stream = new MemoryStream(byteArray))
using (XmlReader reader = new XmlTextReader(stream))
{
try
{
ds.ReadXml(reader);
}
catch (ConstraintException ex)
{
throw new Exception("Error while parsing results from getting other Customer Environments to terminate", ex);
}
}
XDocument xd = XDocument.Parse(ngpDataSet.DataXML);

foreach (DataTable dt in ds.Tables)
{
var rs = xd.Descendants(dt.TableName).ToArray();

for (int i = 0; i < rs.Length; i++)
{
var r = rs[i];
DataRowState state = DataRowState.Added;
if (r.Attribute("RowState") != null)
{
state = (DataRowState)Enum.Parse(typeof(DataRowState), r.Attribute("RowState").Value);
}

DataRow dr = dt.Rows[i];
dr.AcceptChanges();

switch (state)
{
case DataRowState.Added:
dr.SetAdded();
break;
case DataRowState.Deleted:
dr.Delete();
break;
case DataRowState.Modified:
dr.SetModified();
break;
case DataRowState.Detached:
case DataRowState.Unchanged:
default:
break;
}
}
}

return ds;
}

#endregion

/// <summary>
/// Gets object by Id
/// </summary>
Expand All @@ -41,7 +127,7 @@ public CustomerPortalClient(ISession session)
return output.Instance as T;
}

public async Task<T> LoadObjectRelations<T>(T obj, System.Collections.ObjectModel.Collection<string> relationsNames) where T : CoreBase, new()
public async Task<T> LoadObjectRelations<T>(T obj, Collection<string> relationsNames) where T : CoreBase, new()
{
return (await new LoadObjectRelationsInput
{
Expand All @@ -50,6 +136,119 @@ public CustomerPortalClient(ISession session)
}.LoadObjectRelationsAsync(true)).Object as T;
}

public async Task<DataSet> ExecuteQuery(QueryObject queryObject)
{
return NgpDataSetToDataSet((await new ExecuteQueryInput
{
QueryObject = queryObject
}.ExecuteQueryAsync(true)).NgpDataSet);
}

public async Task<T> TerminateObjects<T, U>(T obj, OperationAttributeCollection operationAttributes = null) where T : List<U>, new() where U : new()
{
return (await new TerminateObjectsInput
{
Objects = new Collection<object>(obj.ConvertAll(x => x as object)),
OperationAttributes = operationAttributes,
IgnoreLastServiceId = true
}.TerminateObjectsAsync(true)).Objects as T;
}

public async Task<CustomerEnvironmentCollection> GetCustomerEnvironmentsById(long[] ids)
{
QueryObject query = new QueryObject
{
EntityTypeName = "CustomerEnvironment",
Name = "GetEnvironmentsById",
Query = new Query()
};
query.Query.Distinct = false;
query.Query.HasParameters = true;
query.Query.Filters = new FilterCollection() {
new Filter()
{
Name = "Id",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
Operator = Cmf.Foundation.Common.FieldOperator.In,
Value = ids,
LogicalOperator = Cmf.Foundation.Common.LogicalOperator.Nothing,
FilterType = Cmf.Foundation.BusinessObjects.QueryObject.Enums.FilterType.Normal,
}
};
query.Query.Fields = new FieldCollection() {
new Field()
{
Alias = "Id",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
IsUserAttribute = false,
Name = "Id",
Position = 0,
Sort = Cmf.Foundation.Common.FieldSort.NoSort
},
new Field()
{
Alias = "DefinitionId",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
IsUserAttribute = false,
Name = "DefinitionId",
Position = 1,
Sort = Cmf.Foundation.Common.FieldSort.NoSort
},
new Field()
{
Alias = "Name",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
IsUserAttribute = false,
Name = "Name",
Position = 2,
Sort = Cmf.Foundation.Common.FieldSort.NoSort
},
new Field()
{
Alias = "Status",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
IsUserAttribute = false,
Name = "Status",
Position = 3,
Sort = Cmf.Foundation.Common.FieldSort.NoSort
},
new Field()
{
Alias = "UniversalState",
ObjectName = "CustomerEnvironment",
ObjectAlias = "CustomerEnvironment_1",
IsUserAttribute = false,
Name = "UniversalState",
Position = 4,
Sort = Cmf.Foundation.Common.FieldSort.NoSort
}
};
query.Query.Relations = new RelationCollection();

// execute query
var result = await ExecuteQuery(query);

var customerEnvironments = new CustomerEnvironmentCollection();
foreach (DataRow row in result?.Tables?[0]?.Rows)
{
customerEnvironments.Add(new CustomerEnvironment
{
Id = (long)row["Id"],
DefinitionId = (long)row["DefinitionId"],
Name = (string)row["Name"],
Status = (DeploymentStatus)row["Status"],
UniversalState = (UniversalState)row["UniversalState"]
});
}

return customerEnvironments;
}

/// <summary>
/// Setup Message Bus Transport
/// </summary>
Expand Down
26 changes: 24 additions & 2 deletions src/Common/Handlers/NewEnvironmentHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Cmf.Foundation.Common.Licenses.Enums;
using Cmf.LightBusinessObjects.Infrastructure.Errors;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

Expand Down Expand Up @@ -38,6 +39,7 @@ public async Task Run(
string customerInfrastructureName,
string description,
string templateName,
bool terminateOtherVersions,
bool isInfrastructureAgent
)
{
Expand Down Expand Up @@ -85,9 +87,30 @@ bool isInfrastructureAgent
environment.DeploymentTarget = _newEnvironmentUtilities.GetDeploymentTargetValue(target);
environment.Parameters = rawParameters;
environment.ChangeSet = null;


environment = (await new CreateObjectVersionInput { Object = environment }.CreateObjectVersionAsync(true)).Object as CustomerEnvironment;

// terminate other versions
if (terminateOtherVersions)
{
Session.LogInformation("Terminating other versions...");

var customerEnvironmentsToTerminate = await _newEnvironmentUtilities.GetOtherVersionToTerminate(environment);
await _customerPortalClient.TerminateObjects<List<CustomerEnvironment>, CustomerEnvironment>(customerEnvironmentsToTerminate,
new Foundation.BusinessObjects.OperationAttributeCollection
{
new Foundation.BusinessObjects.OperationAttribute
{
Name = "AuthBearer",
Value = $"Bearer {Session.AccessToken}"
}
});

// wait until they're terminated
await _environmentDeploymentHandler.WaitForEnvironmentsToBeTerminated(customerEnvironmentsToTerminate);

Session.LogInformation("Other versions terminated!");
}
}
// if not, check if we are creating a new environment for an infrastructure
else if (!string.IsNullOrWhiteSpace(customerInfrastructureName))
Expand Down Expand Up @@ -127,7 +150,6 @@ bool isInfrastructureAgent

environment = (await new CreateObjectVersionInput { Object = environment }.CreateObjectVersionAsync(true)).Object as CustomerEnvironment;
}


// handle installation
await _environmentDeploymentHandler.Handle(interactive, environment, target, outputDir);
Expand Down
Loading

0 comments on commit a44322a

Please sign in to comment.