-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use IO in transaction handlers The transaction handlers now have to return Eff<RT, RfcRc>. Any error will be mapped to RfcRc.EXTERNAL_FAILURE as specified by SAP. fixed code documentations improved stability of mapper caching fixed some code qualitity issues improved samples reduced traits to HasSAPRfc and HasSAPRfcServer fixed runIO to pass IConnection reference
- Loading branch information
Showing
90 changed files
with
1,333 additions
and
814 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
using System.Text; | ||
using Dbosoft.YaNco; | ||
using Dbosoft.YaNco.Live; | ||
using Dbosoft.YaNco.Traits; | ||
using Dbosoft.YaNco.TypeMapping; | ||
using ExportMATMAS.MaterialMaster; | ||
using LanguageExt; | ||
using LanguageExt.Sys.Traits; | ||
|
||
namespace ExportMATMAS; | ||
|
||
/// <summary> | ||
/// Runtime environment for the console application | ||
/// It provides access to the SAP RFC runtime environment, the console and file IO | ||
/// It is expected that you create your own runtime environment for your application. | ||
/// </summary> | ||
public readonly struct ConsoleRuntime : | ||
HasConsole<ConsoleRuntime>, | ||
HasFile<ConsoleRuntime>, | ||
HasSAPRfc<ConsoleRuntime>, | ||
HasSAPRfcServer<ConsoleRuntime>, | ||
HasMaterialManager<ConsoleRuntime> | ||
{ | ||
|
||
private readonly SAPRfcRuntimeEnv<SAPServerSettings> _env; | ||
|
||
/// <summary> | ||
/// Constructor | ||
/// </summary> | ||
private ConsoleRuntime(SAPRfcRuntimeEnv<SAPServerSettings> env) => | ||
_env = env; | ||
|
||
|
||
/// <summary> | ||
/// Configuration environment accessor | ||
/// </summary> | ||
public SAPRfcRuntimeEnv<SAPServerSettings> Env => | ||
_env ?? throw new InvalidOperationException("Runtime Env not set. Perhaps because of using default(Runtime) or new Runtime() rather than Runtime.New()"); | ||
|
||
SAPRfcRuntimeEnv<SAPRfcRuntimeSettings> IHasEnvRuntimeSettings.Env => | ||
Env.ToRuntimeSettings(); | ||
|
||
|
||
/// <summary> | ||
/// Constructor function | ||
/// </summary> | ||
public static ConsoleRuntime New(CancellationTokenSource cancellationTokenSource, SAPServerSettings settings) => | ||
new(new SAPRfcRuntimeEnv<SAPServerSettings>(cancellationTokenSource, settings)); | ||
|
||
|
||
/// <summary> | ||
/// Create a new Runtime with a fresh cancellation token | ||
/// </summary> | ||
/// <remarks>Used by localCancel to create new cancellation context for its sub-environment</remarks> | ||
/// <returns>New runtime</returns> | ||
public ConsoleRuntime LocalCancel => | ||
new(new SAPRfcRuntimeEnv<SAPServerSettings>(new CancellationTokenSource(), Env.Settings)); | ||
|
||
/// <summary> | ||
/// Direct access to cancellation token | ||
/// </summary> | ||
public CancellationToken CancellationToken => | ||
Env.Token; | ||
|
||
/// <summary> | ||
/// Directly access the cancellation token source | ||
/// </summary> | ||
/// <returns>CancellationTokenSource</returns> | ||
public CancellationTokenSource CancellationTokenSource => | ||
Env.Source; | ||
|
||
public Eff<ConsoleRuntime, ConsoleIO> ConsoleEff => | ||
Prelude.SuccessEff(LanguageExt.Sys.Live.ConsoleIO.Default); | ||
|
||
public Encoding Encoding => Encoding.UTF8; | ||
|
||
public Eff<ConsoleRuntime, FileIO> FileEff => Prelude.SuccessEff(LanguageExt.Sys.Live.FileIO.Default); | ||
|
||
public Option<ILogger> RfcLogger => Env.Settings.Logger == null ? Option<ILogger>.None : Prelude.Some(Env.Settings.Logger); | ||
|
||
private SAPRfcDataIO DataIO => Env.Settings.RfcDataIO ?? new LiveSAPRfcDataIO(RfcLogger, Env.Settings.FieldMapper, Env.Settings.Options); | ||
private SAPRfcFunctionIO FunctionIO => Env.Settings.RfcFunctionIO ?? new LiveSAPRfcFunctionIO(RfcLogger, DataIO); | ||
private SAPRfcConnectionIO ConnectionIO => Env.Settings.RfcConnectionIO ?? new LiveSAPRfcConnectionIO(RfcLogger); | ||
private SAPRfcServerIO ServerIO => Env.Settings.RfcServerIO ?? new LiveSAPRfcServerIO(RfcLogger); | ||
|
||
public Eff<ConsoleRuntime, Option<ILogger>> RfcLoggerEff => Prelude.Eff<ConsoleRuntime, Option<ILogger>>(rt => rt.RfcLogger); | ||
|
||
public Eff<ConsoleRuntime, SAPRfcDataIO> RfcDataEff => Prelude.Eff<ConsoleRuntime, SAPRfcDataIO>(rt => rt.DataIO); | ||
|
||
|
||
public Eff<ConsoleRuntime, SAPRfcFunctionIO> RfcFunctionsEff => | ||
Prelude.Eff<ConsoleRuntime, SAPRfcFunctionIO>(rt => rt.FunctionIO); | ||
|
||
public Eff<ConsoleRuntime, IFieldMapper> FieldMapperEff => | ||
Prelude.Eff<ConsoleRuntime, IFieldMapper>(rt => rt.Env.Settings.FieldMapper); | ||
|
||
public Eff<ConsoleRuntime, SAPRfcConnectionIO> RfcConnectionEff => Prelude.Eff<ConsoleRuntime, SAPRfcConnectionIO>( | ||
rt => rt.ConnectionIO); | ||
|
||
public Eff<ConsoleRuntime, SAPRfcServerIO> RfcServerEff => Prelude.Eff<ConsoleRuntime, SAPRfcServerIO>( | ||
rt => rt.ServerIO); | ||
|
||
public Eff<ConsoleRuntime, TransactionManager<MaterialMasterRecord>> MaterialManagerEff => | ||
Prelude.Eff<ConsoleRuntime, TransactionManager<MaterialMasterRecord>>(rt => | ||
rt.Env.Settings.TaManager); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using ExportMATMAS.MaterialMaster; | ||
using LanguageExt; | ||
using LanguageExt.Effects.Traits; | ||
|
||
namespace ExportMATMAS; | ||
|
||
public interface HasMaterialManager<RT> : HasCancel<RT> | ||
where RT : struct, HasCancel<RT> | ||
{ | ||
Eff<RT, TransactionManager<MaterialMasterRecord>> MaterialManagerEff { get; } | ||
} |
2 changes: 1 addition & 1 deletion
2
samples/net6.0/ExportMATMAS/ClientData.cs → ...ExportMATMAS/MaterialMaster/ClientData.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
namespace ExportMATMAS; | ||
namespace ExportMATMAS.MaterialMaster; | ||
|
||
public record ClientData(string Unit); |
2 changes: 1 addition & 1 deletion
2
...es/net6.0/ExportMATMAS/DescriptionData.cs → ...tMATMAS/MaterialMaster/DescriptionData.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
namespace ExportMATMAS; | ||
namespace ExportMATMAS.MaterialMaster; | ||
|
||
public record DescriptionData(string Language, string Description); |
2 changes: 1 addition & 1 deletion
2
...t6.0/ExportMATMAS/MaterialMasterRecord.cs → ...AS/MaterialMaster/MaterialMasterRecord.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
namespace ExportMATMAS; | ||
namespace ExportMATMAS.MaterialMaster; | ||
|
||
public record MaterialMasterRecord(string MaterialNo, ClientData ClientData, DescriptionData[] Descriptions, PlantData[] PlantData); |
100 changes: 100 additions & 0 deletions
100
samples/net6.0/ExportMATMAS/MaterialMaster/MaterialMasterTransactionalRfcHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
using Dbosoft.YaNco; | ||
using System.Text.Encodings.Web; | ||
using System.Text.Json; | ||
using LanguageExt; | ||
using LanguageExt.Sys; | ||
using LanguageExt.Sys.Traits; | ||
|
||
namespace ExportMATMAS.MaterialMaster; | ||
|
||
|
||
/// <summary> | ||
/// This is a sample implementation of a transactional RFC handler. | ||
/// </summary> | ||
public class MaterialMasterTransactionalRfcHandler<RT> : ITransactionalRfcHandler<RT> | ||
where RT : struct, HasConsole<RT>, HasMaterialManager<RT> | ||
{ | ||
|
||
public Eff<RT, RfcRc> OnCheck(IRfcHandle rfcHandle, string transactionId) => | ||
from uLog in Console<RT>.writeLine($"Checking transaction '{transactionId}'") | ||
from tm in default(RT).MaterialManagerEff | ||
let result = tm.GetTransaction(transactionId).Match( | ||
None: () => | ||
{ | ||
tm.AddTransaction(transactionId); | ||
return RfcRc.RFC_OK; | ||
}, | ||
Some: ta => | ||
{ | ||
//check if TA is in valid state, inform sender in case TA is already executed | ||
return ta.State switch | ||
{ | ||
TransactionState.Created => RfcRc.RFC_OK, | ||
TransactionState.Executed => RfcRc.RFC_EXECUTED, | ||
TransactionState.Committed => RfcRc.RFC_EXECUTED, | ||
TransactionState.RolledBack => RfcRc.RFC_OK, | ||
_ => throw new ArgumentOutOfRangeException() | ||
}; | ||
}) | ||
select result; | ||
|
||
public Eff<RT, RfcRc> OnCommit(IRfcHandle rfcHandle, string transactionId) => | ||
from uLog in Console<RT>.writeLine($"Commit transaction '{transactionId}'") | ||
from tm in default(RT).MaterialManagerEff | ||
from ta in tm.GetTransaction(transactionId) | ||
.ToEff(RfcError.Error($"Transaction {transactionId} not found", RfcRc.RFC_EXTERNAL_FAILURE)) | ||
|
||
from gNotExecuted in Prelude.guard(ta.State == TransactionState.Executed, | ||
RfcError.Error($"Transaction {transactionId} not executed", RfcRc.RFC_EXTERNAL_FAILURE).AsError) | ||
from gHasData in Prelude.guardnot(ta.Data == null, RfcError.Error($"Transaction {transactionId} has no data", RfcRc.RFC_EXTERNAL_FAILURE).AsError) | ||
|
||
|
||
// where you would normally commit the transaction, but here we just print the data | ||
from printData in PrettyPrintMaterial(ta.Data) | ||
from uPrint in Console<RT>.writeLine(printData) | ||
|
||
from rc in Prelude.Eff(() => | ||
{ | ||
ta.State = TransactionState.Committed; | ||
return RfcRc.RFC_OK; | ||
}) | ||
select rc; | ||
|
||
public Eff<RT, RfcRc> OnRollback(IRfcHandle rfcHandle, string transactionId) => | ||
from uLog in Console<RT>.writeLine($"Rollback transaction '{transactionId}'") | ||
from tm in default(RT).MaterialManagerEff | ||
let result = tm.GetTransaction(transactionId).Match( | ||
None: () => RfcRc.RFC_EXTERNAL_FAILURE, | ||
Some: ta => | ||
{ | ||
ta.State = TransactionState.RolledBack; | ||
return RfcRc.RFC_OK; | ||
}) | ||
select result; | ||
|
||
public Eff<RT, RfcRc> OnConfirm(IRfcHandle rfcHandle, string transactionId) => | ||
from uLog in Console<RT>.writeLine($"Confirm transaction '{transactionId}'") | ||
from tm in default(RT).MaterialManagerEff | ||
from result in Prelude.Eff<RT, RfcRc>(_ => | ||
{ | ||
// cleanup transaction data | ||
tm.RemoveTransaction(transactionId); | ||
return RfcRc.RFC_OK; | ||
}) select result; | ||
|
||
private static Eff<string> PrettyPrintMaterial(MaterialMasterRecord record) | ||
{ | ||
return Prelude.Eff( () =>JsonSerializer.Serialize(record, Json.JsonOptions)); | ||
} | ||
|
||
} | ||
|
||
internal class Json | ||
{ | ||
public static readonly JsonSerializerOptions JsonOptions = new() | ||
{ | ||
//json don't has to be valid, so disable text encoding for unicode chars | ||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, | ||
WriteIndented = true | ||
}; | ||
} |
5 changes: 4 additions & 1 deletion
5
samples/net6.0/ExportMATMAS/MatmasTypes.cs → ...xportMATMAS/MaterialMaster/MatmasTypes.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
samples/net6.0/ExportMATMAS/PlantData.cs → .../ExportMATMAS/MaterialMaster/PlantData.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
namespace ExportMATMAS; | ||
namespace ExportMATMAS.MaterialMaster; | ||
|
||
public record PlantData(string Plant, string PurchasingGroup); |
Oops, something went wrong.