Skip to content

Commit ac1e18f

Browse files
enzo-crance-statnettCopilotkrilor
authored
docs: structure data synchronisation (FLEX-1023) (#593)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Kristoffer Lorentsen <kristoffer.lorentsen@statnett.no>
1 parent a1c3141 commit ac1e18f

File tree

5 files changed

+149
-15
lines changed

5 files changed

+149
-15
lines changed
57.7 KB
Loading
85.5 KB
Loading
33.2 KB
Loading

docs/technical/resource-synchronisation.md

Lines changed: 0 additions & 15 deletions
This file was deleted.

docs/technical/structure-data.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Structure data from external sources
2+
3+
The FIS relies on some structure data that originate and are maintained
4+
elsewhere/by other systems. The data is used for reference purposes and to
5+
ensure consistency.
6+
7+
We call the process of getting this data into the FIS database
8+
_synchronisation_. And we split this in two steps: _fetching_ and _updates_. The
9+
diagram below shows a conceptual overview of the synchronisation process.
10+
11+
![Structure data sync conceptual overview](../diagrams/structure_data_sync.drawio.png)
12+
13+
The left _target table_ is the target of the synchronisation process. It is the
14+
table whose data will be used by the rest of the system as a trusted source of
15+
information. The right _staging table_ represents a kind of intermediary step,
16+
splitting the fetching and update steps.
17+
18+
Fetching is the process
19+
of getting data from the external source and loading it into a staging
20+
table. The updates functionality is responsible for comparing existing data
21+
with the staging table and updating the target table accordingly.
22+
23+
The structure data that must be synchronised is summarised in the table below.
24+
25+
| Data | Description/comment | Size in records (NO) | Authority (NO) | Loading | Update |
26+
|----------------------------------------|---------------------------------------------------------------------|----------------------|----------------|---------|-----------|
27+
| Party | Market participants (SP and SO) | ~500 | Ediel | Merge | Notice |
28+
| Price Area | NO1-5 in Norway | ~5 | Statnett | Merge | Notice |
29+
| Metering Grid Area (MGA) | Grid areas used in settlement, including SO and price area relation | ~500 | Statnett | Merge | Notice |
30+
| Energy Supplier Balance Responsibility | Balance responsibility of each ES, MGA and direction | ~100k | eSett | Replace | Automatic |
31+
32+
As you can see from the last column in the table, there are two different
33+
strategies for _doing updates_: notice and automatic. These will be
34+
described in more detail below, but let's first look at the general pattern.
35+
36+
## Fetching mechanism
37+
38+
This data must be fetched and loaded by a component that is external to the FIS
39+
itself. The reason for keeping this responsibility outside of the FIS is that
40+
depending on what country/context the system is deployed in, the data may be
41+
sourced from different places. Baking the data loading process into the FIS
42+
would tie the system to a specific set of data sources, which is not desirable.
43+
44+
Data is loaded into the staging structure with business identifiers from the
45+
external data source.
46+
It is the responsibility of the fetching component and staging structure to
47+
ensure that the data is of the right format and quality.
48+
49+
### Getting data
50+
51+
When synchronising data, in general, we can distinguish between three different
52+
technical approaches:
53+
54+
* `full` - The whole dataset is fetched and compared to the existing data.
55+
* `delta` - Changes since the last synchronisation are fetched and applied to
56+
the existing data.
57+
* `event-based` - Changes are sent as they happen, and the existing data is
58+
updated accordingly.
59+
60+
In addition to this, the `full` and `delta` approaches can be either `scheduled`
61+
or triggered `ad-hoc` by users.
62+
63+
The FIS synchronisations only currently use the `full` approach, based on a
64+
`scheduled` external mechanism. Other approaches will be added on an as-needed
65+
basis.
66+
67+
All these structure data types are slow-moving, meaning that they do not change
68+
very often. Synchronising the data can be done on a nightly basis, and it is not
69+
critical if the data is a few hours or even a day or two old.
70+
71+
Interdependencies among our resources (such as foreign key constraints) also make
72+
bulk updates impossible to run without extra care to avoid introducing too many
73+
inconsistencies.
74+
75+
### Database interface
76+
77+
The data fetching component interfaces directly with the database to load the
78+
data into the staging structure. We do this via dedicated views, procedures and
79+
unlogged tables in a separate `staging` schema. This is to ensure decoupling and
80+
prevent assuming an internal database structure from the outside, which makes us
81+
free to change the internal details over time if needed.
82+
83+
## Loading mechanism
84+
85+
We use two different strategies for loading the data into the staging structure,
86+
depending on the size of the dataset and the update mechanism we have in place.
87+
88+
### Replace
89+
90+
For bigger datasets, using the automatic update strategy, we replace the whole
91+
dataset with the new one. This is largely for performance and simplicity. Since
92+
the system does not rely on the data always being present in the staging tables,
93+
this allows us to use unlogged tables, truncate and PostgreSQL copy command to
94+
efficiently load the data.
95+
96+
### Merge
97+
98+
Datasets that are small and rely on the notice update mechanism depend on
99+
having the data always available in the staging tables. We must use a merge
100+
strategy for loading the data. This means that the fetching component must
101+
update, insert, delete existing records in the staging table as needed.
102+
103+
## Update mechanism
104+
105+
We have two different mechanisms for _doing updates_ into the target tables in
106+
the system: notice and automatic. We are picking the mechanism based on the size
107+
and significance of the data.
108+
109+
### Notice
110+
111+
For data that is not too big and whose updates are not too frequent, we rely on
112+
a FIS operator to review the data and decide whether to accept it or not. The
113+
operator is mostly in the loop to be informed, but can also do/request changes
114+
to the data in upstream systems in case something is wrong.
115+
116+
The operator is made aware of the updates via
117+
[notices](../concepts/notification-and-notice.md#notice).
118+
119+
For instance, party synchronisation is done manually by the appropriate users,
120+
after they have received _notices_ about the inconsistency or out-of-sync state
121+
to review and resolve, whereas balance responsibility is to be loaded
122+
automatically every day by a background process.
123+
124+
### Automatic
125+
126+
For data that is bigger and/or more frequently updated, we cannot rely on manual
127+
review and acceptance. Instead we accept all updates and need to bake in safety
128+
logic to ensure that we do not accept bad data/updates. The energy supplier
129+
balance responsibility data is loaded with this strategy.
130+
131+
## Examples
132+
133+
The following two sections illustrate how the above mechanisms are used for two
134+
of the structure data types we synchronise in the system.
135+
136+
### Party synchronisation
137+
138+
Party synchronisation is using the merge loading strategy and the notice update
139+
strategy. The diagram below shows how this is done in the system.
140+
141+
![Party synchronisation overview](../diagrams/structure_data_party.drawio.png)
142+
143+
### Energy Supplier Balance Responsibility synchronisation
144+
145+
Energy Supplier Balance Responsibility (ES BR) synchronisation is using the
146+
replace loading strategy and the automatic update strategy.
147+
The diagram below shows how this is done in the system.
148+
149+
![Energy Supplier Balance Responsibility synchronisation overview](../diagrams/structure_data_es_br.drawio.png)

0 commit comments

Comments
 (0)