Skip to content

Commit fb94640

Browse files
committed
Modify email tutorial to use mu-authorization and delta-notifier
1 parent 3ece2e2 commit fb94640

File tree

1 file changed

+56
-122
lines changed

1 file changed

+56
-122
lines changed

TUTORIALS.md

Lines changed: 56 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -590,14 +590,29 @@ Then add the prefix to the `repository.lisp` file:
590590
(add-prefix "example" "http://example.com/")
591591
```
592592

593-
We are almost there for a first test! The only thing left to do is to add the `/mails` route to the dispatcher (for more info check the documentation on http://mu.semte.ch). To do this add the following block of code to the `dispatcher.ex` file:
593+
We're almost there for a first test! Two small pieces of wiring left to do:
594+
595+
First add the `/mails` route to the dispatcher (for more info check [the documentation](https://github.com/mu-semtech/mu-dispatcher/)). To do this add the following block of code to the `dispatcher.ex` file:
594596

595597
```
596598
match "/mails/*path" do
597599
Proxy.forward conn, path, "http://resource/mails/"
598600
end
599601
```
600602

603+
Second, configure `mu-authorization` to allow anyone to edit Mail resources. We won't add proper access rules as that's a topic for a different tutorial and more info can be found [in the repo for the project](https://github.com/mu-semtech/mu-authorization). We edit the file `config/authorization/config.ex` to add to the public `GroupSpec`:
604+
605+
```diff
606+
graphs: [ %GraphSpec{
607+
graph: "http://mu.semte.ch/graphs/public",
608+
constraint: %ResourceConstraint{
609+
resource_types: [
610+
- "http://xmlns.com/foaf/0.1/Person"
611+
+ "http://xmlns.com/foaf/0.1/Person",
612+
+ "http://example.com/Mail"
613+
],
614+
```
615+
601616
Now fire this up and lets see what we have by running the following command in the project root directory:
602617

603618
```bash
@@ -678,56 +693,6 @@ To verify the original get request again, this now produces:
678693
}
679694
```
680695

681-
#### Enabling the reactive database
682-
Before we can start writing our reactive mail managing micro-service, we will need to add a monitoring service to monitor the DB. This will be a lot easier than it sounds with mu.semte.ch. To start, open the `docker-compose.yml` file and add the following lines at the bottom of the file:
683-
684-
```yaml
685-
# ...
686-
delta:
687-
image: semtech/mu-delta-service:beta-0.7
688-
links:
689-
- database:database
690-
volumes:
691-
- ./config/delta-service:/config
692-
environment:
693-
CONFIGFILE: "/config/config.properties"
694-
SUBSCRIBERSFILE: "/config/subscribers.json"
695-
```
696-
697-
This will add the monitoring service to our installation. The last thing to do for now is to change the link on the `resource` microservice by replacing
698-
```yaml
699-
links:
700-
- database:database
701-
```
702-
with
703-
```yaml
704-
links:
705-
- delta:database
706-
```
707-
708-
The final steps are to create the configuration and subscribers files. Create a file called `config.properties` at the location `config/delta-service/config.properties` and write the following lines in that file:
709-
710-
```conf
711-
# made by Langens Jonathan
712-
queryURL=http://database:8890/sparql
713-
updateURL=http://database:8890/sparql
714-
sendUpdateInBody=true
715-
calculateEffectives=true
716-
```
717-
718-
and then create `config/delta-service/subscribers.json` and put this JSON inside:
719-
720-
```json
721-
{
722-
"potentials":[
723-
],
724-
"effectives":[
725-
]
726-
}
727-
```
728-
729-
If we run `docker-compose rm` and then `docker-compose up` again, the delta service will be booting and already monitoring the changes that happen in the database! Of course we are not doing anything with them yet. So we will create a new micro-service just for this purpose.
730-
731696
#### The mail-fetching microservice
732697
The next step is to build our mail handling microservice. To do this we create a new directory called `mail-service` in our base directory. Then we create a file in that directory called `Dockerfile`. We will start from a mu.semte.ch template to make developing this microservice that much quicker. Mu.semte.ch has templates for a bunch of languages ruby, javascript, python, … For this microservice we will go for python 3. To do this we simply need to create a dockerfile to build the container and a `web.py` file which will serve as the location for our code. First we create the file 'Dockerfile' in our mail-service directory:
733698

@@ -840,81 +805,54 @@ The last step to create this service is to add it to our docker-compose.yml file
840805
- ./mail-service:/app
841806
```
842807
808+
Running `docker-compose up` again will start our new service, which should auto reload with changes to the python code, though changing the configuration of our other services will require to restart them for the changes to be picked up.
809+
843810
At this point, we have:
844811
- Defined a JSONAPI through which we can access our emails, using the standard mu.semte.ch stack
845812
- Built a custom service which fetches the emails from our mail account and inserts them into the triplestore using the right model
846813

847-
Now we will use these services in combination with the delta service, to discover which emails were inserted into the database, and to perform reactive computations on it.
848-
849-
#### The delta service
850-
851-
The delta service’s responsibilities are:
814+
Now we will use these services in combination with the delta notifier, to discover which emails were inserted into the database, and to perform reactive computations on it.
852815

853-
- Acting as the SPARQL endpoint for the microservices
854-
- Calculating the differences (deltas) that a query will introduce in the database
855-
- Notifying interested parties of these differences
816+
#### Mu-authorization and the delta-notifier
856817

857-
For this hands on we use version beta-0.8 of the delta service.
818+
You may have noticed that the default mu-project docker-compose.yml contains a service called `database` but the image is `semtech/mu-authorization`, this has two responsibilities:
858819

859-
##### What do these delta reports look like?
860-
There are 2 types of delta reports, you have potential inserts and effective inserts. A report for either will look like:
861-
```json
862-
{
863-
"delta": [
864-
{
865-
"type": "effective",
866-
"graph": "http://mu.semte.ch/application",
867-
"inserts": [
868-
{
869-
"s": {
870-
"value": "http://example.com/mails/58B187FA6AA88E0009000001",
871-
"type": "uri"
872-
},
873-
"p": {
874-
"value": "http://example.com/subject",
875-
"type": "uri"
876-
},
877-
"o": {
878-
"value": "Mu Semtech Mail Server",
879-
"type": "literal"
880-
}
881-
},
882-
...
883-
}
884-
```
885-
*You can view the full version [here](https://gist.githubusercontent.com/langens-jonathan/cd5db8e9f68861662d888dad77f93662/raw/84adc69f9fd3143f45c05c0a5cefdf1ca9b95b55/gistfile1.txt).*
820+
- Act as the SPARQL endpoint, handling authorization logic before forwarding approved queries or updates to the triplestore
821+
- Producing 'delta's describing the changes and forwarding them to clients defined in `config/authorization/delta.ex`
886822

887-
A report states the query that was sent, an array of inserted objects and an array of deleted objects: Inserted or deleted objects represent a single triple with s, p and o being subject, predicate and object.
823+
This is already configured for us to send these deltas to another service, the delta-notifier. This service is configured in `config/delta/rules.js`, which defines which triples different microservices are interested in. It sends matching deltas to these services using REST. The format for these messages is detailed [in the delta-notifier repository](https://github.com/mu-semtech/delta-notifier#delta-formats).
888824

889825
#### Expanding our mail handling microservice
890-
We need to notify the delta service of the existence of our mail handling service. We do this using the `subscribers.json` file that was created before. Change it so it looks like:
891826

892-
```json
893-
{
894-
"potentials":[
895-
],
896-
"effectives":[
897-
"http://mailservice/process_delta"
898-
]
899-
}
900-
```
827+
We need to notify the delta-notifier of the existence of our mail handling service. To do this we replace the `config/delta/rules.js` file to send any deltas for subjects of `rdf:type` `example:Mail` to the mail service:
901828

902-
In the `docker-compose.yml` file we need to alter the delta-service definition to look like:
903-
904-
```yaml
905-
delta:
906-
image: semtech/mu-delta-service:beta-0.8
907-
links:
908-
- database:database
909-
- mailservice:mailservice
910-
volumes:
911-
- ./config/delta-service:/config
912-
environment:
913-
CONFIGFILE: "/config/config.properties"
914-
SUBSCRIBERSFILE: "/config/subscribers.json"
829+
```js
830+
export default [
831+
{
832+
match: {
833+
predicate: {
834+
type: "uri",
835+
value: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
836+
},
837+
object: {
838+
type: "uri",
839+
value: "http://example.com/Mail",
840+
},
841+
},
842+
callback: {
843+
url: "http://mailservice/process_delta",
844+
method: "POST",
845+
},
846+
options: {
847+
resourceFormat: "v0.0.1",
848+
gracePeriod: 250,
849+
ignoreFromSelf: true,
850+
},
851+
},
852+
];
915853
```
916854

917-
That way the delta service can talk to the mailservice.
855+
Don't forget to restart your delta notifier with `docker compose restart delta-notifier`.
918856

919857
To handle delta reports in our mail handling microservice we will need 2 things:
920858

@@ -926,9 +864,6 @@ To get access to this we edit `web.py` to define a new method that will:
926864
- Load the delta report into a variable
927865
- Define some variables.
928866

929-
Lastly we define an array that will hold the URIs of all emails that need to be sent.
930-
931-
932867
```python
933868
# mail-service/web.py
934869
import json
@@ -944,16 +879,15 @@ def processDelta():
944879
value_mail_is_ready = "yes"
945880
946881
# Loop over all inserted triples to check for mails that are ready to be sent:
947-
948-
for delta in delta_report['delta']:
949-
for triple in delta['inserts']:
950-
if(triple['p']['value'] == predicate_mail_is_ready):
951-
if(triple['o']['value'] == value_mail_is_ready):
952-
mails_to_send.add(triple['s']['value'])
882+
for delta in delta_report:
883+
for insert in delta['inserts']:
884+
if (insert['predicate']['value'] == predicate_mail_is_ready
885+
and insert['object']['value'] == value_mail_is_ready):
886+
mails_to_send.add(insert['subject']['value'])
953887
# continued later...
954888
```
955889

956-
After this for loop has run, all the URI’s of mails that are ready to be send will be in the `mails_to_send` array. Now we loop over the array and query the database for each URI in the set. And then we will fetch a mail object for every URI that is in the set.
890+
After this for loop has run, all the URIs of mails that are ready to be send will be in the `mails_to_send` array. Now we loop over the array and query the database for each URI in the set. And then we will fetch a mail object for every URI that is in the set.
957891

958892
Add the following code to `mail_helpers.py`:
959893
```python

0 commit comments

Comments
 (0)