docs update

This commit is contained in:
Diamantis Tziotzios 2024-09-19 17:12:18 +03:00
parent aeaad58824
commit 962ee812bd
16 changed files with 1591 additions and 382 deletions

View File

@ -4,3 +4,138 @@ description: A brief introduction to the core entities of the platform
---
# Introduction
## 🧩 **Core Concepts**
OpenCDMP is built around four main entities that work together to provide a structured and flexible approach to managing OMPs:
### **1. Blueprints**
Blueprints define the overall structure of a **Plan** by specifying its **Sections** and the content within each section.
- **Sections**: Each Blueprint is divided into multiple Sections, which can include various input fields and optional **Descriptions**.
- **Customization**: Tailor Blueprints to standardize the format and requirements of OMPs according to industry standards or specific project needs.
### **2. Plans**
A Plan is the primary entity and main output of the OpenCDMP platform, representing a comprehensive OMP.
- **Multiple Descriptions**: Contains multiple **Descriptions** of various inputs or outputs.
- **Structured by Blueprints**: Inherits the structure and content defined by the selected Blueprint, ensuring consistency and completeness.
- **Collaboration Features**: Invite users to a Plan with different roles and access rights—Viewer, Contributor, Reviewer, etc.
- **Access Levels**: Grant access to the entire Plan or specific Sections for fine-grained control.
- **Export and Deposit Options**:
- **Export**: Export the Plan in various formats (XML, JSON, DOCX, PDF) for both human and machine readability.
- **Custom Exports**: Use the pluggable export mechanism to implement your own export plugins.
- **Deposit**: Deposit OMPs directly to repositories for DOI assignment.
- **Custom Deposits**: Use the pluggable deposit mechanism to implement your own deposit plugins for different repositories.
### **3. Description Templates**
Description Templates define the structure of a **Description** within a Plan, supporting a variety of input types to capture detailed information.
- **Supported Input Types**:
- **Select**: Dropdown menus for predefined options.
- **Boolean Decision**: Yes/No choices.
- **RadioBox and CheckBox**: Multiple-choice selections.
- **Text**: Open-ended text fields.
- **File Upload**: Attach documents or files.
- **Date**: Calendar selection for dates.
- **External References**: Integration with external data sources via APIs.
- **Customization**: Configure Description Templates to meet specific data collection needs.
### **4. Descriptions**
Descriptions are detailed entries within a Plan that provide information about specific inputs or outputs.
- **Integration with Sections**: Included in various Sections of a Plan as defined by the Blueprint.
- **Detailed Information**: Offer a granular level of detail for comprehensive documentation.
<!-- ### **5. Collaboration and Review**
Enhance teamwork and ensure quality through robust collaboration and review features.
- **User Roles and Access Rights**:
- **Viewer**: Can view the Plan or specified Sections.
- **Contributor**: Can edit the Plan or specified Sections.
- **Reviewer**: Can review and add annotations to the Plan or specified Sections.
- **Section-Level Access**: Grant permissions at both the Plan and Section levels for precise control over user access.
- **Annotations (Comments)**:
- **Adding Annotations**: Reviewers can add comments to Plans or specific Sections to provide feedback or request changes.
- **Annotation Statuses**: Each annotation has statuses (e.g., Open, In Progress, Resolved, Closed) to track its lifecycle and ensure issues are addressed.
### **6. Notification Features**
Stay informed about updates and changes with flexible notification options.
- **Email Notifications**: Receive email alerts for important events, such as new annotations, status changes, or when you're invited to a Plan.
- **In-App Notifications**: Get real-time notifications within the platform for immediate awareness of updates and activities.
- **Customizable Settings**: Configure notification preferences to receive alerts that are most relevant to you.
### **7. Flexible Export and Deposit Options**
Easily share and integrate your Plans with others through various export formats and repository deposits.
- **Export Options**:
- **Human-Readable Formats**: Export Plans as **DOCX** or **PDF** documents for easy sharing and presentation.
- **Machine-Readable Formats**: Export Plans as **XML** or **JSON** files for integration with other systems or data processing.
- **Pluggable Export Mechanism**:
- **Custom Export Plugins**: Develop and integrate your own export plugins to support additional formats or specialized export needs.
- **Extensibility**: The pluggable mechanism allows for seamless extension of export capabilities without modifying the core system.
- **Repository Deposits**:
- **DOI Assignment**: Deposit OMPs directly to repositories to obtain a **Digital Object Identifier (DOI)**.
- **Pluggable Deposit Mechanism**:
- **Custom Deposit Plugins**: Implement your own deposit plugins to integrate with different repositories.
- **Flexibility**: Supports multiple repositories, allowing you to choose where your OMPs are deposited.
### **8. Validation via Plugins**
Ensure your Plans meet specific standards and requirements through customizable validation.
- **Pluggable Validation Mechanism**:
- **Custom Validation Plugins**: Develop and integrate your own validation plugins to check Plans against particular criteria.
- **Flexibility**: Allows validation processes to be tailored to different industry standards, regulations, or organizational policies.
- **Manual Validation**: Perform validation checks as needed using the integrated tools provided by your custom plugins. -->
<!-- ## 🛠️ **Getting Started**
1. **Create a Blueprint**: Define the overall structure of your Plan by creating a Blueprint with the necessary Sections.
2. **Develop Description Templates**: Configure Description Templates with appropriate input types for the data you need to collect.
3. **Assemble the Plan**: Use the Blueprint to create a new Plan, inheriting the defined Sections and structure.
4. **Add Descriptions**: Within each Section of the Plan, add Descriptions by selecting from the available Description Templates and populating the input fields.
5. **Invite Collaborators**: Invite users to your Plan with specific roles (Viewer, Contributor, Reviewer) and assign access rights to the entire Plan or specific Sections.
6. **Set Up Notifications**: Configure your notification preferences for Email and In-App alerts to stay informed about updates and changes.
7. **Utilize External References**: Configure APIs as External References to include data from external sources, ensuring your Plan has the most up-to-date information.
8. **Review and Annotate**: Reviewers can add annotations to the Plan or specific Descriptions. Track annotation statuses to manage feedback effectively.
9. **Validate Your Plan**:
- **Custom Validation**: Use validation plugins to check your Plan against specific standards or requirements.
- **Manual Checks**: Perform validation manually through the tools provided by your custom plugins.
10. **Export or Deposit Your Plan**:
- **Export**: Choose from various export formats (XML, JSON, DOCX, PDF) to share or integrate your Plan as needed.
- **Custom Exports**: Implement custom export plugins if you have specific export requirements.
- **Deposit**: Deposit your Plan to repositories for DOI assignment.
- **Custom Deposits**: Implement custom deposit plugins to integrate with your preferred repositories.
## 🤝 **Contributing**
We welcome contributions from the community! Please check out our [contributing guidelines](CONTRIBUTING.md) to get started.
## 📄 **License**
OpenCDMP is released under the [MIT License](LICENSE).
---
Start simplifying your Output Management Plans with OpenCDMP today!
# OpenCDMP
**OpenCDMP** (Open Collaborative Data Management Platform) is an open-source, extensible software platform designed to simplify the management, monitoring, and maintenance of **Output Management Plans (OMPs)**, including **Data Management Plans (DMPs)** and **Software Management Plans (SMPs)**. It streamlines complex processes, ensuring efficiency, compliance, and collaboration across projects and organizations. -->

View File

@ -1,8 +0,0 @@
{
"label": "Authentication",
"position": 1,
"link": {
"type": "doc",
"id": "index"
}
}

View File

@ -1,5 +0,0 @@
# Authentication
import DocCardList from '@theme/DocCardList';
<DocCardList />

View File

@ -1,6 +0,0 @@
---
sidebar_position: 1
description: A guide on how Keycloak is configured as an auth provider for the platform
---
# Keycloak

View File

@ -0,0 +1,185 @@
---
sidebar_position: 1
description: A guide for integration with the platform
---
# Integration
# Integrating with OpenCDMP
This documentation provides developers with guidelines on how to use the OAuth2 protocol offered by **Keycloak** to authenticate and integrate with the **OpenCDMP** platform. By following this guide, you will be able to securely access OpenCDMP's APIs and integrate your applications or services.
---
## Prerequisites
- **Access to OpenCDMP**: You should have access to an instance of the OpenCDMP platform.
- **Client Application**: An application or service that needs to integrate with OpenCDMP APIs.
- **Access to OpenCDMP Administrators**: You'll need to request client credentials from the OpenCDMP/Keycloak Admins.
---
## Steps to Integrate
### 1. Request OAuth2 Client Credentials
Contact the OpenCDMP/Keycloak administrators and request the following:
- **Client ID**: A unique identifier for your application.
- **Client Secret**: A secret key associated with your Client ID.
Provide the following information to the administrators:
- **Application Name**: The name of your application or service.
- **Required Scopes**: The application scopes that you want to request access for.
- **Redirect URIs** (if applicable): The URLs to which Keycloak will redirect after authentication (required for web applications using the Authorization Code flow).
### 2. Choose the Appropriate OAuth2 Flow
Depending on your application's type, select one of the OAuth2 flows:
- **Authorization Code Flow**: For web applications where users authenticate via a browser.
- **Client Credentials Flow**: For server-to-server communication without user interaction.
### 3. Configure Your Application
Use the obtained Client ID and Client Secret to configure your application:
- **OAuth2 Endpoints**:
- **Authorization Endpoint**: `https://(KEYCLOAK_URL)/auth/realms/(REALM_NAME)/protocol/openid-connect/auth`
- **Token Endpoint**: `https://(KEYCLOAK_URL)/auth/realms/(REALM_NAME)/protocol/openid-connect/token`
- **User Info Endpoint**: `https://(KEYCLOAK_URL)/auth/realms/(REALM_NAME)/protocol/openid-connect/userinfo`
Replace `(KEYCLOAK_URL)` with the Keycloak server URL and `(REALM_NAME)` with the realm name used by OpenCDMP.
- **Scopes**: Ensure that the necessary scopes are included in your requests, such as `openid`, `profile`, `email`, or any custom scopes provided by the administrators.
### 4. Implement the OAuth2 Flow
#### Authorization Code Flow (For Web Applications)
1. **Redirect User to Authorization Endpoint**:
- Construct a URL to the Authorization Endpoint with the following query parameters:
- `client_id`: Your Client ID.
- `redirect_uri`: Your application's redirect URI.
- `response_type`: `code`
- `scope`: Requested scopes (e.g., `openid profile email`).
2. **Handle Authorization Response**:
- After the user authenticates, Keycloak will redirect to your `redirect_uri` with a `code` parameter.
3. **Exchange Authorization Code for Access Token**:
- Make a POST request to the Token Endpoint with:
- `grant_type`: `authorization_code`
- `code`: The authorization code received.
- `redirect_uri`: Same as above.
- `client_id` and `client_secret`: Your credentials.
4. **Store and Use the Access Token**:
- Receive the access token and optional refresh token.
- Use the access token to access OpenCDMP APIs.
#### Client Credentials Flow (For Server-to-Server Communication)
1. **Request Access Token**:
- Make a POST request to the Token Endpoint with:
- `grant_type`: `client_credentials`
- `client_id` and `client_secret`: Your credentials.
2. **Use the Access Token**:
- Receive the access token.
- Use the token to authenticate API requests to OpenCDMP.
### 5. Access OpenCDMP APIs
With the access token, include it in the `Authorization` header of your HTTP requests:
```http
Authorization: Bearer {access_token}
```
Replace `access_token` with the token obtained from Keycloak.
### 6. Refresh Tokens (If Applicable)
If your application receives a refresh token, you can use it to obtain new access tokens without re-authenticating:
- Make a POST request to the Token Endpoint with:
- `grant_type`: `refresh_token`
- `refresh_token`: The refresh token received.
- `client_id` and `client_secret`: Your credentials.
## Additional Considerations
- **Token Validation**: It's recommended to validate tokens before use, either by decoding the JWT or using Keycloak's introspection endpoint.
- **SSL/TLS**: Ensure all communication with Keycloak and OpenCDMP APIs is over HTTPS to protect credentials and tokens.
- **Error Handling**: Implement proper error handling for authentication failures and token expiration.
- **Scope Management**: Request only the scopes necessary for your application to follow the principle of least privilege.
- **Logout**: If your application requires user logout functionality, redirect users to the Keycloak logout endpoint.
- **Refresh Tokens**: Be cautious with refresh tokens and store them securely to prevent unauthorized access.
---
## Sample Code Snippets
### Requesting an Access Token (Client Credentials Flow)
```bash
curl -X POST \
'https://(KEYCLOAK_URL)/auth/realms/(REALM_NAME)/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET'
```
### Accessing an OpenCDMP API Endpoint
```bash
curl -H "Authorization: Bearer {access_token}" \
'https://(OPENCMP_API_URL)/api/endpoint'
```
---
## Contacting OpenCDMP/Keycloak Administrators
When reaching out to OpenCDMP/Keycloak administrators, provide the following information:
- **Your Name and Contact Information**
- **Purpose of Integration**: Brief description of your application's use case.
- **Required Access**: Specify the OpenCDMP resources your application needs to access.
- **Redirect URIs**: For web applications using the Authorization Code flow.
- **Desired Scopes**: Any specific scopes your application requires.
---
## Useful Links
- **Keycloak Documentation**: [https://www.keycloak.org/documentation](https://www.keycloak.org/documentation)
- **OAuth2 Specification**: [https://oauth.net/2/](https://oauth.net/2/)
- **OpenID Connect Specification**: [https://openid.net/connect/](https://openid.net/connect/)
- **OpenCDMP API Reference**: [https://opencdmp.org/api-docs](https://opencdmp.org/api-docs)
---
## Support
If you have any questions or need assistance with integration:
- **Email**: support@opencdmp.org
<!-- - **Community Forum**: [OpenCDMP Discussion Forum](https://forum.opencdmp.org) -->
- **GitHub Issues**: [https://github.com/YourUsername/OpenCDMP/issues](https://github.com/YourUsername/OpenCDMP/issues)
---
**Note**: This guide assumes you have basic knowledge of OAuth2 and HTTP requests. Always ensure you follow best security practices when handling client credentials and access tokens.

View File

@ -7,22 +7,12 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Admonition from '@theme/Admonition';
# Swagger
# Swagger UI
The swagger UI is available at the `/swagger-ui/index.html` url. It contains documentation for the following API endpoints.
The Swagger UI is available at the `/swagger-ui/index.html` url. It contains documentation for the following API endpoints.
<Tabs>
<TabItem value="legacy" label="Legacy">
- **/api/public/dmps/\*\***
- **/api/public/descriptions/\*\***
<Admonition type="info">
<p>These endpoints do not require authentication.</p>
</Admonition>
</TabItem>
<TabItem value="current" label="Current">
<TabItem value="current" label="Current">
- **/api/dmp/\*\***
- **/api/description/\*\***
@ -44,4 +34,14 @@ The swagger UI is available at the `/swagger-ui/index.html` url. It contains doc
</Admonition>
</TabItem>
<TabItem value="legacy" label="Legacy">
- **/api/public/dmps/\*\***
- **/api/public/descriptions/\*\***
<Admonition type="info">
<p>These endpoints do not require authentication.</p>
</Admonition>
</TabItem>
</Tabs>

View File

@ -0,0 +1,218 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0" version="24.7.14">
<diagram id="jrXY4hO8n29qiqvIHeQG" name="Page-1">
<mxGraphModel dx="2586" dy="2383" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="znfC-1mL89MJGpif9Dxd-3" value="Internal Network" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#147EBA;fillColor=#E6F2F8;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=0;" vertex="1" parent="1">
<mxGeometry x="-1030" y="-860" width="940" height="620" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-98" value="RabbitMQ" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=bottom;fontStyle=0;fontColor=#5A6C86;align=left;" vertex="1" parent="1">
<mxGeometry x="-1005" y="-820" width="890" height="360" as="geometry" />
</mxCell>
<mxCell id="5G6M97Ru5O6IGqaMy1Rf-37" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" parent="1" vertex="1">
<mxGeometry x="-1007.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-2" value="Reverse Proxy" style="points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#248814;fillColor=#E9F3E6;verticalAlign=top;align=left;spacingLeft=30;fontColor=#248814;dashed=0;" vertex="1" parent="1">
<mxGeometry x="-1030" y="-1020" width="940" height="60" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-6" value="Data Persistency " style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-670" y="-440" width="230" height="140" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-4" value="PostgreSQL" style="outlineConnect=0;gradientColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.database;fillColor=none;strokeColor=#3334B9;fontColor=#3334B9;" vertex="1" parent="1">
<mxGeometry x="-630" y="-400" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-5" value="Elastics&lt;span style=&quot;background-color: initial;&quot;&gt;earch&lt;/span&gt;" style="outlineConnect=0;gradientColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.database;fillColor=none;strokeColor=#3334B9;fontColor=#3334B9;" vertex="1" parent="1">
<mxGeometry x="-527.76" y="-400" width="60" height="60" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-102" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-9" target="znfC-1mL89MJGpif9Dxd-30">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-103" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-9" target="znfC-1mL89MJGpif9Dxd-46">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-105" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-9" target="znfC-1mL89MJGpif9Dxd-6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="-950" y="-670" />
<mxPoint x="-950" y="-370" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-9" value="Main APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-985" y="-790" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-8" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-930" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-14" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-910" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-15" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-890" y="-753.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-16" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-830" y="-710" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-20" target="znfC-1mL89MJGpif9Dxd-6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="-450" y="-630" />
<mxPoint x="-270" y="-630" />
<mxPoint x="-270" y="-370" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-20" value="Notification APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-550" y="-790" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-21" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-495" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-22" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-475" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-23" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-455" y="-753.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-24" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-395" y="-710" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-104" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-25" target="znfC-1mL89MJGpif9Dxd-6">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="-665" y="-640" />
<mxPoint x="-555" y="-640" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-25" value="Annotation APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-765" y="-790" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-26" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-710" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-27" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-690" y="-754.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-28" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-670" y="-753.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-29" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-610" y="-710" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-30" value="Deposit plugin APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-985" y="-620" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-31" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-930" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-32" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-910" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-33" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-890" y="-583.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-34" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-830" y="-540" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-101" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-46" target="znfC-1mL89MJGpif9Dxd-51">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-46" value="File transformer APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-765" y="-620" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-47" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-710" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-48" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-690" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-49" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-670" y="-583.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-50" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-610" y="-540" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-51" value="PDF Service APIs" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-535" y="-620" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-52" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-480" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-53" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-460" y="-584.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-54" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-440" y="-583.5" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-55" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-380" y="-540" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-95" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-56" target="znfC-1mL89MJGpif9Dxd-94">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-96" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-56" target="znfC-1mL89MJGpif9Dxd-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-56" value="" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-1052.5" y="-1220" width="725" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-60" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-117.5" y="-1140" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-62" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=https://www.xpand-it.com/wp-content/uploads/2020/06/Keycloak-logo.png;" vertex="1" parent="1">
<mxGeometry x="-248.14" y="-1183.25" width="161.27" height="46.5" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-9" target="znfC-1mL89MJGpif9Dxd-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-71" value="Web Application" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-335" y="-790.5" width="200" height="120" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-72" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-280" y="-755" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-73" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-260" y="-755" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-74" value="" style="aspect=fixed;sketch=0;html=1;dashed=0;whitespace=wrap;verticalLabelPosition=bottom;verticalAlign=top;fillColor=#2875E2;strokeColor=#ffffff;points=[[0.005,0.63,0],[0.1,0.2,0],[0.9,0.2,0],[0.5,0,0],[0.995,0.63,0],[0.72,0.99,0],[0.5,1,0],[0.28,0.99,0]];shape=mxgraph.kubernetes.icon2;prIcon=api" vertex="1" parent="1">
<mxGeometry x="-240" y="-754" width="50" height="48" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-75" value="" style="image;sketch=0;aspect=fixed;html=1;points=[];align=center;fontSize=12;image=img/lib/mscae/Docker.svg;" vertex="1" parent="1">
<mxGeometry x="-180" y="-710.5" width="37.8" height="31" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-78" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-2" target="znfC-1mL89MJGpif9Dxd-25">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-79" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-2" target="znfC-1mL89MJGpif9Dxd-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-80" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-2" target="znfC-1mL89MJGpif9Dxd-71">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;curved=1;" edge="1" parent="1" source="znfC-1mL89MJGpif9Dxd-2" target="znfC-1mL89MJGpif9Dxd-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-84" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" vertex="1" parent="1">
<mxGeometry x="-767.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-85" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" vertex="1" parent="1">
<mxGeometry x="-877.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-90" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" vertex="1" parent="1">
<mxGeometry x="-647.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-91" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" vertex="1" parent="1">
<mxGeometry x="-407.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-92" value="Users" style="outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3E;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.users;" vertex="1" parent="1">
<mxGeometry x="-517.5" y="-1180" width="40" height="40" as="geometry" />
</mxCell>
<mxCell id="znfC-1mL89MJGpif9Dxd-94" value="" style="fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;" vertex="1" parent="1">
<mxGeometry x="-267.5" y="-1220" width="200" height="120" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@ -1,8 +1,149 @@
---
sidebar_position: 3
sidebar_position: 2
description: A guide for the platform architecture
---
# Architecture
# System Architecture
OpenCDMP is designed using a **microservices architecture**, leveraging Docker containers for deployment and scalability. This approach allows each component of the system to be developed, deployed, and scaled independently, ensuring flexibility and robustness in managing Output Management Plans (OMPs).
## Overview
The architecture comprises multiple services, each responsible for specific functionalities within the OpenCDMP platform. These services communicate with each other through well-defined APIs and messaging queues, ensuring seamless integration and data flow.
Below is a list of the services included in the architecture:
- **Nginx Reverse Proxy**: Acts as the entry point and reverse proxy. It is the only service that needs external connectivity.
- **API Service**: Main APIs handling the core business logic.
- **Webapp Service**: Frontend of the application, providing the user interface.
- **Notification Service**: Handles notifications (Email and In-App). *Closed source project, but with a free-to-use license.*
- **Annotation Service**: Manages annotations (comments) and reviews. *Closed source project, but with a free-to-use license.*
- **Repository Deposit Services**: Multiple services acting as deposit plugins to repositories for DOI assignment.
- **File Transformation Services**: Multiple services acting as export/import plugins for file transformations.
- **Keycloak**: Authentication server for managing users and roles.
- **PostgreSQL**: Main database storage for persisting data.
- **RabbitMQ**: Message broker for microservices intercommunication.
- **Elasticsearch**: Used for indexing and searching data.
- **PDF Generator Service**: Generates PDF documents from Plans.
The following diagram provides a high-level overview of the architecture:
![Export plans](architecture.png)
### **Services Breakdown**
#### **Nginx Reverse Proxy**
- **Purpose**: Acts as the gateway to the application, routing incoming HTTP/HTTPS requests to the appropriate internal services.
- **Features**:
- SSL termination
- Load balancing
- Reverse proxying to backend services
- **Notes**:
- It is the only service exposed to the external network.
- Enhances security by hiding internal services from direct external access.
#### **API Service**
- **Purpose**: Serves as the main backend, handling core business logic and API endpoints.
- **Features**:
- Processes requests from the Webapp Service.
- Interacts with PostgreSQL for data persistence.
- Interacts with Elastisearch for indexing.
- Evaluating authentication against Keyclaok.
- Communicates with other microservices via RabbitMQ.
- Implements RESTful APIs for frontend consumption.
#### **Webapp Service**
- **Purpose**: Provides the frontend user interface for OpenCDMP.
- **Features**:
- Built using modern web technologies.
- Communicates with the API Service.
- Offers a user-friendly interface for managing Plans, Blueprints, Templates, etc.
#### **Notification Service**
- **Purpose**: Manages email and in-app notifications.
- **Features**:
- Sends notifications based on events (e.g., Annotations added, Plan updates, Invitations).
- *Closed source*, but available under a free-to-use license.
- **Notes**:
- Communicates with other services via RabbitMQ.
- Configurable notification preferences.
- Configurable notification templates.
#### **Annotation Service**
- **Purpose**: Handles annotations (comments) and the review process.
- **Features**:
- Allows reviewers to add annotations to Plans or specific Sections.
- Tracks annotation statuses for lifecycle management.
- *Closed source*, but available under a free-to-use license.
- **Notes**:
- Enhances collaboration and quality control.
#### **Repository Deposit Services**
- **Purpose**: Deposits OMPs to external repositories for DOI assignment.
- **Features**:
- Multiple services acting as plugins for different repositories.
- Pluggable mechanism to implement custom deposit plugins.
- **Examples**:
- Integration with repositories like Zenodo, Dataverse, etc.
#### **File Transformation Services**
- **Purpose**: Manages export/import functionalities.
- **Features**:
- Supports exporting Plans and Descriptions in formats like XML, JSON, DOCX, and PDF.
- Multiple services acting as plugins for different file transformations.
- Pluggable mechanism to implement custom export/import plugins.
#### **Keycloak**
- **Purpose**: Provides authentication and authorization.
- **Features**:
- Manages user identities, roles, and permissions.
- Supports protocols like OpenID Connect, OAuth 2.0, and SAML 2.0.
- **Notes**:
- Centralized security management.
- Integrates with the Webapp and API Services for secure access control.
#### **PostgreSQL**
- **Purpose**: Main relational database for storing application data.
- **Features**:
- Stores data for Plans, Users, Templates, Annotations, etc.
- Provides data integrity and transactional support.
- **Notes**:
- Ensures reliable data persistence.
- Scalable and supports complex queries.
#### **RabbitMQ**
- **Purpose**: Message broker facilitating communication between microservices.
- **Features**:
- Supports asynchronous messaging.
- Enhances scalability and decouples services.
- **Notes**:
- Critical for inter-service communication.
- Improves system resilience.
#### **Elasticsearch**
- **Purpose**: Provides powerful search and indexing capabilities.
- **Features**:
- Enables full-text search over various data fields.
- Real-time data indexing.
- **Notes**:
- Enhances user experience with quick and efficient search functionality.
#### **PDF Generator Service**
- **Purpose**: Generates PDF documents from Plans.
- **Features**:
- Converts Plans into professional PDF formats.
- Supports custom templates and styling.
- **Notes**:
- Facilitates easy sharing and presentation of Plans.

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View File

@ -1,6 +1,6 @@
{
"label": "APIs",
"position": 2,
"label": "Configuration",
"position": 4,
"link": {
"type": "doc",
"id": "index"

View File

@ -0,0 +1,31 @@
---
sidebar_position: 3
description: A guide for the platform installation process
---
# Application
# Configuring the `.env` File
The `.env` file is a crucial component for deploying **OpenCDMP** using Docker Compose. It contains environment variables that specify:
- Versions of the container images.
- Docker registry to be used.
- Exposed ports for the proxy, API, and PostgreSQL services.
This file is located in the same directory as the `docker-compose.yml` files.
# Configuring the `.env` File
The `.env` file is a crucial component for deploying **OpenCDMP** using Docker Compose. It contains environment variables that specify:
- Versions of the container images.
- Docker registry to be used.
- Exposed ports for the proxy, API, and PostgreSQL services.
This file is located in the same directory as the `docker-compose.yml` files.
---
Configuring the `.env` file correctly is essential for the successful deployment of OpenCDMP. Adjust the variables according to your deployment environment and ensure consistency across all services.

View File

@ -0,0 +1,31 @@
---
sidebar_position: 2
description: A guide for the platform installation process
---
# Docker
# Configuring the `.env` File
The `.env` file is a crucial component for deploying **OpenCDMP** using Docker Compose. It contains environment variables that specify:
- Versions of the container images.
- Docker registry to be used.
- Exposed ports for the proxy, API, and PostgreSQL services.
This file is located in the same directory as the `docker-compose.yml` files.
# Configuring the `.env` File
The `.env` file is a crucial component for deploying **OpenCDMP** using Docker Compose. It contains environment variables that specify:
- Versions of the container images.
- Docker registry to be used.
- Exposed ports for the proxy, API, and PostgreSQL services.
This file is located in the same directory as the `docker-compose.yml` files.
---
Configuring the `.env` file correctly is essential for the successful deployment of OpenCDMP. Adjust the variables according to your deployment environment and ensure consistency across all services.

View File

@ -1,4 +1,4 @@
# APIs
# Plans
import DocCardList from '@theme/DocCardList';

View File

@ -0,0 +1,558 @@
---
sidebar_position: 1
description: A guide for the platform installation process
---
# Keycloak
### **Setting Up Keycloak**
This guide provides step-by-step instructions to set up Keycloak for **OpenCDMP**. Keycloak is used for authentication and authorization within the OpenCDMP platform.
#### **Prerequisites**
- Keycloak installed and running.
- Administrative access to Keycloak Admin Console.
---
## Step 1: Create a New Realm
1. **Log In** to the Keycloak Admin Console at `http://localhost:8080/auth` (replace `localhost` with your Keycloak server's address).
2. Click on the **Master** realm dropdown on the left sidebar.
3. Click on **Add Realm**.
4. **Name** the new realm (e.g., `OpenCDMP`) and click **Create**.
---
## Step 2: Create OpenID Connect Clients
Create the following five OpenID Connect clients:
- `api`
- `annotation`
- `notification`
- `plugins`
- `webapp`
### General Client Settings
For **all clients except `webapp`**, set the following options:
- **Client Authentication**: **On**
- **Direct Access Grants Enabled**: **On**
- **Service Accounts Enabled**: **On**
- **Standard Flow Enabled**: **Off**
For the **`webapp` client**, set:
- **Client Authentication**: **Off**
- **Direct Access Grants Enabled**: **Off**
- **Service Accounts Enabled**: **Off**
- **Standard Flow Enabled**: **On**
### Client: `api`
1. Navigate to **Clients** in the left menu and click **Create**.
2. **Client ID**: `api`
3. **Client Protocol**: **openid-connect**
4. **Root URL**: *(leave blank)*
5. Click **Save**.
6. In the **Settings** tab, ensure the general client settings are applied as specified.
7. Click **Save**.
8. Go to the **Roles** tab and create the following roles:
- **Admin**
- **User**
- **InstallationAdmin**
### Client: `annotation`
1. Create a new client with **Client ID**: `annotation`.
2. Apply the general client settings.
3. In the **Roles** tab, create:
- **Admin**
- **User**
### Client: `notification`
1. Create a new client with **Client ID**: `notification`.
2. Apply the general client settings.
3. In the **Roles** tab, create:
- **Admin**
- **User**
### Client: `plugins`
1. Create a new client with **Client ID**: `plugins`.
2. Apply the general client settings.
3. In the **Roles** tab, create:
- **app-service**
### Client: `webapp`
1. Create a new client with **Client ID**: `webapp`.
2. **Client Protocol**: **openid-connect**
3. **Root URL**: `https://(APP_URL)/home`
4. Click **Save**.
5. In the **Settings** tab, set:
- **Client Authentication**: **Off**
- **Direct Access Grants Enabled**: **Off**
- **Service Accounts Enabled**: **Off**
- **Standard Flow Enabled**: **On**
- **Home URL**: `https://(APP_URL)/home`
- **Valid Redirect URIs**: `https://(APP_URL)/*`
- **Web Origins**: `https://(APP_URL)`
6. Click **Save**.
---
## Step 3: Create Realm Roles
1. In the left menu, click on **Roles**.
2. Click **Add Role**.
3. Create the following roles:
- **Role Name**: `Admin`
- Click **Save**.
- **Role Name**: `User`
- Click **Save**.
---
## Step 4: Create Client Scopes
Create the following six client scopes:
- `api`
- `annotation`
- `notification`
- `plugins`
- `identity_provider`
- `tenant_role`
For each client scope:
1. Go to **Client Scopes** in the left menu.
2. Click **Create**.
3. **Name**: *(one of the client scope names above)*
4. **Description**: *(optional)*
5. **Type**: **None**
6. **Protocol**: **openid-connect**
7. Click **Save**.
8. For `identity_provider` and `tenant_role` client scopes:
- **Include in Token Scope**: **On**
---
## Step 5: Configure Mappers for Client Scopes
### Audience Mappers for `api`, `annotation`, `notification`, `plugins`
For each of the client scopes `api`, `annotation`, `notification`, and `plugins`:
1. Go to **Client Scopes** and select the client scope.
2. Navigate to the **Mappers** tab.
3. Click **Create**.
4. **Name**: `Audience`
5. **Mapper Type**: **Audience**
6. **Included Client Audience**: *(select the client scope name, e.g., `api`)*
7. Click **Save**.
### Assign Roles to Client Scopes
For the `api`, `annotation`, and `notification` client scopes:
1. Go to the **Scope** tab of each client scope.
2. In **Available Roles**, select the **Realm Roles**:
- **Admin**
- **User**
3. Click **Add Selected** to move them to **Assigned Roles**.
### User Session Note Mapper for `identity_provider`
1. Go to **Client Scopes** and select `identity_provider`.
2. Navigate to the **Mappers** tab.
3. Click **Create**.
4. **Name**: `identity_provider`
5. **Mapper Type**: **User Session Note**
6. **User Session Note**: `identity_provider`
7. **Token Claim Name**: `identity_provider`
8. **Add to Access Token**: **On**
9. Click **Save**.
### User Attribute Mapper for `tenant_role`
1. Go to **Client Scopes** and select `tenant_role`.
2. Navigate to the **Mappers** tab.
3. Click **Create**.
4. **Name**: `tenant_role`
5. **Mapper Type**: **User Attribute**
6. **User Attribute**: `tenant_role`
7. **Token Claim Name**: `tenant_role`
8. **Add to Access Token**: **On**
9. **Multivalued**: **On**
10. **Aggregate Attribute Values**: **On**
11. Click **Save**.
---
## Step 6: Assign Client Scopes to Clients
### Client: `api`
1. Go to **Clients** and select `api`.
2. Navigate to the **Client Scopes** tab.
3. In **Optional Client Scopes**, add:
- `plugins`
### Client: `webapp`
1. Go to **Clients** and select `webapp`.
2. Navigate to the **Client Scopes** tab.
3. In **Default Client Scopes**, add:
- `identity_provider`
- `tenant_role`
4. In **Optional Client Scopes**, add:
- `api`
- `annotation`
- `notification`
---
## Step 7: Set Up Groups
Groups represent roles within the application. Assigning users to groups grants them specific access rights.
### Create Root Group: `opencdmp`
1. Navigate to **Groups** in the left menu.
2. Click **New**.
3. **Name**: `opencdmp`
4. Click **Save**.
### Create Subgroups
Under the `opencdmp` group, create the following subgroups:
- `role-admin`
- `role-installation-admin`
- `role-user`
- `tenant-config-manager`
- `tenant-plan-manager`
- `tenant-role-admin`
- `tenant-role-user`
#### Steps to Create a Subgroup
1. Select the `opencdmp` group.
2. Go to the **Sub Groups** tab.
3. Click **New**.
4. **Name**: *(e.g., `role-admin`)*
5. Click **Save**.
### Assign Roles to Groups
#### Group: `role-admin`
1. Select `role-admin` under `opencdmp`.
2. Navigate to **Role Mappings**.
3. In **Client Roles**, select client `api`:
- Add **Admin**
4. Repeat for clients `annotation` and `notification`:
- Add **Admin**
#### Group: `role-installation-admin`
1. Select `role-installation-admin` under `opencdmp`.
2. Navigate to **Role Mappings**.
3. In **Client Roles**, select client `api`:
- Add **InstallationAdmin**
- Add **User**
4. For client `notification`:
- Add **User**
#### Group: `role-user`
1. Select `role-user` under `opencdmp`.
2. Navigate to **Role Mappings**.
3. In **Client Roles**, select clients `api`, `annotation`, `notification`:
- Add **User**
### Create Subgroups for Tenant Roles
For each tenant role group (`tenant-config-manager`, `tenant-plan-manager`, `tenant-role-admin`, `tenant-role-user`):
1. Select the tenant role group under `opencdmp`.
2. Go to the **Sub Groups** tab.
3. Click **New**.
4. **Name**: `tenant-default`
5. Click **Save**.
6. Select the `tenant-default` subgroup.
7. Navigate to the **Attributes** tab.
8. Click **Add Attribute**.
9. **Key**: `tenant_role`
10. **Value**: *(corresponding value)*
- For `tenant-config-manager`: `TenantConfigManager:default`
- For `tenant-plan-manager`: `TenantPlanManager:default`
- For `tenant-role-admin`: `TenantAdmin:default`
- For `tenant-role-user`: `TenantUser:default`
11. Click **Save**.
---
## Step 8: Set Default Groups for Users
All users should by default be members of:
- `/opencdmp/role-user`
- `/opencdmp/tenant-role-user/tenant-default`
### Assign Default Groups
1. Navigate to **Realm Settings**.
2. Go to the **Default Groups** tab.
3. Click **Add Groups**.
4. Select:
- `/opencdmp/role-user`
- `/opencdmp/tenant-role-user/tenant-default`
5. Click **Add Selected**.
---
## Step 9: Create Users
### Create an Admin User
1. Navigate to **Users**.
2. Click **Add User**.
3. **Username**: *(e.g., `admin`)*
4. **Email Verified**: **On**
5. Click **Save**.
6. Go to the **Credentials** tab.
- Set a password.
- Disable **Temporary Password**.
7. Go to the **Groups** tab.
- Click **Join Groups**.
- Add `/opencdmp/role-admin`.
### Create a Regular User
1. Repeat steps to create a new user.
2. Add user to `/opencdmp/role-user` and `/opencdmp/tenant-role-user/tenant-default` groups.
---
## Step 10: Create `keycloak-api` User
This user allows the application to access Keycloak's REST API.
1. Navigate to **Users**.
2. Click **Add User**.
3. **Username**: `keycloak-api`
4. **Email Verified**: **On**
5. Click **Save**.
6. Go to the **Credentials** tab.
- Set a password.
- Disable **Temporary Password**.
7. Go to the **Role Mappings** tab.
- In **Client Roles**, select `realm-management`.
- Add **realm-admin**.
8. Go to the **Groups** tab.
- Add to:
- `/opencdmp/role-user`
- `/opencdmp/tenant-role-user/tenant-default`
---
## Step 11: Configure Realm Settings
### Enable Email Verification
1. Navigate to **Realm Settings**.
2. In the **Login** tab, enable:
- **Email Verified**: **On**
### Configure Email Settings
1. In **Realm Settings**, go to the **Email** tab.
2. Set up SMTP settings for sending emails.
- **Host**
- **Port**
- **From**
- **Encryption**
- **Authentication**
3. Click **Save**.
### Enable User Registration
1. In **Realm Settings**, go to the **Login** tab.
2. Enable **User Registration**: **On**
3. Under **Default Roles**, add:
- `/opencdmp/role-user`
- `/opencdmp/tenant-role-user/tenant-default`
---
## Step 12: Configure Identity Providers (Optional)
1. Navigate to **Identity Providers** in the left menu.
2. Click **Add Provider**.
3. Select the provider you wish to integrate (e.g., **Google**, **Facebook**).
4. Enter the required credentials and settings.
5. Click **Save**.
---
## Conclusion
Your Keycloak setup for OpenCDMP is now complete. This configuration enables secure authentication and authorization across the various services and components of the platform.
- **Important**: Replace `(APP_URL)` with your actual application URL throughout the configuration.
- **Note**: Ensure that all settings are double-checked for accuracy.
---
## References
- **Keycloak Documentation**: [https://www.keycloak.org/documentation](https://www.keycloak.org/documentation)
- **OpenID Connect Clients**: [Keycloak Clients](https://www.keycloak.org/docs/latest/server_admin/#oidc-clients)
- **Client Scopes**: [Keycloak Client Scopes](https://www.keycloak.org/docs/latest/server_admin/#client-scopes)

View File

@ -1,378 +1,202 @@
---
sidebar_position: 2
sidebar_position: 3
description: A guide for the platform installation process
---
# Installation
This Section shows the steps required to initialize the Keycloak Instance in order to work correctly with the Application. This tutorial assumes that keycloak has already been deployed and is up and running.
# Deployment
# Keycloak Setup
If keycloak is up and ready then you can start the initialization:
1. Login as Admin
2. Create Argos Realm (if doesn't already exist)
3. Enter that Realm
#### **Docker Containers**
## 1) Create Clients
OpenCDMP is containerized using Docker, with each service running in its own Docker container. This isolation ensures consistency across environments and simplifies deployment.
#### Web Client (dmp_web)
1. Create New Client
2. General Settings:
1. Client ID: **dmp_web**
2. Name: **dmp_web**
3. Front channel logout: **Off**
3. Capability config:
1. Client Authentication: **On**
2. Authorization: **Off**
3. Standard flow: **off**
4. Direct access grants: **On**
5. Service accounts roles: **On**
4. Logout settings:
1. Front channel logout: **On**
5. Roles:
1. Create the roles "Admin", "User", "InstallationAdmin"
#### **Deployment Steps**
#### Annotation Client (dmp_annotation)
1. Create New Client
2. General Settings:
1. Client ID: **dmp_annotation**
2. Name: **dmp_annotation**
3. Front channel logout: **Off**
3. Capability config:
1. Client Authentication: **On**
2. Authorization: **Off**
3. Standard flow: **off**
4. Direct access grants: **On**
5. Service accounts roles: **On**
4. Logout settings:
1. Front channel logout: **Off**
5. Roles:
1. Create the roles "Admin", "User"
1. **Install Docker and Docker Compose**:
#### Notification Client (dmp_notification)
1. Create New Client
2. General Settings:
1. Client ID: **dmp_web**
2. Name: **dmp_web**
3. Front channel logout: **Off**
3. Capability config:
1. Client Authentication: **On**
2. Authorization: **Off**
3. Standard flow: **off**
4. Direct access grants: **On**
5. Service accounts roles: **On**
4. Logout settings:
1. Front channel logout: **On**
5. Roles:
1. Create the roles "Admin", "User"
- [Install Docker](https://docs.docker.com/get-docker/) (version 20.10 or higher recommended)
- [Install Docker Compose](https://docs.docker.com/compose/install/) (version 1.29 or higher recommended)
#### Plugin Client (dmp_plugins)
1. Create New Client
2. General Settings:
1. Client ID: **dmp_web**
2. Name: **dmp_web**
3. Front channel logout: **Off**
3. Capability config:
1. Client Authentication: **On**
2. Authorization: **Off**
3. Standard flow: **off**
4. Direct access grants: **On**
5. Service accounts roles: **On**
4. Logout settings:
1. Front channel logout: **On**
5. Roles:
1. Create the role "app-service"
2. **Clone the demo deployemnt Repository**:
#### Webapp Client (dmp_webapp)
1. Create New Client
2. General Settings:
1. Client ID: **dmp_web**
2. Name: **dmp_web**
3. Front channel logout: **Off**
3. Access settings:
1. Root URL: https://(APP_URL)/home
2. Home URL: https://(APP_URL)/home
3. Valid redirect URIs: https://(APP_URL)/*
4. Web Origins: https://(APP_URL)
4. Capability config:
1. Client Authentication: **Off**
2. Authorization: **Off**
3. Standard flow: **on**
4. Direct access grants: **Off**
5. Service accounts roles: **Off**
5. Logout settings:
1. Front channel logout: **On**
```bash
git clone https://github.com/XXXXX/OpenCDMP.git
cd OpenCDMP/deployment
```
3. **Review Configuration Files**:
- Adjust environment variables in the `.env` file or directly in the `docker-compose.yml` and `docker-compose.override.yml` file.
- Modify individual service configurations in their respective directories if necessary.
4. **Start the Services**:
```bash
docker-compose up -d
```
5. **Verify the Deployment**:
```bash
docker-compose ps
```
6. **Access the Application**:
- Open a web browser and navigate to `http://localhost:50000`.
- Replace `localhost` with your domain or IP if configured differently.
7. **Configure Keycloak (Authentication Service)**:
- Navigate to `http://localhost:8080/auth`.
- Log in with Keycloak's admin user.
- Configure realms, clients, users, and roles as needed.
8. **Log In to OpenCDMP**:
- Open a web browser and navigate to `http://localhost:50000`.
- Log in using the user credentials set up in Keycloak.
## 2) Create Realm Roles
1. Create Admin Role (Admin)
2. Create User Role (User)
### **Scalability and Extensibility**
## 3) Create Client Scopes
OpenCDMP is designed with scalability and extensibility in mind, allowing the system to grow and adapt according to organizational needs.
#### Web Scope (dmp_web)
1. Settings:
1. Name: **dmp_web**
2. Type: **None**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **Off**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**Audience**":
1. Name: **Client Id Audience**
2. Included Client Audience: **dmp_web**
3. Add to ID token: **Off**
4. Add to access token: **On**
5. Add to lightweight access token: **Off**
6. Add to token introspection: **On**
3. Scope:
1. "Assign role"
2. Filter by realm roles.
3. Assign role "Admin" and "User" (those are the ones we created on the "Realm roles" section)
#### **Scalability**
#### Annotation Scope (dmp_annotation)
1. Settings:
1. Name: **dmp_annotation**
2. Type: **None**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **Off**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**Audience**":
1. Name: **Client Id Audience**
2. Included Client Audience: **dmp_annotation**
3. Add to ID token: **Off**
4. Add to access token: **On**
5. Add to lightweight access token: **Off**
6. Add to token introspection: **On**
3. Scope:
1. "Assign role"
2. Filter by realm roles.
3. Assign role "Admin" and "User" (those are the ones we created on the "Realm roles" section)
**Horizontal Scaling**: Individual services can be scaled horizontally by adding more instances to handle increased load.
#### Notification Scope (dmp_notification)
1. Settings:
1. Name: **dmp_notification**
2. Type: **None**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **Off**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**Audience**":
1. Name: **Client Id Audience**
2. Included Client Audience: **dmp_notification**
3. Add to ID token: **Off**
4. Add to access token: **On**
5. Add to lightweight access token: **Off**
6. Add to token introspection: **On**
3. Scope:
1. "Assign role"
2. Filter by realm roles.
3. Assign role "Admin" and "User" (those are the ones we created on the "Realm roles" section)
- **Docker Compose Scaling**: Use Docker Compose to scale services. For example, to scale the `api-service` to run three instances:
```bash
docker-compose up -d --scale api-service=3
```
- **Load Balancing**: The Nginx reverse proxy can be configured to distribute incoming requests across multiple instances of services.
#### Plugin Scope (dmp_plugins)
1. Settings:
1. Name: **dmp_plugins**
2. Type: **None**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **Off**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**Audience**":
1. Name: **Client Id Audience**
2. Included Client Audience: **dmp_plugins**
3. Add to ID token: **Off**
4. Add to access token: **On**
5. Add to lightweight access token: **Off**
6. Add to token introspection: **On**
- **Update Nginx Configuration**: Modify the Nginx configuration to include upstream servers.
#### ID Scope (identity_provider)
1. Settings:
1. Name: **identity_provider**
2. Type: **None**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **On**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**User Session Note**":
1. Name: **identity_provider**
2. User Session Note: **identity_provider**
3. Token Claim Name: **identity_provider**
4. Claim JSON Type: **String**
5. Add to ID token: **On**
6. Add to access token: **On**
7. Add to lightweight access token: **Off**
8. Add to userinfo: **On**
9. Add to access token response: **On**
10. Add to token introspection: **On**
```
upstream api_service {
server api-service:8080;
server api-service-1:8080;
server api-service-2:8080;
}
#### Tenant Scope (tenant_role)
1. Settings:
1. Name: **tenant_role**
2. Type: **Optional**
3. Protocol: **OpenID Connect**
4. Display on consent screen: **On**
5. include in token scope: **On**
2. Mappers:
1. "Configure a new mapper"
1. Pick "**User Attribute**"
1. Name: **Tenant role**
2. User Attribute: **tenant_role**
3. Token Claim Name: **tenant_role**
4. Claim JSON Type: **String**
5. Add to ID token: **On**
6. Add to access token: **On**
7. Add to lightweight access token: **Off**
8. Add to userinfo: **On**
9. Add to token introspection: **On**
10. Multivalued: **On**
11. Aggregate attribute values: **On**
server {
listen 80;
location /api/ {
proxy_pass http://api_service/;
# Additional proxy settings
}
}
```
## 4) Finalize Clients
1. Choose clients again
- **Dynamic Scaling**: Use container orchestration platforms like Kubernetes or Docker Swarm for more advanced scaling and management.
#### dmp_web
1. Choose the **dmp_web** client
2. Client scopes:
1. add **dmp_plugins** as "**Optional**"
<!-- #### **Extensibility**
#### dmp_webapp
1. Choose the **dmp_webapp** Client
2. Client scopes:
1. add **dmp_web** as "**Optional**"
2. add **dmp_notification** as "**Optional**"
3. add **dmp_annotation** as "**Optional**"
4. add **identity_provider** as "**Default**"
5. add **tenant_role** as "**Default**"
OpenCDMP's architecture supports extensibility through pluggable mechanisms and modular services.
## 5) Create Groups
**Pluggable Mechanisms**:
- **opencdmp-app**
- **role-admin**
- Role Mapping: Assign role (search "Admin" to find them easily)
- dmp_annotation - Admin
- dmp_notification - Admin
- dmp_web - Admin
- **role-installation-admin**
- Role Mapping: Assign role (search "dmp" to find them easily)
- dmp_web InstallationAdmin
- dmp_web User
- dmp_notification User
- **role-user**
- Role Mapping: Assign role (search "User" to find them easily)
- dmp_annotation User
- dmp_notification User
- dmp_web User
- **tenant-config-manager**
- **tenant-default**
- Attributes:
- tenant_role | TenantConfigManager:default
- **tenant-plan-manager**
- **tenant-default**
- Attributes:
- tenant_role | TenantPlanManager:default
- **tenant-role-admin**
- **tenant-default**
- Attributes:
- tenant_role | TenantAdmin:default
- **tenant-role-user**
- **tenant-default**
- Attributes:
- tenant_role | TenantUser:default
- **Custom Validation**: Develop custom validation plugins to enforce specific standards or organizational policies.
- **Implementation**: Follow the OpenCDMP plugin development guidelines.
- **Deployment**: Add the plugin service to the `docker-compose.yml` file and ensure it communicates via RabbitMQ.
## 6) Create Users
- We will be creating an admin user and a user that will be used for the API in order to authenticate and authorize the users that log in to the Application.
- **Export/Import Plugins**:
#### Admin User
1. Create User:
1. Email Verified: On
2. Username: argos-admin
3. Email: (ADMIN_EMAIL) (ex. argos@admin.gr)
4. firstName: Argos
5. lastName: Admin
2. Credentials:
1. Set a Password for this user with **Temporary: Off**
3. Role mapping:
1. Assign the role **realm-management realm-admin** (search realm-admin to find it easily)
4. Groups:
1. Assign the Groups:
- /opendmp-app/role-admin
- /opendmp-app/role-user
- /opendmp-app/tenant-role-admin/tenant-default
- /opendmp-app/tenant-role-user/tenant-default
- **Custom Formats**: Create plugins to support additional file formats for export/import.
- **Integration**: Ensure the plugin integrates seamlessly with the existing API service.
- **Configuration**: Update configurations to recognize the new plugin.
- **Repository Deposit Plugins**:
- **Custom Deposits**: Develop plugins to deposit OMPs to new repositories.
- **DOI Assignment**: Enable DOI assignment through the integrated repository.
- **Deployment**: Include the plugin in the `docker-compose.yml` and configure it accordingly.
**Adding New Microservices**:
- **Development**:
- **Language and Framework**: Use a language and framework compatible with the rest of the system (e.g., Python with Flask or Node.js with Express).
- **API Design**: Design APIs that adhere to RESTful principles and OpenCDMP's API specifications.
- **Communication**:
- **Message Broker**: Utilize RabbitMQ for inter-service communication.
- **API Endpoints**: Expose necessary endpoints for other services to interact.
- **Deployment**:
- **Containerization**: Dockerize the new service.
- **Compose Integration**: Add the service to the `docker-compose.yml` file.
- **Environment Variables**: Define necessary environment variables for configuration.
#### **Guidelines for Scaling and Extending OpenCDMP**
1. **Assess Requirements**:
- **Scalability Needs**: Identify which services require scaling based on performance metrics.
- **Extension Needs**: Determine functionalities that need to be added or customized.
2. **Plan Infrastructure**:
- **Resource Allocation**: Ensure adequate CPU, memory, and storage resources.
- **Network Configuration**: Plan for network policies, load balancers, and firewalls.
3. **Implement Scaling**:
- **Service Scaling**: Use Docker Compose or orchestration tools to scale services.
- **Database Scaling**: Consider database replication or clustering if necessary.
4. **Develop and Integrate Plugins**:
- **Follow Standards**: Adhere to OpenCDMP's development guidelines for consistency.
- **Testing**: Thoroughly test plugins in a staging environment before deployment.
- **Documentation**: Document the plugin's functionality, configuration, and deployment steps.
5. **Update Configuration Files**:
- **Docker Compose**: Add new services and adjust scaling configurations.
- **Environment Variables**: Update `.env` files with new settings.
- **Nginx Configuration**: Modify `nginx.conf` to route traffic to new service instances.
6. **Deploy Changes**:
- **Rolling Updates**: Deploy changes with minimal downtime.
- **Monitoring**: Keep an eye on logs and metrics during deployment.
7. **Maintain and Optimize**:
- **Regular Monitoring**: Continuously monitor system performance.
- **Feedback Loop**: Collect user feedback to identify areas for improvement.
- **Iterative Enhancement**: Regularly update and optimize services and plugins.
#### **Example: Scaling the API Service**
1. **Scale the Service**:
#### API User
1. Create User:
1. Email Verified: On
2. Username: dmp-keycloak-api
3. Email: (API_EMAIL) (ex. dmp-keycloak-api@gmail.com)
4. firstName: dmp
5. lastName: keycloak
2. Credentials:
1. Set a Password for this user with **Temporary: Off**
3. Role mapping:
1. Assign the role **realm-management realm-admin** (search realm-admin to find it easily)
4. Groups:
1. Assign the Groups:
- /opendmp-app/role-user
- /opendmp-app/tenant-role-user/tenant-default
#### **Docker Compose**
## 7) Realm Settings
- **Purpose**: Orchestrates the deployment of multiple Docker containers.
- **Features**:
- Manages service dependencies.
- Simplifies configuration with `docker-compose.yml` files.
- **Deployment Steps**:
1. Install Docker and Docker Compose.
2. Clone the OpenCDMP repository containing the Docker Compose files.
3. Configure environment variables as needed.
4. Run `docker-compose up -d` to start all services.
5. Access the application via the Nginx reverse proxy URL.
#### Login:
1. Enable the "Verify Email" option
### **Microservices Interaction**
#### Email:
1. On the Template->From text box add the email that will be used by the application to send emails. (ex. no-reply@openaire.eu)
2. On the "Connection & Authentication" section add the required information for the email server used for the application. Then save and Test connection.
#### User registration:
1. Add the groups "tenant-default" and "role-user". The paths should be " /opendmp-app/tenant-role-user/tenant-default" and "/opendmp-app/role-user" respectively. This will be the default roles for every new user that gets created.
## 8) Identity Providers:
1. Google IDP:
1. On the Settings section add the required creds:
1. Redirect URI: https://(KEYCLOAK_URL)/realms/(REALM_NAME)/broker/google/endpoint
2. Client ID: (GOOGLE_CLIENT_ID)
3. Client Secret: (GOOGLE_CLIENT_SECRET)
2. After Creating the IDP, on the Mappers section add a mapper:
1. Name: **identity_provider**
2. Sync mode override: **Force**
3. Mapper type: **Hardcoded User Session Attribute**
4. User Session Attribute: **identity_provider**
5. User Session Attribute Value **google**
2. OpenAIRE AAI Beta or ((IDP_NAME)):
1. Create a "Keycloak OpenID Connect" type IDP
2. Redirect URI: https://(KEYCLOAK_URL)/realms/(REALM_NAME)/broker/(ALIAS_NAME)/endpoint
3. Alias: (ALIAS_NAME)
4. Display name: (IDP_NAME)
5. Use discovery endpoint: **Off**
6. Authorization URL: https://beta.aai.openaire.eu/auth/realms/openaire/protocol/openid-connect/auth
7. Token URL: https://beta.aai.openaire.eu/auth/realms/openaire/protocol/openid-connect/token
8. Logout URL: https://beta.aai.openaire.eu/auth/realms/openaire/protocol/openid-connect/logout
9. User Info URL: https://beta.aai.openaire.eu/auth/realms/openaire/protocol/openid-connect/userinfo
10. Issuer: https://beta.aai.openaire.eu/auth/realms/openaire
11. Validate Signatures: **On**
12. Use JWKS URL: **On**
13. JWKS URL: https://beta.aai.openaire.eu/auth/realms/openaire/protocol/openid-connect/certs
14. Use PKCE: **Off**
15. Client authentication: **Client secret sent as post**
16. Client ID: (CLIENT_ID)
17. Client Secret: (CLIENT_SECRET)
18. Client assertion signature algorithm: **Algorithm not specified**
19. Store tokens: **Off**
20. Stored tokens readable: **Off**
21. Access Token is JWT: **Off**
22. Trust Email: **Off**
23. Account linking only: **Off**
24. Hide on login page: **Off**
25. Verify essential claim: **Off**
26. First login flow override **first broker login**
27. Post login flow: **None**
28. Sync mode: **Import**
#### **Communication Flow**
- **External Requests**: Users interact with the Webapp Service through the Nginx Reverse Proxy.
- **Frontend to Backend**: The Webapp Service communicates with the API Service for all backend operations.
- **Authentication**: Keycloak handles authentication requests from both the Webapp and API Services.
- **Inter-Service Communication**: Services like Notification Service, Annotation Service, Repository Deposit Services, and File Transformation Services communicate with the API Service and each other via RabbitMQ.
- **Database Operations**: The API Service interacts with PostgreSQL for CRUD operations.
- **Search Operations**: The API Service communicates with Elasticsearch for search functionalities.
- **Notifications**: Triggered by events in the API Service and handled by the Notification Service. -->

View File

@ -5,4 +5,109 @@ description: A brief introduction to the platform features
# Introduction
**OpenCDMP** is an open and extensible software platform designed to simplify the management, monitoring, and maintenance of **Output Management Plans (OMPs)**, such as **Data Management Plans (DMPs)** and **Software Management Plans (SMPs)**. It provides a flexible and customizable environment that streamlines the complex processes involved in handling OMPs, ensuring efficiency, compliance, and collaboration across various projects and organizations.
## 🚀 **Key Features**
- **Modular Architecture**: Easily extend the platform with new modules and plugins to meet specific needs.
- **Evaluation via Plugins**: Perform evaluation through customizable plugins tailored to specific standards and requirements.
- **Collaborative Environment**: Supports teamwork with multi-user access, version control, and change tracking.
- **Role-Based Access Control**: Invite users to a Plan with different roles—Viewer, Contributor, Reviewer, etc.—and set access rights at the Plan or Section level.
- **Review and Annotation System**: Reviewers can add annotations (comments) to Plans or Desriptions, with statuses to track their lifecycle.
- **Notification Features**: Receive Email and In-App notifications for updates, comments, and changes to Plans or Desriptions you're involved in.
- **Flexible Export Options**: Export Plans in human and machine-readable formats like XML, JSON, DOCX, and PDF.
- **Pluggable Export Mechanism**: Implement custom export plugins to suit specific requirements.
- **Repository Deposits for DOI Assignment**: Deposit OMPs directly to repositories for DOI (Digital Object Identifier) assignment.
- **Pluggable Deposit Mechanism**: Implement custom deposit plugins to integrate with different repositories.
- **Customizable Templates**: Offers a library of templates for various types of OMPs, customizable to fit specific project requirements.
- **Integration Capabilities**: Seamlessly connects with other software tools and platforms, enabling data import/export and interoperability via APIs.
<!-- - **Real-Time Monitoring**: Interactive dashboards to track the progress of OMPs, with updates and alerts for changes or issues. -->
---
## 🧩 **Core Concepts**
- #### **Blueprints**
Define the structure of a Plan by specifying its Sections and content.
- #### **Plans**
Primary entities representing comprehensive OMPs, structured by Blueprints.
- #### **Description Templates**
Define the structure of Descriptions within a Plan, supporting various input types.
- #### **Descriptions**
Detailed entries providing information about specific inputs or outputs.
---
## 🛠️ **Getting Started**
1. **Deploy OpenCDMP**: Follow the [Deployment Guide](https://github.com/YourUsername/OpenCDMP/blob/main/INSTALLATION.md) to set up the platform.
2. **Configure OpenCDMP**: Set up authentication and authorization by following the [Keycloak Setup Instructions](https://github.com/YourUsername/OpenCDMP/blob/main/KEYCLOAK_SETUP.md).
3. **Create your plans**: Create your Plans by leveraging the features of the platform.
---
## 🌟 **Benefits**
- **Efficiency**: Streamlines the creation, management, and distribution of OMPs, saving time and resources.
- **Enhanced Collaboration**: Robust features like role-based access control, annotations, and notifications improve teamwork and communication.
- **Quality Control**: The review and annotation system ensures thorough examination and quality assurance of Plans.
- **Flexible Sharing and Distribution**: Diverse export and deposit options enable easy sharing, integration, and official registration of your Plans.
- **Customizability**: The pluggable mechanisms for validation, export, and deposit allow for tailored solutions to meet specific organizational needs.
- **Stay Informed**: Notification features ensure that team members are promptly aware of important updates and actions required.
- **Flexibility and Scalability**: Suits organizations of all sizes due to its flexible and extensible design.
<!-- - **Compliance Assurance**: Customizable validation plugins help keep OMPs aligned with specific standards and regulations. -->
---
## 📖 **Documentation**
- **User Guide**: Learn how to use OpenCDMP effectively.
- **Developer Guide**: For those interested in extending the platform.
<!-- - **API Reference**: Detailed documentation of available APIs. -->
- **Deployment Instructions**: Steps to deploy OpenCDMP in your environment.
- **Configuration Guides**:
- [Environment Variables Configuration](https://github.com/YourUsername/OpenCDMP/blob/main/ENV_CONFIGURATION.md)
- [Keycloak Setup](https://github.com/YourUsername/OpenCDMP/blob/main/KEYCLOAK_SETUP.md)
- [Scalability and Extensibility](https://github.com/YourUsername/OpenCDMP/blob/main/SCALABILITY_EXTENSIBILITY.md)
---
## 🤝 **Community and Support**
- **GitHub Repository**: [https://github.com/YourUsername/OpenCDMP](https://github.com/YourUsername/OpenCDMP)
- **Issue Tracker**: Report bugs or request features.
- **Discussion Forum**: Join the community to discuss and share ideas.
- **Contributing Guidelines**: Learn how to contribute to OpenCDMP. Please check out our [contributing guidelines](CONTRIBUTING.md) to get started.
---
## 📄 **License**
OpenCDMP is released under the [MIT License](https://github.com/YourUsername/OpenCDMP/blob/main/LICENSE).
---
## 🌐 **Contact**
For questions or support, please contact:
- **Email**: support@opencdmp.org
- **Twitter**: [@OpenCDMP](https://twitter.com/OpenCDMP)
- **LinkedIn**: [OpenCDMP Page](https://www.linkedin.com/company/opencdmp)
---
Start simplifying your Output Management Plans with OpenCDMP today!
[Download Now](https://github.com/YourUsername/OpenCDMP/releases)