Commit a8a3ebca80fee7982b76e71b557a5b95ea8c3dea
1 parent
663586ee
Rework infrastructure documentation and fix a few issues
Showing
6 changed files
with
91 additions
and
41 deletions
README.md
@@ -26,14 +26,15 @@ BeuthBot is a master project of the Beuth University of Applied Sciences Berlin. | @@ -26,14 +26,15 @@ BeuthBot is a master project of the Beuth University of Applied Sciences Berlin. | ||
26 | 26 | ||
27 | - Oracle Java 8 | 27 | - Oracle Java 8 |
28 | - Gradle Build - build system | 28 | - Gradle Build - build system |
29 | -- Postgres SQL - relational database | 29 | +- PostgreSQL - relational database |
30 | +- Hibernate - object relational mapping | ||
30 | - Adminer - database administration | 31 | - Adminer - database administration |
31 | - WildFly 10 | 32 | - WildFly 10 |
32 | - Docker | 33 | - Docker |
33 | 34 | ||
34 | <!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --> | 35 | <!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --> |
35 | 36 | ||
36 | -## Firtst steps | 37 | +## First steps |
37 | 38 | ||
38 | The following five steps clarify what is necessary to set up the BeuthBot for the first time. Most of the steps are also useful during development to ultimately test the changes in the application. | 39 | The following five steps clarify what is necessary to set up the BeuthBot for the first time. Most of the steps are also useful during development to ultimately test the changes in the application. |
39 | 40 | ||
@@ -108,7 +109,23 @@ The following command can be used to stop the running application: | @@ -108,7 +109,23 @@ The following command can be used to stop the running application: | ||
108 | 109 | ||
109 | ## Project documention | 110 | ## Project documention |
110 | 111 | ||
111 | -In addition to this general documentation, the directory `docu/` also contains the [project_documentation](docu/project_documentation.md). This section also discuss the individual modules of the application. | 112 | +In addition to this general documentation, the directory `docu/` also contains several sections about the project documentation itself. |
113 | + | ||
114 | +General | ||
115 | + | ||
116 | +- [infrastructure](docu/infrastructure.md) - The individual modules of the application | ||
117 | +- [persistence](docu/persistence.md) - DAOs, Entities, Hibernate, PostgreSQL | ||
118 | + | ||
119 | +Individual modules | ||
120 | + | ||
121 | +- [api.ai](docu/apiai.md) - Usage of API.ai natural language processing | ||
122 | +- [attachment store](docu/attachmentstore.md) - Storing files that come with chat messages | ||
123 | +- [bing speech](docu/bingspeechapi.md) - Usage of bing speech API | ||
124 | +- [canteen parser](docu/canteenParser.md) - Extracting data from the canteen HTML web page | ||
125 | +- [drools](docu/drools.md) - Manage business rules defining the chat bot's behavior | ||
126 | +- [facebook](docu/facebook.md) - Facebook adapter, utils and Facebook app | ||
127 | +- [rasa](docu/rasa.md) - Bringing data from API.ai to Rasa | ||
128 | +- [telegram](docu/telegram.md) - Telegram bot API and Telegram adapter | ||
112 | 129 | ||
113 | <!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --> | 130 | <!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --> |
114 | 131 | ||
@@ -195,7 +212,7 @@ NOTE: Localtunnel tends to crash every now and then, displaying an error message | @@ -195,7 +212,7 @@ NOTE: Localtunnel tends to crash every now and then, displaying an error message | ||
195 | 212 | ||
196 | ## Debugging | 213 | ## Debugging |
197 | 214 | ||
198 | -At the moment, the JBoss server is always started with open debugging ports. To attach to the process using IntelliJ, a remote debug configuration has to be created. To do so, perform the following steps: | 215 | +At the moment, the JBoss server is always started with open debugging ports. To attach to the running docker container process using IntelliJ, a remote debug configuration has to be created. To do so, perform the following steps: |
199 | 216 | ||
200 | - Go to `Run` -> `Edit Configurations...` | 217 | - Go to `Run` -> `Edit Configurations...` |
201 | - Add a new configuration using the button in the top left corner of the dialog | 218 | - Add a new configuration using the button in the top left corner of the dialog |
docu/apiai.md
docu/infrastructure.md
0 → 100644
1 | +# Infrastructure of BHT-Chatbot Project | ||
2 | + | ||
3 | +The whole project is built using gradle and divided into a couple of sub projects (cf. [Sub projects section](#subprojects)). | ||
4 | +Each module is loosely connected through a Java Message Service. The application is running on a JBoss Wildfly 10 inside of a docker container. Another docker container is used for the Rasa backend, one for the PostgreSQL database and one for the Adminer database management tool. | ||
5 | + | ||
6 | +- see [docker compose file](../docker/docker-compose.yml) | ||
7 | + | ||
8 | +The productive project is represented by a separate Git repository in absent of a continuous integration server. | ||
9 | +Pushing into the master branch of this repository should automatically trigger a rebuild of the productive environment. | ||
10 | +- confer [post-receive](../scripts/post-receive) - Git hook for auto deploying the application | ||
11 | + | ||
12 | +## Sub projects | ||
13 | + | ||
14 | +_**DISCLAIMER:** Please note that the following information is documented by the second project team who felt that a deeper look into the project structure should be a requirement for teams working on the project. This means that information is written 'as understood'. The original designers of the system had great knowledge of their architecture but sadly forgot to share it._ | ||
15 | + | ||
16 | +The different modules of the application are deployed as individual services where no service knows whether the other services exist or not. The Java Massage Service is a bus like system where a service can send a message with a key and interested services can wait for messages with a certain key. | ||
17 | +An exception to this is the `common` module which is referenced by every other module. To lesser the dependencies here, the `common` module contains only interfaces and enums. The implementations to these interfaces lie in the `global` module which is unknown by the other modules. | ||
18 | + | ||
19 | +The `mainBot` module contains the core chat bot logic defining the specific use cases the bot supports. | ||
20 | + | ||
21 | +To read more about modules in Wildfly 10, see [JBoss configuration and usage](jboss.md). | ||
22 | + | ||
23 | +To read the story behind a very nasty issue with global entity classes, see [Why is the persistence layer located in `common` instead of `global`?](persistence.md#Why-is-the-persistence-layer-located-in-`common`-instead-of-`global`?) | ||
24 | + | ||
25 | +### MainBot | ||
26 | + | ||
27 | +- [Canteen Parser](canteenParser.md) - web crawler for collecting data of the beuth university canteen | ||
28 | +- Common - holding common classes used by all other subprojects | ||
29 | +- [Drools](drools.md) - Business Rules Management System used to generate the right answer | ||
30 | +- Global - global available services | ||
31 | + | ||
32 | +### Natural Language Processing | ||
33 | + | ||
34 | +- [ApiAi](apiai.md) - simple RESTEasy client application calling googles Api.ai API | ||
35 | +- [Rasa](rasa.md) - simple RESTEasy client application calling the rasa backend rest API | ||
36 | + | ||
37 | +### Messenger | ||
38 | + | ||
39 | +- [Facebook](facebook.md) - Facebook Messenger connector | ||
40 | +- [Telegram](telegram.md) - Telegram Messenger connector | ||
41 | + | ||
42 | +### Text <-> Speech Processing | ||
43 | + | ||
44 | +- [Bing Speech](bingspeechapi.md) - REST client for Microsofts Bing Speech API | ||
0 | \ No newline at end of file | 45 | \ No newline at end of file |
docu/jboss.md
0 → 100644
1 | +# JBoss configuration and usage | ||
2 | + | ||
3 | +The intent of this file is not to provide a full documentation about JBoss, EJBs or dependency injection but to give some hints that might be useful when working on the project. | ||
4 | + | ||
5 | +## Main configuration file | ||
6 | + | ||
7 | +A JBoss application server is configured mostly using XML files. The most important one is the `standalone.xml` which is located in `docker/wildfly/standalone.xaml`. | ||
8 | + | ||
9 | +## Building and deploying the services | ||
10 | + | ||
11 | +When building with gradle, the modules result in seperate `.war` archives which are copied into the JBoss docker container. JBoss should then reload them automatically. | ||
0 | \ No newline at end of file | 12 | \ No newline at end of file |
docu/persistence.md
@@ -42,7 +42,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | @@ -42,7 +42,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | ||
42 | } | 42 | } |
43 | ``` | 43 | ``` |
44 | 44 | ||
45 | -# How can a DAO instance be used? | 45 | +## How can a DAO instance be used? |
46 | 46 | ||
47 | - using dependency injection in a class that is managed by JBoss | 47 | - using dependency injection in a class that is managed by JBoss |
48 | 48 | ||
@@ -51,7 +51,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | @@ -51,7 +51,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | ||
51 | private AppUserDAO userDAO; | 51 | private AppUserDAO userDAO; |
52 | ``` | 52 | ``` |
53 | 53 | ||
54 | -# How to create an entity? | 54 | +## How to create an entity? |
55 | 55 | ||
56 | - currently a DAO is responsible for creating instances of its context entity, e.g. `AppUser newUser = userDAO.createUser()` | 56 | - currently a DAO is responsible for creating instances of its context entity, e.g. `AppUser newUser = userDAO.createUser()` |
57 | - direct creation of an entity like `AppUser newUser = new AppUser()` were not possible at first, but could be used now, too | 57 | - direct creation of an entity like `AppUser newUser = new AppUser()` were not possible at first, but could be used now, too |
@@ -66,7 +66,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | @@ -66,7 +66,7 @@ public interface AppUserDAO extends GenericDAO<AppUser, Long> { | ||
66 | 66 | ||
67 | - the entity can then be modified and updated in the database using the DAO instance | 67 | - the entity can then be modified and updated in the database using the DAO instance |
68 | 68 | ||
69 | -# AppUsers have generic attributes. How can they be used? | 69 | +## AppUsers have generic attributes. How can they be used? |
70 | 70 | ||
71 | - the **Entity-Attribute-Value model (EAV)** is a common pattern in relational database design which aims at structuring a database schema in rows instead of columns; please do some research to really understand it | 71 | - the **Entity-Attribute-Value model (EAV)** is a common pattern in relational database design which aims at structuring a database schema in rows instead of columns; please do some research to really understand it |
72 | - the pattern is implemented and used in the `AppUser` entity to give developers the ability to define attributes at runtime | 72 | - the pattern is implemented and used in the `AppUser` entity to give developers the ability to define attributes at runtime |
@@ -88,11 +88,11 @@ userDAO.saveOrUpdate(u); | @@ -88,11 +88,11 @@ userDAO.saveOrUpdate(u); | ||
88 | - instead of this, the EAV structure can be build manually, too | 88 | - instead of this, the EAV structure can be build manually, too |
89 | - please note that complex data types and lists are not supported using this syntax at the moment; to add support, the custom serializers and deserializers found in `common/persistence` must be extended | 89 | - please note that complex data types and lists are not supported using this syntax at the moment; to add support, the custom serializers and deserializers found in `common/persistence` must be extended |
90 | 90 | ||
91 | -# How does the implementation of the EAV pattern work internally for the AppUser entity? | 91 | +## How does the implementation of the EAV pattern work internally for the AppUser entity? |
92 | 92 | ||
93 | ![Domain model as UML class diagram](img/persistence/domain-model.png) | 93 | ![Domain model as UML class diagram](img/persistence/domain-model.png) |
94 | 94 | ||
95 | -# How to retrieve the generic attributes of an AppUser? | 95 | +## How to retrieve the generic attributes of an AppUser? |
96 | 96 | ||
97 | - the following snippet shows the retrieval using the convenience method | 97 | - the following snippet shows the retrieval using the convenience method |
98 | - instead of this, the EAV structure can be queried an walked manually, too | 98 | - instead of this, the EAV structure can be queried an walked manually, too |
@@ -105,7 +105,7 @@ boolean testValueBool = u.getProperty("test_property_bool", Boolean.class); | @@ -105,7 +105,7 @@ boolean testValueBool = u.getProperty("test_property_bool", Boolean.class); | ||
105 | Double testValueDouble = u.getProperty("test_property_double", Double.class); | 105 | Double testValueDouble = u.getProperty("test_property_double", Double.class); |
106 | ``` | 106 | ``` |
107 | 107 | ||
108 | -# How does the convenience method for accessing the `GenericEntity` hierarchy actually work? | 108 | +## How does the convenience method for accessing the `GenericEntity` hierarchy actually work? |
109 | 109 | ||
110 | A trivial implementation providing access to the structure with getters and setters is provided, but it gives the responsibility of traversing this structure to the using component. To simplify this for developers, a mechanic using custom JSON serializers and deserializers has been implemented. | 110 | A trivial implementation providing access to the structure with getters and setters is provided, but it gives the responsibility of traversing this structure to the using component. To simplify this for developers, a mechanic using custom JSON serializers and deserializers has been implemented. |
111 | When setting a generic attribute, the given value is serialized to JSON using a common serializer. The value as JSON is then given to the custom deserializers which can create a GenericEntity structure from this JSON. | 111 | When setting a generic attribute, the given value is serialized to JSON using a common serializer. The value as JSON is then given to the custom deserializers which can create a GenericEntity structure from this JSON. |
@@ -174,4 +174,10 @@ The custom serializers instead have something like the following output: | @@ -174,4 +174,10 @@ The custom serializers instead have something like the following output: | ||
174 | } | 174 | } |
175 | ``` | 175 | ``` |
176 | 176 | ||
177 | -This result can be used as input for a common JSON deserializer which can create an instance of a desired type from it as long as the type has exactly the same attributes as the structure has in JSON. | ||
178 | \ No newline at end of file | 177 | \ No newline at end of file |
178 | +This result can be used as input for a common JSON deserializer which can create an instance of a desired type from it as long as the type has exactly the same attributes as the structure has in JSON. | ||
179 | + | ||
180 | +## Why is the persistence layer located in `common` instead of `global`? | ||
181 | + | ||
182 | +Short story that might be useful to read: When implementing the persistence layer, the approach was to define entity interfaces and DAO interfaces in `common` and seperate implementations in `global`. From outside of the `global` module a developer should only be able to interact with the entities through their interfaces. Although this is the clean way which even compiled without problems, the entity instances could not be used all the time. In some cases a `ClassCastException` arose when trying to cast an entity instance to its interface. This should work fine normally. Research showed that **each module in Wildfly 10 has its own class loader**. That is why an instance created in a module which is not directly referenced can lead to problems. This can even happen when casting an object to its own class because the instance and the class have been loaded by different class loaders that cannot resolve types loaded by the other loader. | ||
183 | + | ||
184 | +Because nobody was able to deal with this problem correctly, we decided to move the whole persistence layer implementation to `common` although this is clearly a design flaw. | ||
179 | \ No newline at end of file | 185 | \ No newline at end of file |
docu/project_documentation.md deleted
100755 → 0
1 | -# BHT-Chatbot Project | ||
2 | -The hole project is build by gradle and divided into a couple of subprojects (cf. [Subprojects section](#subprojects) ). | ||
3 | -Each module is loosely connected through a Java Message Service. The application is running on a Jboss Wildfly | ||
4 | -inside of a docker container. Another docker container is used for the Rasa backend. | ||
5 | - | ||
6 | -## Infrastructure | ||
7 | -- see [docker compose file](../docker/docker-compose.yml) | ||
8 | - | ||
9 | -The productive project is represented by a separate Git repository in absent of a continuous integration server. | ||
10 | -Pushing into this repository will automatically trigger a rebuild of the productive environment. | ||
11 | -- confer [post-receive](../scripts/post-receive) - Git hook for auto deploying the application | ||
12 | - | ||
13 | -### Subprojects | ||
14 | - | ||
15 | -#### MainBot | ||
16 | -- [Canteen Parser](canteenParser.md) - web crawler for collecting data of the beuth university canteen | ||
17 | -- Common - holding common classes used by all other subprojects | ||
18 | -- [Drools](drools.md) - Business Rules Management System used to generate the right answer | ||
19 | -- Global - global available services | ||
20 | - | ||
21 | -#### Natural Language Processing | ||
22 | -- [ApiAi](apiai.md) - simple RESTEasy client application calling googles Api.ai API | ||
23 | -- [Rasa](rasa.md) - simple RESTEasy client application calling the rasa backend rest API | ||
24 | - | ||
25 | -#### Messenger | ||
26 | -- [Facebook](facebook.md) - Facebook Messenger connector | ||
27 | -- [Telegram](telegram.md) - Telegram Messenger connector | ||
28 | - | ||
29 | -#### Text <-> Speech Processing | ||
30 | -- [Bing Speech](binspeechapi.md) - REST client for Microsofts Bing Speech API | ||
31 | \ No newline at end of file | 0 | \ No newline at end of file |