Skip to content

Commit 9d5f67d

Browse files
committed
Create ArtefactGeneration.Tool
- Generate JSON schema - Generate Markdown documentation - Update README.md
1 parent 8457a2f commit 9d5f67d

File tree

15 files changed

+1251
-8
lines changed

15 files changed

+1251
-8
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Change log
2+
3+
Represents the **NuGet** versions.
4+
5+
<br/>
6+
7+
## v1.0.1
8+
- *New:* Initial publish to GitHub. This was originally harvested from, and will replace, the core CDC code-generation and runtime within [Beef](https://github.com/Avanade/Beef).

LICENCE LICENSE

File renamed without changes.

NTangle.sln

+33-5
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,48 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{07E22463
1111
EndProject
1212
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8E857EA7-5ADC-4FD3-BAAE-EC8DC07AFCF1}"
1313
ProjectSection(SolutionItems) = preProject
14+
CHANGELOG.md = CHANGELOG.md
1415
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
1516
CONTRIBUTING.md = CONTRIBUTING.md
16-
LICENCE = LICENCE
17+
LICENSE = LICENSE
1718
README.md = README.md
1819
SECURITY.md = SECURITY.md
1920
EndProjectSection
2021
EndProject
21-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NTangle.Test", "tests\NTangle.Test\NTangle.Test.csproj", "{F2B7EC0C-9268-4E15-B014-6598682BFF4A}"
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NTangle.Test", "tests\NTangle.Test\NTangle.Test.csproj", "{F2B7EC0C-9268-4E15-B014-6598682BFF4A}"
2223
EndProject
2324
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{3A0B49DA-7D84-4B96-A4F3-FAF77C3E2FB3}"
2425
EndProject
2526
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SqlServerDemo", "SqlServerDemo", "{54E2D3C7-1AC1-4EA6-A8CA-42EC12A6E299}"
2627
EndProject
27-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerDemo.CodeGen", "samples\SqlServerDemo\SqlServerDemo.CodeGen\SqlServerDemo.CodeGen.csproj", "{1335C8D9-27AF-4BA2-AAB3-620841FCAEE9}"
28+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlServerDemo.CodeGen", "samples\SqlServerDemo\SqlServerDemo.CodeGen\SqlServerDemo.CodeGen.csproj", "{1335C8D9-27AF-4BA2-AAB3-620841FCAEE9}"
2829
EndProject
2930
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "SqlServerDemo.Database", "samples\SqlServerDemo\SqlServerDemo.Database\SqlServerDemo.Database.sqlproj", "{393D4F63-1F80-42A5-8ED7-E211698CCD94}"
3031
EndProject
31-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerDemo.Publisher", "samples\SqlServerDemo\SqlServerDemo.Publisher\SqlServerDemo.Publisher.csproj", "{3BA33E87-F92A-444E-A67D-224A9BC605E3}"
32+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlServerDemo.Publisher", "samples\SqlServerDemo\SqlServerDemo.Publisher\SqlServerDemo.Publisher.csproj", "{3BA33E87-F92A-444E-A67D-224A9BC605E3}"
3233
EndProject
33-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerDemo.Test", "samples\SqlServerDemo\SqlServerDemo.Test\SqlServerDemo.Test.csproj", "{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C}"
34+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SqlServerDemo.Test", "samples\SqlServerDemo\SqlServerDemo.Test\SqlServerDemo.Test.csproj", "{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C}"
35+
EndProject
36+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{780B69CA-D467-45CF-B115-A3FEB0B88BD1}"
37+
EndProject
38+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NTangle.ArtefactGenerate.Tool", "tools\NTangle.ArtefactGenerate.Tool\NTangle.ArtefactGenerate.Tool.csproj", "{D43AAE26-31A4-4F9B-9521-0A7CEB776386}"
39+
EndProject
40+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Schemas", "Schemas", "{4715F738-C8FE-49C4-8F18-83875CF4D974}"
41+
ProjectSection(SolutionItems) = preProject
42+
schemas\ntangle.json = schemas\ntangle.json
43+
EndProjectSection
44+
EndProject
45+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{5B2FCA11-CC69-40D7-9FC3-DC7707C77D45}"
46+
EndProject
47+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generated", "Generated", "{54D9318B-8D30-41FF-A5DD-554C13AC62F3}"
48+
ProjectSection(SolutionItems) = preProject
49+
docs\generated\join.md = docs\generated\join.md
50+
docs\generated\joinmapping.md = docs\generated\joinmapping.md
51+
docs\generated\joinon.md = docs\generated\joinon.md
52+
docs\generated\root.md = docs\generated\root.md
53+
docs\generated\table.md = docs\generated\table.md
54+
docs\generated\tablemapping.md = docs\generated\tablemapping.md
55+
EndProjectSection
3456
EndProject
3557
Global
3658
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -68,6 +90,10 @@ Global
6890
{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
6991
{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
7092
{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C}.Release|Any CPU.Build.0 = Release|Any CPU
93+
{D43AAE26-31A4-4F9B-9521-0A7CEB776386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
94+
{D43AAE26-31A4-4F9B-9521-0A7CEB776386}.Debug|Any CPU.Build.0 = Debug|Any CPU
95+
{D43AAE26-31A4-4F9B-9521-0A7CEB776386}.Release|Any CPU.ActiveCfg = Release|Any CPU
96+
{D43AAE26-31A4-4F9B-9521-0A7CEB776386}.Release|Any CPU.Build.0 = Release|Any CPU
7197
EndGlobalSection
7298
GlobalSection(SolutionProperties) = preSolution
7399
HideSolutionNode = FALSE
@@ -79,6 +105,8 @@ Global
79105
{393D4F63-1F80-42A5-8ED7-E211698CCD94} = {54E2D3C7-1AC1-4EA6-A8CA-42EC12A6E299}
80106
{3BA33E87-F92A-444E-A67D-224A9BC605E3} = {54E2D3C7-1AC1-4EA6-A8CA-42EC12A6E299}
81107
{A5F7177D-3747-45DF-BAF0-1E5F466A8C3C} = {54E2D3C7-1AC1-4EA6-A8CA-42EC12A6E299}
108+
{D43AAE26-31A4-4F9B-9521-0A7CEB776386} = {780B69CA-D467-45CF-B115-A3FEB0B88BD1}
109+
{54D9318B-8D30-41FF-A5DD-554C13AC62F3} = {5B2FCA11-CC69-40D7-9FC3-DC7707C77D45}
82110
EndGlobalSection
83111
GlobalSection(ExtensibilityGlobals) = postSolution
84112
SolutionGuid = {B97E5639-3430-4AD7-9942-D35EF26F263B}

README.md

+146-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,151 @@
1-
<br/>
1+
<br/>
22

33
![Logo](./images/Logo256x256.png "OnRamp")
44

55
<br/>
66

7-
## Introduction
7+
## Introduction
8+
9+
_nTangle_ is a Change Data Capture (CDC) code generation tool and corresponding runtime. Unlike other CDC-based technologies which replicate changes to rows _nTangle_ is designed to replicate business entities (aggregate) changes.
10+
11+
For example if a database contains a `Person` and one-to-many related `Address` table, a traditional CDC replicator would leverage the CDC-capabilities of the database as the data source and replicate all changes from both tables largely distinct from each other. Additional logic would then be required within the downstream systems to aggregate these distinct changes back into a holistic business entity, if possible.
12+
13+
_nTangle_ tackles this differently by packaging the changes at the source into an aggregated entity which is then replicated. With _nTangle_ the CDC-capabilities of the database are leveraged as the trigger, with a corresponding query across all related tables to produce a holistic business entity. Therefore, if a change is made to `Person` or `Address` this will result in the publishing of the entity. Where transactional changes are made to both `Person` and `Address` a single holistic business entity will be published including all changes.
14+
15+
This has a key advantage of being an excellent candidate within event-streaming scenarios where business entities are to be published based on underlying database changes.
16+
17+
<br/>
18+
19+
## Status
20+
21+
[![CI](https://github.com/Avanade/NTangle/workflows/CI/badge.svg)](https://github.com/Avanade/NTangle/actions?query=workflow%3ACI) [![NuGet version](https://badge.fury.io/nu/NTangle.svg)](https://badge.fury.io/nu/NTangle)
22+
23+
The included [change log](CHANGELOG.md) details all key changes per published version.
24+
25+
<br/>
26+
27+
## Approach
28+
29+
The _nTangle_ CDC approach taken here is to consolidate the tracking of individual tables (one or more) into a aggregated _entity_ to simplify the publishing to an event stream (or equivalent). The advantage of this is where a change occurs to any of the rows related to an entity, even where multiples rows are updated, this will only result in a single event. This makes it easier (more logical) for downstream subscribers to consume.
30+
31+
This is achieved by defining (configuring) the entity, being the primary (parent) table, and its related secondary (child) tables. For example, a `SalesOrder`, may be made up multiple tables - when any of these change then a single `SalesOrder` event should occur. These relationships are also defined with a cardinality of either `OneToMany` or `OneToOne`.
32+
33+
```
34+
SalesOrder // Parent
35+
└── SalesOrderAddress // Child 1:n - One or more addresses (e.g. Billing and Shipping)
36+
└── SalesOrderItem // Child 1:n - One or more items
37+
```
38+
39+
The CDC capability is used specifically as a trigger for change (being `Create`, `Update` or `Delete`). The resulting data that is published is the latest, not a snapshot in time (CDC captured). The reason for this is two-fold:
40+
1. Given how the CDC data is retrieved there is no guarantee that the interim data represents a final intended state suitable for publishing; and,
41+
1. This process is intended to be running near real-time so getting the latest version will produce the most current committed version as at that time.
42+
43+
To further guarantee only a single event for a specific version is published the resulting _entity_ is JSON serialized and hashed; this value is checked (and saved) against the prior version to ensure a publish contains data that is actionable. This will minimize redundant publishing, whilst also making the underlying processing more efficient.
44+
45+
<br/>
46+
47+
## Additional reading
48+
49+
This [article](https://www.mssqltips.com/sqlservertip/5212/sql-server-temporal-tables-vs-change-data-capture-vs-change-tracking--part-2/) provides an excellent overview of the Microsoft SQL Server CDC-capabilities and walks through the process of setting up and using to aid in the fundamental understanding.
50+
51+
Although throughout references will be made to [Microsoft SQL Server](https://www.microsoft.com/en-us/sql-server), the intention of _nTangle_ is that it is largely agnostic to the database technology, and therefore support for other databases will (or may) be supported in the future based on demand.
52+
53+
<br/>
54+
55+
## Capabilities
56+
57+
_nTangle_ has been created to provide a seamless means to create CDC-enabled aggregated entity publishing solution. The _nTangle_ solution is composed of the following:
58+
59+
1. [Code generation](#Code-generation) - a configuration file defines the database tables and, none or more relationships, which also includes other functionality-based properties, that are used to drive the database-driven code-generation to create the required solution artefacts.
60+
2. [Runtime](#Runtime) - the generated solution artefacts leverage a number of .NET runtime components/capabilities to support and enable. The code-generated solution then uses these at runtime to execute and orchestrate the CDC-triggered aggregated entity publishing process.
61+
62+
<br/>
63+
64+
### Code-generation
65+
66+
The code-generation is managed via a console application using the [`CodeGenConsole`](./src/NTangle/Console/CodeGenConsole.cs) to manage. This internally leverages [OnRamp](https://github.com/Avanade/onramp) to enable.
67+
68+
Additionally, the code-generator inspects (queries) the database to infer the underlying table schema for all tables and their columns. This is used as a source in which the configuration references to validate, whilst also minimizes configuration where the inferred schema information can be used. The code-generation adopts a gen-many philosophy, therefore where schema changes are made, the code-generation can be executed again to update accordingly.
69+
70+
As stated, the code-generation is driven by a configuration file, typically named `ntangle.yaml`. Both YAML and JSON formats are supported; there is also a corresponding [JSON schema](./schemas/ntangle.json) to enable editor intellisense, etc.
71+
72+
The _nTangle_ configuration is as follows:
73+
74+
```
75+
Root
76+
└── Table(s)
77+
└── Join(s)
78+
└── JoinOn(s)
79+
└── JoinMapping(s)
80+
└── TableMapping(s)
81+
```
82+
83+
Documentation related to each of the above are as follows:
84+
- [`Root`](./docs/generated/root.md) - defines the root configuration settings.
85+
- [`Table`](./docs/generated/table.md) - defines the primary table as being the entity aggregate.
86+
- [`Join`](./docs/generated/join.md) - defines none or more table joins to include within the entity.
87+
- [`JoinOn`](./docs/generated/joinon.md) - defines the join on column characteristics.
88+
- [`JoinMapping`](./docs/generated/joinmapping.md) - defines global identifier mappings for any of the join table columns.
89+
- [`TableMapping`](./docs/generated/tablemapping.md) - - defines global identifier mappings for any of the primary table columns.
90+
91+
An example [ntangle.yaml](./samples/SqlServerDemo/SqlServerDemo.CodeGen/ntangle.yaml) configuration file exists within the [`SqlServerDemo`](./samples/SqlServerDemo) sample. The [`SqlServerDemo.CodeGen`](./samples/SqlServerDemo/SqlServerDemo.CodeGen) sample also demonstrates how to invoke the code generator from the underlying [`Program`](./samples/SqlServerDemo/SqlServerDemo.CodeGen/Program.cs).
92+
93+
The code-generator will output a number of generated artefacts (see [`SqlServerDemo.Database`](./samples/SqlServerDemo/SqlServerDemo.Database) sample); these will be either database-related or additional .NET runtime components (see [`SqlServerDemo.Publisher`](./samples/SqlServerDemo/SqlServerDemo.Publisher) sample).
94+
95+
96+
The following [`NTangle`](./src/NTangle) namespaces provide code-generation capabilties:
97+
98+
Namespace | Description
99+
- | -
100+
[`Config`](./src/NTangle/Config) | The _internal_ code that supports the YAML/JSON configuration.
101+
[`Console`](./src/NTangle/Console) | The code-generation tooling capabilities, primarily [`CodeGenConsole`](./src/NTangle/Console/CodeGenConsole.cs).
102+
[`Generators`](./src/NTangle/Generators) | The _internal_ code-generators used to select configuration for one or more templates.
103+
104+
<br/>
105+
106+
### Runtime
107+
108+
Generally, a runtime publisher is required to orchestrate the CDC-triggered aggregated entity publishing process (see [`SqlServerDemo.Publisher`](./samples/SqlServerDemo/SqlServerDemo.Publisher) sample). This in turn takes a dependency on the _nTangle_ runtime to enable.
109+
110+
The following [`NTangle`](./src/NTangle) namespaces provide runtime capabilties:
111+
112+
Namespace | Description
113+
- | -
114+
[`Cdc`](./src/NTangle/Cdc) | The CDC-orchestration capabilities, primarily [`EntityOrchestrator`](./src/NTangle/Cdc/EntityOrchestrator.cs).
115+
[`Data`](./src/NTangle/Data) | The database access capabilities, primarily [`Database`](./src/NTangle/Data/Database.cs).
116+
[`Events`](./src/NTangle/Events) | The event capabilities, primarily [`IEventPublisher`](./src/NTangle/Events/IEventPublisher.cs) and [`CloudEventSerializer`](./src/NTangle/Events/CloudEventSerializer.cs).
117+
[`Services`](./src/NTangle/Services) | The service hosting capabilities, primarily [`HostedService`](./src/NTangle/Services/HostedServiceT.cs).
118+
119+
<br/>
120+
121+
## Samples
122+
123+
The following samples are provided to guide usage:
124+
125+
Sample | Description
126+
-|-
127+
[`SqlServerDemo`](./samples/SqlServerDemo) | A sample as an end-to-end solution walkthrough to demonstrate the usage of _nTangle_ against a Microsoft SQL Server database.
128+
129+
<br/>
130+
131+
## License
132+
133+
_OnRamp_ is open source under the [MIT license](./LICENSE) and is free for commercial use.
134+
135+
<br/>
136+
137+
## Contributing
138+
139+
One of the easiest ways to contribute is to participate in discussions on GitHub issues. You can also contribute by submitting pull requests (PR) with code changes. Contributions are welcome. See information on [contributing](./CONTRIBUTING.md), as well as our [code of conduct](https://avanade.github.io/code-of-conduct/).
140+
141+
<br/>
142+
143+
## Security
144+
145+
See our [security disclosure](./SECURITY.md) policy.
146+
147+
<br/>
148+
149+
## Who is Avanade?
150+
151+
[Avanade](https://www.avanade.com) is the leading provider of innovative digital and cloud services, business solutions and design-led experiences on the Microsoft ecosystem, and the power behind the Accenture Microsoft Business Group.

0 commit comments

Comments
 (0)