Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3591] Add EditProject subtitle extension point #3592

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ This dialog presents diagram elements in a tree and allows to select them and up
image:doc/screenshots/diagramFilterView.png[Diagram Filter View, 70%]
- https://github.com/eclipse-sirius/sirius-web/issues/3523[#3523] [gantt] Support rounding dates when changing dates from gantt
- https://github.com/eclipse-sirius/sirius-web/issues/3655[#3655] [gantt] Support "Delete Task Dependency" tool in gantt
- https://github.com/eclipse-sirius/sirius-web/issues/3591[#3591] [sirius-web] Add EditProject subtitle extension point

=== Improvements

Expand Down
144 changes: 144 additions & 0 deletions doc/how-to/debug-persistence-related-issues.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
= How to debug persistence related issues

Let's consider that you are trying to debug an issue related to the persistence of the data.
There are multiple tools that can be used to have an overview of the situation, monitor the application and detect potential issues.

== How to see what is in the database?

If you want to see the data in the database, you can use a tool like DBeaver:"https://dbeaver.io" or pgAdmin:"https://www.pgadmin.org".
Using such tool, you can open a connection with the database and send SQL queries to see your data.

You can also do it using various command line tools but we recommend a tool with a user interface since they tend to be more user friendly.

You can easily see the list of all projects, representation data or semantic data using a couple of SQL queries such as:

- `SELECT * FROM project`
- `SELECT * FROM semantic_data`
- `SELECT * FROM representation_data`

You can also have a look at the Liquibase changelog using `SELECT * FROM databasechangelog`.


== How much data do we have in the database?

If you want to see the volume of data contained in the database, you can ask for the size of every tables using this query:

```
SELECT table_schema, table_name, pg_total_relation_size('"'||table_schema||'"."'||table_name||'"')
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY 3 DESC
```

== How to monitor the activity of the database?

If you are trying to debug issues with database transactions or locks, start by executing `SELECT * FROM pg_stat_activity`.
Look for all the activity from applications with the name `PostgreSQL JDBC Driver` since it's the default name of the driver used to connect Spring Boot with PostgreSQL.
Using this query, you will see the last activity of all the clients of the PostgreSQL database.

If you see multiple clients with `SET application_name = 'PostgreSQL JDBC Driver'` as their last query and in an `idle` state, do not worry.
These are the threads of the Hikari thread pool used to connect Spring Boot to PostgreSQL.
By default, you should have 10 of them.

If you see a couple of clients with `COMMIT` as their last query, those are Hikaru clients which have at least been used once and which have completed their job.
Their last visible activity was commiting a transaction.

On the other hand, if you see in the activity a client with an `idle` state and a meaningful query from Sirius Web as their last activity, you may have found a transaction which is not properly commited.
If you see a client with an `active` state which stay this way a bit loo long, you may have discover an performance issue with a query which is taking too long to run.

== How to log what is going on with the database?

In order to log the interactions between Sirius Web and the database, you have multiple options.

=== JDBC logging

You can first activate the log of the JDBC layer using `logging.level.org.springframework.jdbc=debug` as an environment variable of your launch configuration.
With this setting, you will have a lot of details on the lifecycle and interactions with the database like this:

```
2024-06-21T15:57:44.867+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Creating new transaction with name [org.eclipse.sirius.web.application.project.services.ProjectApplicationService.findAll]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly
2024-06-21T15:57:44.872+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Acquired Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]] for JDBC transaction
2024-06-21T15:57:44.878+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.datasource.DataSourceUtils : Setting JDBC Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]] read-only
2024-06-21T15:57:44.879+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Switching JDBC Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]] to manual commit
2024-06-21T15:57:44.881+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Participating in existing transaction
2024-06-21T15:57:45.035+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2024-06-21T15:57:45.036+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT "project"."id" AS "id", "project"."name" AS "name", "project"."created_on" AS "created_on", "project"."last_modified_on" AS "last_modified_on" FROM "project" LIMIT 20 OFFSET 0]
2024-06-21T15:57:45.123+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL query
2024-06-21T15:57:45.123+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [SELECT "nature"."name" AS "name" FROM "nature" WHERE "nature"."project_id" = ?]
2024-06-21T15:57:45.159+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Initiating transaction commit
2024-06-21T15:57:45.160+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Committing JDBC transaction on Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]]
2024-06-21T15:57:45.161+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.datasource.DataSourceUtils : Resetting read-only flag of JDBC Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]]
2024-06-21T15:57:45.162+02:00 DEBUG 13542 --- [nio-8080-exec-2] o.s.jdbc.support.JdbcTransactionManager : Releasing JDBC Connection [HikariProxyConnection [HikariProxyConnection@1326502956 wrapping org.postgresql.jdbc.PgConnection@ace2408]] after transaction
```

As a result, it will be easier for you to understand when a transaction is opened, which part of the code triggered it and what queries have been executed by the transaction.

=== DataSource logging

The JDBC logging support is very easy to activate but it does not list the parameters given the SQL queries.
If you want to have a bit more details, you can add a temporary dependency in `sirius-web` to:

```
<dependency>
<groupId>com.github.gavlyukovskiy</groupId>
<artifactId>datasource-proxy-spring-boot-starter</artifactId>

<!-- A new version may have been released, don't just copy this version number as is -->
<version>1.9.0</version>
</dependency>
```

On top of that, you will need to add `logging.level.net.ttddyy.dsproxy.listener=debug`.
Thanks to this dependency and this log level, you will be able to see all the queries sent to the database, like this:

```
2024-06-21T15:57:45.046+02:00 DEBUG 13542 --- [nio-8080-exec-2] n.t.d.l.l.SLF4JQueryLoggingListener :
Name:dataSource, Connection:3, Time:2, Success:True
Type:Prepared, Batch:False, QuerySize:1, BatchSize:0
Query:["SELECT "project"."id" AS "id", "project"."name" AS "name", "project"."created_on" AS "created_on", "project"."last_modified_on" AS "last_modified_on" FROM "project" LIMIT 20 OFFSET 0"]
Params:[()]
```

Most of the time, this level of details may not be relevant but it's nice to know that this option is available.


== How to figure out if a query is too complex

If you need to know why your query is taking too much time, you can ask PostgreSQL to explain what will happen when it will execute it.
Here is a simple example:

```
EXPLAIN (analyze, buffers, format text)
INSERT INTO project (
id,
name,
created_on,
last_modified_on
) VALUES (
'250cabc0-a211-438c-8015-2d2aa136eb81',
'Empty Studio',
'2024-01-01 9:42:0.000',
'2024-01-02 9:42:0.000'
);
```

As a result, PostgreSQL will indicate what will be done and how much time each step will take:

```
"Insert on project (cost=0.00..0.01 rows=0 width=0) (actual time=0.349..0.349 rows=0 loops=1)"
" Buffers: shared hit=12 dirtied=2"
" -> Result (cost=0.00..0.01 rows=1 width=64) (actual time=0.002..0.002 rows=1 loops=1)"
"Planning Time: 0.020 ms"
"Execution Time: 0.406 ms"
```

== How to view PostgreSQL internal log?

If you want to see as much log from PostgreSQL as possible, you can configure the PostgreSQL inside the Docker container to log every single details with the following command:

```
docker run -p 5438:5432 --name sirius-web-postgresql -e POSTGRES_USER=dbuser -e POSTGRES_PASSWORD=dbpwd -e POSTGRES_DB=sirius-web-db -itd postgres -c logging_collector=on -d 5
```

With those settings, PostgreSQL will log a massive amount of details (probably way to much for a regular use case) but you can change the value of `-d 5` to a lower number like `-d 1` to select the level that matches your needs.
After that, you can look inside the Docker container to find the logs of the PostgreSQL instance, for example in `/var/lib/postgresql/data/log`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services.api.ISemanticDataUpdateService;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
Expand Down Expand Up @@ -61,6 +62,7 @@ public EditingContextPersistenceService(ISemanticDataUpdateService semanticDataU
}

@Override
@Transactional
public void persist(IEditingContext editingContext) {
long start = System.currentTimeMillis();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
Expand Down Expand Up @@ -85,6 +86,7 @@ public EditingContextSearchService(IProjectSearchService projectSearchService, I
}

@Override
@Transactional(readOnly = true)
public boolean existsById(String editingContextId) {
return new UUIDParser().parse(editingContextId)
.map(AggregateReference::<Project, UUID>to)
Expand All @@ -93,6 +95,7 @@ public boolean existsById(String editingContextId) {
}

@Override
@Transactional(readOnly = true)
public Optional<IEditingContext> findById(String editingContextId) {
return new UUIDParser().parse(editingContextId)
.flatMap(this.projectSearchService::findById)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.sirius.web.application.studio.services.api.IStudioColorPalettesLoader;
import org.eclipse.sirius.web.domain.boundedcontexts.semanticdata.services.api.ISemanticDataSearchService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* Used to contribute the domain and view models found to the editing context.
Expand All @@ -62,6 +63,7 @@ public EditingContextInitializer(ISemanticDataSearchService semanticDataSearchSe
}

@Override
@Transactional(readOnly = true)
public void preProcess(IEditingContext editingContext) {
if (editingContext instanceof EditingContext siriusWebEditingContext) {
List<Domain> domains = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
* Spring Data JDBC configuration.
*
* @author sbegaudeau
*/
@Configuration
@EnableTransactionManagement
@EnableJdbcRepositories(basePackages = { "org.eclipse.sirius.web.domain" })
public class JDBCConfiguration {
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ export {
navigationBarRightContributionExtensionPoint,
} from './navigationBar/NavigationBarExtensionPoints';
export { routerExtensionPoint } from './router/RouterExtensionPoints';
export { type EditProjectNavbarSubtitleProps } from './views/edit-project/EditProjectNavbar/EditProjectNavbar.types';
export { editProjectNavbarSubtitleExtensionPoint } from './views/edit-project/EditProjectNavbar/EditProjectNavbarExtensionPoints';
export { type CreateProjectAreaCardProps } from './views/project-browser/create-projects-area/CreateProjectArea.types';
export { createProjectAreaCardExtensionPoint } from './views/project-browser/create-projects-area/CreateProjectAreaExtensionPoints';
export { projectActionButtonMenuItemExtensionPoint } from './views/project-browser/list-projects-area/ProjectActionButtonExtensionPoints';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Obeo - initial API and implementation
*******************************************************************************/
import { gql, useSubscription } from '@apollo/client';
import { ServerContext, ServerContextValue, Toast } from '@eclipse-sirius/sirius-components-core';
import { ServerContext, ServerContextValue, Toast, useComponent } from '@eclipse-sirius/sirius-components-core';
import IconButton from '@material-ui/core/IconButton';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
Expand All @@ -32,6 +32,7 @@ import { RenameProjectModal } from '../../../modals/rename-project/RenameProject
import { NavigationBar } from '../../../navigationBar/NavigationBar';
import { EditProjectNavbarProps, GQLProjectEventSubscription } from './EditProjectNavbar.types';

import { editProjectNavbarSubtitleExtensionPoint } from './EditProjectNavbarExtensionPoints';
import {
EditProjectNavbarContext,
EditProjectNavbarEvent,
Expand Down Expand Up @@ -63,10 +64,15 @@ const projectEventSubscription = gql`
const useEditProjectViewNavbarStyles = makeStyles((theme) => ({
center: {
display: 'flex',
flexDirection: 'row',
flexDirection: 'column',
alignItems: 'center',
},
title: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
},
titleLabel: {
marginRight: theme.spacing(2),
overflow: 'hidden',
textOverflow: 'ellipsis',
Expand Down Expand Up @@ -163,24 +169,30 @@ export const EditProjectNavbar = ({ project }: EditProjectNavbarProps) => {
modal = <DeleteProjectModal project={project} onSuccess={onProjectDeleted} onCancel={onCloseModal} />;
}
}

const { Component: ProjectSubtitle } = useComponent(editProjectNavbarSubtitleExtensionPoint);
return (
<>
<NavigationBar>
<div className={classes.center}>
<Typography variant="h6" noWrap className={classes.title} data-testid={`navbar-${projectName}`}>
{projectName}
</Typography>
<IconButton
className={classes.onDarkBackground}
edge="start"
aria-label="more"
aria-controls="more-menu"
aria-haspopup="true"
onClick={onMoreClick}
color="inherit"
data-testid="more">
<MoreVertIcon />
</IconButton>
<div className={classes.title}>
<Typography variant="h6" noWrap className={classes.titleLabel} data-testid={`navbar-${projectName}`}>
{projectName}
</Typography>
<IconButton
className={classes.onDarkBackground}
edge="start"
size="small" // Per #3591 it should remain "small" to keep vertical space for a potential subtitle
aria-label="more"
aria-controls="more-menu"
aria-haspopup="true"
onClick={onMoreClick}
color="inherit"
data-testid="more">
<MoreVertIcon />
</IconButton>
</div>
<ProjectSubtitle />
</div>
</NavigationBar>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 Obeo.
* Copyright (c) 2021, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -17,6 +17,8 @@ export interface EditProjectNavbarProps {
project: Project;
}

export interface EditProjectNavbarSubtitleProps {}

export interface GQLProjectEventSubscription {
projectEvent: GQLProjectEventPayload;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2021, 2024 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/

import { ComponentExtensionPoint } from '@eclipse-sirius/sirius-components-core';
import { EditProjectNavbarSubtitleProps } from './EditProjectNavbar.types';

export const editProjectNavbarSubtitleExtensionPoint: ComponentExtensionPoint<EditProjectNavbarSubtitleProps> = {
identifier: 'editProjectNavbar#subtitle',
FallbackComponent: () => null,
};
Loading
Loading