ArchitectureΒΆ
High level overview:
![digraph d {
node [shape=component style=filled fillcolor=grey];
subgraph cluster_app {
label="application";
ucp_doc [label="manage\ndocuments" shape=ellipse];
ucp_sub [label="manage\nsubscriptions" shape=ellipse];
ucp_msg [label="manage\nmessages" shape=ellipse];
uc_rx_callback [label="receive\ncallback" shape=ellipse];
}
doc_api [label="document\nAPI" shape=component];
ucp_doc -> doc_api;
msg_api [label="message\nAPI" shape=component];
ucp_msg -> msg_api;
repo_api_outbox [label="<<rdbms>>\nAPI\noutbox" fillcolor=green];
repo_api_inbox [label="<<sqs>>\nAPI\ninbox" fillcolor=green];
repo_bc_inbox [label="<<sqs>>\nblockchain\ninbox" fillcolor=green];
subgraph cluster_ws {
websub [label="subscription\nAPI (websub)" fillcolor=purple];
}
repo_message_lake [label="<<s3>>\nmessage\nlake" fillcolor=orange];
repo_object_lake [label="<<s3>>\nobject\nlake" fillcolor=orange];
repo_object_acl [label="<<s3>>\nobject\nACL" fillcolor=orange];
repo_object_ret_q [
label="<<sqs>>\nobject\nretreival"
fillcolor=green
];
ucp_sub -> websub;
repo_foreign_objects [label="foreign\nobject\nproxy"];
uc_get_objects -> repo_foreign_objects;
uc_authenticated_object_access [
label="authenticated\nobject access"
shape=ellipse
fillcolor=orange
];
doc_api -> uc_authenticated_object_access -> repo_object_acl;
uc_authenticated_object_access -> repo_object_lake;
uc_record_object [
label="record\nobject"
shape=ellipse
fillcolor=orange
];
doc_api -> uc_record_object -> repo_object_lake;
uc_submit_message [
label="post message\nto api inbox"
shape=ellipse
fillcolor=orange
];
uc_check_message [
label="get message\nby reference id"
shape=ellipse
fillcolor=orange
];
msg_api -> uc_check_message -> repo_message_lake;
msg_api -> uc_submit_message -> repo_api_inbox;
uc_api_inout [
label="enqueue\ninbound\nmessages"
shape=ellipse fillcolor=green
];
repo_api_inbox -> uc_api_inout [dir=back];
repo_api_outbox -> uc_api_inout [dir=back];
w_api_inout [label="<<docker>>\nmessage\nreception\nworker"];
uc_api_inout -> w_api_inout;
mcu [label="<<docker>>\nmulti-channel\nblockchain\nrouter"];
uc_bc_tx_submit [
label="submit\nblockchain\ntransactions"
shape=ellipse
fillcolor=orange
];
repo_rejected_messages [
label="<<sqs>>\nrejected\nmessages"
fillcolor=green
];
mcu -> uc_bc_tx_submit;
uc_bc_tx_submit -> repo_api_outbox;
uc_bc_tx_submit -> repo_bc_channel;
uc_bc_tx_submit -> repo_rejected_messages;
uc_update_status_rejected [
label="update status\nof rejected\nmessages"
shape=ellipse
fillcolor=orange
];
repo_rejected_messages -> uc_update_status_rejected [dir=back];
repo_message_lake -> uc_update_status_rejected [dir=back];
w_status_updater [label="<<docker>>\nrejected\nstatus\nupdater"]
uc_update_status_rejected -> w_status_updater [dir=back];
subgraph cluster_chan {
label="channel specific";
repo_bc_channel [
label="<<blockchain>>\nchannels"
fillcolor=orange
shape=folder
];
scbcep [
label="<<docker>>\nsingle-channel\nblockchain\nevent processor"
];
uc_bc_rx_events [
label="receive\ninbound\nblockchain\nevents"
shape=ellipse
fillcolor=orange
];
uc_bc_rx_events -> scbcep [dir=back];
}
repo_bc_channel -> uc_bc_rx_events [dir=back];
mp [label="<<docker>>\ninbound\nmessage\nprocessor"]
uc_bc_proc_events [
label="initiate\ninbound message\nprocessing tasks"
shape=ellipse
fillcolor=green
];
repo_bc_inbox -> uc_bc_proc_events [dir=back];
uc_bc_proc_events -> mp [dir=back];
websub -> uc_bc_proc_events [dir=back];
repo_object_acl -> uc_bc_proc_events [dir=back];
repo_message_lake -> uc_bc_proc_events [dir=back];
repo_object_ret_q -> uc_bc_proc_events [dir=back];
uc_rx_callback -> websub [dir=back];
uc_get_objects [
label="retrieve and store\nforeign documents"
shape=ellipse
fillcolor=green
];
repo_object_lake -> uc_get_objects [dir=back];
repo_object_ret_q -> uc_get_objects [dir=back];
uc_enqueue_received_message [
label="enqueue\nreceived\nmessage"
shape=ellipse
fillcolor=green
];
repo_bc_inbox -> uc_enqueue_received_message [dir=back];
//uc_enqueue_received_message -> uc_synth_hidden_messages [dir=back];
reception_api [label="message\nreception\nAPI"]
uc_enqueue_received_message -> reception_api [dir=back];
post_msg_from_bc [
label="POST\nmessage\n(from blockchain)"
shape=ellipse
];
post_msg_from_bc -> reception_api;
uc_bc_rx_events -> post_msg_from_bc;
spider [label="<<docker>>\ndocument\nspider"];
uc_get_objects -> spider [dir=back];
}](_images/graphviz-4ac4f8750976066826787c5b62075fb7eeca93fa.png)
Document API and components:
![digraph d {
node [shape=component style=filled fillcolor=grey];
subgraph cluster_app {
label="application";
ucp_doc [label="manage\ndocuments" shape=ellipse];
}
doc_api [label="document\nAPI" shape=component];
ucp_doc -> doc_api;
repo_object_lake [label="<<s3>>\nobject\nlake" fillcolor=orange];
repo_object_acl [label="<<s3>>\nobject\nACL" fillcolor=orange];
repo_object_ret_q [
label="<<sqs>>\nobject\nretreival"
fillcolor=green
];
repo_foreign_objects [label="foreign\nobject\nproxy"];
uc_get_objects -> repo_foreign_objects;
uc_authenticated_object_access [
label="authenticated\nobject access"
shape=ellipse
fillcolor=orange
];
doc_api -> uc_authenticated_object_access -> repo_object_acl;
uc_authenticated_object_access -> repo_object_lake;
uc_record_object [
label="record\nobject"
shape=ellipse
fillcolor=orange
];
doc_api -> uc_record_object -> repo_object_lake;
uc_bc_proc_events [
label="initiate\ninbound message\nprocessing tasks"
shape=ellipse
fillcolor=green
];
repo_object_acl -> uc_bc_proc_events [dir=back];
repo_object_ret_q -> uc_bc_proc_events [dir=back];
uc_get_objects [
label="retrieve and store\nforeign documents"
shape=ellipse
fillcolor=green
];
repo_object_lake -> uc_get_objects [dir=back];
repo_object_ret_q -> uc_get_objects [dir=back];
spider [label="<<docker>>\ndocument\nspider"];
uc_get_objects -> spider [dir=back];
}](_images/graphviz-eaf5120fee0b41c24a5ec516f740ae42a6d51b3c.png)
Message API and components:
![digraph d {
node [shape=component style=filled fillcolor=grey];
subgraph cluster_app {
label="application";
ucp_sub [label="manage\nsubscriptions" shape=ellipse];
ucp_msg [label="manage\nmessages" shape=ellipse];
uc_rx_callback [label="receive\ncallback" shape=ellipse];
}
msg_api [label="message\nAPI" shape=component];
ucp_msg -> msg_api;
repo_api_outbox [label="<<rdbms>>\nAPI\noutbox" fillcolor=green];
repo_api_inbox [label="<<sqs>>\nAPI\ninbox" fillcolor=green];
repo_bc_inbox [label="<<sqs>>\nblockchain\ninbox" fillcolor=green];
subgraph cluster_ws {
websub [label="subscription\nAPI (websub)" fillcolor=purple];
}
repo_message_lake [label="<<s3>>\nmessage\nlake" fillcolor=orange];
ucp_sub -> websub;
uc_submit_message [
label="post message\nto api inbox"
shape=ellipse
fillcolor=orange
];
uc_check_message [
label="get message\nby reference id"
shape=ellipse
fillcolor=orange
];
msg_api -> uc_check_message -> repo_message_lake;
msg_api -> uc_submit_message -> repo_api_inbox;
uc_api_inout [
label="enqueue\ninbound\nmessages"
shape=ellipse fillcolor=green
];
repo_api_inbox -> uc_api_inout [dir=back];
repo_api_outbox -> uc_api_inout [dir=back];
w_api_inout [label="<<docker>>\nmessage\nreception\nworker"];
uc_api_inout -> w_api_inout;
mcu [label="<<docker>>\nmulti-channel\nblockchain\nrouter"];
uc_bc_tx_submit [
label="submit\nblockchain\ntransactions"
shape=ellipse
fillcolor=orange
];
repo_rejected_messages [
label="<<sqs>>\nrejected\nmessages"
fillcolor=green
];
mcu -> uc_bc_tx_submit;
uc_bc_tx_submit -> repo_api_outbox;
uc_bc_tx_submit -> channel;
uc_bc_tx_submit -> repo_rejected_messages;
uc_update_status_rejected [
label="update status\nof rejected\nmessages"
shape=ellipse
fillcolor=orange
];
repo_rejected_messages -> uc_update_status_rejected [dir=back];
repo_message_lake -> uc_update_status_rejected [dir=back];
w_status_updater [label="<<docker>>\nrejected\nstatus\nupdater"]
uc_update_status_rejected -> w_status_updater [dir=back];
mp [label="<<docker>>\ninbound\nmessage\nprocessor"]
uc_bc_proc_events [
label="initiate\ninbound message\nprocessing tasks"
shape=ellipse
fillcolor=green
];
repo_bc_inbox -> uc_bc_proc_events [dir=back];
uc_bc_proc_events -> mp [dir=back];
websub -> uc_bc_proc_events [dir=back];
repo_message_lake -> uc_bc_proc_events [dir=back];
uc_rx_callback -> websub [dir=back];
uc_enqueue_received_message [
label="enqueue\nreceived\nmessage"
shape=ellipse
fillcolor=green
];
repo_bc_inbox -> uc_enqueue_received_message [dir=back];
reception_api [label="message\nreception\nAPI"]
uc_enqueue_received_message -> reception_api [dir=back];
channel [
label="channel"
shape=cloud
];
channel -> reception_api;
}](_images/graphviz-0839ca06a808cd3c2f83cdbdc7cad2d5f40cd8c6.png)
Channel API and components:
![digraph d {
node [shape=component style=filled fillcolor=grey];
local_node [label="<<Intergov>>\nNode"];
channel_endpoint [label="<<Flask API>>\nChannel Endpoint\nand\nSubscription Hub", fillcolor=green];
sending_db [label="<<DB>>\nSending DB", fillcolor=lightblue];
receiving_db [label="<<DB>>\nReceiving DB", fillcolor=lightblue];
channel_media [label="<<blockchain>>\nChannel Media", fillcolor=purple];
subscription_processor [label="<<lambda>>\nSubscription\nProcessor", fillcolor=green];
subscription_store [label="<<s3>>\nSubscription\nStore", fillcolor=lightblue];
callback_spreader [label="<<lambda>>\nCallback\nSpreader", fillcolor=green];
subscription_event_queue [label="<<sqs>>\nSubscription\nEvent Queue", fillcolor=lightblue];
# grouping for nicer display
subgraph node_channel_interface{
rank="same"
channel_endpoint
callback_spreader
}
subgraph channel_stores{
rank="same"
sending_db
receiving_db
subscription_store
}
# Efferent messages
# node posts to channel
local_node -> channel_endpoint;
channel_endpoint -> sending_db;
channel_endpoint -> channel_media;
# node subscribe to updates about that message
// local_node -> channel_endpoint;
channel_endpoint -> subscription_store;
# subscription processor delivers events
subscription_processor -> sending_db;
subscription_processor -> subscription_event_queue;
callback_spreader -> subscription_event_queue;
callback_spreader -> local_node;
# Afferent messages
# channel observes new messages
// channel_endpoint -> channel_media;
channel_endpoint -> receiving_db;
# node subscribes to new messages
// local_node -> channel_endpoint;
// channel_endpoint -> subscription_store;
# subscription processor delivers events
subscription_processor -> receiving_db;
// subscription_processor -> subscription_event_queue;
// callback_spreader -> subscription_event_queue;
// callback_spreader -> local_node;
}](_images/graphviz-21ccdb8baeecbe32e6541536efc904ef46b2144b.png)
With processes:
![digraph d {
node [shape=component style=filled fillcolor=grey];
local_node [label="<<Intergov>>\nNode"];
uc_node_post_message [label="post\nmessage" shape=ellipse];
uc_subscribe_to_message_by_id [label="subscribe to\nmessage by id" shape=ellipse];
uc_subscribe_to_messages_by_jurisdiction [label="subscribe to\nmessage by\njurisdiction" shape=ellipse];
uc_deliver_subscription_event [label="deliver\nsubscription\nevent" shape=ellipse];
channel_endpoint [label="<<Flask API>>\nChannel Endpoint\nand\nSubscription Hub", fillcolor=green];
uc_channel_post_message [label="CHAN post\nmessage" shape=ellipse];
sending_db [label="<<DB>>\nSending DB", fillcolor=lightblue];
uc_get_new_messages [label="get new\nmessages" shape=ellipse];
receiving_db [label="<<DB>>\nReceiving DB", fillcolor=lightblue];
uc_write_subscription [label="write\nsubscription" shape=ellipse];
channel_media [label="<<blockchain>>\nChannel Media", fillcolor=purple];
subscription_processor [label="<<lambda>>\nSubscription\nProcessor", fillcolor=green];
subscription_store [label="<<s3>>\nSubscription\nStore", fillcolor=lightblue];
uc_notify_subscribers [label="notify\nsubscribers" shape=ellipse];
callback_spreader [label="<<lambda>>\nCallback\nSpreader", fillcolor=green];
uc_get_subscription_event [label="get\nsubscription\nevents" shape=ellipse];
subscription_event_queue [label="<<sqs>>\nSubscription\nEvent Queue", fillcolor=lightblue];
# Grouping for nicer display
subgraph node_channel_interface{
rank="same"
channel_endpoint
callback_spreader
}
subgraph node_ucs{
rank="same"
uc_node_post_message
uc_subscribe_to_message_by_id
uc_subscribe_to_messages_by_jurisdiction
uc_deliver_subscription_event
}
subgraph channel_components{
rank="same"
channel_endpoint
subscription_processor
callback_spreader
}
subgraph channel_ucs{
rank="same"
uc_channel_post_message
uc_get_new_messages
uc_write_subscription
uc_get_subscription_event
}
subgraph channel_stores{
rank="same"
sending_db
receiving_db
subscription_store
subscription_event_queue
}
# Efferent messages
# node posts to channel
local_node -> uc_node_post_message;
uc_node_post_message -> channel_endpoint;
uc_channel_post_message -> channel_endpoint [dir=back];
uc_channel_post_message -> sending_db;
uc_channel_post_message -> channel_media;
# node subscribe to updates about that message
local_node -> uc_subscribe_to_message_by_id;
uc_subscribe_to_message_by_id -> channel_endpoint;#subscription_hub
uc_write_subscription -> channel_endpoint [dir=back];
uc_write_subscription -> subscription_store;
# Afferent messages
# channel observes new messages
channel_endpoint -> uc_get_new_messages;
uc_get_new_messages -> channel_media;
uc_get_new_messages -> receiving_db;
# node subscribes to new messages
local_node -> uc_subscribe_to_messages_by_jurisdiction;
uc_subscribe_to_messages_by_jurisdiction -> channel_endpoint;#subscription_hub
# Subscriptions
# subscription processor delivers events
subscription_processor -> uc_notify_subscribers;
uc_notify_subscribers -> receiving_db;
uc_notify_subscribers -> sending_db;
uc_notify_subscribers -> subscription_event_queue;
# callback spreader makes callbacks
callback_spreader -> uc_get_subscription_event;
uc_get_subscription_event -> subscription_event_queue;
callback_spreader -> uc_deliver_subscription_event;
uc_deliver_subscription_event -> local_node;
}](_images/graphviz-d1bae2cff89676634bc89c17137593e4a001280e.png)
Document API - storage of local documents and retrieval of foreign documents
Message API - posting messages to a foreign jurisdiction and retrieving messages from a foreign jurisdiction
Subscription API - a hub to subscribe to updates about messages