blob: 3281812afe77d8767251f47c0318a2d17d8897b4 [file] [log] [blame]
////
******************************************************************************
* Copyright © 2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
*
* http://www.eclipse.org/legal/epl-v10.html
*
******************************************************************************
////
openKonsequenz - Architecture of the module "portal@openK"
==========================================================
:Author: Frank Dietrich
:Email: frank.dietrich@pta.de
:Date: 2017-09-18
:Revision: 1
:icons:
:source-highlighter: highlightjs
:highlightjs-theme: solarized_dark
This documentation bases on ARC42-Template (v7.0):
*About arc42*
arc42, the Template for documentation of software and system architecture.
By Dr. Gernot Starke, Dr. Peter Hruschka and contributors.
Template Revision: 7.0 EN (based on asciidoc), January 2017
© We acknowledge that this document uses material from the arc 42 architecture template, http://www.arc42.de.
Created by Dr. Peter Hruschka & Dr. Gernot Starke.
<<<
== Introduction and Goals
=== Requirements Overview
[...]
=== Quality Goals
[...]
=== Stakeholders
.Stakeholders
[options="header,footer"]
|=========================================================
|Role/Name|Contact|Expectations
|Product Owner (represents the Distribution System Operators)|Gordon Pickford, Oliver Tantu|The software must fulfil their functional and nonfunctional Requirements.
|Module Developer|Michel Allessandrini, Jonas Tewolde, Frank Dietrich|All relevant business and technical information must be available for implementing the software.
|External Reviewer (represents the AC/QC)|Martin Jung, Anja Berschneider|The software and the documentation is realized according the Quality and Architecture Handbook of openKONSEQUENZ.
|System Integrator||A documentation for the integration of the module in the DSO specific environments must be available.
|=========================================================
== Architecture Constraints
The main architecture constraints are:
[...]
=== Technical Constraints
The following technical constraints are given:
.Technical Contraints
[options="header,footer"]
|========================================================
|Component|Constraints
|Basis components of the reference platform|
- Application Server Tomcat
- JPA EclipseLink
- Database PostgreSQL
|Enterprise Service Bus|
* ESB Talend
* Communication via RESTful Webservices
|Programming Language Frontend
a|* Angular
* Bootstrap
* jQuery
* REST/JSON Interfaces
|GUI design
a|* According to oK-GUI-Styleguide
|Java QA environment|Sonarqube 5.6.6
|Programming Language
a|* Backend: Java 1.8
* Frontend: Angular 4.0.0 (Javascript, Typescript, HTML5, CSS3)
|IDE
a|* Not restricted (Eclipse, IntelliJ, Microsoft Developer Studio, Microsoft Visual Code ...)
|Build system
a|* Backend: Maven
* Frontend: NodeJS + Angular/cli
|Libraries, Frameworks,Components
a|* Used Libraries/Frameworks have to be compatible to the Eclipse Public License
|Architecture Documentation|* According ARC42-Template
|========================================================
=== Technical Dependencies
The following libraries are used:
.Libraries
[options="header,footer"]
|=========================================================
|Name of the library|Version|Artefact-id|Usage|License|Tier
|org.apache.httpcomponents.httpclient|4.5.3
a|
[source,xml]
----
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
----
|Backend, Http-Client|Apache 2.0|Backend
|org.json.json|20160810
a|
[source,xml]
----
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
----
|Backend - Json functionality|Json|Backend
|org.jboss.resteasy.resteasy-jaxrs|3.0.21_Final
a|
[source,xml]
----
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.21.Final</version>
</dependency>
----
|Backend - RestServer|Apache 2.0 / CC0.1.0/ Public|Backend
|org.jboss.resteasy.jaxrs-api|3.0.12.Final
a|
[source,xml]
----
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.12.Final</version>
</dependency>
----
|Rest-Server|Apache 2.0|Backend
|javax.servlet.servlet-api|3.0.1
a|
[source,xml]
----
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
----
|Backend - Logging Servlet |CDDL GLP 2.0|Backend
|com.google.code.gson.gson|2.8.0
a|
[source,xml]
----
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
----
|Backend Json de-serialization|Apache 2.0|Backend
|log4j.log4j|1.2.17
a|
[source,xml]
----
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
----
|Backend logging|Apache 2.0|Backend
|commons-io|2.5
a|
[source,xml]
----
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
----
|IO utils|Apache 2.0| Backend
|junit.junit|4.12
a|
[source,xml]
----
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
----
|Unit testing|EPL 1.0|Backend
|org.easymock.easymock|3.4
a|
[source,xml]
----
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.4</version>
</dependency>
----
|Unit testing|Apache 2.0|Backend
|org.powermock.powermock-api-easymock|1.6.6
a|
[source,xml]
----
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.6.6</version>
</dependency>
----
|Unit testing|Apache 2.0|Backend
|org.jacoco.jacoco-maven-plugin|0.7.9
a|
[source,xml]
----
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.9</version>
</dependency>
----
|Test coverage|EPL 1.0|Backend
|=========================================================
== System Scope and Context
=== Business Context
[...]
=== Technical Context
[...]
=== Solution Strategy
<TODO>
== Building Block View
=== Whitebox Overall System
The module Auth&Auth consists of the following components:
.Module components
[plantuml]
....
interface authAndAuthAPI
node AuthAndAuthEnvironment {
component portalBE [
portalBackend
]
component portalFE [
portalFrontend
]
component keycloak [
KeyCloak
]
portalFE-(0-portalBE
portalBE-(0-keycloak
}
node openKModule [
openKonsequenz module
]
portalBE #--authAndAuthAPI
openKModule->authAndAuthAPI
....
. *portalFrontend* - The user interface of the portal. Consists of the login page and the module overview grid
. *portalBackend* - Provides the services for its frontend.
. *authAndAuthAPI* - Additionally the portalBackend provides general user and security services for
for all openKonsequenz-Modules.
. *KeyCloak* - KeyCloak implements most of the security aspects for the portal application and the modules.
It provides an userinterface for user and role management of the modules and generates the JSON Web Token (JWT)
for the session and access control.
==== Auth&Auth-API
The Auth&Auth needs information from the system Keycloak. Therefore, it must provide an interface for receiving the according data, see figure 1.
=== Level 2
==== portalFE SPA (Frontend tier)
The frontend component implements the concept of a single-page application (SPA). The framework used is Angular2. It divides the portalFE into three layers:
1.Components - The components (Pages, Lists, Dialogs, Common Comp.) represent the presentation layer and the control layer. A component contains the control logic (.ts-file), an HTML-fragment as presentation description (.html-file) and a style definition (.css-file).
2.Services - The service component communicates with the interfaces of the backend via HTTP requests by using the model component.
3.Model - The model corresponds to the View-Model of the backend tier.
.Frontend tier
[plantuml]
....
node Backend-portalBE {
component RESTServices
component ViewModel
}
RESTServices.>ViewModel
node Frontend-portalFE {
component services
node Components {
component pages
component commonComp
component dialogs
}
component model
}
services-(0-RESTServices
model<->ViewModel
services.>model
Components.>services
....
==== portal.war (Backend tier)
The backend tier contains five components which can be summarized in three layers:
. *Presentation layer* - Represented by
.. REST-Srv
.. View Model
. *Controller layer* - Represented by
.. Controller
. *Model layer* - Represented by
.. auth2 (Connection to "KeyCloak")
.Backend tier
[plantuml]
....
node PortalFrontend [
PortalFrontend
]
node ESB {
interface Auth_n_auth
}
node BackendLAN {
left to right direction
node KeyCloak {
component KeyCloakImplementation
}
node Backend-Portal {
skinparam rectangle {
roundCorner 25
}
rectangle "Presentation layer" {
component RESTServices
component ViewModel
}
rectangle "Controller layer" {
component Controller
}
rectangle "Model layer" {
component auth2
}
RESTServices.>Controller
RESTServices.>ViewModel
Controller.>auth2
}
RESTServices -- Auth_n_auth
interface OAuth2
interface KeyCloakAdmin
KeyCloak -- KeyCloakAdmin
KeyCloak -- OAuth2
auth2 -> OAuth2
auth2 -> KeyCloakAdmin
}
PortalFrontend-->Auth_n_auth
node openKModule [
openKModule
]
openKModule --> Auth_n_auth
....
KeyCloak provides different interfaces. The backend uses the *OAuth2*-Interface for authentication
and the *KeyCloak-admin* interface for other tasks (for example for getting users). The component *auth2* provides
functionality for the access to KeyCloak. The Presentation layer consists of the *RESTServices* and the
*ViewModel*. The *RESTServices* access the *Controller layer* in order to perform their tasks.
The whole backend provides the *Auth&Auth* interface which is used by the *portalFrontend* and
other *openKonsequenz-Modules* for authentication and other related tasks. The *Auth&Auth* interface is
to be exported via ESB.
== Runtime View
=== Login / Authentication
.Login sequence
[plantuml]
....
actor User
participant PortalFrontend
participant PortalBackend
participant KeyCloak
User->PortalFrontend: Login page
PortalFrontend->PortalBackend: /login(loginCredentials)
PortalBackend->KeyCloak: /.../realms/.../protocol/openid-connect/token(?loginInfo)
KeyCloak --> PortalBackend: return JWT
PortalBackend -> PortalBackend: Create Session with JWT
PortalBackend --> PortalFrontend: return JWT
PortalFrontend -> PortalFrontend: store JWT
PortalFrontend --> User: Navigate to ModuleGrid
....
=== Logout
.Logout sequence
[plantuml]
....
actor User
participant oK_Module
participant PortalBackend
User->oK_Module: logout
oK_Module->PortalBackend: /logout with JWT
PortalBackend->PortalBackend: Remove Session with JWT
PortalBackend-->oK_Module:
oK_Module->oK_Module: Navigate to Logout/closing page
oK_Module-->User
....
=== Check authorization
.CheckAuth sequence
[plantuml]
....
actor User
participant oK_Module
participant PortalBackend
User->oK_Module: Any action that requires an auth check
oK_Module->PortalBackend: /checkAuth with JWT
group authorize
PortalBackend->PortalBackend: Check if valid session with JWT exists
group check failed
PortalBackend-->oK_Module: raise HttpCode "Unauthorized 401"
end
group check succeeded
PortalBackend-->oK_Module: return HttpCode "Success 200"
end
end
oK_Module->oK_Module: react on HttpCode
oK_Module-->User:
....
=== Get users for role
.GetUsersForRole sequence
[plantuml]
....
actor User
participant oK_Module
participant KeyCloak
participant PortalBackend
actor Timer_cycl
group refresh usersWithRoles cache
Timer_cycl->PortalBackend: Get userWithRoles
PortalBackend->KeyCloak: Login with admin user
KeyCloak-->PortalBackend
PortalBackend->KeyCloak: Get realm users
KeyCloak-->PortalBackend
group repeat for each user
PortalBackend->KeyCloak:Get role-mapping for user
KeyCloak-->PortalBackend
end
PortalBackend->PortalBackend: update cache
PortalBackend-->Timer_cycl
end
...
User->oK_Module: Any action that needs all users having a role
oK_Module->PortalBackend: /usersForRole/{userRole}
PortalBackend->PortalBackend: evaluate from usersWithRoles cache
PortalBackend-->oK_Module: return result
oK_Module-->User
....
=== Open module in portal frontend
.Start module sequence
[plantuml]
....
actor User
participant PortalFE
participant openKModule
User->PortalFE: User (logged in) opens module
PortalFE->openKModule: Open configured URL in new browser tab, providing the JWT
....
== Deployment View
The Auth&Auth application consists of 3 parts regarding the deployment.
. Frontend: "portalFE"-Directory
. Backend: "portal.war"
. Keycloak: OAuth2 and JWT Service implementation
=== Deployment of the application components
==== Deployment of the frontend
The Frontend SPA is built as a folder, that contains all the required files for
the application. When deploying the frontend application, the content of the "dist"-folder
within the Frontend development-directory has to be copied into the
target-directory of the apache-tomcat:
<Apache-Tomcat>/webapps/portalFE
If the target folder does not exist, it has to be created manually.
==== Deployment of the backend
The backend REST-services are built in form of a "WAR"-file (to be found
in the "target"-directory of the MAVEN-directory structure).
For deployment, this file has to be copied to the directory
<Apache-Tomcat>/webapps
==== Deployment of Keycloak
. Get "Keycloak 3.2.1 Final" ("keycloak-3.2.1.Final.zip") from the Keycloak download page. +
Download "Server Standalone server distribution": http://www.keycloak.org/archive/downloads-3.2.1.html
. Extract the content.
. To create an initial admin account for Keycloak run the script `add-user-keycloak.sh` with username 'admin'
and a strong password.
<Keycloak-Directory>/bin/add-user-keycloak.sh -r master -u <username> -p <password>
. To start Keycloak create a *Linux-Service which executes* the `standalone.sh` script to be found in the Keycloak `bin`
directory.
<Keycloak-Directory>/bin/standalone.sh
TIP: Keycloaks default port is 8080 you can change it to for example to port 1234 with the following
execution parameter: -Djboss.http.port=1234
<Keycloak-Directory>/bin/standalone.sh -Djboss.http.port=1234
==== Configuration of the system
===== Configuration of the webserver
There exists the file *context.xml* in the "conf" subdirectory (*<TOMCAT>/conf*) of the target apache tomcat installation.
Add the following parameter and resource in order to access the correct backend configurations and to
gain access to the database (see "Configuration of the backend" below):
.context.xml
[source,xml]
----
[...]
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--Manager pathname=""/>
<Parameter name="environment" override="false" value="Development"/-->
<Parameter name="OK_PORTAL_ENVIRONMENT" override="false" value="Production"/>
<!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle) -->
[...]
----
===== Configuration of the backend
After the backend war file has been deployed and unpacked inside of the *<TOMCAT>/webapps* folder there are different
backend config files to be found in the folder *<TOMCAT>/webapps/elogbook/WEB-INF/classes*
* backendConfig*.json
* moduleConfig*.json
The active configuration is chosen by parameter *OK_PORTAL_ENVIRONMENT* (see context.xml above).
Possible values are:
* *Custom* (for backendConfigCustom.json and moduleConfigCustom.json)
* *DevLocal* (for backendConfigDevLocal.json and moduleConfigDevLocal.json)
* *DevServer* (for backendConfigDevServer.json and moduleConfigDevServer.json)
* *Production* (for backendConfigProduction.json and moduleConfigProduction.json)
After choosing an environment the corresponding json files have to be configured:
.backendConfigXXX.json
[source,json]
----
{
"internalSessionLengthMillis": 46800000,
"reloadUsersInSec": 300,
"authServerUrl": "http://localhost:8080/",
"keycloakRealm": "OpenKRealm",
"keycloakClient": "OpenKClient",
"keycloakAdmin": "admin",
"keycloakPW": "adminpwd",
"maxLoadUsers": 1000
}
----
* *internalSessionLengthMillis* - Maximum allowed duration of inactivity, before a session ends
* *reloadUsersInSec* - Polling interval for getting all users from keycloak
* *authServerUrl* - Base url of the keycloak instance
* *keycloakRealm* - Configured realm on keycloak
* *keycloakClient* - Configured client on keycloak
* *keycloakAdmin* - user for admin access on keycloak
* *keycloakPW* - password of the admin user
* *maxLoadUsers* - Sets the maximum of users that are loaded from keycloak. KC itself is limited here. The value
should be set to the amount of *all* users in the target "keycloakRealm".
.moduleConfigXXX.json
[source,json]
----
[
{
"name": "Betriebstagebuch",
"cols": 1,
"rows": 1,
"color": "#ffffff",
"link": "http://172.18.22.160:8880/elogbookFE",
"pictureLink": "https://www.openkonsequenz.de/.../m_logbuch_2443636.jpg",
"requiredRole": "elogbook-access"
},
{
"name": "Bereitschaftsplanung",
"cols": 1,
"rows": 1,
"color": "#ffffff",
"link": "https://www.openkonsequenz.de/..../94-bereitschaftsplan",
"pictureLink": "https://www.openkonsequenz.de/medien/.../l_bereitschaftsplan_57882047.jpg",
"requiredRole": "planning-access"
},
...
]
----
* *name* - Name/description of the module
* *cols* - always "1"
* *rows* - always "1"
* *color* - always "#ffffff"
* *link* - URL for the module
* *pictureLink* - URL for picture belonging to the module
* *requiredRole* - Name of the role (on keycloak) the user must have to access the module
===== Configuration of Keycloak
. Login in Keycloak
.. Go to http://<KEYCLOAK-SERVER-IP>:<CONFIGURED-KEYCLOAK-PORT>/ +
Hit the `Administration Console` -Link and login with admin account created during the Keycloak-deployment
(see above).
. Add a new realm: `MainDonauNetz`
.Add a new realm overview
[options="header,footer"]
image::newRealm1.png[new Realm]
.Add a new realm
[options="header,footer"]
image::newRealm2.png[new Realm]
[start=3]
. Create a client with client ID `elogbook-backend`.
.Create a client overview
[options="header,footer"]
image::createClient.png[create Client]
.Add a client
[options="header,footer"]
image::addClient.png[add Client]
[start=4]
. Set the client settings accordingly:
.Client settings of elogbook-backend
[options="header,footer"]
image::clientSettings.png[Client settings]
Go to tab `Mappers`. Press `Create`...
.Mappers of elogbook-backend
[option="header,footer"]
image::CreateMapper.png[Mapper settings]
and add the `role` mapping accordingly:
.Role mapper
[option="header,footer"]
image::CreateRoleMapper.png[Role mapper settings]
[start=5]
. Add the roles under `Roles` press `Add Role`. Add the following Roles:
- elogbook-normaluser
- elogbook-superuser
- elogbook-access
- planning-access
- feedin-management-access
- planned-policies-access
- planned-policies-normaluser
- planned-policies-superuser
. Configuring a superuser role. Under Roles, hit on a superuser(elogbook-superuser or planned-policies-superuser) or press `Edit`
.. Switch `Composite Roles` to on.
.. Add the Realm Role 'elogbook-normaluser' or 'planned-policies-normaluser' correspondingly from the `Available Roles`
.. Select from the `Client Roles` Dropdown-List 'realm-management' and add the role 'view-users'.
.Elogbook superuser composite role
[options="header,footer"]
image::rolesSuperUser.png[Elogbook superuser composite role]
[start=7]
. Adding users under `Users` press `Add User`.
.Add a user
[options="header,footer"]
image::addingUsers.png[Add a User]
.. Fill in username, First Name, Last Name, else is default and save it.
.. Go to the `Credentials` tab and type in a new password and the confirmation as well, disable `Temporary`. Press `Reset Password`.
Press `Change Password`.
.Credentials tab
[options="header,footer"]
image::credentials.png[Credentials tab]
[start=3]
.. Go to the `Role Mappings` tab. +
Here you grant rights/roles to the users:
Select the from the previously created roles in `Available Roles` and hit `Add selected`. +
... User right in the distinct modul elogbook (`elogbook-access` required of course):
- elogbook-normaluser = standard user in the elogbook-app
- elogbook-superuser = admin user in the elogbook-app
... User right in the distinct modul Planned Grid Measures (`planned-policies-access` required of course):
- planned-policies-normaluser = standard user in the plannedGridMeasures-app
- planned-policies-superuser = admin user in the plannedGridMeasures-app
... Access rights to the specific modul:
- elogbook-access
- planning-access
- feedin-management-access
- planned-policies-access
.Role Mappings tab
[options="header,footer"]
image::roleMappings.png[Role Mapping]
[start=4]
.. Go back to the `Details` tab and make sure `Recquired User Actions` is empty. Delete anything which is in there with a press on the little cross.
[start=8]
. Add an admin user. (Mandatory) +
Same procedure like adding a User (see 7.) but with the role 'elogbook-superuser' or 'planned-policies-superuser' instead of
'elogbook-normaluser' or 'planned-policies-normaluser' correspondingly.
IMPORTANT: We use this admin account (username & password) also to configure the backend. +
See "Configuration of the backend",
username & password from here is keycloakAdmin & keycloakPW there.
=== CI- and CD-Components
==== GIT-Repository
<TODO>
==== Hudson
<TODO>
==== Sonar
<TODO>
==== Code-Coverage of the Frontend - Karma-Istanbul-Output
<TODO>
=== Continuous Deployment
== Design Decisions
All architecture decisions based on the Architecture Committee Handbook. There are no deviations.
== Quality Requirements
TODO: Muss noch beschrieben werden
=== Quality Tree
TODO: Muss noch beschrieben werden
=== Quality Scenarios
TODO: Muss noch beschrieben werden
== Risks and Technical Debts
(Muss noch beschrieben werden)
<<<
== Glossary
=== Technical Constraints
.Technical Contraints
[options="header,footer"]
|========================================================
|Short|Long|German|Description
|AC|Architecture Committee|Architektur-Komittee|Gives Framework and Constraints according to architecture for oK projects.
|CNCU|Central Network Control Unit||
|DAO|Data Access Objects||
|DSO|Distribution System Operator|Verteilnetz-betreiber (VNB)|Manages the distribution network for energy, gas or water.
|EPL|Eclipse Public License||Underlying license model for Eclipse projects like elogbook@openK
|ESB|Enterprise Service Bus||Central instance for exchange of data to overcome point-to-point connections.
|oK|openKONSEQUENZ|openKONSEQUENZ|Name of the consortium of DSOs
|QC|Quality Committee|Qualitätskomitee|Gives framework and constraints according to quality for oK projects.
|SCADA|Supervisory Control and Data Acquisition|Netzleitsystem|System, that allows DSOs view/control actual parameters of their power grid.
|========================================================