Commit a8a3ebca80fee7982b76e71b557a5b95ea8c3dea

Authored by Benjamin Rühl
1 parent 663586ee

Rework infrastructure documentation and fix a few issues

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
1 # api.ai API 1 # api.ai API
2 2
  3 +**IMPORTANT NOTE: API.ai by Google has become Dialogflow. That's why some information on this page might be out of date.**
  4 +
3 <!-- MarkdownTOC --> 5 <!-- MarkdownTOC -->
4 6
5 - [api.ai Setup](#api.ai-setup) 7 - [api.ai Setup](#api.ai-setup)
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&lt;AppUser, Long&gt; { @@ -42,7 +42,7 @@ public interface AppUserDAO extends GenericDAO&lt;AppUser, Long&gt; {
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&lt;AppUser, Long&gt; { @@ -51,7 +51,7 @@ public interface AppUserDAO extends GenericDAO&lt;AppUser, Long&gt; {
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&lt;AppUser, Long&gt; { @@ -66,7 +66,7 @@ public interface AppUserDAO extends GenericDAO&lt;AppUser, Long&gt; {
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(&quot;test_property_bool&quot;, Boolean.class); @@ -105,7 +105,7 @@ boolean testValueBool = u.getProperty(&quot;test_property_bool&quot;, 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