diff --git a/assembly/assembly-wsmaster-war/.deps/prod.md b/assembly/assembly-wsmaster-war/.deps/prod.md
index 99089f049c9..9b0d23e47c5 100644
--- a/assembly/assembly-wsmaster-war/.deps/prod.md
+++ b/assembly/assembly-wsmaster-war/.deps/prod.md
@@ -179,29 +179,12 @@
| `org.eclipse.che.multiuser/che-multiuser-api-authentication-commons@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-api-authorization-impl@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-api-authorization@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-api-organization-shared@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-api-organization@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-api-permission-shared@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-api-permission@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-api-resource-shared@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-api-resource@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-api-workspace-activity@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-keycloak-server@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-keycloak-shared@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-keycloak-token-provider@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-keycloak-user-remover@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-machine-authentication-shared@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-machine-authentication@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.che.multiuser/che-multiuser-oidc@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-devfile@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-logger@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-resource@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-system@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-user@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-workspace-activity@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-permission-workspace@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-personal-account@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
-| `org.eclipse.che.multiuser/che-multiuser-sql-schema@7.41.0-SNAPSHOT` | EPL-2.0 | ecd.che |
| `org.eclipse.persistence/jakarta.persistence@2.2.3` | - | eclipse |
| `org.eclipse.persistence/org.eclipse.persistence.antlr@2.7.9` | - | eclipse |
| `org.eclipse.persistence/org.eclipse.persistence.asm@9.1.0` | - | eclipse |
diff --git a/assembly/assembly-wsmaster-war/pom.xml b/assembly/assembly-wsmaster-war/pom.xml
index f16542fd140..ec1c5062204 100644
--- a/assembly/assembly-wsmaster-war/pom.xml
+++ b/assembly/assembly-wsmaster-war/pom.xml
@@ -251,14 +251,6 @@
org.eclipse.che.multiuserche-multiuser-api-authorization-impl
-
- org.eclipse.che.multiuser
- che-multiuser-api-permission
-
-
- org.eclipse.che.multiuser
- che-multiuser-keycloak-token-provider
- org.eclipse.che.multiuserche-multiuser-machine-authentication
@@ -267,34 +259,6 @@
org.eclipse.che.multiuserche-multiuser-oidc
-
- org.eclipse.che.multiuser
- che-multiuser-permission-devfile
-
-
- org.eclipse.che.multiuser
- che-multiuser-permission-logger
-
-
- org.eclipse.che.multiuser
- che-multiuser-permission-system
-
-
- org.eclipse.che.multiuser
- che-multiuser-permission-workspace
-
-
- org.eclipse.che.multiuser
- che-multiuser-permission-workspace-activity
-
-
- org.eclipse.che.multiuser
- che-multiuser-personal-account
-
-
- org.eclipse.che.multiuser
- che-multiuser-sql-schema
- org.eclipse.persistenceorg.eclipse.persistence.core
@@ -426,7 +390,6 @@
io.jaegertracing:jaeger-clientio.jaegertracing:jaeger-tracerresolverorg.eclipse.che.multiuser:che-multiuser-personal-account
- org.eclipse.che.multiuser:che-multiuser-keycloak-token-providerorg.eclipse.persistence:org.eclipse.persistence.extensionorg.eclipse.persistence:org.eclipse.persistence.jpaorg.jgroups.kubernetes:jgroups-kubernetes
diff --git a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
index 52ec056fab5..c6e011f35df 100644
--- a/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
+++ b/assembly/assembly-wsmaster-war/src/main/java/org/eclipse/che/api/deploy/WsMasterModule.java
@@ -14,7 +14,6 @@
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.inject.matcher.Matchers.subclassesOf;
import static org.eclipse.che.inject.Matchers.names;
-import static org.eclipse.che.multiuser.api.permission.server.SystemDomain.SYSTEM_DOMAIN_ACTIONS;
import com.auth0.jwk.JwkProvider;
import com.google.inject.AbstractModule;
@@ -65,6 +64,7 @@
import org.eclipse.che.api.workspace.server.WorkspaceEntityProvider;
import org.eclipse.che.api.workspace.server.devfile.DevfileModule;
import org.eclipse.che.api.workspace.server.hc.ServersCheckerFactory;
+import org.eclipse.che.api.workspace.server.jpa.WorkspaceJpaModule;
import org.eclipse.che.api.workspace.server.spi.provision.env.AgentAuthEnableEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiEnvVarProvider;
import org.eclipse.che.api.workspace.server.spi.provision.env.CheApiExternalEnvVarProvider;
@@ -270,6 +270,7 @@ protected void configure() {
install(new org.eclipse.che.security.oauth.GitLabModule());
install(new org.eclipse.che.security.oauth.AzureDevOpsModule());
install(new org.eclipse.che.security.oauth.GithubModule());
+ install(new WorkspaceJpaModule());
configureMultiUserMode(persistenceProperties, infrastructure);
@@ -315,33 +316,6 @@ private void configureMultiUserMode(
bind(KubernetesClientConfigFactory.class).to(KubernetesOidcProviderConfigFactory.class);
- persistenceProperties.put(
- PersistenceUnitProperties.EXCEPTION_HANDLER_CLASS,
- "org.eclipse.che.core.db.postgresql.jpa.eclipselink.PostgreSqlExceptionHandler");
-
- install(
- new org.eclipse.che.multiuser.permission.workspace.server.WorkspaceApiPermissionsModule());
- install(
- new org.eclipse.che.multiuser.permission.workspace.server.jpa
- .MultiuserWorkspaceJpaModule());
- install(
- new org.eclipse.che.multiuser.permission.devfile.server.jpa
- .MultiuserUserDevfileJpaModule());
- install(
- new org.eclipse.che.multiuser.permission.devfile.server.UserDevfileApiPermissionsModule());
-
- // Permission filters
- bind(org.eclipse.che.multiuser.permission.system.SystemServicePermissionsFilter.class);
- bind(org.eclipse.che.multiuser.permission.system.JvmServicePermissionsFilter.class);
- bind(
- org.eclipse.che.multiuser.permission.system.SystemEventsSubscriptionPermissionsCheck.class);
-
- Multibinder binder =
- Multibinder.newSetBinder(binder(), String.class, Names.named(SYSTEM_DOMAIN_ACTIONS));
- bind(org.eclipse.che.multiuser.permission.logger.LoggerServicePermissionsFilter.class);
-
- bind(org.eclipse.che.multiuser.permission.workspace.activity.ActivityPermissionsFilter.class);
-
bind(RequestTokenExtractor.class).to(HeaderRequestTokenExtractor.class);
if (isOpenShiftOAuthEnabled()) {
bind(AuthorizationChecker.class).to(OpenShiftAuthorizationCheckerImpl.class);
diff --git a/infrastructures/infrastructure-permission/pom.xml b/infrastructures/infrastructure-permission/pom.xml
index acf9c027b20..855397108af 100644
--- a/infrastructures/infrastructure-permission/pom.xml
+++ b/infrastructures/infrastructure-permission/pom.xml
@@ -42,10 +42,6 @@
org.eclipse.che.multiuserche-multiuser-api-permission
-
- org.eclipse.che.multiuser
- che-multiuser-permission-workspace
- ch.qos.logbacklogback-classic
diff --git a/infrastructures/infrastructure-permission/src/main/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilter.java b/infrastructures/infrastructure-permission/src/main/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilter.java
index 0251ae2277c..66f6679f672 100644
--- a/infrastructures/infrastructure-permission/src/main/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilter.java
+++ b/infrastructures/infrastructure-permission/src/main/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
+ * Copyright (c) 2012-2026 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -23,7 +23,6 @@
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;
import org.eclipse.che.multiuser.api.permission.server.jsonrpc.JsonRpcPermissionsFilterAdapter;
-import org.eclipse.che.multiuser.permission.workspace.server.WorkspaceDomain;
import org.eclipse.che.workspace.infrastructure.kubernetes.wsplugins.events.BrokerService;
/**
@@ -56,8 +55,7 @@ public void doAccept(String method, Object... params) throws ForbiddenException
}
Subject currentSubject = EnvironmentContext.getCurrent().getSubject();
- if (!currentSubject.hasPermission(
- WorkspaceDomain.DOMAIN_ID, workspaceId, WorkspaceDomain.RUN)) {
+ if (!currentSubject.hasPermission("workspace", workspaceId, "run")) {
throw new ForbiddenException(
"User doesn't have the required permissions to the specified workspace");
}
diff --git a/infrastructures/infrastructure-permission/src/test/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilterTest.java b/infrastructures/infrastructure-permission/src/test/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilterTest.java
index c2aede4190a..c7d54973f97 100644
--- a/infrastructures/infrastructure-permission/src/test/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilterTest.java
+++ b/infrastructures/infrastructure-permission/src/test/java/org/eclipse/che/multiuser/permission/workspace/infra/kubernetes/BrokerServicePermissionFilterTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
+ * Copyright (c) 2012-2026 Red Hat, Inc.
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -23,7 +23,6 @@
import org.eclipse.che.commons.env.EnvironmentContext;
import org.eclipse.che.commons.subject.Subject;
import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.permission.workspace.server.WorkspaceDomain;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.AfterMethod;
@@ -74,8 +73,7 @@ public void shouldRegisterItself() {
"User doesn't have the required permissions to the specified workspace")
public void shouldThrowExceptionIfUserDoesNotHaveRunPermission(String method) throws Exception {
// given
- when(subject.hasPermission(eq(WorkspaceDomain.DOMAIN_ID), eq("ws123"), eq(WorkspaceDomain.RUN)))
- .thenReturn(false);
+ when(subject.hasPermission(eq("workspace"), eq("ws123"), eq("run"))).thenReturn(false);
// when
permissionFilter.doAccept(
@@ -87,8 +85,7 @@ public void shouldThrowExceptionIfUserDoesNotHaveRunPermission(String method) th
@Test(dataProvider = "coveredMethods")
public void shouldDoNothingIfUserHasRunPermissions(String method) throws Exception {
// given
- when(subject.hasPermission(WorkspaceDomain.DOMAIN_ID, "ws123", WorkspaceDomain.RUN))
- .thenReturn(true);
+ when(subject.hasPermission("workspace", "ws123", "run")).thenReturn(true);
// when
permissionFilter.doAccept(
diff --git a/infrastructures/infrastructure-permission/src/test/resources/logback-test.xml b/infrastructures/infrastructure-permission/src/test/resources/logback-test.xml
index c7a7b0b5cf3..c7107c8a4f7 100644
--- a/infrastructures/infrastructure-permission/src/test/resources/logback-test.xml
+++ b/infrastructures/infrastructure-permission/src/test/resources/logback-test.xml
@@ -1,7 +1,7 @@
-
- 4.0.0
-
- che-multiuser-api
- org.eclipse.che.multiuser
- 7.117.0-SNAPSHOT
-
- che-multiuser-api-organization-shared
- jar
- Che Multiuser :: Organization :: Shared
-
-
- org.eclipse.che.core
- che-core-api-core
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-api-model
-
-
- org.eclipse.che.core
- che-core-api-user-shared
-
-
- org.eclipse.che.core
- che-core-commons-annotations
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-resource-shared
-
-
-
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/Constants.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/Constants.java
deleted file mode 100644
index d66ac852061..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/Constants.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared;
-
-/**
- * Constants for Organization API
- *
- * @author Sergii Leschenko
- */
-public final class Constants {
- public static final String LINK_REL_SELF = "self";
- public static final String LINK_REL_SUBORGANIZATIONS = "organization.suborganizations";
-
- private Constants() {}
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberAddedEventDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberAddedEventDto.java
deleted file mode 100644
index 0c1e8b8b9f6..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberAddedEventDto.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import org.eclipse.che.api.core.notification.EventOrigin;
-import org.eclipse.che.api.user.shared.dto.UserDto;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-
-/**
- * DTO for member added event.
- *
- * @author Anton Korneta
- */
-@DTO
-@EventOrigin("organization")
-public interface MemberAddedEventDto extends OrganizationEventDto {
-
- @Override
- MemberAddedEventDto withOrganization(OrganizationDto organization);
-
- @Override
- MemberAddedEventDto withType(EventType eventType);
-
- UserDto getMember();
-
- void setMember(UserDto member);
-
- MemberAddedEventDto withMember(UserDto member);
-
- /** Returns name of user who initiated member invitation */
- String getInitiator();
-
- void setInitiator(String initiator);
-
- MemberAddedEventDto withInitiator(String initiator);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberRemovedEventDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberRemovedEventDto.java
deleted file mode 100644
index 293b15dd8ba..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/MemberRemovedEventDto.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import org.eclipse.che.api.core.notification.EventOrigin;
-import org.eclipse.che.api.user.shared.dto.UserDto;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-
-/**
- * DTO for organization member removed event.
- *
- * @author Anton Korneta
- */
-@DTO
-@EventOrigin("organization")
-public interface MemberRemovedEventDto extends OrganizationEventDto {
-
- @Override
- MemberRemovedEventDto withOrganization(OrganizationDto organization);
-
- @Override
- MemberRemovedEventDto withType(EventType eventType);
-
- UserDto getMember();
-
- void setMember(UserDto member);
-
- MemberRemovedEventDto withMember(UserDto member);
-
- /** Returns name of user who initiated member removal */
- String getInitiator();
-
- void setInitiator(String initiator);
-
- MemberRemovedEventDto withInitiator(String initiator);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDistributedResourcesDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDistributedResourcesDto.java
deleted file mode 100644
index 9093f969b10..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDistributedResourcesDto.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface OrganizationDistributedResourcesDto extends OrganizationDistributedResources {
- @Override
- String getOrganizationId();
-
- void setOrganizationId(String organizationId);
-
- OrganizationDistributedResourcesDto withOrganizationId(String organizationId);
-
- @Override
- List getResourcesCap();
-
- void setResourcesCap(List resourcesCap);
-
- OrganizationDistributedResourcesDto withResourcesCap(List resourcesCap);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDto.java
deleted file mode 100644
index ae99d425361..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationDto.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.api.core.rest.shared.dto.Hyperlinks;
-import org.eclipse.che.api.core.rest.shared.dto.Link;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface OrganizationDto extends Organization, Hyperlinks {
- @Override
- String getId();
-
- void setId(String id);
-
- OrganizationDto withId(String id);
-
- @Override
- String getName();
-
- void setName(String name);
-
- OrganizationDto withName(String name);
-
- @Override
- String getQualifiedName();
-
- void setQualifiedName(String qualifiedName);
-
- OrganizationDto withQualifiedName(String qualifiedName);
-
- @Override
- String getParent();
-
- void setParent(String parent);
-
- OrganizationDto withParent(String parent);
-
- @Override
- OrganizationDto withLinks(List links);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationEventDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationEventDto.java
deleted file mode 100644
index deea6789ee7..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationEventDto.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import org.eclipse.che.api.core.notification.EventOrigin;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-import org.eclipse.che.multiuser.organization.shared.event.OrganizationEvent;
-
-/**
- * DTO for {@link OrganizationEvent}.
- *
- * @author Anton Korneta
- */
-@DTO
-@EventOrigin("organization")
-public interface OrganizationEventDto extends OrganizationEvent {
-
- @Override
- OrganizationDto getOrganization();
-
- void setOrganization(OrganizationDto organization);
-
- OrganizationEventDto withOrganization(OrganizationDto organization);
-
- void setType(EventType eventType);
-
- OrganizationEventDto withType(EventType eventType);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRemovedEventDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRemovedEventDto.java
deleted file mode 100644
index 5e996a6bf06..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRemovedEventDto.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.api.core.notification.EventOrigin;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-
-/**
- * DTO for organization removed event.
- *
- * @author Anton Korneta
- */
-@DTO
-@EventOrigin("organization")
-public interface OrganizationRemovedEventDto extends OrganizationEventDto {
-
- @Override
- OrganizationRemovedEventDto withOrganization(OrganizationDto organization);
-
- @Override
- OrganizationRemovedEventDto withType(EventType eventType);
-
- /** Returns name of user who initiated organization removal */
- String getInitiator();
-
- void setInitiator(String initiator);
-
- OrganizationRemovedEventDto withInitiator(String initiator);
-
- List getMembers();
-
- void setMembers(List members);
-
- OrganizationRemovedEventDto withMembers(List members);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRenamedEventDto.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRenamedEventDto.java
deleted file mode 100644
index bb9b27faf44..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/dto/OrganizationRenamedEventDto.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.dto;
-
-import org.eclipse.che.api.core.notification.EventOrigin;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-
-/**
- * DTO for organization renamed event.
- *
- * @author Anton Korneta
- */
-@DTO
-@EventOrigin("organization")
-public interface OrganizationRenamedEventDto extends OrganizationEventDto {
-
- @Override
- OrganizationRenamedEventDto withOrganization(OrganizationDto organization);
-
- @Override
- OrganizationRenamedEventDto withType(EventType eventType);
-
- /** Returns organization name before renaming */
- String getOldName();
-
- void setOldName(String oldName);
-
- OrganizationRenamedEventDto withOldName(String oldName);
-
- /** Returns organization name after renaming */
- String getNewName();
-
- void setNewName(String newName);
-
- OrganizationRenamedEventDto withNewName(String newName);
-
- /** Returns name of user who initiated organization rename */
- String getInitiator();
-
- void setInitiator(String initiator);
-
- OrganizationRenamedEventDto withInitiator(String initiator);
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/EventType.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/EventType.java
deleted file mode 100644
index ce734a2e4e7..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/EventType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.event;
-
-/**
- * Defines organizations event types.
- *
- * @author Anton Korneta
- */
-public enum EventType {
-
- /** Published when organization name changed. */
- ORGANIZATION_RENAMED,
-
- /** Published when organization removed. */
- ORGANIZATION_REMOVED,
-
- /** Published when new member added to organization. */
- MEMBER_ADDED,
-
- /** Published when member removed from organization. */
- MEMBER_REMOVED
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/MemberEvent.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/MemberEvent.java
deleted file mode 100644
index 27c36840ba0..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/MemberEvent.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.event;
-
-import org.eclipse.che.api.core.model.user.User;
-
-/**
- * Defines organization member event.
- *
- * @author Anton Korneta
- */
-public interface MemberEvent extends OrganizationEvent {
-
- /** Returns the member associated with this event. */
- User getMember();
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/OrganizationEvent.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/OrganizationEvent.java
deleted file mode 100644
index 1956c705ffc..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/event/OrganizationEvent.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.event;
-
-import org.eclipse.che.commons.annotation.Nullable;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * The base interface for organization event.
- *
- * @author Anton Korneta
- */
-public interface OrganizationEvent {
-
- /** Returns organization related to this event. */
- Organization getOrganization();
-
- /** Returns type of this event. */
- EventType getType();
-
- /** Returns name of user who acted with organization or null if user is undefined. */
- @Nullable
- String getInitiator();
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Member.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Member.java
deleted file mode 100644
index b4f0c66b592..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Member.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.model;
-
-import java.util.List;
-
-/**
- * Describes relations of user and organization
- *
- * @author gazarenkov
- * @author Sergii Leschenko
- */
-public interface Member {
- /** Returns id of user */
- String getUserId();
-
- /** Returns id of organization */
- String getOrganizationId();
-
- /** Returns list of actions that user can perform in organization */
- List getActions();
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Organization.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Organization.java
deleted file mode 100644
index 60946cf274b..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/Organization.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.model;
-
-import org.eclipse.che.commons.annotation.Nullable;
-
-/**
- * Describes group of users that can use common resources
- *
- * @author gazarenkov
- * @author Sergii Leschenko
- */
-public interface Organization {
-
- /**
- * Returns the identifier of the organization (e.g. "organization0x1234567890"). The identifier
- * value is unique and mandatory.
- */
- String getId();
-
- /**
- * Returns name of organization. The name is mandatory and updatable. The name is unique per
- * parent organization.
- */
- String getName();
-
- /**
- * Returns the qualified name that includes all parent's names and the name of current
- * organization separated by '/' symbol e.g. "parentOrgName/subOrgName/subSubOrgName". The
- * qualified name is unique.
- */
- String getQualifiedName();
-
- /**
- * Returns id of parent organization. The returned value can be nullable in case when organization
- * is root
- */
- @Nullable
- String getParent();
-}
diff --git a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/OrganizationDistributedResources.java b/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/OrganizationDistributedResources.java
deleted file mode 100644
index 4605d94f868..00000000000
--- a/multiuser/api/che-multiuser-api-organization-shared/src/main/java/org/eclipse/che/multiuser/organization/shared/model/OrganizationDistributedResources.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.shared.model;
-
-import java.util.List;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Defines resources which are distributed for suborganization by parent organization
- *
- * @author Sergii Leschenko
- */
-public interface OrganizationDistributedResources {
- /** Id of organization that owns these distributed resources */
- String getOrganizationId();
-
- /**
- * Returns resources cap that limit usage of parent organization's resources.
- *
- *
Note that suborganization is not limited to use parent organization's resources if resource
- * is not capped.
- */
- List extends Resource> getResourcesCap();
-}
diff --git a/multiuser/api/che-multiuser-api-organization/pom.xml b/multiuser/api/che-multiuser-api-organization/pom.xml
deleted file mode 100644
index 6f2eb8c0cf9..00000000000
--- a/multiuser/api/che-multiuser-api-organization/pom.xml
+++ /dev/null
@@ -1,308 +0,0 @@
-
-
-
- 4.0.0
-
- che-multiuser-api
- org.eclipse.che.multiuser
- 7.117.0-SNAPSHOT
-
- che-multiuser-api-organization
- jar
- Che Multiuser :: Organization
-
- ${project.build.directory}/generated-sources/dto/
-
-
-
- com.google.code.gson
- gson
-
-
- com.google.guava
- guava
-
-
- com.google.inject
- guice
-
-
- com.google.inject.extensions
- guice-persist
-
-
- io.swagger.core.v3
- swagger-annotations-jakarta
-
-
- jakarta.annotation
- jakarta.annotation-api
-
-
- jakarta.inject
- jakarta.inject-api
-
-
- jakarta.ws.rs
- jakarta.ws.rs-api
-
-
- org.eclipse.che.core
- che-core-api-account
-
-
- org.eclipse.che.core
- che-core-api-core
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-api-model
-
-
- org.eclipse.che.core
- che-core-api-user
-
-
- org.eclipse.che.core
- che-core-api-user-shared
-
-
- org.eclipse.che.core
- che-core-commons-annotations
-
-
- org.eclipse.che.core
- che-core-commons-lang
-
-
- org.eclipse.che.core
- che-core-commons-test
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-organization-shared
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-permission
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-permission-shared
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-resource
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-resource-shared
-
-
- org.eclipse.persistence
- jakarta.persistence
-
-
- org.everrest
- everrest-core
-
-
- org.slf4j
- slf4j-api
-
-
- jakarta.websocket
- jakarta.websocket-api
- provided
-
-
- ch.qos.logback
- logback-classic
- test
-
-
- commons-fileupload
- commons-fileupload
- test
-
-
- io.rest-assured
- rest-assured
- test
-
-
- org.eclipse.che.core
- che-core-sql-schema
- test
-
-
- org.eclipse.che.multiuser
- che-multiuser-sql-schema
- test
-
-
- org.eclipse.persistence
- org.eclipse.persistence.core
- test
-
-
- org.eclipse.persistence
- org.eclipse.persistence.jpa
- test
-
-
- org.everrest
- everrest-assured
- test
-
-
- org.hamcrest
- hamcrest
- test
-
-
- org.mockito
- mockito-core
- test
-
-
- org.mockito
- mockito-testng
- test
-
-
- org.testng
- testng
- test
-
-
-
-
-
- org.eclipse.che.core
- che-core-api-dto-maven-plugin
- ${project.version}
-
-
- process-sources
-
- generate
-
-
-
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-organization-shared
- ${project.version}
-
-
-
-
- org.eclipse.che.multiuser.organization.shared.dto
-
- ${dto-generator-out-directory}
- org.eclipse.che.multiuser.organization.api.dto.DtoServerImpls
- server
-
-
-
- maven-compiler-plugin
-
-
- pre-compile
- generate-sources
-
- compile
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
-
-
- add-domain
- process-sources
-
- add-resource
-
-
-
-
- ${dto-generator-out-directory}/META-INF
- META-INF
-
-
-
-
-
- add-source
- process-sources
-
- add-source
-
-
-
- ${dto-generator-out-directory}
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
-
-
- test-jar
-
-
-
- **/spi/tck/*.*
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- resource-dependencies
- process-test-resources
-
- unpack-dependencies
-
-
- che-core-sql-schema,
- che-multiuser-sql-schema
- che-schema/
- ${project.build.directory}
-
-
-
-
-
-
-
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/DtoConverter.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/DtoConverter.java
deleted file mode 100644
index 0bb08f445b4..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/DtoConverter.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static org.eclipse.che.dto.server.DtoFactory.newDto;
-
-import java.util.stream.Collectors;
-import org.eclipse.che.multiuser.organization.api.event.MemberAddedEvent;
-import org.eclipse.che.multiuser.organization.api.event.MemberRemovedEvent;
-import org.eclipse.che.multiuser.organization.api.event.OrganizationRemovedEvent;
-import org.eclipse.che.multiuser.organization.api.event.OrganizationRenamedEvent;
-import org.eclipse.che.multiuser.organization.shared.dto.MemberAddedEventDto;
-import org.eclipse.che.multiuser.organization.shared.dto.MemberRemovedEventDto;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDistributedResourcesDto;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationEventDto;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationRemovedEventDto;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationRenamedEventDto;
-import org.eclipse.che.multiuser.organization.shared.event.OrganizationEvent;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-
-/**
- * Helps to convert objects related to organization to DTOs.
- *
- * @author Sergii Leschenko
- */
-public final class DtoConverter {
- private DtoConverter() {}
-
- public static OrganizationDto asDto(Organization organization) {
- return newDto(OrganizationDto.class)
- .withId(organization.getId())
- .withName(organization.getName())
- .withQualifiedName(organization.getQualifiedName())
- .withParent(organization.getParent());
- }
-
- public static OrganizationDistributedResourcesDto asDto(
- OrganizationDistributedResources distributedResources) {
- return newDto(OrganizationDistributedResourcesDto.class)
- .withOrganizationId(distributedResources.getOrganizationId())
- .withResourcesCap(
- distributedResources.getResourcesCap().stream()
- .map(org.eclipse.che.multiuser.resource.api.DtoConverter::asDto)
- .collect(Collectors.toList()));
- }
-
- public static OrganizationRemovedEventDto asDto(OrganizationRemovedEvent event) {
- return newDto(OrganizationRemovedEventDto.class)
- .withType(event.getType())
- .withOrganization(asDto(event.getOrganization()))
- .withMembers(event.getMembers())
- .withInitiator(event.getInitiator());
- }
-
- public static OrganizationRenamedEventDto asDto(OrganizationRenamedEvent event) {
- return newDto(OrganizationRenamedEventDto.class)
- .withType(event.getType())
- .withOrganization(asDto(event.getOrganization()))
- .withOldName(event.getOldName())
- .withNewName(event.getNewName())
- .withInitiator(event.getInitiator());
- }
-
- public static MemberAddedEventDto asDto(MemberAddedEvent event) {
- return newDto(MemberAddedEventDto.class)
- .withType(event.getType())
- .withOrganization(asDto(event.getOrganization()))
- .withInitiator(event.getInitiator())
- .withMember(org.eclipse.che.api.user.server.DtoConverter.asDto(event.getMember()));
- }
-
- public static MemberRemovedEventDto asDto(MemberRemovedEvent event) {
- return newDto(MemberRemovedEventDto.class)
- .withType(event.getType())
- .withOrganization(asDto(event.getOrganization()))
- .withInitiator((event.getInitiator()))
- .withMember(org.eclipse.che.api.user.server.DtoConverter.asDto(event.getMember()));
- }
-
- public static OrganizationEventDto asDto(OrganizationEvent event) {
- switch (event.getType()) {
- case ORGANIZATION_RENAMED:
- return asDto((OrganizationRenamedEvent) event);
- case ORGANIZATION_REMOVED:
- return asDto((OrganizationRemovedEvent) event);
- case MEMBER_ADDED:
- return asDto((MemberAddedEvent) event);
- case MEMBER_REMOVED:
- return asDto((MemberRemovedEvent) event);
- default:
- throw new IllegalArgumentException(
- "Can't convert event to dto, event type '" + event.getType() + "' is unknown");
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationApiModule.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationApiModule.java
deleted file mode 100644
index 5da9b999196..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationApiModule.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.multibindings.MapBinder;
-import com.google.inject.multibindings.Multibinder;
-import com.google.inject.name.Names;
-import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
-import org.eclipse.che.multiuser.api.permission.server.account.AccountPermissionsChecker;
-import org.eclipse.che.multiuser.api.permission.shared.model.PermissionsDomain;
-import org.eclipse.che.multiuser.organization.api.listener.MemberEventsPublisher;
-import org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationPermissionsFilter;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationRemoteSubscriptionPermissionsChecks;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationResourceDistributionServicePermissionsFilter;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationalAccountPermissionsChecker;
-import org.eclipse.che.multiuser.organization.api.resource.DefaultOrganizationResourcesProvider;
-import org.eclipse.che.multiuser.organization.api.resource.OrganizationResourceLockKeyProvider;
-import org.eclipse.che.multiuser.organization.api.resource.OrganizationalAccountAvailableResourcesProvider;
-import org.eclipse.che.multiuser.organization.api.resource.SuborganizationResourcesProvider;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.ResourceLockKeyProvider;
-import org.eclipse.che.multiuser.resource.api.ResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.free.DefaultResourcesProvider;
-
-/**
- * @author Sergii Leschenko
- */
-public class OrganizationApiModule extends AbstractModule {
- @Override
- protected void configure() {
-
- bind(OrganizationPermissionsFilter.class);
- bind(OrganizationRemoteSubscriptionPermissionsChecks.class);
-
- Multibinder.newSetBinder(binder(), DefaultResourcesProvider.class)
- .addBinding()
- .to(DefaultOrganizationResourcesProvider.class);
-
- Multibinder.newSetBinder(binder(), ResourcesProvider.class)
- .addBinding()
- .to(SuborganizationResourcesProvider.class);
-
- MapBinder.newMapBinder(binder(), String.class, AvailableResourcesProvider.class)
- .addBinding(OrganizationImpl.ORGANIZATIONAL_ACCOUNT)
- .to(OrganizationalAccountAvailableResourcesProvider.class);
-
- Multibinder.newSetBinder(binder(), ResourceLockKeyProvider.class)
- .addBinding()
- .to(OrganizationResourceLockKeyProvider.class);
-
- Multibinder.newSetBinder(binder(), AccountPermissionsChecker.class)
- .addBinding()
- .to(OrganizationalAccountPermissionsChecker.class);
-
- bind(OrganizationResourceDistributionServicePermissionsFilter.class);
-
- bind(OrganizationEventsWebsocketBroadcaster.class).asEagerSingleton();
- bind(MemberEventsPublisher.class).asEagerSingleton();
-
- Multibinder.newSetBinder(
- binder(),
- PermissionsDomain.class,
- Names.named(SuperPrivilegesChecker.SUPER_PRIVILEGED_DOMAINS))
- .addBinding()
- .to(OrganizationDomain.class);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationJpaModule.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationJpaModule.java
deleted file mode 100644
index 7390df2c064..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationJpaModule.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.TypeLiteral;
-import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
-
-/**
- * @author Sergii Leschenko
- */
-public class OrganizationJpaModule extends AbstractModule {
- @Override
- protected void configure() {
-
- bind(new TypeLiteral>() {}).to(OrganizationDomain.class);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjector.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjector.java
deleted file mode 100644
index aba39ac11ab..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import jakarta.ws.rs.HttpMethod;
-import jakarta.ws.rs.core.UriBuilder;
-import java.util.ArrayList;
-import java.util.List;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.rest.ServiceContext;
-import org.eclipse.che.api.core.rest.shared.dto.Link;
-import org.eclipse.che.api.core.util.LinksHelper;
-import org.eclipse.che.multiuser.organization.shared.Constants;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-
-/**
- * Helps to inject {@link OrganizationService} related links.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class OrganizationLinksInjector {
- public OrganizationDto injectLinks(
- OrganizationDto organizationDto, ServiceContext serviceContext) {
- final UriBuilder uriBuilder = serviceContext.getBaseUriBuilder();
- final List links = new ArrayList<>(2);
- links.add(
- LinksHelper.createLink(
- HttpMethod.GET,
- uriBuilder
- .clone()
- .path(OrganizationService.class)
- .path(OrganizationService.class, "getById")
- .build(organizationDto.getId())
- .toString(),
- null,
- APPLICATION_JSON,
- Constants.LINK_REL_SELF));
- links.add(
- LinksHelper.createLink(
- HttpMethod.GET,
- uriBuilder
- .clone()
- .path(OrganizationService.class)
- .path(OrganizationService.class, "getByParent")
- .build(organizationDto.getId())
- .toString(),
- null,
- APPLICATION_JSON,
- Constants.LINK_REL_SUBORGANIZATIONS));
- return organizationDto.withLinks(links);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationManager.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationManager.java
deleted file mode 100644
index 2bebedbf1fa..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationManager.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static java.util.Objects.requireNonNull;
-import static org.eclipse.che.multiuser.organization.api.DtoConverter.asDto;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Sets;
-import com.google.inject.persist.Transactional;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ApiException;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.Pages;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.notification.EventService;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.lang.NameGenerator;
-import org.eclipse.che.multiuser.organization.api.event.OrganizationRemovedEvent;
-import org.eclipse.che.multiuser.organization.api.event.OrganizationRenamedEvent;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.shared.model.Member;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.MemberDao;
-import org.eclipse.che.multiuser.organization.spi.OrganizationDao;
-import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-
-/**
- * Facade for Organization related operations.
- *
- * @author gazarenkov
- * @author Sergii Leschenko
- */
-@Singleton
-public class OrganizationManager {
-
- private final EventService eventService;
- private final OrganizationDao organizationDao;
- private final MemberDao memberDao;
- private final Set reservedNames;
-
- @Inject
- public OrganizationManager(
- EventService eventService,
- OrganizationDao organizationDao,
- MemberDao memberDao,
- @Named("che.auth.reserved_user_names") String[] reservedNames) {
- this.eventService = eventService;
- this.organizationDao = organizationDao;
- this.memberDao = memberDao;
- this.reservedNames = Sets.newHashSet(reservedNames);
- }
-
- /**
- * Creates new organization.
- *
- * @param newOrganization organization to create
- * @return created organization
- * @throws NullPointerException when {@code organization} is null
- * @throws NotFoundException when parent organization was not found
- * @throws ConflictException when organization with such id/name already exists
- * @throws ConflictException when specified organization name is reserved
- * @throws ServerException when any other error occurs during organization creation
- */
- @Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
- public Organization create(Organization newOrganization)
- throws NotFoundException, ConflictException, ServerException {
- requireNonNull(newOrganization, "Required non-null organization");
- requireNonNull(newOrganization.getName(), "Required non-null organization name");
-
- String qualifiedName;
- if (newOrganization.getParent() != null) {
- final Organization parent = getById(newOrganization.getParent());
- qualifiedName = parent.getQualifiedName() + "/" + newOrganization.getName();
- } else {
- qualifiedName = newOrganization.getName();
- }
- checkNameReservation(qualifiedName);
-
- final OrganizationImpl organization =
- new OrganizationImpl(
- NameGenerator.generate("organization", 16), qualifiedName, newOrganization.getParent());
- organizationDao.create(organization);
- addFirstMember(organization);
- return organization;
- }
-
- /**
- * Updates organization with new entity.
- *
- * @param organizationId id of organization to update
- * @param update organization update
- * @throws NullPointerException when {@code organizationId} or {@code update} is null
- * @throws NotFoundException when organization with given id doesn't exist
- * @throws ConflictException when name updated with a value which is reserved or is not unique
- * @throws ServerException when any other error occurs organization updating
- */
- @Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
- public Organization update(String organizationId, Organization update)
- throws NotFoundException, ConflictException, ServerException {
- requireNonNull(organizationId, "Required non-null organization id");
- requireNonNull(update, "Required non-null organization");
- requireNonNull(update.getName(), "Required non-null organization name");
-
- final OrganizationImpl organization = organizationDao.getById(organizationId);
- final String oldQualifiedName = organization.getQualifiedName();
- final String oldName = organization.getName();
-
- final String newName = update.getName();
- final String newQualifiedName = buildQualifiedName(oldQualifiedName, update.getName());
-
- checkNameReservation(newQualifiedName);
- organization.setQualifiedName(newQualifiedName);
-
- organizationDao.update(organization);
- if (!newName.equals(oldName)) {
- updateSuborganizationsQualifiedNames(oldQualifiedName, organization.getQualifiedName());
-
- final String performerName = EnvironmentContext.getCurrent().getSubject().getUserName();
- // should be DTO as it sent via json rpc
- eventService.publish(
- asDto(new OrganizationRenamedEvent(performerName, oldName, newName, organization)));
- }
- return organization;
- }
-
- /**
- * Removes organization with given id
- *
- * @param organizationId organization id
- * @throws NullPointerException when {@code organizationId} is null
- * @throws ServerException when any other error occurs during organization removing
- */
- @Transactional(rollbackOn = {RuntimeException.class, ApiException.class})
- public void remove(String organizationId) throws ServerException {
- requireNonNull(organizationId, "Required non-null organization id");
- try {
- OrganizationImpl organization = organizationDao.getById(organizationId);
- removeSuborganizations(organizationId);
- final List members = removeMembers(organizationId);
- organizationDao.remove(organizationId);
- final String initiator = EnvironmentContext.getCurrent().getSubject().getUserName();
- eventService.publish(asDto(new OrganizationRemovedEvent(initiator, organization, members)));
- } catch (NotFoundException e) {
- // organization is already removed
- }
- }
-
- /**
- * Gets organization by identifier.
- *
- * @param organizationId organization id
- * @return organization instance
- * @throws NullPointerException when {@code organizationId} is null
- * @throws NotFoundException when organization with given id was not found
- * @throws ServerException when any other error occurs during organization fetching
- */
- public Organization getById(String organizationId) throws NotFoundException, ServerException {
- requireNonNull(organizationId, "Required non-null organization id");
- return organizationDao.getById(organizationId);
- }
-
- /**
- * Gets organization by name.
- *
- * @param organizationName organization name
- * @return organization instance
- * @throws NullPointerException when {@code organizationName} is null
- * @throws NotFoundException when organization with given name was not found
- * @throws ServerException when any other error occurs during organization fetching
- */
- public Organization getByName(String organizationName) throws NotFoundException, ServerException {
- requireNonNull(organizationName, "Required non-null organization name");
- return organizationDao.getByName(organizationName);
- }
-
- /**
- * Gets child organizations by given parent.
- *
- * @param parent id of parent organizations
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of children organizations
- * @throws NullPointerException when {@code parent} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- public Page extends Organization> getByParent(String parent, int maxItems, long skipCount)
- throws ServerException {
- requireNonNull(parent, "Required non-null parent");
- return organizationDao.getByParent(parent, maxItems, skipCount);
- }
-
- /**
- * Gets all child organizations by specified parent qualified name.
- *
- *
Note that the result will includes all direct and nested suborganizations.
- *
- * @param parentQualifiedName qualified name of parent organization
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of children organizations
- * @throws NullPointerException when {@code parentQualifiedName} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- public Page getSuborganizations(
- String parentQualifiedName, int maxItems, long skipCount) throws ServerException {
- requireNonNull(parentQualifiedName, "Required non-null parent qualified name");
- return organizationDao.getSuborganizations(parentQualifiedName, maxItems, skipCount);
- }
-
- /**
- * Gets list organizations where user is member.
- *
- * @param userId user id
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of organizations where user is member
- * @throws NullPointerException when {@code userId} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- public Page extends Organization> getByMember(String userId, int maxItems, int skipCount)
- throws ServerException {
- requireNonNull(userId, "Required non-null user id");
- return memberDao.getOrganizations(userId, maxItems, skipCount);
- }
-
- private String buildQualifiedName(String oldQualifiedName, String newName) {
- int lastSlashIndex = oldQualifiedName.lastIndexOf("/");
- if (lastSlashIndex != -1) { // check that it is not root organization
- return oldQualifiedName.substring(0, lastSlashIndex + 1) + newName;
- } else {
- return newName;
- }
- }
-
- private void updateSuborganizationsQualifiedNames(
- String oldQualifiedName, String newQualifiedName)
- throws NotFoundException, ConflictException, ServerException {
- for (OrganizationImpl suborganization :
- Pages.iterate(
- (maxItems, skipCount) ->
- organizationDao.getSuborganizations(oldQualifiedName, maxItems, skipCount))) {
- suborganization.setQualifiedName(
- suborganization.getQualifiedName().replaceFirst(oldQualifiedName, newQualifiedName));
- organizationDao.update(suborganization);
- }
- }
-
- /**
- * Gets list of members by specified organization id.
- *
- * @param organizationId organization identifier
- * @param maxItems the maximum number of members to return
- * @param skipCount the number of members to skip
- * @return list of members
- * @throws NullPointerException when {@code organizationId} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- public Page extends Member> getMembers(String organizationId, int maxItems, long skipCount)
- throws ServerException {
- requireNonNull(organizationId, "Required non-null organization id");
- return memberDao.getMembers(organizationId, maxItems, skipCount);
- }
-
- protected void addFirstMember(Organization organization) throws ServerException {
- memberDao.store(
- new MemberImpl(
- EnvironmentContext.getCurrent().getSubject().getUserId(),
- organization.getId(),
- OrganizationDomain.getActions()));
- }
-
- /**
- * Removes suborganizations of given parent organization page by page
- *
- * @param organizationId parent organization id
- */
- @VisibleForTesting
- void removeSuborganizations(String organizationId) throws ServerException {
- Page extends Organization> suborganizationsPage;
- do {
- // skip count always equals to 0 because elements will be shifted after removing previous
- // items
- suborganizationsPage = organizationDao.getByParent(organizationId, 100, 0);
- for (Organization suborganization : suborganizationsPage.getItems()) {
- remove(suborganization.getId());
- }
- } while (suborganizationsPage.hasNextPage());
- }
-
- @VisibleForTesting
- List removeMembers(String organizationId) throws ServerException {
- List removed = new ArrayList<>();
- Page membersPage;
- do {
- // skip count always equals to 0 because elements will be shifted after removing previous
- // items
- membersPage = memberDao.getMembers(organizationId, 100, 0);
- for (MemberImpl member : membersPage.getItems()) {
- removed.add(member.getUserId());
- memberDao.remove(member.getUserId(), member.getOrganizationId());
- }
- } while (membersPage.hasNextPage());
- return removed;
- }
-
- /**
- * Checks reservation of organization name
- *
- * @param organizationName organization name to check
- * @throws ConflictException when organization name is reserved and can be used by user
- */
- private void checkNameReservation(String organizationName) throws ConflictException {
- if (reservedNames.contains(organizationName.toLowerCase())) {
- throw new ConflictException(
- String.format("Organization name '%s' is reserved", organizationName));
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationService.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationService.java
deleted file mode 100644
index 904ed21bab9..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationService.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.eclipse.che.multiuser.organization.api.DtoConverter.asDto;
-
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.media.ArraySchema;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DELETE;
-import jakarta.ws.rs.DefaultValue;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.Response;
-import javax.inject.Inject;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.rest.Service;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Defines Organization REST API.
- *
- * @author Sergii Leschenko
- */
-@Tag(name = "organization", description = "Organization REST API")
-@Path("/organization")
-public class OrganizationService extends Service {
- private final OrganizationManager organizationManager;
- private final OrganizationLinksInjector linksInjector;
- private final OrganizationValidator organizationValidator;
-
- @Inject
- public OrganizationService(
- OrganizationManager organizationManager,
- OrganizationLinksInjector linksInjector,
- OrganizationValidator organizationValidator) {
- this.organizationManager = organizationManager;
- this.linksInjector = linksInjector;
- this.organizationValidator = organizationValidator;
- }
-
- @POST
- @Consumes(APPLICATION_JSON)
- @Produces(APPLICATION_JSON)
- @Operation(
- summary = "Create new organization",
- responses = {
- @ApiResponse(
- responseCode = "201",
- description = "The organization successfully created",
- content = @Content(schema = @Schema(implementation = OrganizationDto.class))),
- @ApiResponse(
- responseCode = "400",
- description = "Missed required parameters, parameters are not valid"),
- @ApiResponse(
- responseCode = "409",
- description =
- "Conflict error occurred during the organization creation"
- + "(e.g. The organization with such name already exists)"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public Response create(
- @Parameter(description = "Organization to create", required = true)
- OrganizationDto organization)
- throws BadRequestException, NotFoundException, ConflictException, ServerException {
- organizationValidator.checkOrganization(organization);
- return Response.status(201)
- .entity(
- linksInjector.injectLinks(
- asDto(organizationManager.create(organization)), getServiceContext()))
- .build();
- }
-
- @POST
- @Path("/{id}")
- @Consumes(APPLICATION_JSON)
- @Produces(APPLICATION_JSON)
- @Operation(
- summary = "Update organization",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "The organization successfully updated",
- content = @Content(schema = @Schema(implementation = OrganizationDto.class))),
- @ApiResponse(
- responseCode = "400",
- description = "Missed required parameters, parameters are not valid"),
- @ApiResponse(
- responseCode = "404",
- description = "The organization with given id was not found"),
- @ApiResponse(
- responseCode = "409",
- description =
- "Conflict error occurred during the organization creation"
- + "(e.g. The organization with such name already exists)"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public OrganizationDto update(
- @Parameter(description = "Organization id") @PathParam("id") String organizationId,
- @Parameter(description = "Organization to update", required = true)
- OrganizationDto organization)
- throws BadRequestException, ConflictException, NotFoundException, ServerException {
- organizationValidator.checkOrganization(organization);
- return linksInjector.injectLinks(
- asDto(organizationManager.update(organizationId, organization)), getServiceContext());
- }
-
- @DELETE
- @Path("/{id}")
- @Operation(
- summary = "Remove organization with given id",
- responses = {
- @ApiResponse(responseCode = "204", description = "The organization successfully removed"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public void remove(
- @Parameter(description = "Organization id") @PathParam("id") String organization)
- throws ServerException {
- organizationManager.remove(organization);
- }
-
- @GET
- @Produces(APPLICATION_JSON)
- @Path("/{organizationId}")
- @Operation(
- summary = "Get organization by id",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "The organization successfully fetched",
- content = @Content(schema = @Schema(implementation = OrganizationDto.class))),
- @ApiResponse(
- responseCode = "404",
- description = "The organization with given id was not found"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public OrganizationDto getById(
- @Parameter(description = "Organization id") @PathParam("organizationId")
- String organizationId)
- throws NotFoundException, ServerException {
- return linksInjector.injectLinks(
- asDto(organizationManager.getById(organizationId)), getServiceContext());
- }
-
- @GET
- @Produces(APPLICATION_JSON)
- @Path("/find")
- @Operation(
- summary = "Find organization by name",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "The organization successfully fetched",
- content = @Content(schema = @Schema(implementation = OrganizationDto.class))),
- @ApiResponse(
- responseCode = "400",
- description = "Missed required parameters, parameters are not valid"),
- @ApiResponse(
- responseCode = "404",
- description = "The organization with given name was not found"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public OrganizationDto find(
- @Parameter(description = "Organization name", required = true) @QueryParam("name")
- String organizationName)
- throws NotFoundException, ServerException, BadRequestException {
- checkArgument(organizationName != null, "Missed organization's name");
- return linksInjector.injectLinks(
- asDto(organizationManager.getByName(organizationName)), getServiceContext());
- }
-
- @GET
- @Produces(APPLICATION_JSON)
- @Path("/{parent}/organizations")
- @Operation(
- summary = "Get child organizations",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "The child organizations successfully fetched",
- content =
- @Content(
- array =
- @ArraySchema(schema = @Schema(implementation = OrganizationDto.class)))),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public Response getByParent(
- @Parameter(description = "Parent organization id") @PathParam("parent") String parent,
- @Parameter(description = "Max items") @QueryParam("maxItems") @DefaultValue("30")
- int maxItems,
- @Parameter(description = "Skip count") @QueryParam("skipCount") @DefaultValue("0")
- int skipCount)
- throws ServerException, BadRequestException {
-
- checkArgument(maxItems >= 0, "The number of items to return can't be negative.");
- checkArgument(skipCount >= 0, "The number of items to skip can't be negative.");
- final Page extends Organization> organizationsPage =
- organizationManager.getByParent(parent, maxItems, skipCount);
- return Response.ok()
- .entity(
- organizationsPage.getItems(
- organization ->
- linksInjector.injectLinks(asDto(organization), getServiceContext())))
- .header("Link", createLinkHeader(organizationsPage))
- .build();
- }
-
- @GET
- @Produces(APPLICATION_JSON)
- @Operation(
- summary =
- "Get user's organizations. When user parameter is missed then will be fetched current user's organizations",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "The organizations successfully fetched",
- content =
- @Content(
- array =
- @ArraySchema(schema = @Schema(implementation = OrganizationDto.class)))),
- @ApiResponse(
- responseCode = "400",
- description = "Missed required parameters, parameters are not valid"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public Response getOrganizations(
- @Parameter(description = "User id") @QueryParam("user") String userId,
- @Parameter(description = "Max items") @QueryParam("maxItems") @DefaultValue("30")
- int maxItems,
- @Parameter(description = "Skip count") @QueryParam("skipCount") @DefaultValue("0")
- int skipCount)
- throws ServerException, BadRequestException {
-
- checkArgument(maxItems >= 0, "The number of items to return can't be negative.");
- checkArgument(skipCount >= 0, "The number of items to skip can't be negative.");
- if (userId == null) {
- userId = EnvironmentContext.getCurrent().getSubject().getUserId();
- }
- final Page extends Organization> organizationsPage =
- organizationManager.getByMember(userId, maxItems, skipCount);
- return Response.ok()
- .entity(
- organizationsPage.getItems(
- organization ->
- linksInjector.injectLinks(asDto(organization), getServiceContext())))
- .header("Link", createLinkHeader(organizationsPage))
- .build();
- }
-
- /**
- * Ensures the truth of an expression involving one or more parameters to the calling method.
- *
- * @param expression a boolean expression
- * @param errorMessage the exception message to use if the check fails
- * @throws BadRequestException if {@code expression} is false
- */
- private void checkArgument(boolean expression, String errorMessage) throws BadRequestException {
- if (!expression) {
- throw new BadRequestException(errorMessage);
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationValidator.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationValidator.java
deleted file mode 100644
index b4bdbfdc50c..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/OrganizationValidator.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-
-import javax.inject.Inject;
-import org.eclipse.che.account.spi.AccountValidator;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Utils for organization validation.
- *
- * @author Sergii Leschenko
- */
-public class OrganizationValidator {
- @Inject private AccountValidator accountValidator;
-
- /**
- * Checks whether given organization is valid.
- *
- * @param organization organization to check
- * @throws BadRequestException when organization is not valid
- */
- public void checkOrganization(Organization organization) throws BadRequestException {
- if (organization == null) {
- throw new BadRequestException("Organization required");
- }
- if (isNullOrEmpty(organization.getName())) {
- throw new BadRequestException("Organization name required");
- }
- if (!accountValidator.isValidName(organization.getName())) {
- throw new BadRequestException(
- "Organization name may only contain alphanumeric characters or single hyphens inside");
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberAddedEvent.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberAddedEvent.java
deleted file mode 100644
index fe9d52ca39f..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberAddedEvent.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.event;
-
-import static org.eclipse.che.multiuser.organization.shared.event.EventType.MEMBER_ADDED;
-
-import org.eclipse.che.api.core.model.user.User;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-import org.eclipse.che.multiuser.organization.shared.event.MemberEvent;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Defines the event of adding the organization member.
- *
- * @author Anton Korneta
- */
-public class MemberAddedEvent implements MemberEvent {
-
- private final String initiator;
- private final User member;
- private final Organization organization;
-
- public MemberAddedEvent(String initiator, User member, Organization organization) {
- this.initiator = initiator;
- this.member = member;
- this.organization = organization;
- }
-
- @Override
- public Organization getOrganization() {
- return organization;
- }
-
- @Override
- public EventType getType() {
- return MEMBER_ADDED;
- }
-
- @Override
- public String getInitiator() {
- return initiator;
- }
-
- @Override
- public User getMember() {
- return member;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberRemovedEvent.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberRemovedEvent.java
deleted file mode 100644
index fddbf23b166..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/MemberRemovedEvent.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.event;
-
-import org.eclipse.che.api.core.model.user.User;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-import org.eclipse.che.multiuser.organization.shared.event.MemberEvent;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Defines the event for organization member removal.
- *
- * @author Anton Korneta
- */
-public class MemberRemovedEvent implements MemberEvent {
-
- private final String initiator;
- private final User member;
- private final Organization organization;
-
- public MemberRemovedEvent(String initiator, User member, Organization organization) {
- this.initiator = initiator;
- this.member = member;
- this.organization = organization;
- }
-
- @Override
- public EventType getType() {
- return EventType.MEMBER_REMOVED;
- }
-
- @Override
- public Organization getOrganization() {
- return organization;
- }
-
- @Override
- public User getMember() {
- return member;
- }
-
- @Override
- public String getInitiator() {
- return initiator;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRemovedEvent.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRemovedEvent.java
deleted file mode 100644
index dee94e20b28..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRemovedEvent.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.event;
-
-import static org.eclipse.che.multiuser.organization.shared.event.EventType.ORGANIZATION_REMOVED;
-
-import java.util.List;
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-import org.eclipse.che.multiuser.organization.shared.event.OrganizationEvent;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Defines organization removed event.
- *
- * @author Anton Korneta
- */
-public class OrganizationRemovedEvent implements OrganizationEvent {
-
- private final String initiator;
- private final Organization organization;
- private final List members;
-
- public OrganizationRemovedEvent(
- String initiator, Organization organization, List members) {
- this.initiator = initiator;
- this.organization = organization;
- this.members = members;
- }
-
- @Override
- public EventType getType() {
- return ORGANIZATION_REMOVED;
- }
-
- @Override
- public Organization getOrganization() {
- return organization;
- }
-
- public List getMembers() {
- return members;
- }
-
- /** Returns name of user who initiated organization removal */
- @Override
- public String getInitiator() {
- return initiator;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRenamedEvent.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRenamedEvent.java
deleted file mode 100644
index 0f60ff7afce..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/event/OrganizationRenamedEvent.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.event;
-
-import static org.eclipse.che.multiuser.organization.shared.event.EventType.ORGANIZATION_RENAMED;
-
-import org.eclipse.che.multiuser.organization.shared.event.EventType;
-import org.eclipse.che.multiuser.organization.shared.event.OrganizationEvent;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Defines organization renamed event.
- *
- * @author Anton Korneta
- */
-public class OrganizationRenamedEvent implements OrganizationEvent {
-
- private final String initiator;
- private final String oldName;
- private final String newName;
- private final Organization organization;
-
- public OrganizationRenamedEvent(
- String initiator, String oldName, String newName, Organization organization) {
- this.initiator = initiator;
- this.oldName = oldName;
- this.newName = newName;
- this.organization = organization;
- }
-
- @Override
- public Organization getOrganization() {
- return organization;
- }
-
- @Override
- public EventType getType() {
- return ORGANIZATION_RENAMED;
- }
-
- public String getOldName() {
- return oldName;
- }
-
- public String getNewName() {
- return newName;
- }
-
- @Override
- public String getInitiator() {
- return initiator;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/MemberEventsPublisher.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/MemberEventsPublisher.java
deleted file mode 100644
index 53e6ba76e6a..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/MemberEventsPublisher.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.listener;
-
-import static org.eclipse.che.multiuser.organization.api.DtoConverter.asDto;
-
-import jakarta.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.model.user.User;
-import org.eclipse.che.api.core.notification.EventService;
-import org.eclipse.che.api.core.notification.EventSubscriber;
-import org.eclipse.che.api.user.server.UserManager;
-import org.eclipse.che.multiuser.api.permission.shared.event.PermissionsEvent;
-import org.eclipse.che.multiuser.api.permission.shared.model.Permissions;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.api.event.MemberAddedEvent;
-import org.eclipse.che.multiuser.organization.api.event.MemberRemovedEvent;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Maps permissions to organization related events.
- *
- * @author Anton Korneta
- */
-@Singleton
-public class MemberEventsPublisher implements EventSubscriber {
-
- private final EventService eventService;
- private final UserManager userManager;
- private final OrganizationManager organizationManager;
-
- @Inject
- public MemberEventsPublisher(
- EventService eventService, UserManager userManager, OrganizationManager organizationManager) {
- this.eventService = eventService;
- this.userManager = userManager;
- this.organizationManager = organizationManager;
- }
-
- @PostConstruct
- private void subscribe() {
- eventService.subscribe(this);
- }
-
- @Override
- public void onEvent(PermissionsEvent event) {
- final Permissions permissions = event.getPermissions();
- if (OrganizationDomain.DOMAIN_ID.equals(permissions.getDomainId())) {
- try {
- switch (event.getType()) {
- case PERMISSIONS_ADDED:
- {
- final String initiator = event.getInitiator();
- final User addedMember = userManager.getById(permissions.getUserId());
- final Organization org = organizationManager.getById(permissions.getInstanceId());
- eventService.publish(asDto(new MemberAddedEvent(initiator, addedMember, org)));
- break;
- }
- case PERMISSIONS_REMOVED:
- {
- final String initiator = event.getInitiator();
- final User removedMember = userManager.getById(permissions.getUserId());
- final Organization org = organizationManager.getById(permissions.getInstanceId());
- eventService.publish(asDto(new MemberRemovedEvent(initiator, removedMember, org)));
- break;
- }
- default:
- // do nothing
- }
- } catch (NotFoundException | ServerException ignored) {
- }
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/OrganizationEventsWebsocketBroadcaster.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/OrganizationEventsWebsocketBroadcaster.java
deleted file mode 100644
index 9385b579483..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/listener/OrganizationEventsWebsocketBroadcaster.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.listener;
-
-import static org.eclipse.che.multiuser.organization.shared.event.EventType.MEMBER_ADDED;
-import static org.eclipse.che.multiuser.organization.shared.event.EventType.MEMBER_REMOVED;
-
-import jakarta.annotation.PostConstruct;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.notification.RemoteSubscriptionManager;
-import org.eclipse.che.multiuser.organization.shared.dto.MemberAddedEventDto;
-import org.eclipse.che.multiuser.organization.shared.dto.MemberRemovedEventDto;
-import org.eclipse.che.multiuser.organization.shared.event.OrganizationEvent;
-
-/**
- * Broadcasts organization events through websocket connection.
- *
- * @author Anton Korneta
- */
-@Singleton
-public class OrganizationEventsWebsocketBroadcaster {
-
- private final RemoteSubscriptionManager remoteSubscriptionManager;
-
- public static final String ORGANIZATION_MEMBERSHIP_METHOD_NAME = "organization/membershipChanged";
- public static final String ORGANIZATION_CHANGED_METHOD_NAME = "organization/statusChanged";
-
- @Inject
- public OrganizationEventsWebsocketBroadcaster(
- RemoteSubscriptionManager remoteSubscriptionManager) {
- this.remoteSubscriptionManager = remoteSubscriptionManager;
- }
-
- @PostConstruct
- private void subscribe() {
- remoteSubscriptionManager.register(
- ORGANIZATION_MEMBERSHIP_METHOD_NAME, OrganizationEvent.class, this::predicate);
- remoteSubscriptionManager.register(
- ORGANIZATION_CHANGED_METHOD_NAME, OrganizationEvent.class, this::predicate);
- }
-
- private boolean predicate(OrganizationEvent event, Map scope) {
- if (MEMBER_ADDED == event.getType()) {
- return ((MemberAddedEventDto) event).getMember().getId().equals(scope.get("userId"));
- } else if (MEMBER_REMOVED == event.getType()) {
- return ((MemberRemovedEventDto) event).getMember().getId().equals(scope.get("userId"));
- } else {
- return event.getOrganization().getId().equals(scope.get("organizationId"));
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationDomain.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationDomain.java
deleted file mode 100644
index d4fd34fa34f..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationDomain.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import com.google.common.collect.ImmutableList;
-import java.util.List;
-import org.eclipse.che.multiuser.api.permission.server.AbstractPermissionsDomain;
-import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
-
-/**
- * Domain for storing organizations' permissions
- *
- * @author Sergii Leschenko
- */
-public class OrganizationDomain extends AbstractPermissionsDomain {
- public static final String DOMAIN_ID = "organization";
-
- public static final String UPDATE = "update";
- public static final String DELETE = "delete";
- public static final String MANAGE_SUBORGANIZATIONS = "manageSuborganizations";
- public static final String MANAGE_RESOURCES = "manageResources";
- public static final String CREATE_WORKSPACES = "createWorkspaces";
- public static final String MANAGE_WORKSPACES = "manageWorkspaces";
-
- private static final List ACTIONS =
- ImmutableList.of(
- SET_PERMISSIONS,
- UPDATE,
- DELETE,
- MANAGE_SUBORGANIZATIONS,
- MANAGE_RESOURCES,
- CREATE_WORKSPACES,
- MANAGE_WORKSPACES);
-
- /** Returns all the available actions for {@link OrganizationDomain}. */
- public static List getActions() {
- return ACTIONS;
- }
-
- public OrganizationDomain() {
- super(DOMAIN_ID, ACTIONS);
- }
-
- @Override
- protected MemberImpl doCreateInstance(
- String userId, String instanceId, List allowedActions) {
- return new MemberImpl(userId, instanceId, allowedActions);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilter.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilter.java
deleted file mode 100644
index 0257c6f24c8..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilter.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.DOMAIN_ID;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.MANAGE_SUBORGANIZATIONS;
-
-import jakarta.ws.rs.Path;
-import javax.inject.Inject;
-import org.eclipse.che.api.core.ApiException;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.everrest.CheMethodInvokerFilter;
-import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.api.OrganizationService;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.everrest.core.Filter;
-import org.everrest.core.resource.GenericResourceMethod;
-
-/**
- * Restricts access to methods of {@link OrganizationService} by users' permissions
- *
- *
Filter contains rules for protecting of all methods of {@link OrganizationService}.
- * In case when requested method is unknown filter throws {@link ForbiddenException}
- *
- * @author Sergii Leschenko
- */
-@Filter
-@Path("/organization{path:(?!/resource)(/.*)?}")
-public class OrganizationPermissionsFilter extends CheMethodInvokerFilter {
- static final String CREATE_METHOD = "create";
- static final String UPDATE_METHOD = "update";
- static final String REMOVE_METHOD = "remove";
- static final String GET_BY_PARENT_METHOD = "getByParent";
- static final String GET_ORGANIZATIONS_METHOD = "getOrganizations";
- static final String GET_BY_ID_METHOD = "getById";
- static final String FIND_METHOD = "find";
-
- @Inject private OrganizationManager manager;
- @Inject private SuperPrivilegesChecker superPrivilegesChecker;
-
- @Override
- protected void filter(GenericResourceMethod genericMethodResource, Object[] arguments)
- throws ApiException {
- final String methodName = genericMethodResource.getMethod().getName();
-
- final Subject currentSubject = EnvironmentContext.getCurrent().getSubject();
- String action;
- String organizationId;
-
- switch (methodName) {
- case CREATE_METHOD:
- final OrganizationDto organization = (OrganizationDto) arguments[0];
- if (organization.getParent() != null) {
- organizationId = organization.getParent();
- action = OrganizationDomain.MANAGE_SUBORGANIZATIONS;
- break;
- }
- // anybody can create root organization
- return;
-
- case UPDATE_METHOD:
- organizationId = ((String) arguments[0]);
- action = OrganizationDomain.UPDATE;
- break;
-
- case REMOVE_METHOD:
- organizationId = ((String) arguments[0]);
- action = OrganizationDomain.DELETE;
- break;
-
- case GET_BY_PARENT_METHOD:
- organizationId = ((String) arguments[0]);
- action = OrganizationDomain.MANAGE_SUBORGANIZATIONS;
- if (superPrivilegesChecker.hasSuperPrivileges()) {
- return;
- }
- break;
-
- case GET_ORGANIZATIONS_METHOD:
- final String userId = (String) arguments[0];
- if (userId != null
- && !userId.equals(currentSubject.getUserId())
- && !superPrivilegesChecker.hasSuperPrivileges()) {
- throw new ForbiddenException("The user is able to specify only his own id");
- }
- // user specified his user id or has super privileges
- return;
-
- // methods accessible to every user
- case GET_BY_ID_METHOD:
- case FIND_METHOD:
- return;
-
- default:
- throw new ForbiddenException("The user does not have permission to perform this operation");
- }
-
- // user is not admin and it is need to check permissions on organization instance level
- final Organization organization = manager.getById(organizationId);
- final String parentOrganizationId = organization.getParent();
- // check permissions on parent organization level when updating or removing child organization
- if (parentOrganizationId != null
- && (OrganizationDomain.UPDATE.equals(action) || OrganizationDomain.DELETE.equals(action))) {
- if (currentSubject.hasPermission(
- OrganizationDomain.DOMAIN_ID, parentOrganizationId, MANAGE_SUBORGANIZATIONS)) {
- // user has permissions to manage organization on parent organization level
- return;
- }
- }
-
- if (!currentSubject.hasPermission(DOMAIN_ID, organizationId, action)) {
- throw new ForbiddenException(
- "The user does not have permission to "
- + action
- + " organization with id '"
- + organizationId
- + "'");
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecks.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecks.java
deleted file mode 100644
index 1e41e2ae9d4..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecks.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster.ORGANIZATION_CHANGED_METHOD_NAME;
-import static org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster.ORGANIZATION_MEMBERSHIP_METHOD_NAME;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
-import org.eclipse.che.multiuser.api.permission.server.jsonrpc.RemoteSubscriptionPermissionCheck;
-import org.eclipse.che.multiuser.api.permission.server.jsonrpc.RemoteSubscriptionPermissionManager;
-import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
-import org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster;
-
-/**
- * Holds and registers permissions checks for organization related events.
- *
- *
Covers events published via {@link OrganizationEventsWebsocketBroadcaster}.
- *
- * @author Sergii Leshchenko
- */
-@Singleton
-public class OrganizationRemoteSubscriptionPermissionsChecks {
-
- private final PermissionsManager permissionsManager;
-
- @Inject
- public OrganizationRemoteSubscriptionPermissionsChecks(PermissionsManager permissionsManager) {
- this.permissionsManager = permissionsManager;
- }
-
- @Inject
- public void register(RemoteSubscriptionPermissionManager permissionFilter) {
- MembershipsChangedSubscriptionCheck membershipsEventsCheck =
- new MembershipsChangedSubscriptionCheck();
-
- permissionFilter.registerCheck(membershipsEventsCheck, ORGANIZATION_MEMBERSHIP_METHOD_NAME);
-
- OrganizationChangedSubscriptionCheck organizationChangedCheck =
- new OrganizationChangedSubscriptionCheck(permissionsManager);
- permissionFilter.registerCheck(organizationChangedCheck, ORGANIZATION_CHANGED_METHOD_NAME);
- }
-
- @VisibleForTesting
- static class MembershipsChangedSubscriptionCheck implements RemoteSubscriptionPermissionCheck {
-
- @Override
- public void check(String methodName, Map scope) throws ForbiddenException {
- String userId = scope.get("userId");
- if (userId == null) {
- throw new ForbiddenException("User id must be specified in scope");
- }
-
- String currentUserId = EnvironmentContext.getCurrent().getSubject().getUserId();
-
- if (!currentUserId.equals(userId)) {
- throw new ForbiddenException("It is only allowed to listen to own memberships changes");
- }
- }
- }
-
- @VisibleForTesting
- static class OrganizationChangedSubscriptionCheck implements RemoteSubscriptionPermissionCheck {
-
- private final PermissionsManager permissionsManager;
-
- public OrganizationChangedSubscriptionCheck(PermissionsManager permissionsManager) {
- this.permissionsManager = permissionsManager;
- }
-
- @Override
- public void check(String methodName, Map scope) throws ForbiddenException {
- String organizationId = scope.get("organizationId");
- if (organizationId == null) {
- throw new ForbiddenException("Organization id must be specified in scope");
- }
-
- String currentUserId = EnvironmentContext.getCurrent().getSubject().getUserId();
-
- try {
- // check if user has any permissions in organisation
- // to listen to related events
- AbstractPermissions permissions =
- permissionsManager.get(currentUserId, OrganizationDomain.DOMAIN_ID, organizationId);
- } catch (ConflictException | ServerException e) {
- throw new ForbiddenException("Error occurred while permission fetching: " + e.getMessage());
- } catch (NotFoundException e) {
- throw new ForbiddenException(
- "User doesn't have any permissions for the specified organization");
- }
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilter.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilter.java
deleted file mode 100644
index ed711cceeb7..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilter.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import jakarta.ws.rs.Path;
-import javax.inject.Inject;
-import org.eclipse.che.api.core.ApiException;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.everrest.CheMethodInvokerFilter;
-import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.api.resource.OrganizationResourcesDistributionService;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.everrest.core.Filter;
-import org.everrest.core.resource.GenericResourceMethod;
-
-/**
- * Restricts access to methods of {@link OrganizationResourcesDistributionService} by users'
- * permissions.
- *
- *
Filter contains rules for protecting of all methods of {@link
- * OrganizationResourcesDistributionService}.
- * In case when requested method is unknown filter throws {@link ForbiddenException}.
- *
- * @author Sergii Leschenko
- */
-@Filter
-@Path("/organization/resource{path:(/.*)?}")
-public class OrganizationResourceDistributionServicePermissionsFilter
- extends CheMethodInvokerFilter {
- static final String CAP_RESOURCES_METHOD = "capResources";
- static final String GET_RESOURCES_CAP_METHOD = "getResourcesCap";
- static final String GET_DISTRIBUTED_RESOURCES = "getDistributedResources";
-
- @Inject private OrganizationManager organizationManager;
- @Inject private SuperPrivilegesChecker superPrivilegesChecker;
-
- @Override
- protected void filter(GenericResourceMethod genericMethodResource, Object[] arguments)
- throws ApiException {
- final String methodName = genericMethodResource.getMethod().getName();
-
- final Subject currentSubject = EnvironmentContext.getCurrent().getSubject();
- String organizationId;
- switch (methodName) {
- case GET_RESOURCES_CAP_METHOD:
- if (superPrivilegesChecker.hasSuperPrivileges()) {
- // user is able to see information about all organizations
- return;
- }
- // fall through
- case CAP_RESOURCES_METHOD:
- // we should check permissions on parent organization level
- Organization organization = organizationManager.getById((String) arguments[0]);
- organizationId = organization.getParent();
- if (organizationId == null) {
- // requested organization is root so manager should throw exception
- return;
- }
- break;
-
- case GET_DISTRIBUTED_RESOURCES:
- organizationId = (String) arguments[0];
- // get organization to ensure that organization exists
- organizationManager.getById(organizationId);
- if (superPrivilegesChecker.hasSuperPrivileges()) {
- // user is able to see information about all organizations
- return;
- }
- break;
-
- default:
- throw new ForbiddenException("The user does not have permission to perform this operation");
- }
-
- if (!currentSubject.hasPermission(
- OrganizationDomain.DOMAIN_ID, organizationId, OrganizationDomain.MANAGE_RESOURCES)) {
- throw new ForbiddenException(
- "The user does not have permission to manage resources of organization with id '"
- + organizationId
- + "'");
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsChecker.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsChecker.java
deleted file mode 100644
index a6a0a593d29..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsChecker.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.CREATE_WORKSPACES;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.DOMAIN_ID;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.MANAGE_RESOURCES;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.MANAGE_WORKSPACES;
-
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.multiuser.api.permission.server.account.AccountOperation;
-import org.eclipse.che.multiuser.api.permission.server.account.AccountPermissionsChecker;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-
-/**
- * Defines permissions checking for organizational accounts.
- *
- * @author Sergii Leshchenko
- */
-@Singleton
-public class OrganizationalAccountPermissionsChecker implements AccountPermissionsChecker {
- @Override
- public void checkPermissions(String accountId, AccountOperation operation)
- throws ForbiddenException {
- Subject subject = EnvironmentContext.getCurrent().getSubject();
- switch (operation) {
- case CREATE_WORKSPACE:
- if (!subject.hasPermission(
- OrganizationDomain.DOMAIN_ID, accountId, OrganizationDomain.CREATE_WORKSPACES)) {
- throw new ForbiddenException(
- "User is not authorized to create workspaces in specified namespace.");
- }
- break;
- case MANAGE_WORKSPACES:
- if (!subject.hasPermission(
- OrganizationDomain.DOMAIN_ID, accountId, OrganizationDomain.MANAGE_WORKSPACES)) {
- throw new ForbiddenException("User is not authorized to use specified namespace.");
- }
- break;
- case SEE_RESOURCE_INFORMATION:
- if (subject.hasPermission(DOMAIN_ID, accountId, CREATE_WORKSPACES)
- || subject.hasPermission(DOMAIN_ID, accountId, MANAGE_WORKSPACES)
- || subject.hasPermission(DOMAIN_ID, accountId, MANAGE_RESOURCES)) {
-
- // user is able to see resources usage information
- return;
- }
- throw new ForbiddenException(
- "User is not authorized to see resources information of requested organization.");
- default:
- throw new ForbiddenException("User is not authorized to use specified namespace.");
- }
- }
-
- @Override
- public String getAccountType() {
- return OrganizationImpl.ORGANIZATIONAL_ACCOUNT;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProvider.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProvider.java
deleted file mode 100644
index ffc287bc6b4..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProvider.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Arrays.asList;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.commons.lang.Size;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.free.DefaultResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.type.RamResourceType;
-import org.eclipse.che.multiuser.resource.api.type.RuntimeResourceType;
-import org.eclipse.che.multiuser.resource.api.type.TimeoutResourceType;
-import org.eclipse.che.multiuser.resource.api.type.WorkspaceResourceType;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Provided free resources that are available for usage by organizational accounts by default.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class DefaultOrganizationResourcesProvider implements DefaultResourcesProvider {
- private final OrganizationManager organizationManager;
- private final long ramPerOrganization;
- private final int workspacesPerOrganization;
- private final int runtimesPerOrganization;
- private final long timeout;
-
- @Inject
- public DefaultOrganizationResourcesProvider(
- OrganizationManager organizationManager,
- @Named("che.limits.organization.workspaces.ram") String ramPerOrganization,
- @Named("che.limits.organization.workspaces.count") int workspacesPerOrganization,
- @Named("che.limits.organization.workspaces.run.count") int runtimesPerOrganization,
- @Named("che.limits.workspace.idle.timeout") long timeout) {
- this.timeout = TimeUnit.MILLISECONDS.toMinutes(timeout);
- this.organizationManager = organizationManager;
- this.ramPerOrganization =
- "-1".equals(ramPerOrganization) ? -1 : Size.parseSizeToMegabytes(ramPerOrganization);
- this.workspacesPerOrganization = workspacesPerOrganization;
- this.runtimesPerOrganization = runtimesPerOrganization;
- }
-
- @Override
- public String getAccountType() {
- return OrganizationImpl.ORGANIZATIONAL_ACCOUNT;
- }
-
- @Override
- public List getResources(String accountId)
- throws ServerException, NotFoundException {
- final Organization organization = organizationManager.getById(accountId);
- // only root organizations should have own resources
- if (organization.getParent() == null) {
- return asList(
- new ResourceImpl(TimeoutResourceType.ID, timeout, TimeoutResourceType.UNIT),
- new ResourceImpl(RamResourceType.ID, ramPerOrganization, RamResourceType.UNIT),
- new ResourceImpl(
- WorkspaceResourceType.ID, workspacesPerOrganization, WorkspaceResourceType.UNIT),
- new ResourceImpl(
- RuntimeResourceType.ID, runtimesPerOrganization, RuntimeResourceType.UNIT));
- }
-
- return Collections.emptyList();
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProvider.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProvider.java
deleted file mode 100644
index bbcd871f898..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.ResourceLockKeyProvider;
-
-/**
- * Provides resources lock key for accounts with organizational type.
- *
- *
A lock key for any organization is an identifier of the root organization.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class OrganizationResourceLockKeyProvider implements ResourceLockKeyProvider {
- private final OrganizationManager organizationManager;
-
- @Inject
- public OrganizationResourceLockKeyProvider(OrganizationManager organizationManager) {
- this.organizationManager = organizationManager;
- }
-
- @Override
- public String getLockKey(String accountId) throws ServerException {
- String currentOrganizationId = accountId;
- try {
- Organization organization = organizationManager.getById(currentOrganizationId);
- while (organization.getParent() != null) {
- currentOrganizationId = organization.getParent();
- organization = organizationManager.getById(currentOrganizationId);
- }
- return organization.getId();
- } catch (NotFoundException e) {
- // should not happen
- throw new ServerException(e.getLocalizedMessage(), e);
- }
- }
-
- @Override
- public String getAccountType() {
- return OrganizationImpl.ORGANIZATIONAL_ACCOUNT;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionService.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionService.java
deleted file mode 100644
index 8d0bae84b0b..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionService.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-import static java.lang.String.format;
-import static java.util.stream.Collectors.toList;
-
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.media.ArraySchema;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.DefaultValue;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.POST;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.core.Response;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.inject.Inject;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.rest.Service;
-import org.eclipse.che.multiuser.organization.api.DtoConverter;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDistributedResourcesDto;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-import org.eclipse.che.multiuser.resource.api.free.ResourceValidator;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-
-/**
- * REST API for resources distribution between suborganizations.
- *
- * @author Sergii Leschenko
- */
-@Tag(
- name = "organization-resource",
- description = "REST API for resources distribution between suborganizations")
-@Path("/organization/resource")
-public class OrganizationResourcesDistributionService extends Service {
- private final OrganizationResourcesDistributor resourcesDistributor;
- private final ResourceValidator resourceValidator;
-
- @Inject
- public OrganizationResourcesDistributionService(
- OrganizationResourcesDistributor resourcesDistributor, ResourceValidator resourceValidator) {
- this.resourcesDistributor = resourcesDistributor;
- this.resourceValidator = resourceValidator;
- }
-
- @POST
- @Path("/{suborganizationId}/cap")
- @Consumes(APPLICATION_JSON)
- @Operation(
- summary =
- "Cap usage of shared resources.. By default suborganization is able to use all parent organization resources."
- + "Cap allow to limit usage of shared resources by suborganization.",
- responses = {
- @ApiResponse(responseCode = "204", description = "Resources successfully capped"),
- @ApiResponse(
- responseCode = "400",
- description = "Missed required parameters, parameters are not valid"),
- @ApiResponse(responseCode = "404", description = "Specified organization was not found"),
- @ApiResponse(
- responseCode = "409",
- description = "Specified organization is root organization"),
- @ApiResponse(
- responseCode = "409",
- description = "Suborganization is using shared resources"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public void capResources(
- @Parameter(description = "Suborganization id") @PathParam("suborganizationId")
- String suborganizationId,
- @Parameter(description = "Resources to cap") List resourcesCap)
- throws BadRequestException, NotFoundException, ConflictException, ServerException {
- checkArgument(resourcesCap != null, "Missed resources caps.");
- Set resourcesToSet = new HashSet<>();
- for (ResourceDto resource : resourcesCap) {
- if (!resourcesToSet.add(resource.getType())) {
- throw new BadRequestException(
- format(
- "Resources to cap must contain only one resource with type '%s'.",
- resource.getType()));
- }
- resourceValidator.validate(resource);
- }
-
- resourcesDistributor.capResources(suborganizationId, resourcesCap);
- }
-
- @GET
- @Path("/{suborganizationId}/cap")
- @Produces(APPLICATION_JSON)
- @Operation(
- summary = "Get resources cap of specified suborganization.",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Resources caps successfully fetched",
- content =
- @Content(
- array =
- @ArraySchema(
- schema =
- @Schema(
- implementation = OrganizationDistributedResourcesDto.class)))),
- @ApiResponse(responseCode = "404", description = "Specified organization was not found"),
- @ApiResponse(
- responseCode = "409",
- description = "Specified organization is root organization"),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public List getResourcesCap(
- @Parameter(description = "Suborganization id") @PathParam("suborganizationId")
- String suborganization)
- throws NotFoundException, ConflictException, ServerException {
- return resourcesDistributor.getResourcesCaps(suborganization).stream()
- .map(org.eclipse.che.multiuser.resource.api.DtoConverter::asDto)
- .collect(toList());
- }
-
- @GET
- @Path("/{organizationId}")
- @Produces(APPLICATION_JSON)
- @Operation(
- summary = "Get resources which are distributed by specified parent.",
- responses = {
- @ApiResponse(
- responseCode = "200",
- description = "Resources caps successfully fetched",
- content =
- @Content(
- array =
- @ArraySchema(
- schema =
- @Schema(
- implementation = OrganizationDistributedResourcesDto.class)))),
- @ApiResponse(responseCode = "500", description = "Internal server error occurred")
- })
- public Response getDistributedResources(
- @Parameter(description = "Organization id") @PathParam("organizationId")
- String organizationId,
- @Parameter(description = "Max items") @QueryParam("maxItems") @DefaultValue("30")
- int maxItems,
- @Parameter(description = "Skip count") @QueryParam("skipCount") @DefaultValue("0")
- long skipCount)
- throws BadRequestException, ServerException {
- checkArgument(maxItems >= 0, "The number of items to return can't be negative.");
- checkArgument(skipCount >= 0, "The number of items to skip can't be negative.");
-
- final Page extends OrganizationDistributedResources> distributedResourcesPage =
- resourcesDistributor.getByParent(organizationId, maxItems, skipCount);
- return Response.ok()
- .entity(distributedResourcesPage.getItems(DtoConverter::asDto))
- .header("Link", createLinkHeader(distributedResourcesPage))
- .build();
- }
-
- /**
- * Ensures the truth of an expression involving one or more parameters to the calling method.
- *
- * @param expression a boolean expression
- * @param errorMessage the exception message to use if the check fails
- * @throws BadRequestException if {@code expression} is false
- */
- private void checkArgument(boolean expression, String errorMessage) throws BadRequestException {
- if (!expression) {
- throw new BadRequestException(errorMessage);
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributor.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributor.java
deleted file mode 100644
index 7a7c2a6cdf5..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributor.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Collections.emptyList;
-import static java.util.Objects.requireNonNull;
-import static java.util.stream.Collectors.toList;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.commons.lang.concurrent.Unlocker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-import org.eclipse.che.multiuser.organization.spi.OrganizationDistributedResourcesDao;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationDistributedResourcesImpl;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.api.type.RamResourceType;
-import org.eclipse.che.multiuser.resource.api.type.RuntimeResourceType;
-import org.eclipse.che.multiuser.resource.api.type.WorkspaceResourceType;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.api.usage.ResourcesLocks;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Facade for organization resources operations.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class OrganizationResourcesDistributor {
- private final OrganizationDistributedResourcesDao organizationDistributedResourcesDao;
- private final OrganizationManager organizationManager;
- private final ResourcesLocks resourcesLocks;
- private final ResourceManager resourceManager;
- private final ResourceAggregator resourceAggregator;
-
- @Inject
- public OrganizationResourcesDistributor(
- OrganizationDistributedResourcesDao organizationDistributedResourcesDao,
- OrganizationManager organizationManager,
- ResourcesLocks resourcesLocks,
- ResourceManager resourceManager,
- ResourceAggregator resourceAggregator) {
- this.organizationDistributedResourcesDao = organizationDistributedResourcesDao;
- this.organizationManager = organizationManager;
- this.resourcesLocks = resourcesLocks;
- this.resourceManager = resourceManager;
- this.resourceAggregator = resourceAggregator;
- }
-
- /**
- * Cap usage of shared resources.
- *
- *
By default suborganization is able to use all parent organization resources Cap allow to
- * limit usage of shared resources by suborganization.
- *
- * @param suborganizationId suborganization id
- * @param resourcesCaps resources to capped
- * @throws NotFoundException when specified suborganization was not found
- * @throws ConflictException when organization with specified id is root organization
- * @throws ConflictException when suborganization is currently using more shared resources than
- * should be capped
- * @throws ServerException when any other error occurs
- */
- public void capResources(String suborganizationId, List extends Resource> resourcesCaps)
- throws NotFoundException, ConflictException, ServerException {
- requireNonNull(suborganizationId, "Required non-null suborganization id");
- requireNonNull(resourcesCaps, "Required non-null resources to capResources");
- checkIsSuborganization(suborganizationId);
-
- // remove caps with amount -1
- resourcesCaps = resourcesCaps.stream().filter(res -> res.getAmount() != -1).collect(toList());
-
- // locking resources by suborganization should lock resources whole organization tree
- // so we can check resource availability for suborganization organization
- try (@SuppressWarnings("unused")
- Unlocker u = resourcesLocks.lock(suborganizationId)) {
- if (resourcesCaps.isEmpty()) {
- organizationDistributedResourcesDao.remove(suborganizationId);
- } else {
- checkResourcesAvailability(suborganizationId, resourcesCaps);
-
- organizationDistributedResourcesDao.store(
- new OrganizationDistributedResourcesImpl(suborganizationId, resourcesCaps));
- }
- }
- }
-
- /**
- * Returns resources cap or empty list.
- *
- * @param suborganizationId suborganization id to fetch resources cap
- * @return resources cap or empty list
- * @throws NotFoundException when specified suborganization was not found
- * @throws ConflictException when organization with specified id is root organization
- * @throws ServerException when any other error occurs
- */
- public List extends Resource> getResourcesCaps(String suborganizationId)
- throws NotFoundException, ConflictException, ServerException {
- requireNonNull(suborganizationId, "Required non-null suborganization id");
- checkIsSuborganization(suborganizationId);
- try {
- return organizationDistributedResourcesDao.get(suborganizationId).getResourcesCap();
- } catch (NotFoundException e) {
- return emptyList();
- }
- }
-
- /**
- * Returns distributed resources for specified suborganization.
- *
- * @param suborganizationId organization id
- * @return distributed resources for suborganization with specified id
- * @throws NullPointerException when either {@code suborganizationId} is null
- * @throws NotFoundException when there is not distributed resources for specified suborganization
- * @throws ServerException when any other error occurs
- */
- public OrganizationDistributedResources get(String suborganizationId)
- throws NotFoundException, ServerException {
- requireNonNull(suborganizationId, "Required non-null organization id");
-
- return organizationDistributedResourcesDao.get(suborganizationId);
- }
-
- /**
- * Returns distributed resources for suborganizations by specified parent organization.
- *
- * @param organizationId organization id
- * @return distributed resources for suborganizations by specified parent organization
- * @throws NullPointerException when either {@code organizationId} is null
- * @throws ServerException when any other error occurs
- */
- public Page extends OrganizationDistributedResources> getByParent(
- String organizationId, int maxItems, long skipCount) throws ServerException {
- requireNonNull(organizationId, "Required non-null organization id");
-
- return organizationDistributedResourcesDao.getByParent(organizationId, maxItems, skipCount);
- }
-
- /**
- * Checks that suborganization is using less resources that new resources cap defines.
- *
- * @param suborganizationId identifier of suborganization
- * @param newResourcesCap resources to capResources
- * @throws ConflictException when parent organization doesn't have enough resources to increase
- * distributed resource amount
- * @throws ConflictException when resources can't be distributed because suborganization is using
- * existing resources or when they are distributed to next organizations level
- * @throws ServerException when any other error occurs
- */
- @VisibleForTesting
- void checkResourcesAvailability(
- String suborganizationId, List extends Resource> newResourcesCap)
- throws NotFoundException, ConflictException, ServerException {
- Map usedResources =
- resourceManager.getUsedResources(suborganizationId).stream()
- .collect(Collectors.toMap(Resource::getType, Function.identity()));
- for (Resource resourceToCheck : newResourcesCap) {
- Resource usedResource = usedResources.get(resourceToCheck.getType());
- if (usedResource != null) {
- try {
- resourceAggregator.deduct(resourceToCheck, usedResource);
- } catch (NoEnoughResourcesException e) {
- throw new ConflictException(
- "Resources are currently in use. "
- + getMessage(e.getMissingResources().get(0).getType()));
- }
- }
- }
- }
-
- @VisibleForTesting
- String getMessage(String requiredResourceType) {
- switch (requiredResourceType) {
- case RamResourceType.ID:
- return "You can't decrease RAM CAP, while the resources are in use. "
- + "Free resources, by stopping workspaces, before changing the RAM CAP.";
- case WorkspaceResourceType.ID:
- return "You can't reduce the workspaces CAP to a value lower than the number of workspaces currently created. "
- + "Free resources, by removing workspaces, before changing the workspaces CAP.";
- case RuntimeResourceType.ID:
- return "You can't reduce the running workspaces CAP to a value lower than the number of workspaces currently running. "
- + "Free resources, by stopping workspaces, before changing the running workspaces CAP.";
- default:
- return "You can't reduce them while they are used. "
- + "Free resources before changing the resources CAP.";
- }
- }
-
- private String checkIsSuborganization(String organizationId)
- throws NotFoundException, ConflictException, ServerException {
- String parentOrganization = organizationManager.getById(organizationId).getParent();
- if (parentOrganization == null) {
- throw new ConflictException("It is not allowed to cap resources for root organization.");
- }
- return parentOrganization;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProvider.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProvider.java
deleted file mode 100644
index 12cbc5e51fe..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProvider.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Pages;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides available resources for organizational and suborganizational accounts.
- *
- *
Root organizational account can use resources by itself or share them for its
- * suborganizations. So available resources equal to total resources minus resources which are
- * already used by organization or by any of its suborganizations.
- *
- *
Suborganizational account can use all of parent resources or limited amount. So available
- * resource equal to minimum of parent available resources and parent shared resources minus
- * resources which are used by suborganization and its suborganizations.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class OrganizationalAccountAvailableResourcesProvider implements AvailableResourcesProvider {
- private static final Logger LOG =
- LoggerFactory.getLogger(OrganizationalAccountAvailableResourcesProvider.class);
-
- private final Provider resourceManagerProvider;
- private final ResourceAggregator resourceAggregator;
- private final OrganizationManager organizationManager;
-
- @Inject
- public OrganizationalAccountAvailableResourcesProvider(
- Provider resourceManagerProvider,
- ResourceAggregator resourceAggregator,
- OrganizationManager organizationManager) {
- this.resourceManagerProvider = resourceManagerProvider;
- this.resourceAggregator = resourceAggregator;
- this.organizationManager = organizationManager;
- }
-
- @Override
- public List extends Resource> getAvailableResources(String accountId)
- throws NotFoundException, ServerException {
- Organization organization = organizationManager.getById(accountId);
-
- if (organization.getParent() == null) {
- return getAvailableOrganizationResources(organization);
- } else {
- Organization parentOrganization = organizationManager.getById(organization.getParent());
- return resourceAggregator.min(
- resourceAggregator.intersection(
- getAvailableOrganizationResources(parentOrganization),
- getAvailableOrganizationResources(organization)));
- }
- }
-
- /**
- * Returns total resources minus resources which are already used by organization or by any of its
- * suborganizations.
- *
- * @param organization organization id to calculate its available resources
- * @return resources which are available for usage by specified organization
- * @throws NotFoundException when organization with specified id doesn't exist
- * @throws ServerException when any other exception occurs on calculation of available resources
- */
- @VisibleForTesting
- List extends Resource> getAvailableOrganizationResources(Organization organization)
- throws NotFoundException, ServerException {
- final ResourceManager resourceManager = resourceManagerProvider.get();
- final List extends Resource> total = resourceManager.getTotalResources(organization.getId());
- final List unavailable =
- new ArrayList<>(resourceManager.getUsedResources(organization.getId()));
- unavailable.addAll(getUsedResourcesBySuborganizations(organization.getQualifiedName()));
- try {
- return resourceAggregator.deduct(total, unavailable);
- } catch (NoEnoughResourcesException e) {
- LOG.warn(
- "Organization with id {} uses more resources {} than it has {}.",
- organization.getId(),
- format(unavailable),
- format(total));
- return resourceAggregator.excess(total, unavailable);
- }
- }
-
- /**
- * Returns resources which are used by suborganizations of specified organization.
- *
- *
Note that the result will includes used resources of all direct and nested suborganizations.
- *
- * @param parentQualifiedName parent qualified name, e.g. 'parentName/suborgName
- * @return resources which are used by suborganizations of specified organization.
- * @throws ServerException when any other exception occurs on calculation of used resources
- */
- @VisibleForTesting
- List getUsedResourcesBySuborganizations(String parentQualifiedName)
- throws NotFoundException, ServerException {
- ResourceManager resourceManager = resourceManagerProvider.get();
- List usedResources = new ArrayList<>();
- for (Organization suborganization :
- Pages.iterate(
- (maxItems, skipCount) ->
- organizationManager.getSuborganizations(
- parentQualifiedName, maxItems, skipCount))) {
- usedResources.addAll(resourceManager.getUsedResources(suborganization.getId()));
- }
- return usedResources;
- }
-
- /** Returns formatted string for list of resources. */
- private static String format(Collection extends Resource> resources) {
- return '['
- + resources.stream()
- .map(
- resource -> resource.getAmount() + resource.getUnit() + " of " + resource.getType())
- .collect(Collectors.joining(", "))
- + ']';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProvider.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProvider.java
deleted file mode 100644
index 6ce55870d2b..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProvider.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static java.util.stream.Collectors.toMap;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-import org.eclipse.che.account.api.AccountManager;
-import org.eclipse.che.account.shared.model.Account;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.ResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ProvidedResourcesImpl;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Provides resources that are shared for suborganization by its parent organization.
- *
- *
By default suborganizations are able to use parent's resources. Parent organization can limit
- * usage of resources by suborganization by setting resources caps.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class SuborganizationResourcesProvider implements ResourcesProvider {
- public static final String PARENT_RESOURCES_PROVIDER = "parentOrganization";
-
- private final AccountManager accountManager;
- private final OrganizationManager organizationManager;
- private final Provider distributorProvider;
- private final Provider resourceManagerProvider;
-
- @Inject
- public SuborganizationResourcesProvider(
- AccountManager accountManager,
- OrganizationManager organizationManager,
- Provider distributorProvider,
- Provider resourceManagerProvider) {
- this.accountManager = accountManager;
- this.organizationManager = organizationManager;
- this.distributorProvider = distributorProvider;
- this.resourceManagerProvider = resourceManagerProvider;
- }
-
- @Override
- public List getResources(String accountId)
- throws NotFoundException, ServerException {
- final Account account = accountManager.getById(accountId);
- String parent;
-
- if (!OrganizationImpl.ORGANIZATIONAL_ACCOUNT.equals(account.getType())
- || (parent = organizationManager.getById(accountId).getParent()) == null) {
- return emptyList();
- }
-
- // given account is suborganization's account and can have resources provided by parent
- List extends Resource> parentTotalResources =
- resourceManagerProvider.get().getTotalResources(parent);
-
- if (!parentTotalResources.isEmpty()) {
- try {
- List extends Resource> resourcesCaps =
- distributorProvider.get().getResourcesCaps(accountId);
-
- return singletonList(
- new ProvidedResourcesImpl(
- PARENT_RESOURCES_PROVIDER,
- null,
- accountId,
- -1L,
- -1L,
- cap(parentTotalResources, resourcesCaps)));
- } catch (ConflictException e) {
- throw new ServerException(e.getLocalizedMessage());
- }
- }
-
- return emptyList();
- }
-
- private List cap(
- Collection extends Resource> source, List extends Resource> caps) {
- final Map resourcesCaps =
- caps.stream().collect(toMap(Resource::getType, Function.identity()));
- return source.stream()
- .map(
- resource -> {
- Resource resourceCap = resourcesCaps.get(resource.getType());
- if (resourceCap != null) {
- if (resource.getAmount() == -1) {
- return resourceCap;
- } else if (resourceCap.getAmount() < resource.getAmount()) {
- return resourceCap;
- }
- }
- return resource;
- })
- .map(ResourceImpl::new)
- .collect(Collectors.toList());
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/MemberDao.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/MemberDao.java
deleted file mode 100644
index 279495d4c9a..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/MemberDao.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi;
-
-import java.util.List;
-import java.util.Optional;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-
-/**
- * Defines data access object for {@link MemberImpl}
- *
- * @author Sergii Leschenko
- */
-public interface MemberDao {
- /**
- * Stores (adds or updates) member.
- *
- * @param member member to store
- * @return optional with updated member, other way empty optional must be returned
- * @throws NullPointerException when {@code member} is null
- * @throws ServerException when organization or user doesn't exist
- * @throws ServerException when any other error occurs during member storing
- */
- Optional store(MemberImpl member) throws ServerException;
-
- /**
- * Removes member with given organization and user
- *
- * @param userId id of user
- * @param organizationId id of organization
- * @throws NullPointerException when {@code organizationId} or {@code userId} is null
- * @throws ServerException when any other error occurs during member removing
- */
- void remove(String userId, String organizationId) throws ServerException;
-
- /**
- * Returns member for specified organization and user
- *
- * @param organizationId organization id
- * @param userId user id
- * @return member for specified organization and user
- * @throws NullPointerException when {@code organizationId} or {@code userId} is null
- * @throws NotFoundException when member for given user and organization was not found
- * @throws ServerException when any other error occurs during member fetching
- */
- MemberImpl getMember(String organizationId, String userId)
- throws NotFoundException, ServerException;
-
- /**
- * Returns all members of given organization
- *
- * @param organizationId organization id
- * @param maxItems the maximum number of members to return
- * @param skipCount the number of members to skip
- * @throws NullPointerException when {@code organizationId} is null
- * @throws ServerException when any other error occurs during members fetching
- */
- Page getMembers(String organizationId, int maxItems, long skipCount)
- throws ServerException;
-
- /**
- * Returns all memberships of given user
- *
- * @param userId user id
- * @throws NullPointerException when {@code userId} is null
- * @throws ServerException when any other error occurs during members fetching
- */
- List getMemberships(String userId) throws ServerException;
-
- /**
- * Gets list organizations where user is member.
- *
- * @param userId user id
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of organizations where user is member
- * @throws NullPointerException when {@code userId} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- Page getOrganizations(String userId, int maxItems, long skipCount)
- throws ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDao.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDao.java
deleted file mode 100644
index 44352d29b5c..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDao.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi;
-
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-
-/**
- * Defines data access object for {@link OrganizationImpl}
- *
- * @author Sergii Leschenko
- */
-public interface OrganizationDao {
- /**
- * Creates organization.
- *
- * @param organization organization to create
- * @throws NullPointerException when {@code organization} is null
- * @throws ConflictException when organization with such id/name already exists
- * @throws ServerException when any other error occurs during organization creation
- */
- void create(OrganizationImpl organization) throws ServerException, ConflictException;
-
- /**
- * Updates organization with new entity.
- *
- * @param update organization update
- * @throws NullPointerException when {@code update} is null
- * @throws NotFoundException when organization with id {@code organization.getId()} doesn't exist
- * @throws ConflictException when name updated with a value which is not unique
- * @throws ServerException when any other error occurs organization updating
- */
- void update(OrganizationImpl update) throws NotFoundException, ConflictException, ServerException;
-
- /**
- * Removes organization with given id
- *
- * @param organizationId organization id
- * @throws NullPointerException when {@code organizationId} is null
- * @throws ServerException when any other error occurs during organization removing
- */
- void remove(String organizationId) throws ServerException;
-
- /**
- * Gets organization by identifier.
- *
- * @param organizationId organization id
- * @return organization instance
- * @throws NullPointerException when {@code organizationId} is null
- * @throws NotFoundException when organization with given id was not found
- * @throws ServerException when any other error occurs during organization fetching
- */
- OrganizationImpl getById(String organizationId) throws NotFoundException, ServerException;
-
- /**
- * Gets organization by name.
- *
- * @param organizationName organization name
- * @return organization instance
- * @throws NullPointerException when {@code organizationName} is null
- * @throws NotFoundException when organization with given name was not found
- * @throws ServerException when any other error occurs during organization fetching
- */
- OrganizationImpl getByName(String organizationName) throws NotFoundException, ServerException;
-
- /**
- * Gets child organizations by given parent.
- *
- * @param parent id of parent organization
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of children organizations
- * @throws NullPointerException when {@code parent} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- Page getByParent(String parent, int maxItems, long skipCount)
- throws ServerException;
-
- /**
- * Gets all child organizations by specified parent qualified name.
- *
- *
Note that the result will includes all direct and nested suborganizations.
- *
- * @param parentQualifiedName qualified name of parent organization
- * @param maxItems the maximum number of organizations to return
- * @param skipCount the number of organizations to skip
- * @return list of children organizations
- * @throws NullPointerException when {@code parentQualifiedName} is null
- * @throws ServerException when any other error occurs during organizations fetching
- */
- Page getSuborganizations(
- String parentQualifiedName, int maxItems, long skipCount) throws ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDistributedResourcesDao.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDistributedResourcesDao.java
deleted file mode 100644
index be69fd60a06..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/OrganizationDistributedResourcesDao.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi;
-
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationDistributedResourcesImpl;
-
-/**
- * Defines data access object contract for {@link OrganizationDistributedResourcesImpl}.
- *
- * @author Sergii Leschenko
- */
-public interface OrganizationDistributedResourcesDao {
- /**
- * Stores (creates or updated) distributed resources for suborganization.
- *
- * @param distributedResources distributed resources to store
- * @throws NullPointerException when either {@code distributedResources} is null
- * @throws ServerException when any other error occurs
- */
- void store(OrganizationDistributedResourcesImpl distributedResources) throws ServerException;
-
- /**
- * Returns distributed resources for specified suborganization.
- *
- * @param organizationId organization id
- * @return distributed resources for specified suborganization
- * @throws NullPointerException when either {@code organizationId} is null
- * @throws NotFoundException when organization with specified id doesn't have distributed
- * resources
- * @throws ServerException when any other error occurs
- */
- OrganizationDistributedResourcesImpl get(String organizationId)
- throws NotFoundException, ServerException;
-
- /**
- * Returns distributed resources for suborganizations of given parent organization.
- *
- * @param organizationId organization id
- * @return distributed resources for suborganizations of given parent organization
- * @throws NullPointerException when either {@code organizationId} is null
- * @throws ServerException when any other error occurs
- */
- Page getByParent(
- String organizationId, int maxItems, long skipCount) throws ServerException;
-
- /**
- * Remove distributed organization resources.
- *
- * @param organizationId organization id
- * @throws NullPointerException when either {@code organizationId} is null
- * @throws ServerException when any other error occurs
- */
- void remove(String organizationId) throws ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/MemberImpl.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/MemberImpl.java
deleted file mode 100644
index c794b14ad69..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/MemberImpl.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi.impl;
-
-import java.util.List;
-import javax.persistence.CollectionTable;
-import javax.persistence.Column;
-import javax.persistence.ElementCollection;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.Table;
-import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.shared.model.Member;
-
-/**
- * Data object for {@link Member}.
- *
- * @author Sergii Leschenko
- */
-@Entity(name = "Member")
-@NamedQueries({
- @NamedQuery(
- name = "Member.getMember",
- query =
- "SELECT m "
- + "FROM Member m "
- + "WHERE m.userId = :userId AND m.organizationId = :organizationId"),
- @NamedQuery(
- name = "Member.getByOrganization",
- query = "SELECT m " + "FROM Member m " + "WHERE m.organizationId = :organizationId"),
- @NamedQuery(
- name = "Member.getCountByOrganizationId",
- query = "SELECT COUNT(m) " + "FROM Member m " + "WHERE m.organizationId = :organizationId"),
- @NamedQuery(
- name = "Member.getByUser",
- query = "SELECT m " + "FROM Member m " + "WHERE m.userId = :userId"),
- @NamedQuery(
- name = "Member.getOrganizations",
- query = "SELECT org " + "FROM Member m, m.organization org " + "WHERE m.userId = :userId"),
- @NamedQuery(
- name = "Member.getOrganizationsCount",
- query = "SELECT COUNT(m) " + "FROM Member m " + "WHERE m.userId = :userId ")
-})
-@Table(name = "che_member")
-public class MemberImpl extends AbstractPermissions implements Member {
- @Column(name = "organization_id")
- private String organizationId;
-
- @ElementCollection(fetch = FetchType.EAGER)
- @Column(name = "actions")
- @CollectionTable(name = "che_member_actions", joinColumns = @JoinColumn(name = "member_id"))
- protected List actions;
-
- @ManyToOne
- @JoinColumn(
- name = "organization_id",
- referencedColumnName = "id",
- insertable = false,
- updatable = false)
- private OrganizationImpl organization;
-
- public MemberImpl() {}
-
- public MemberImpl(String userId, String organizationId, List actions) {
- super(userId);
- this.organizationId = organizationId;
- if (actions != null) {
- this.actions = actions;
- }
- }
-
- public MemberImpl(Member member) {
- this(member.getUserId(), member.getOrganizationId(), member.getActions());
- }
-
- @Override
- public String getInstanceId() {
- return organizationId;
- }
-
- @Override
- public String getDomainId() {
- return OrganizationDomain.DOMAIN_ID;
- }
-
- @Override
- public List getActions() {
- return actions;
- }
-
- @Override
- public String getOrganizationId() {
- return organizationId;
- }
-
- @Override
- public String toString() {
- return "MemberImpl{"
- + "userId='"
- + userId
- + '\''
- + ", organizationId='"
- + organizationId
- + '\''
- + ", actions="
- + actions
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationDistributedResourcesImpl.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationDistributedResourcesImpl.java
deleted file mode 100644
index 8142f144230..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationDistributedResourcesImpl.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToMany;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.Table;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Data object for {@link OrganizationDistributedResources}.
- *
- * @author Sergii Leschenko
- */
-@Entity(name = "OrganizationDistributedResources")
-@NamedQueries({
- @NamedQuery(
- name = "OrganizationDistributedResources.get",
- query =
- "SELECT r "
- + "FROM OrganizationDistributedResources r "
- + "WHERE r.organizationId = :organizationId"),
- @NamedQuery(
- name = "OrganizationDistributedResources.getByParent",
- query =
- "SELECT r "
- + "FROM OrganizationDistributedResources r "
- + "WHERE r.organization.parent = :parent"),
- @NamedQuery(
- name = "OrganizationDistributedResources.getCountByParent",
- query =
- "SELECT COUNT(r) "
- + "FROM OrganizationDistributedResources r "
- + "WHERE r.organization.parent = :parent")
-})
-@Table(name = "che_organization_distributed_resources")
-public class OrganizationDistributedResourcesImpl implements OrganizationDistributedResources {
- @Id
- @Column(name = "organization_id")
- private String organizationId;
-
- @PrimaryKeyJoinColumn private OrganizationImpl organization;
-
- @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
- @JoinTable(
- name = "che_organization_distributed_resources_resource",
- joinColumns = @JoinColumn(name = "organization_distributed_resources_id"),
- inverseJoinColumns = @JoinColumn(name = "resource_id"))
- private List resourcesCap;
-
- public OrganizationDistributedResourcesImpl() {}
-
- public OrganizationDistributedResourcesImpl(
- OrganizationDistributedResources organizationDistributedResource) {
- this(
- organizationDistributedResource.getOrganizationId(),
- organizationDistributedResource.getResourcesCap());
- }
-
- public OrganizationDistributedResourcesImpl(
- String organizationId, List extends Resource> resourcesCap) {
- this.organizationId = organizationId;
- if (resourcesCap != null) {
- this.resourcesCap = resourcesCap.stream().map(ResourceImpl::new).collect(Collectors.toList());
- }
- }
-
- @Override
- public String getOrganizationId() {
- return organizationId;
- }
-
- @Override
- public List getResourcesCap() {
- if (resourcesCap == null) {
- resourcesCap = new ArrayList<>();
- }
- return resourcesCap;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof OrganizationDistributedResourcesImpl)) {
- return false;
- }
- final OrganizationDistributedResourcesImpl that = (OrganizationDistributedResourcesImpl) obj;
- return Objects.equals(organizationId, that.organizationId)
- && Objects.equals(organization, that.organization)
- && getResourcesCap().equals(that.getResourcesCap());
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 31 * hash + Objects.hashCode(organizationId);
- hash = 31 * hash + Objects.hashCode(organization);
- hash = 31 * hash + getResourcesCap().hashCode();
- return hash;
- }
-
- @Override
- public String toString() {
- return "OrganizationDistributedResourcesImpl{"
- + "organizationId='"
- + organizationId
- + '\''
- + ", organization="
- + organization
- + ", resourcesCaps="
- + getResourcesCap()
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationImpl.java b/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationImpl.java
deleted file mode 100644
index fa8a56dd02e..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/java/org/eclipse/che/multiuser/organization/spi/impl/OrganizationImpl.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi.impl;
-
-import java.util.Objects;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToOne;
-import javax.persistence.Table;
-import org.eclipse.che.account.spi.AccountImpl;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-
-/**
- * Data object for {@link Organization}.
- *
- * @author Sergii Leschenko
- */
-@Entity(name = "Organization")
-@NamedQueries({
- @NamedQuery(
- name = "Organization.getByName",
- query = "SELECT o " + "FROM Organization o " + "WHERE o.account.name = :name"),
- @NamedQuery(
- name = "Organization.getByParent",
- query = "SELECT o " + "FROM Organization o " + "WHERE o.parent = :parent "),
- @NamedQuery(
- name = "Organization.getByParentCount",
- query = "SELECT COUNT(o) " + "FROM Organization o " + "WHERE o.parent = :parent "),
- @NamedQuery(
- name = "Organization.getSuborganizations",
- query = "SELECT o " + "FROM Organization o " + "WHERE o.account.name LIKE :qualifiedName "),
- @NamedQuery(
- name = "Organization.getSuborganizationsCount",
- query =
- "SELECT COUNT(o) " + "FROM Organization o " + "WHERE o.account.name LIKE :qualifiedName ")
-})
-@Table(name = "che_organization")
-public class OrganizationImpl implements Organization {
- public static final String ORGANIZATIONAL_ACCOUNT = "organizational";
-
- @Id
- @Column(name = "id")
- private String id;
-
- @OneToOne(cascade = CascadeType.ALL)
- @JoinColumn(name = "account_id", nullable = false)
- private AccountImpl account;
-
- @Column(name = "parent")
- private String parent;
-
- // Mapping exists for explicit constraints which allows
- // jpa backend to perform operations in correct order
- @ManyToOne
- @JoinColumn(name = "parent", insertable = false, updatable = false)
- private OrganizationImpl parentObj;
-
- public OrganizationImpl() {}
-
- public OrganizationImpl(Organization organization) {
- this(organization.getId(), organization.getQualifiedName(), organization.getParent());
- }
-
- public OrganizationImpl(String id, String qualifiedName, String parent) {
- this.id = id;
- this.account = new AccountImpl(id, qualifiedName, ORGANIZATIONAL_ACCOUNT);
- this.parent = parent;
- }
-
- @Override
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- @Override
- public String getName() {
- String qualifiedName = getQualifiedName();
- if (qualifiedName == null) {
- return null;
- }
-
- int lastSlashIndex = qualifiedName.lastIndexOf("/");
-
- if (lastSlashIndex == -1) {
- return qualifiedName;
- }
-
- return qualifiedName.substring(lastSlashIndex + 1);
- }
-
- @Override
- public String getQualifiedName() {
- if (account != null) {
- return account.getName();
- }
- return null;
- }
-
- public void setQualifiedName(String qualifiedName) {
- if (account != null) {
- account.setName(qualifiedName);
- }
- }
-
- @Override
- public String getParent() {
- return parent;
- }
-
- public void setParent(String parent) {
- this.parent = parent;
- }
-
- public AccountImpl getAccount() {
- return account;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof OrganizationImpl)) {
- return false;
- }
- OrganizationImpl that = (OrganizationImpl) o;
- return Objects.equals(id, that.id)
- && Objects.equals(getName(), that.getName())
- && Objects.equals(parent, that.parent);
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 31 * hash + Objects.hashCode(id);
- hash = 31 * hash + Objects.hashCode(getName());
- hash = 31 * hash + Objects.hashCode(getQualifiedName());
- hash = 31 * hash + Objects.hashCode(parent);
- return hash;
- }
-
- @Override
- public String toString() {
- return "OrganizationImpl{"
- + "id='"
- + id
- + '\''
- + ", name='"
- + getName()
- + '\''
- + ", qualifiedName='"
- + getQualifiedName()
- + '\''
- + ", parent='"
- + parent
- + '\''
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/main/resources/st-html-templates/organization_deleted b/multiuser/api/che-multiuser-api-organization/src/main/resources/st-html-templates/organization_deleted
deleted file mode 100644
index d19467bc298..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/main/resources/st-html-templates/organization_deleted
+++ /dev/null
@@ -1,23 +0,0 @@
-\
-\
-\
-\
-\
-\
-\
-\
-
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjectorTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjectorTest.java
deleted file mode 100644
index 4a8f079c933..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationLinksInjectorTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import jakarta.ws.rs.core.UriBuilder;
-import org.eclipse.che.api.core.rest.ServiceContext;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.organization.shared.Constants;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.everrest.core.impl.uri.UriBuilderImpl;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link org.eclipse.che.multiuser.organization.api.OrganizationLinksInjector}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationLinksInjectorTest {
- private static final String URI_BASE = "http://localhost:8080";
-
- @Mock ServiceContext context;
-
- OrganizationLinksInjector organizationLinksInjector = new OrganizationLinksInjector();
-
- @BeforeMethod
- public void setUp() {
- final UriBuilder uriBuilder = new UriBuilderImpl();
- uriBuilder.uri(URI_BASE);
-
- when(context.getBaseUriBuilder()).thenReturn(uriBuilder);
- }
-
- @Test
- public void shouldInjectLinks() {
- final OrganizationDto organization = DtoFactory.newDto(OrganizationDto.class).withId("org123");
-
- final OrganizationDto withLinks = organizationLinksInjector.injectLinks(organization, context);
-
- assertEquals(withLinks.getLinks().size(), 2);
- assertNotNull(withLinks.getLink(Constants.LINK_REL_SELF));
- assertNotNull(withLinks.getLink(Constants.LINK_REL_SUBORGANIZATIONS));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationManagerTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationManagerTest.java
deleted file mode 100644
index 44e4bd4c9fe..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationManagerTest.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2012-2026 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static java.util.Collections.singletonList;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.Collections;
-import java.util.List;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.notification.EventService;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.SubjectImpl;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.shared.model.Member;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.MemberDao;
-import org.eclipse.che.multiuser.organization.spi.OrganizationDao;
-import org.eclipse.che.multiuser.organization.spi.impl.MemberImpl;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link org.eclipse.che.multiuser.organization.api.OrganizationManager}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationManagerTest {
- @Captor private ArgumentCaptor organizationCaptor;
-
- private static final String USER_NAME = "user-name";
- private static final String USER_ID = "user-id";
-
- @Mock private OrganizationDao organizationDao;
-
- @Mock private MemberDao memberDao;
-
- @Mock private EventService eventService;
-
- private OrganizationManager manager;
-
- @BeforeMethod
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- manager =
- spy(
- new OrganizationManager(
- eventService, organizationDao, memberDao, new String[] {"reserved"}));
-
- lenient()
- .when(eventService.publish(any()))
- .thenAnswer(invocation -> invocation.getArguments()[0]);
- EnvironmentContext.getCurrent()
- .setSubject(
- new SubjectImpl(USER_NAME, Collections.emptyList(), USER_ID, "userToken", false));
- }
-
- @AfterMethod
- public void tearDown() throws Exception {
- EnvironmentContext.reset();
- }
-
- @Test
- public void shouldCreateOrganization() throws Exception {
- final Organization toCreate = DtoFactory.newDto(OrganizationDto.class).withName("newOrg");
-
- manager.create(toCreate);
-
- verify(organizationDao).create(organizationCaptor.capture());
- final OrganizationImpl createdOrganization = organizationCaptor.getValue();
- assertEquals(createdOrganization.getName(), toCreate.getName());
- assertEquals(createdOrganization.getQualifiedName(), toCreate.getName());
- assertEquals(createdOrganization.getParent(), toCreate.getParent());
- verify(memberDao)
- .store(
- new MemberImpl(USER_ID, createdOrganization.getId(), OrganizationDomain.getActions()));
- }
-
- @Test
- public void shouldCreateSuborganization() throws Exception {
- final OrganizationImpl parentOrganization = new OrganizationImpl("org123", "parentOrg", null);
- when(organizationDao.getById(anyString())).thenReturn(parentOrganization);
- final Organization toCreate = new OrganizationImpl(null, "orgName", parentOrganization.getId());
-
- manager.create(toCreate);
-
- verify(organizationDao).create(organizationCaptor.capture());
- final OrganizationImpl createdOrganization = organizationCaptor.getValue();
- assertEquals(createdOrganization.getName(), toCreate.getName());
- assertEquals(
- createdOrganization.getQualifiedName(),
- parentOrganization.getQualifiedName() + "/" + toCreate.getName());
- assertEquals(createdOrganization.getParent(), toCreate.getParent());
- verify(memberDao)
- .store(
- new MemberImpl(USER_ID, createdOrganization.getId(), OrganizationDomain.getActions()));
- }
-
- @Test
- public void shouldGenerateIdentifierWhenCreatingOrganization() throws Exception {
- final Organization organization =
- DtoFactory.newDto(OrganizationDto.class).withName("newOrg").withId("identifier");
-
- manager.create(organization);
-
- verify(organizationDao).create(organizationCaptor.capture());
- final String id = organizationCaptor.getValue().getId();
- assertNotNull(id);
- assertNotEquals(id, "identifier");
- }
-
- @Test(expectedExceptions = ConflictException.class)
- public void shouldThrowConflictExceptionOnCreationIfOrganizationNameIsReserved()
- throws Exception {
- final Organization organization =
- DtoFactory.newDto(OrganizationDto.class).withName("reserved").withParent(null);
-
- manager.create(organization);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenCreatingNullableOrganization() throws Exception {
- manager.create(null);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenUpdatingOrganizationWithNullEntity() throws Exception {
- manager.update("organizationId", null);
- }
-
- @Test
- public void shouldUpdateOrganizationAndIgnoreNewIdAndParentFields() throws Exception {
- final OrganizationImpl existing = new OrganizationImpl("org123", "oldName", "parent123");
- final OrganizationImpl expectedExistingToUpdate = new OrganizationImpl(existing);
- expectedExistingToUpdate.setQualifiedName("newName");
-
- final OrganizationImpl suborganization =
- new OrganizationImpl("org321", "oldName/suborgName", "org123");
- final OrganizationImpl expectedSuborganizationToUpdate = new OrganizationImpl(suborganization);
- expectedSuborganizationToUpdate.setQualifiedName(
- expectedExistingToUpdate.getQualifiedName() + "/" + suborganization.getName());
-
- when(organizationDao.getById(any())).thenReturn(existing);
- doReturn(new Page<>(singletonList(suborganization), 0, 1, 1))
- .when(organizationDao)
- .getSuborganizations(anyString(), anyInt(), anyLong());
- final OrganizationImpl update = new OrganizationImpl("newId", "newName", "newParentId");
-
- final Organization updated = manager.update("organizationId", update);
-
- verify(organizationDao).getById("organizationId");
- verify(organizationDao, times(2)).update(organizationCaptor.capture());
- List updatedOrganizations = organizationCaptor.getAllValues();
- assertEquals(updatedOrganizations.get(0), expectedExistingToUpdate);
- assertEquals(updatedOrganizations.get(1), expectedSuborganizationToUpdate);
- verify(organizationDao).getSuborganizations(eq("oldName"), anyInt(), anyLong());
- assertEquals(updated, expectedExistingToUpdate);
- }
-
- @Test(expectedExceptions = ConflictException.class)
- public void shouldThrowConflictExceptionOnUpdatingIfOrganizationNameIsReserved()
- throws Exception {
- when(organizationDao.getById("id")).thenReturn(new OrganizationImpl("id", "oldName", null));
-
- manager.update("id", new OrganizationImpl("id", "reserved", null));
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenUpdatingOrganizationByNullId() throws Exception {
- manager.update(null, new OrganizationImpl());
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenRemovingOrganizationByNullId() throws Exception {
- manager.remove(null);
- }
-
- @Test
- public void shouldRemoveOrganization() throws Exception {
- doNothing().when(manager).removeSuborganizations(anyString());
- final List members = Collections.singletonList(mock(Member.class));
- doReturn(members).when(manager).removeMembers(anyString());
- OrganizationImpl toRemove = new OrganizationImpl("org123", "toRemove", null);
- when(organizationDao.getById(anyString())).thenReturn(toRemove);
-
- manager.remove(toRemove.getId());
-
- verify(organizationDao).remove(toRemove.getId());
- verify(manager).removeMembers(eq(toRemove.getId()));
- verify(manager).removeSuborganizations(eq(toRemove.getId()));
- }
-
- @Test
- public void shouldRemoveMembersByOrganizationId() throws Exception {
- MemberImpl member1 = new MemberImpl("user1", "org1", singletonList("read"));
- MemberImpl member2 = new MemberImpl("user2", "org1", singletonList("read"));
- doReturn(new Page<>(singletonList(member1), 0, 1, 2))
- .doReturn(new Page<>(singletonList(member2), 1, 1, 2))
- .when(memberDao)
- .getMembers(anyString(), anyInt(), anyLong());
-
- manager.removeMembers("org1");
-
- verify(memberDao, times(2)).getMembers("org1", 100, 0);
- verify(memberDao).remove("user1", "org1");
- verify(memberDao).remove("user2", "org1");
- }
-
- @Test
- public void shouldRemoveSuborganizationsByParentOrganizationId() throws Exception {
- doNothing().when(manager).remove(any());
- OrganizationImpl subOrg1 = new OrganizationImpl("subOrg1", "subOrg1", "org1");
- OrganizationImpl subOrg2 = new OrganizationImpl("subOrg2", "subOrg2", "org1");
- doReturn(new Page<>(singletonList(subOrg1), 0, 1, 2))
- .doReturn(new Page<>(singletonList(subOrg2), 1, 1, 2))
- .when(organizationDao)
- .getByParent(anyString(), anyInt(), anyLong());
-
- manager.removeSuborganizations("org1");
-
- verify(organizationDao, times(2)).getByParent("org1", 100, 0);
- verify(manager).remove("subOrg1");
- verify(manager).remove("subOrg2");
- }
-
- @Test
- public void shouldNotTryToRemoveOrganizationWhenItIsNotExistRemoveOrganization()
- throws Exception {
- when(organizationDao.getById(anyString())).thenThrow(new NotFoundException("not found"));
-
- manager.remove("id");
-
- verify(organizationDao, never()).remove(anyString());
- verify(eventService, never()).publish(any());
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenGettingOrganizationByNullName() throws Exception {
- manager.getById(null);
- }
-
- @Test
- public void shouldGetOrganizationByName() throws Exception {
- final OrganizationImpl toFetch = new OrganizationImpl("org123", "toFetchOrg", "org321");
- when(organizationDao.getByName(eq("org123"))).thenReturn(toFetch);
-
- final Organization fetched = manager.getByName("org123");
-
- assertEquals(fetched, toFetch);
- verify(organizationDao).getByName("org123");
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenGettingOrganizationByNullId() throws Exception {
- manager.getById(null);
- }
-
- @Test
- public void shouldGetOrganizationById() throws Exception {
- final OrganizationImpl toFetch = new OrganizationImpl("org123", "toFetchOrg", "org321");
- when(organizationDao.getById(eq("org123"))).thenReturn(toFetch);
-
- final Organization fetched = manager.getById("org123");
-
- assertEquals(fetched, toFetch);
- verify(organizationDao).getById("org123");
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenGettingSuborganizationsByNullParent() throws Exception {
- manager.getByParent(null, 30, 0);
- }
-
- @Test
- public void shouldGetOrganizationsByParent() throws Exception {
- final OrganizationImpl toFetch = new OrganizationImpl("org321", "toFetchOrg", "org123");
- when(organizationDao.getByParent(eq("org123"), anyInt(), anyLong()))
- .thenReturn(new Page<>(singletonList(toFetch), 0, 1, 1));
-
- final Page extends Organization> organizations = manager.getByParent("org123", 30, 0);
-
- assertEquals(organizations.getItemsCount(), 1);
- assertEquals(organizations.getItems().get(0), toFetch);
- verify(organizationDao).getByParent("org123", 30, 0);
- }
-
- @Test
- public void shouldGetSuborganizations() throws Exception {
- final OrganizationImpl toFetch = new OrganizationImpl("org321", "parent/toFetchOrg", "org123");
- when(organizationDao.getSuborganizations(eq("parent"), anyInt(), anyLong()))
- .thenReturn(new Page<>(singletonList(toFetch), 0, 1, 1));
-
- final Page extends Organization> organizations = manager.getSuborganizations("parent", 30, 0);
-
- assertEquals(organizations.getItemsCount(), 1);
- assertEquals(organizations.getItems().get(0), toFetch);
- verify(organizationDao).getSuborganizations("parent", 30, 0);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeOnGettingSuborganizationsByNullParentQualifiedName() throws Exception {
- manager.getSuborganizations(null, 30, 0);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeWhenGettingOrganizationsByNullUserId() throws Exception {
- manager.getByMember(null, 30, 0);
- }
-
- @Test
- public void shouldGetOrganizationsByMember() throws Exception {
- final OrganizationImpl toFetch = new OrganizationImpl("org123", "toFetchOrg", "org321");
- when(memberDao.getOrganizations(eq("org123"), anyInt(), anyLong()))
- .thenReturn(new Page<>(singletonList(toFetch), 0, 1, 1));
-
- final Page extends Organization> organizations = manager.getByMember("org123", 30, 0);
-
- assertEquals(organizations.getItemsCount(), 1);
- assertEquals(organizations.getItems().get(0), toFetch);
- verify(memberDao).getOrganizations("org123", 30, 0);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationServiceTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationServiceTest.java
deleted file mode 100644
index 3c236f7b92c..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/OrganizationServiceTest.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2012-2026 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api;
-
-import static io.restassured.RestAssured.given;
-import static java.util.Collections.singletonList;
-import static java.util.stream.Collectors.toList;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
-import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-
-import io.restassured.response.Response;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.rest.ApiExceptionMapper;
-import org.eclipse.che.api.core.rest.CheJsonProvider;
-import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.SubjectImpl;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.everrest.assured.EverrestJetty;
-import org.everrest.core.Filter;
-import org.everrest.core.GenericContainerRequest;
-import org.everrest.core.RequestFilter;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link org.eclipse.che.multiuser.organization.api.OrganizationService}.
- *
- * @author Sergii Leschenko
- */
-@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
-public class OrganizationServiceTest {
-
- private static final String CURRENT_USER_ID = "user123";
-
- @SuppressWarnings("unused") // is declared for deploying by everrest-assured
- private ApiExceptionMapper mapper;
-
- @SuppressWarnings("unused") // is declared for deploying by everrest-assured
- private EnvironmentFilter filter;
-
- @SuppressWarnings("unused") // is declared for deploying by everrest-assured
- private CheJsonProvider jsonProvider = new CheJsonProvider(new HashSet<>());
-
- @Mock private OrganizationManager orgManager;
-
- @Mock private OrganizationLinksInjector linksInjector;
-
- @Mock private OrganizationValidator validator;
-
- @InjectMocks private OrganizationService service;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient()
- .when(linksInjector.injectLinks(any(), any()))
- .thenAnswer(invocation -> invocation.getArguments()[0]);
- }
-
- @Test
- public void shouldCreateOrganization() throws Exception {
- when(orgManager.create(any()))
- .thenAnswer(
- invocationOnMock ->
- new OrganizationImpl((Organization) invocationOnMock.getArguments()[0]));
-
- final OrganizationDto toCreate = createOrganization();
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(toCreate)
- .when()
- .post(SECURE_PATH + "/organization");
- assertEquals(response.statusCode(), 201);
- final OrganizationDto createdOrganization = unwrapDto(response, OrganizationDto.class);
- assertEquals(createdOrganization, toCreate);
- verify(linksInjector).injectLinks(any(), any());
- verify(orgManager).create(eq(toCreate));
- }
-
- @Test
- public void shouldThrowBadRequestWhenCreatingNonValidOrganization() throws Exception {
- doThrow(new BadRequestException("non valid organization"))
- .when(validator)
- .checkOrganization(any());
-
- final OrganizationDto toCreate = createOrganization();
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(toCreate)
- .when()
- .post(SECURE_PATH + "/organization");
- assertEquals(response.statusCode(), 400);
- final ServiceError error = unwrapDto(response, ServiceError.class);
- assertEquals(error.getMessage(), "non valid organization");
- verify(validator).checkOrganization(toCreate);
- }
-
- @Test
- public void shouldUpdateOrganization() throws Exception {
- when(orgManager.update(anyString(), any()))
- .thenAnswer(
- invocationOnMock ->
- new OrganizationImpl((Organization) invocationOnMock.getArguments()[1]));
-
- final OrganizationDto toUpdate = createOrganization();
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(toUpdate)
- .when()
- .post(SECURE_PATH + "/organization/organization123");
- assertEquals(response.statusCode(), 200);
- final OrganizationDto createdOrganization = unwrapDto(response, OrganizationDto.class);
- assertEquals(createdOrganization, toUpdate);
- verify(linksInjector).injectLinks(any(), any());
- verify(orgManager).update(eq("organization123"), eq(toUpdate));
- }
-
- @Test
- public void shouldThrowBadRequestWhenUpdatingNonValidOrganization() throws Exception {
- doThrow(new BadRequestException("non valid organization"))
- .when(validator)
- .checkOrganization(any());
-
- final OrganizationDto toUpdate = createOrganization();
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(toUpdate)
- .when()
- .post(SECURE_PATH + "/organization/organization123");
- assertEquals(response.statusCode(), 400);
- final ServiceError error = unwrapDto(response, ServiceError.class);
- assertEquals(error.getMessage(), "non valid organization");
- verify(validator).checkOrganization(toUpdate);
- }
-
- @Test
- public void shouldRemoveOrganization() throws Exception {
- Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .delete(SECURE_PATH + "/organization/organization123");
- assertEquals(response.statusCode(), 204);
- verify(orgManager).remove(eq("organization123"));
- }
-
- @Test
- public void shouldGetOrganizationById() throws Exception {
- final OrganizationDto toFetch = createOrganization();
-
- when(orgManager.getById(eq("organization123"))).thenReturn(toFetch);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.statusCode(), 200);
- final OrganizationDto fetchedOrganization = unwrapDto(response, OrganizationDto.class);
- assertEquals(fetchedOrganization, toFetch);
- verify(orgManager).getById(eq("organization123"));
- verify(linksInjector).injectLinks(any(), any());
- }
-
- @Test
- public void shouldFindOrganizationByName() throws Exception {
- final OrganizationDto toFetch = createOrganization();
-
- when(orgManager.getByName(eq("subOrg"))).thenReturn(toFetch);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .get(SECURE_PATH + "/organization/find?name=subOrg");
- assertEquals(response.statusCode(), 200);
- final OrganizationDto fetchedOrganization = unwrapDto(response, OrganizationDto.class);
- assertEquals(fetchedOrganization, toFetch);
- verify(orgManager).getByName(eq("subOrg"));
- verify(linksInjector).injectLinks(any(), any());
- }
-
- @Test
- public void shouldThrowBadRequestExceptionWhenFindingOrganizationWithoutName() throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/find")
- .then()
- .assertThat()
- .statusCode(400);
- }
-
- @Test
- public void shouldGetChildOrganizations() throws Exception {
- final OrganizationDto toFetch = createOrganization();
-
- doReturn(new Page<>(singletonList(toFetch), 0, 1, 1))
- .when(orgManager)
- .getByParent(anyString(), anyInt(), anyLong());
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/parentOrg123/organizations?skipCount=0&maxItems=1");
- assertEquals(response.statusCode(), 200);
- final List organizationDtos = unwrapDtoList(response, OrganizationDto.class);
- assertEquals(organizationDtos.size(), 1);
- assertEquals(organizationDtos.get(0), toFetch);
- verify(orgManager).getByParent("parentOrg123", 1, 0);
- verify(linksInjector).injectLinks(any(), any());
- }
-
- @Test
- public void shouldGetOrganizationsByCurrentUserIfParameterIsNotSpecified() throws Exception {
- final OrganizationDto toFetch = createOrganization();
-
- doReturn(new Page<>(singletonList(toFetch), 0, 1, 1))
- .when(orgManager)
- .getByMember(anyString(), anyInt(), anyInt());
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization?skipCount=0&maxItems=1");
- assertEquals(response.statusCode(), 200);
- final List organizationDtos = unwrapDtoList(response, OrganizationDto.class);
- assertEquals(organizationDtos.size(), 1);
- assertEquals(organizationDtos.get(0), toFetch);
- verify(orgManager).getByMember(CURRENT_USER_ID, 1, 0);
- verify(linksInjector).injectLinks(any(), any());
- }
-
- @Test
- public void shouldGetOrganizationsBySpecifiedUser() throws Exception {
- final OrganizationDto toFetch = createOrganization();
-
- doReturn(new Page<>(singletonList(toFetch), 0, 1, 1))
- .when(orgManager)
- .getByMember(anyString(), anyInt(), anyInt());
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization?user=user789&skipCount=0&maxItems=1");
- assertEquals(response.statusCode(), 200);
- final List organizationDtos = unwrapDtoList(response, OrganizationDto.class);
- assertEquals(organizationDtos.size(), 1);
- assertEquals(organizationDtos.get(0), toFetch);
- verify(orgManager).getByMember("user789", 1, 0);
- verify(linksInjector).injectLinks(any(), any());
- }
-
- private static T unwrapDto(Response response, Class dtoClass) {
- return DtoFactory.getInstance().createDtoFromJson(response.body().print(), dtoClass);
- }
-
- private static List unwrapDtoList(Response response, Class dtoClass) {
- return DtoFactory.getInstance()
- .createListDtoFromJson(response.body().print(), dtoClass)
- .stream()
- .collect(toList());
- }
-
- private OrganizationDto createOrganization() {
- return DtoFactory.newDto(OrganizationDto.class)
- .withId("organization123")
- .withName("subOrg")
- .withQualifiedName("parentOrg/subOrg")
- .withParent("parentOrg123");
- }
-
- @Filter
- public static class EnvironmentFilter implements RequestFilter {
- @Override
- public void doFilter(GenericContainerRequest request) {
- EnvironmentContext.getCurrent()
- .setSubject(
- new SubjectImpl(
- "userName", Collections.emptyList(), CURRENT_USER_ID, "token", false));
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilterTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilterTest.java
deleted file mode 100644
index 8288a748f2a..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationPermissionsFilterTest.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static io.restassured.RestAssured.given;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.DELETE;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.DOMAIN_ID;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.MANAGE_SUBORGANIZATIONS;
-import static org.eclipse.che.multiuser.organization.api.permissions.OrganizationDomain.UPDATE;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
-import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import io.restassured.response.Response;
-import io.restassured.specification.RequestSpecification;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.rest.ApiExceptionMapper;
-import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.api.OrganizationService;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDto;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.everrest.assured.EverrestJetty;
-import org.everrest.core.Filter;
-import org.everrest.core.GenericContainerRequest;
-import org.everrest.core.RequestFilter;
-import org.everrest.core.resource.GenericResourceMethod;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.permissions.OrganizationPermissionsFilter}
- *
- * @author Sergii Leschenko
- */
-@Listeners(value = {EverrestJetty.class, MockitoTestNGListener.class})
-public class OrganizationPermissionsFilterTest {
- @SuppressWarnings("unused")
- private static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
-
- @SuppressWarnings("unused")
- private static final EnvironmentFilter FILTER = new EnvironmentFilter();
-
- private static final String USER_ID = "user123";
-
- @Mock private static Subject subject;
-
- @Mock private OrganizationService service;
-
- @Mock private OrganizationManager manager;
-
- @Mock private SuperPrivilegesChecker superPrivilegesChecker;
-
- @InjectMocks private OrganizationPermissionsFilter permissionsFilter;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient().when(subject.getUserId()).thenReturn(USER_ID);
-
- lenient()
- .when(manager.getById(anyString()))
- .thenReturn(new OrganizationImpl("organization123", "test", null));
- }
-
- @Test
- public void shouldTestThatAllPublicMethodsAreCoveredByPermissionsFilter() throws Exception {
- // given
- final List collect =
- Stream.of(OrganizationService.class.getDeclaredMethods())
- .filter(method -> Modifier.isPublic(method.getModifiers()))
- .map(Method::getName)
- .collect(Collectors.toList());
-
- // then
- assertEquals(collect.size(), 7);
- assertTrue(collect.contains(OrganizationPermissionsFilter.CREATE_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.UPDATE_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.REMOVE_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.GET_BY_PARENT_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.GET_ORGANIZATIONS_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.GET_BY_ID_METHOD));
- assertTrue(collect.contains(OrganizationPermissionsFilter.FIND_METHOD));
- }
-
- @Test
- public void shouldNotCheckPermissionsOnGettingOrganizationById() throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/organization123");
-
- verify(service).getById("organization123");
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldNotCheckPermissionsOnGettingOrganizationByName() throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/find?name=test");
-
- verify(service).find("test");
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldNotCheckPermissionsOnOrganizationsFetchingIfUserIdIsNotSpecified()
- throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .expect()
- .statusCode(204)
- .when()
- .get(SECURE_PATH + "/organization");
-
- verify(service).getOrganizations(eq(null), anyInt(), anyInt());
- verify(subject, never()).hasPermission(anyString(), anyString(), anyString());
- }
-
- @Test
- public void shouldNotCheckPermissionsOnOrganizationsFetchingIfUserSpecifiesHisOwnId()
- throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .expect()
- .statusCode(204)
- .when()
- .get(SECURE_PATH + "/organization?user=" + USER_ID);
-
- verify(service).getOrganizations(eq(USER_ID), anyInt(), anyInt());
- verify(subject, never()).hasPermission(anyString(), anyString(), anyString());
- }
-
- @Test
- public void shouldCheckSuperPrivilegesOnOrganizationsFetchingIfUserSpecifiesForeignId()
- throws Exception {
- when(superPrivilegesChecker.hasSuperPrivileges()).thenReturn(true);
-
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .expect()
- .statusCode(204)
- .when()
- .get(SECURE_PATH + "/organization?user=user321");
-
- verify(service).getOrganizations(eq("user321"), anyInt(), anyInt());
- verify(superPrivilegesChecker).hasSuperPrivileges();
- }
-
- @Test
- public void
- shouldThrowForbiddenExceptionOnOrganizationsFetchingIfUserSpecifiesForeignIdAndDoesNotHaveSuperPrivileges()
- throws Exception {
- when(superPrivilegesChecker.hasSuperPrivileges()).thenReturn(false);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .expect()
- .statusCode(403)
- .when()
- .get(SECURE_PATH + "/organization?user=user321");
-
- assertEquals(unwrapError(response), "The user is able to specify only his own id");
- verify(superPrivilegesChecker).hasSuperPrivileges();
- verifyNoMoreInteractions(service);
- }
-
- @Test
- public void shouldCheckPermissionsOnOrganizationUpdating() throws Exception {
- when(subject.hasPermission(DOMAIN_ID, "organization123", UPDATE)).thenReturn(true);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .post(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).update(eq("organization123"), any());
- verify(subject).hasPermission(DOMAIN_ID, "organization123", UPDATE);
- verify(superPrivilegesChecker, never()).hasSuperPrivileges();
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldCheckPermissionsOnParentOrgLevelOnChildOrganizationUpdating() throws Exception {
- when(manager.getById(anyString()))
- .thenReturn(new OrganizationImpl("organization123", "test", "parent123"));
- when(subject.hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS)).thenReturn(true);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .post(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).update(eq("organization123"), any());
- verify(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- verify(superPrivilegesChecker, never()).hasSuperPrivileges();
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void
- shouldCheckPermissionsOnChildOrganizationUpdatingWhenUserDoesNotHavePermissionsOnParentOrgLevel()
- throws Exception {
- when(manager.getById(anyString()))
- .thenReturn(new OrganizationImpl("organization123", "test", "parent123"));
- doReturn(false).when(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- doReturn(true).when(subject).hasPermission(DOMAIN_ID, "organization123", UPDATE);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .post(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).update(eq("organization123"), any());
- verify(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- verify(subject).hasPermission(DOMAIN_ID, "organization123", UPDATE);
- }
-
- @Test
- public void shouldCheckPermissionsOnOrganizationRemoving() throws Exception {
- when(subject.hasPermission(DOMAIN_ID, "organization123", DELETE)).thenReturn(true);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .delete(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).remove(eq("organization123"));
- verify(subject).hasPermission(DOMAIN_ID, "organization123", DELETE);
- verify(superPrivilegesChecker, never()).hasSuperPrivileges();
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldCheckPermissionsOnParentOrgLevelOnChildOrganizationRemoving() throws Exception {
- when(manager.getById(anyString()))
- .thenReturn(new OrganizationImpl("organization123", "test", "parent123"));
- when(subject.hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS)).thenReturn(true);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .delete(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).remove(eq("organization123"));
- verify(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- verify(superPrivilegesChecker, never()).hasSuperPrivileges();
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void
- shouldCheckPermissionsOnChildOrganizationRemovingWhenUserDoesNotHavePermissionsOnParentOrgLevel()
- throws Exception {
- when(manager.getById(anyString()))
- .thenReturn(new OrganizationImpl("organization123", "test", "parent123"));
- doReturn(false).when(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- doReturn(true).when(subject).hasPermission(DOMAIN_ID, "organization123", DELETE);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .delete(SECURE_PATH + "/organization/organization123");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).remove(eq("organization123"));
- verify(subject).hasPermission(DOMAIN_ID, "parent123", MANAGE_SUBORGANIZATIONS);
- verify(subject).hasPermission(DOMAIN_ID, "organization123", DELETE);
- verify(superPrivilegesChecker, never()).hasSuperPrivileges();
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldNotCheckPermissionsOnRootOrganizationCreation() throws Exception {
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .body(DtoFactory.newDto(OrganizationDto.class).withParent(null))
- .post(SECURE_PATH + "/organization");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).create(any());
- verifyNoMoreInteractions(subject);
- }
-
- @Test
- public void shouldCheckPermissionsOnChildOrganizationCreation() throws Exception {
- when(subject.hasPermission(DOMAIN_ID, "parent-org", MANAGE_SUBORGANIZATIONS)).thenReturn(true);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .body(DtoFactory.newDto(OrganizationDto.class).withParent("parent-org"))
- .post(SECURE_PATH + "/organization");
-
- assertEquals(response.getStatusCode(), 204);
- verify(service).create(any());
- verify(subject).hasPermission(DOMAIN_ID, "parent-org", MANAGE_SUBORGANIZATIONS);
- }
-
- @Test
- public void
- shouldThrowForbiddenExceptionOnChildOrganizationCreationIfUserDoesNotHaveCorrespondingPermission()
- throws Exception {
- when(subject.hasPermission(DOMAIN_ID, "parent-org", MANAGE_SUBORGANIZATIONS)).thenReturn(false);
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .body(DtoFactory.newDto(OrganizationDto.class).withParent("parent-org"))
- .post(SECURE_PATH + "/organization");
-
- assertEquals(response.getStatusCode(), 403);
- verifyNoMoreInteractions(service);
- verify(subject).hasPermission(DOMAIN_ID, "parent-org", MANAGE_SUBORGANIZATIONS);
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp =
- "The user does not have permission to perform this operation")
- public void shouldThrowForbiddenExceptionWhenRequestedUnknownMethod() throws Exception {
- final GenericResourceMethod mock = mock(GenericResourceMethod.class);
- Method injectLinks = OrganizationService.class.getMethod("getServiceDescriptor");
- when(mock.getMethod()).thenReturn(injectLinks);
-
- permissionsFilter.filter(mock, new Object[] {});
- }
-
- @Test(dataProvider = "coveredPaths")
- public void shouldThrowForbiddenExceptionWhenUserDoesNotHavePermissionsForPerformOperation(
- String path, String method, String action) throws Exception {
- when(subject.hasPermission(anyString(), anyString(), anyString())).thenReturn(false);
-
- Response response =
- request(
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when(),
- SECURE_PATH + path,
- method);
-
- assertEquals(response.getStatusCode(), 403);
- assertEquals(
- unwrapError(response),
- "The user does not have permission to "
- + action
- + " organization with id 'organization123'");
-
- verifyNoMoreInteractions(service);
- }
-
- @Test(dataProvider = "coveredPaths")
- public void shouldThrowNotFoundWhenUserRequestsNonExistedOrganization(
- String path, String method, String ignored) throws Exception {
- when(manager.getById(anyString()))
- .thenThrow(new NotFoundException("Organization was not found"));
-
- Response response =
- request(
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when(),
- SECURE_PATH + path,
- method);
-
- assertEquals(response.getStatusCode(), 404);
- assertEquals(unwrapError(response), "Organization was not found");
-
- verifyNoMoreInteractions(service);
- }
-
- @DataProvider(name = "coveredPaths")
- public Object[][] pathsProvider() {
- return new Object[][] {
- {"/organization/organization123", "post", UPDATE},
- {"/organization/organization123", "delete", DELETE},
- {"/organization/organization123/organizations", "get", MANAGE_SUBORGANIZATIONS}
- };
- }
-
- private Response request(RequestSpecification request, String path, String method) {
- switch (method) {
- case "post":
- return request.post(path);
- case "get":
- return request.get(path);
- case "delete":
- return request.delete(path);
- case "put":
- return request.put(path);
- }
- throw new RuntimeException("Unsupported method");
- }
-
- private static String unwrapError(Response response) {
- return unwrapDto(response, ServiceError.class).getMessage();
- }
-
- private static T unwrapDto(Response response, Class dtoClass) {
- return DtoFactory.getInstance().createDtoFromJson(response.body().print(), dtoClass);
- }
-
- @Filter
- public static class EnvironmentFilter implements RequestFilter {
- @Override
- public void doFilter(GenericContainerRequest request) {
- EnvironmentContext.getCurrent().setSubject(subject);
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecksTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecksTest.java
deleted file mode 100644
index b8b200c8953..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationRemoteSubscriptionPermissionsChecksTest.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster.ORGANIZATION_CHANGED_METHOD_NAME;
-import static org.eclipse.che.multiuser.organization.api.listener.OrganizationEventsWebsocketBroadcaster.ORGANIZATION_MEMBERSHIP_METHOD_NAME;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.multiuser.api.permission.server.PermissionsManager;
-import org.eclipse.che.multiuser.api.permission.server.jsonrpc.RemoteSubscriptionPermissionManager;
-import org.eclipse.che.multiuser.api.permission.server.model.impl.AbstractPermissions;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationRemoteSubscriptionPermissionsChecks.MembershipsChangedSubscriptionCheck;
-import org.eclipse.che.multiuser.organization.api.permissions.OrganizationRemoteSubscriptionPermissionsChecks.OrganizationChangedSubscriptionCheck;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests {@link OrganizationRemoteSubscriptionPermissionsChecks}.
- *
- * @author Sergii Leshchenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationRemoteSubscriptionPermissionsChecksTest {
- @Mock private Subject subject;
-
- @Mock private PermissionsManager permissionsManager;
- @Mock private RemoteSubscriptionPermissionManager permissionManager;
-
- @InjectMocks private OrganizationRemoteSubscriptionPermissionsChecks permissionsChecks;
-
- @BeforeMethod
- public void setUp() {
- EnvironmentContext.getCurrent().setSubject(subject);
- }
-
- @AfterMethod
- public void tearDown() {
- EnvironmentContext.reset();
- }
-
- @Test
- public void shouldRegisterChecks() {
- // when
- permissionsChecks.register(permissionManager);
-
- // then
- verify(permissionManager)
- .registerCheck(
- any(OrganizationChangedSubscriptionCheck.class), eq(ORGANIZATION_CHANGED_METHOD_NAME));
- verify(permissionManager)
- .registerCheck(
- any(MembershipsChangedSubscriptionCheck.class),
- eq(ORGANIZATION_MEMBERSHIP_METHOD_NAME));
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp = "User id must be specified in scope")
- public void shouldThrowExceptionIfUserIdIsMissing() throws Exception {
- // given
- MembershipsChangedSubscriptionCheck check = new MembershipsChangedSubscriptionCheck();
- when(subject.getUserId()).thenReturn("user2");
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, Collections.emptyMap());
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp = "It is only allowed to listen to own memberships changes")
- public void shouldThrowExceptionIfUserTryToListenToForeignMemberships() throws Exception {
- // given
- MembershipsChangedSubscriptionCheck check = new MembershipsChangedSubscriptionCheck();
- when(subject.getUserId()).thenReturn("user2");
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, ImmutableMap.of("userId", "user1"));
- }
-
- @Test
- public void shouldDoNothingIfUserTryToListenToOwnMemberships() throws Exception {
- // given
- MembershipsChangedSubscriptionCheck check = new MembershipsChangedSubscriptionCheck();
- when(subject.getUserId()).thenReturn("user1");
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, ImmutableMap.of("userId", "user1"));
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp = "Organization id must be specified in scope")
- public void shouldThrowExceptionIfOrganizationIdIsMissing() throws Exception {
- // given
- OrganizationChangedSubscriptionCheck check =
- new OrganizationChangedSubscriptionCheck(permissionsManager);
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, Collections.emptyMap());
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp =
- "User doesn't have any permissions for the specified organization")
- public void shouldThrowExceptionIfUserDoesNotHaveAnyPermissionsToRequestedOrganization()
- throws Exception {
- // given
- OrganizationChangedSubscriptionCheck check =
- new OrganizationChangedSubscriptionCheck(permissionsManager);
- when(subject.getUserId()).thenReturn("user1");
- when(permissionsManager.get("user1", OrganizationDomain.DOMAIN_ID, "org123"))
- .thenThrow(new NotFoundException(""));
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, ImmutableMap.of("organizationId", "org123"));
- }
-
- @Test
- public void shouldDoNothingIfUserTryToListenEventsOfOrganizationWhereHeHasPermissions()
- throws Exception {
- // given
- OrganizationChangedSubscriptionCheck check =
- new OrganizationChangedSubscriptionCheck(permissionsManager);
- when(subject.getUserId()).thenReturn("user1");
- when(permissionsManager.get("user1", OrganizationDomain.DOMAIN_ID, "org123"))
- .thenReturn(mock(AbstractPermissions.class));
-
- // when
- check.check(ORGANIZATION_MEMBERSHIP_METHOD_NAME, ImmutableMap.of("organizationId", "org123"));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilterTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilterTest.java
deleted file mode 100644
index d774a58c731..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationResourceDistributionServicePermissionsFilterTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static io.restassured.RestAssured.given;
-import static java.util.Collections.emptyList;
-import static java.util.stream.Collectors.toList;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
-import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import jakarta.ws.rs.core.MediaType;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.stream.Stream;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.api.core.rest.ApiExceptionMapper;
-import org.eclipse.che.api.core.rest.CheJsonProvider;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.api.permission.server.SuperPrivilegesChecker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.api.resource.OrganizationResourcesDistributionService;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-import org.everrest.assured.EverrestJetty;
-import org.everrest.core.Filter;
-import org.everrest.core.GenericContainerRequest;
-import org.everrest.core.RequestFilter;
-import org.everrest.core.resource.GenericResourceMethod;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.permissions.OrganizationResourceDistributionServicePermissionsFilter}
- *
- * @author Sergii Leschenko
- */
-@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
-public class OrganizationResourceDistributionServicePermissionsFilterTest {
- @SuppressWarnings("unused")
- private static final ApiExceptionMapper MAPPER = new ApiExceptionMapper();
-
- @SuppressWarnings("unused")
- private static final EnvironmentFilter FILTER = new EnvironmentFilter();
-
- @SuppressWarnings("unused")
- private static final CheJsonProvider JSON_PROVIDER = new CheJsonProvider(new HashSet<>());
-
- private static final String SUBORGANIZATION = "org123";
- private static final String PARENT_ORGANIZATION = "parentOrg123";
-
- @Mock private static Subject subject;
-
- @Mock private OrganizationResourcesDistributionService service;
-
- @Mock private OrganizationManager manager;
-
- @Mock private SuperPrivilegesChecker superPrivilegesChecker;
-
- @InjectMocks private OrganizationResourceDistributionServicePermissionsFilter permissionsFilter;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient()
- .when(manager.getById(SUBORGANIZATION))
- .thenReturn(new OrganizationImpl(SUBORGANIZATION, "testOrg", PARENT_ORGANIZATION));
- lenient()
- .when(manager.getById(PARENT_ORGANIZATION))
- .thenReturn(new OrganizationImpl(PARENT_ORGANIZATION, "parentOrg", null));
-
- lenient().when(subject.hasPermission(anyString(), anyString(), anyString())).thenReturn(true);
- }
-
- @Test
- public void shouldTestThatAllPublicMethodsAreCoveredByPermissionsFilter() throws Exception {
- // given
- final List collect =
- Stream.of(OrganizationResourcesDistributionService.class.getDeclaredMethods())
- .filter(method -> Modifier.isPublic(method.getModifiers()))
- .map(Method::getName)
- .collect(toList());
-
- // then
- assertEquals(collect.size(), 3);
- assertTrue(
- collect.contains(
- OrganizationResourceDistributionServicePermissionsFilter.CAP_RESOURCES_METHOD));
- assertTrue(
- collect.contains(
- OrganizationResourceDistributionServicePermissionsFilter.GET_RESOURCES_CAP_METHOD));
- assertTrue(
- collect.contains(
- OrganizationResourceDistributionServicePermissionsFilter.GET_DISTRIBUTED_RESOURCES));
- }
-
- @Test
- public void shouldCheckManageResourcesPermissionsOnResourcesCappingForSuborganization()
- throws Exception {
- List resources =
- Collections.singletonList(
- DtoFactory.newDto(ResourceDto.class).withType("test").withAmount(123).withUnit("unit"));
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType(MediaType.APPLICATION_JSON)
- .body(resources)
- .expect()
- .statusCode(204)
- .when()
- .post(SECURE_PATH + "/organization/resource/" + SUBORGANIZATION + "/cap");
-
- verify(service).capResources(SUBORGANIZATION, resources);
- verify(subject)
- .hasPermission(
- OrganizationDomain.DOMAIN_ID, PARENT_ORGANIZATION, OrganizationDomain.MANAGE_RESOURCES);
- }
-
- @Test
- public void shouldNotCheckPermissionsOnResourcesCappingForRootOrganization() throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType(MediaType.APPLICATION_JSON)
- .body(emptyList())
- .expect()
- .statusCode(204)
- .when()
- .post(SECURE_PATH + "/organization/resource/" + PARENT_ORGANIZATION + "/cap");
-
- verify(service).capResources(PARENT_ORGANIZATION, emptyList());
- verify(subject, never()).hasPermission(anyString(), anyString(), anyString());
- }
-
- @Test
- public void
- shouldCheckManageResourcesPermissionsOnGettingDistributedResourcesWhenUserDoesNotHaveSuperPrivileges()
- throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .expect()
- .statusCode(204)
- .when()
- .get(SECURE_PATH + "/organization/resource/" + PARENT_ORGANIZATION);
-
- verify(service).getDistributedResources(eq(PARENT_ORGANIZATION), anyInt(), anyLong());
- verify(subject)
- .hasPermission(
- OrganizationDomain.DOMAIN_ID, PARENT_ORGANIZATION, OrganizationDomain.MANAGE_RESOURCES);
- verify(superPrivilegesChecker).hasSuperPrivileges();
- }
-
- @Test
- public void
- shouldNotCheckManageResourcesPermissionsOnGettingDistributedResourcesWhenUserHasSuperPrivileges()
- throws Exception {
- when(superPrivilegesChecker.hasSuperPrivileges()).thenReturn(true);
-
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .expect()
- .statusCode(204)
- .when()
- .get(SECURE_PATH + "/organization/resource/" + PARENT_ORGANIZATION);
-
- verify(service).getDistributedResources(eq(PARENT_ORGANIZATION), anyInt(), anyLong());
- verify(subject, never())
- .hasPermission(
- OrganizationDomain.DOMAIN_ID, PARENT_ORGANIZATION, OrganizationDomain.MANAGE_RESOURCES);
- verify(superPrivilegesChecker).hasSuperPrivileges();
- }
-
- @Test
- public void
- shouldCheckManageResourcesPermissionsOnGettingResourcesCapWhenUserDoesNotHaveSuperPrivileges()
- throws Exception {
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .expect()
- .statusCode(200)
- .when()
- .get(SECURE_PATH + "/organization/resource/" + SUBORGANIZATION + "/cap");
-
- verify(service).getResourcesCap(SUBORGANIZATION);
- verify(subject)
- .hasPermission(
- OrganizationDomain.DOMAIN_ID, PARENT_ORGANIZATION, OrganizationDomain.MANAGE_RESOURCES);
- verify(superPrivilegesChecker).hasSuperPrivileges();
- }
-
- @Test
- public void
- shouldNotCheckManageResourcesPermissionsOnGettingResourcesCapWhenUserHasSuperPrivileges()
- throws Exception {
- when(superPrivilegesChecker.hasSuperPrivileges()).thenReturn(true);
-
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .expect()
- .statusCode(200)
- .when()
- .get(SECURE_PATH + "/organization/resource/" + SUBORGANIZATION + "/cap");
-
- verify(service).getResourcesCap(SUBORGANIZATION);
- verify(subject, never())
- .hasPermission(
- OrganizationDomain.DOMAIN_ID, PARENT_ORGANIZATION, OrganizationDomain.MANAGE_RESOURCES);
- verify(superPrivilegesChecker).hasSuperPrivileges();
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp =
- "The user does not have permission to perform this operation")
- public void shouldThrowForbiddenExceptionWhenRequestedUnknownMethod() throws Exception {
- final GenericResourceMethod mock = mock(GenericResourceMethod.class);
- Method unknownMethod =
- OrganizationResourcesDistributionService.class.getMethod("getServiceDescriptor");
- when(mock.getMethod()).thenReturn(unknownMethod);
-
- permissionsFilter.filter(mock, new Object[] {});
- }
-
- @Filter
- public static class EnvironmentFilter implements RequestFilter {
- @Override
- public void doFilter(GenericContainerRequest request) {
- EnvironmentContext.getCurrent().setSubject(subject);
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsCheckerTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsCheckerTest.java
deleted file mode 100644
index f6440097e76..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/permissions/OrganizationalAccountPermissionsCheckerTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.permissions;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.multiuser.api.permission.server.account.AccountOperation;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.permissions.OrganizationalAccountPermissionsChecker}
- *
- * @author Sergii Leshchenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationalAccountPermissionsCheckerTest {
- private static final String ORG_ID = "org123";
-
- @Mock private Subject subject;
-
- private OrganizationalAccountPermissionsChecker permissionsChecker;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient().when(subject.hasPermission(anyString(), anyString(), anyString())).thenReturn(true);
-
- EnvironmentContext.getCurrent().setSubject(subject);
-
- permissionsChecker = new OrganizationalAccountPermissionsChecker();
- }
-
- @AfterMethod
- public void tearDown() throws Exception {
- EnvironmentContext.reset();
- }
-
- @Test
- public void shouldReturnOrganizationalReturnType() throws Exception {
- // then
- assertEquals(permissionsChecker.getAccountType(), OrganizationImpl.ORGANIZATIONAL_ACCOUNT);
- }
-
- @Test
- public void shouldCheckCreateWorkspacesPermissionOnOrganizationDomainLevel() throws Exception {
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.CREATE_WORKSPACE);
-
- verify(subject)
- .hasPermission(OrganizationDomain.DOMAIN_ID, ORG_ID, OrganizationDomain.CREATE_WORKSPACES);
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp =
- "User is not authorized to create workspaces in specified namespace.")
- public void shouldThrowForbiddenWhenUserDoesNotHavePermissionToCreateWorkspaces()
- throws Exception {
- when(subject.hasPermission(
- OrganizationDomain.DOMAIN_ID, ORG_ID, OrganizationDomain.CREATE_WORKSPACES))
- .thenReturn(false);
-
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.CREATE_WORKSPACE);
- }
-
- @Test
- public void shouldCheckManageWorkspacesPermissionOnOrganizationDomainLevel() throws Exception {
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.MANAGE_WORKSPACES);
-
- verify(subject)
- .hasPermission(OrganizationDomain.DOMAIN_ID, ORG_ID, OrganizationDomain.MANAGE_WORKSPACES);
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp = "User is not authorized to use specified namespace.")
- public void shouldThrowForbiddenWhenUserDoesNotHavePermissionToManagerWorkspaces()
- throws Exception {
- when(subject.hasPermission(
- OrganizationDomain.DOMAIN_ID, ORG_ID, OrganizationDomain.MANAGE_WORKSPACES))
- .thenReturn(false);
-
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.MANAGE_WORKSPACES);
- }
-
- @Test(dataProvider = "requiredAction")
- public void
- shouldNotThrowExceptionWhenUserHasAtLeastOnRequiredPermissionOnGettingResourcesInformation(
- String action) throws Exception {
- when(subject.hasPermission(anyString(), anyString(), anyString())).thenReturn(false);
- when(subject.hasPermission(OrganizationDomain.DOMAIN_ID, ORG_ID, action)).thenReturn(true);
-
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.SEE_RESOURCE_INFORMATION);
-
- verify(subject).hasPermission(OrganizationDomain.DOMAIN_ID, ORG_ID, action);
- }
-
- @Test(
- expectedExceptions = ForbiddenException.class,
- expectedExceptionsMessageRegExp =
- "User is not authorized to see resources information of requested organization.")
- public void shouldThrowForbiddenWhenUserDoesNotHavePermissionToSeeResourcesInformation()
- throws Exception {
- when(subject.hasPermission(anyString(), anyString(), anyString())).thenReturn(false);
-
- permissionsChecker.checkPermissions(ORG_ID, AccountOperation.SEE_RESOURCE_INFORMATION);
- }
-
- @DataProvider
- private Object[][] requiredAction() {
- return new Object[][] {
- {OrganizationDomain.CREATE_WORKSPACES},
- {OrganizationDomain.MANAGE_WORKSPACES},
- {OrganizationDomain.MANAGE_RESOURCES}
- };
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProviderTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProviderTest.java
deleted file mode 100644
index 2d0e49bd3d7..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/DefaultOrganizationResourcesProviderTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.resource.api.type.RamResourceType;
-import org.eclipse.che.multiuser.resource.api.type.RuntimeResourceType;
-import org.eclipse.che.multiuser.resource.api.type.TimeoutResourceType;
-import org.eclipse.che.multiuser.resource.api.type.WorkspaceResourceType;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.resource.DefaultOrganizationResourcesProvider}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class DefaultOrganizationResourcesProviderTest {
- @Mock private OrganizationManager organizationManager;
- @Mock private Organization organization;
-
- private DefaultOrganizationResourcesProvider organizationResourcesProvider;
-
- @BeforeMethod
- public void setUp() throws Exception {
- organizationResourcesProvider =
- new DefaultOrganizationResourcesProvider(organizationManager, "2gb", 10, 5, 10 * 60 * 1000);
- when(organizationManager.getById(anyString())).thenReturn(organization);
- }
-
- @Test
- public void shouldNotProvideDefaultResourcesForSuborganization() throws Exception {
- // given
- when(organization.getParent()).thenReturn("parentId");
-
- // when
- final List defaultResources =
- organizationResourcesProvider.getResources("organization123");
-
- // then
- verify(organizationManager).getById("organization123");
- assertTrue(defaultResources.isEmpty());
- }
-
- @Test
- public void shouldProvideDefaultResourcesForRootOrganization() throws Exception {
- // given
- when(organization.getParent()).thenReturn(null);
-
- // when
- final List defaultResources =
- organizationResourcesProvider.getResources("organization123");
-
- // then
- verify(organizationManager).getById("organization123");
- assertEquals(defaultResources.size(), 4);
- assertTrue(
- defaultResources.contains(
- new ResourceImpl(TimeoutResourceType.ID, 10, TimeoutResourceType.UNIT)));
- assertTrue(
- defaultResources.contains(
- new ResourceImpl(RamResourceType.ID, 2048, RamResourceType.UNIT)));
- assertTrue(
- defaultResources.contains(
- new ResourceImpl(WorkspaceResourceType.ID, 10, WorkspaceResourceType.UNIT)));
- assertTrue(
- defaultResources.contains(
- new ResourceImpl(RuntimeResourceType.ID, 5, RuntimeResourceType.UNIT)));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProviderTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProviderTest.java
deleted file mode 100644
index 0323e632bb8..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourceLockKeyProviderTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static org.mockito.Mockito.lenient;
-import static org.testng.Assert.assertEquals;
-
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.resource.OrganizationResourceLockKeyProvider}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationResourceLockKeyProviderTest {
- @Mock private OrganizationManager organizationManager;
-
- @InjectMocks private OrganizationResourceLockKeyProvider lockProvider;
-
- @Test
- public void shouldReturnRootOrganizationId() throws Exception {
- // given
- createOrganization("root", null);
- createOrganization("suborg", "root");
- createOrganization("subsuborg", "suborg");
-
- // when
- final String lockId = lockProvider.getLockKey("subsuborg");
-
- // then
- assertEquals(lockId, "root");
- }
-
- @Test
- public void shouldReturnOrganizationalReturnType() throws Exception {
- // then
- assertEquals(lockProvider.getAccountType(), OrganizationImpl.ORGANIZATIONAL_ACCOUNT);
- }
-
- private void createOrganization(String id, String parentId) throws Exception {
- lenient()
- .when(organizationManager.getById(id))
- .thenReturn(new OrganizationImpl(id, id + "Name", parentId));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionServiceTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionServiceTest.java
deleted file mode 100644
index 1815b4df3f3..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributionServiceTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static io.restassured.RestAssured.given;
-import static java.util.Collections.singletonList;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_NAME;
-import static org.everrest.assured.JettyHttpServer.ADMIN_USER_PASSWORD;
-import static org.everrest.assured.JettyHttpServer.SECURE_PATH;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import io.restassured.response.Response;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.rest.ApiExceptionMapper;
-import org.eclipse.che.api.core.rest.CheJsonProvider;
-import org.eclipse.che.api.core.rest.shared.dto.ServiceError;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.organization.shared.dto.OrganizationDistributedResourcesDto;
-import org.eclipse.che.multiuser.resource.api.free.ResourceValidator;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-import org.everrest.assured.EverrestJetty;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.resource.OrganizationResourcesDistributionService}
- *
- * @author Sergii Leschenko
- */
-@Listeners({EverrestJetty.class, MockitoTestNGListener.class})
-public class OrganizationResourcesDistributionServiceTest {
- @SuppressWarnings("unused") // is declared for deploying by everrest-assured
- private ApiExceptionMapper mapper;
-
- @SuppressWarnings("unused") // is declared for deploying by everrest-assured
- private CheJsonProvider jsonProvider = new CheJsonProvider(new HashSet<>());
-
- @Mock private OrganizationResourcesDistributor organizationResourcesManager;
- @Mock private ResourceValidator resourceValidator;
-
- @InjectMocks private OrganizationResourcesDistributionService service;
-
- @Test
- public void shouldCapOrganizationResources() throws Exception {
- ResourceDto resource =
- DtoFactory.newDto(ResourceDto.class).withType("test").withAmount(1020).withUnit("unit");
- List resources = singletonList(resource);
-
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(resources)
- .when()
- .post(SECURE_PATH + "/organization/resource/organization123/cap")
- .then()
- .assertThat()
- .statusCode(204);
-
- verify(organizationResourcesManager).capResources("organization123", resources);
- verify(resourceValidator).validate(resource);
- }
-
- @Test
- public void
- shouldReturn400WhenBodyContainTwoResourcesWithTheSameTypeOnDistributingOrganizationResources()
- throws Exception {
- List resources =
- Arrays.asList(
- DtoFactory.newDto(ResourceDto.class).withType("test"),
- DtoFactory.newDto(ResourceDto.class).withType("test"));
-
- Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .body(resources)
- .when()
- .post(SECURE_PATH + "/organization/resource/organization123/cap");
- assertEquals(response.statusCode(), 400);
- String errorMessage =
- DtoFactory.getInstance()
- .createDtoFromJson(response.print(), ServiceError.class)
- .getMessage();
- assertEquals(errorMessage, "Resources to cap must contain only one resource with type 'test'.");
- }
-
- @Test
- public void shouldReturnResourcesCapForSuborganization() throws Exception {
- final ResourceDto resourcesCap =
- DtoFactory.newDto(ResourceDto.class).withType("test").withAmount(1020).withUnit("unit");
- final List toFetch = singletonList(resourcesCap);
- doReturn(toFetch).when(organizationResourcesManager).getResourcesCaps(any());
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/resource/organization123/cap");
-
- assertEquals(response.statusCode(), 200);
- final List fetched = unwrapDtoList(response, ResourceDto.class);
- assertEquals(fetched.size(), 1);
- assertTrue(fetched.contains(resourcesCap));
- verify(organizationResourcesManager).getResourcesCaps("organization123");
- }
-
- @Test
- public void shouldReturnOrganizationDistributedResources() throws Exception {
- final OrganizationDistributedResourcesDto distributedResources =
- createOrganizationDistributedResources();
- final List toFetch = singletonList(distributedResources);
- doReturn(new Page<>(toFetch, 1, 1, 3))
- .when(organizationResourcesManager)
- .getByParent(any(), anyInt(), anyLong());
-
- final Response response =
- given()
- .auth()
- .basic(ADMIN_USER_NAME, ADMIN_USER_PASSWORD)
- .contentType("application/json")
- .when()
- .get(SECURE_PATH + "/organization/resource/organization123?maxItems=1&skipCount=1");
- assertEquals(response.statusCode(), 200);
- final List fetched =
- unwrapDtoList(response, OrganizationDistributedResourcesDto.class);
- assertEquals(fetched.size(), 1);
- assertTrue(fetched.contains(distributedResources));
- verify(organizationResourcesManager).getByParent("organization123", 1, 1L);
- }
-
- private static List unwrapDtoList(Response response, Class dtoClass) {
- return DtoFactory.getInstance()
- .createListDtoFromJson(response.body().print(), dtoClass)
- .stream()
- .collect(Collectors.toList());
- }
-
- private OrganizationDistributedResourcesDto createOrganizationDistributedResources() {
- return DtoFactory.newDto(OrganizationDistributedResourcesDto.class)
- .withOrganizationId("organization123")
- .withResourcesCap(
- singletonList(
- DtoFactory.newDto(ResourceDto.class)
- .withType("test")
- .withAmount(1020)
- .withUnit("unit")));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributorTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributorTest.java
deleted file mode 100644
index 21f7b8ebfbb..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationResourcesDistributorTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doCallRealMethod;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collections;
-import java.util.List;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.commons.lang.concurrent.Unlocker;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.OrganizationDistributedResources;
-import org.eclipse.che.multiuser.organization.spi.OrganizationDistributedResourcesDao;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationDistributedResourcesImpl;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.api.usage.ResourcesLocks;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Spy;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link OrganizationResourcesDistributor}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationResourcesDistributorTest {
- private static final String PARENT_ORG_ID = "parentOrg123";
- private static final String ORG_ID = "organization123";
-
- @Mock private Unlocker lock;
- @Mock private OrganizationDistributedResourcesDao distributedResourcesDao;
- @Mock private ResourcesLocks resourcesLocks;
- @Mock private ResourceManager resourceManager;
- @Mock private ResourceAggregator resourceAggregator;
- @Mock private OrganizationManager organizationManager;
-
- @Spy @InjectMocks private OrganizationResourcesDistributor manager;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient().doNothing().when(manager).checkResourcesAvailability(anyString(), any());
- lenient().when(resourcesLocks.lock(anyString())).thenReturn(lock);
-
- lenient()
- .when(organizationManager.getById(ORG_ID))
- .thenReturn(new OrganizationImpl(ORG_ID, ORG_ID + "name", PARENT_ORG_ID));
- lenient()
- .when(organizationManager.getById(PARENT_ORG_ID))
- .thenReturn(new OrganizationImpl(PARENT_ORG_ID, PARENT_ORG_ID + "name", null));
- }
-
- @Test
- public void shouldCapResources() throws Exception {
- List toCap = singletonList(createTestResource(1000));
-
- // when
- manager.capResources(ORG_ID, toCap);
-
- // then
- verify(manager).checkResourcesAvailability(ORG_ID, toCap);
- verify(distributedResourcesDao).store(new OrganizationDistributedResourcesImpl(ORG_ID, toCap));
- verify(resourcesLocks).lock(ORG_ID);
- verify(lock).close();
- }
-
- @Test
- public void shouldRemoveResourceFromListWhenItsAmountEqualsToMinusOne() throws Exception {
- ResourceImpl toCap = new ResourceImpl("test1", 1000, "init");
- ResourceImpl toReset = new ResourceImpl("test2", -1, "init");
- List resourcesToCap = asList(toCap, toReset);
-
- // when
- manager.capResources(ORG_ID, resourcesToCap);
-
- // then
- verify(manager).checkResourcesAvailability(ORG_ID, singletonList(toCap));
- verify(distributedResourcesDao)
- .store(new OrganizationDistributedResourcesImpl(ORG_ID, singletonList(toCap)));
- verify(resourcesLocks).lock(ORG_ID);
- verify(lock).close();
- }
-
- @Test
- public void shouldRemoveResourcesCapWhenInvokeCapWithEmptyList() throws Exception {
- // when
- manager.capResources(ORG_ID, Collections.emptyList());
-
- // then
- verify(manager, never()).checkResourcesAvailability(anyString(), any());
- verify(distributedResourcesDao).remove(ORG_ID);
- verify(resourcesLocks).lock(ORG_ID);
- verify(lock).close();
- }
-
- @Test(
- expectedExceptions = ConflictException.class,
- expectedExceptionsMessageRegExp = "It is not allowed to cap resources for root organization.")
- public void shouldThrowConflictExceptionOnCappingResourcesForRootOrganization() throws Exception {
- // when
- manager.capResources(PARENT_ORG_ID, Collections.emptyList());
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeOnDistributionResourcesWithNullOrganizationId() throws Exception {
- // when
- manager.capResources(null, emptyList());
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeOnDistributionNullResourcesList() throws Exception {
- // when
- manager.capResources(ORG_ID, null);
- }
-
- @Test
- public void shouldGetDistributedResources() throws Exception {
- // given
- final OrganizationDistributedResourcesImpl distributedResources =
- createDistributedResources(1000);
- doReturn(new Page<>(singletonList(distributedResources), 0, 10, 1))
- .when(distributedResourcesDao)
- .getByParent(anyString(), anyInt(), anyLong());
-
- // when
- final Page extends OrganizationDistributedResources> fetchedDistributedResources =
- manager.getByParent(ORG_ID, 10, 0);
-
- // then
- assertEquals(fetchedDistributedResources.getTotalItemsCount(), 1);
- assertEquals(fetchedDistributedResources.getItems().get(0), distributedResources);
- verify(distributedResourcesDao).getByParent(ORG_ID, 10, 0);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeOnGettingDistributedResourcesByNullOrganizationId() throws Exception {
- // when
- manager.getByParent(null, 10, 10);
- }
-
- @Test
- public void shouldGetResourcesCap() throws Exception {
- // given
- final OrganizationDistributedResourcesImpl distributedResources =
- createDistributedResources(1000);
- when(distributedResourcesDao.get(anyString())).thenReturn(distributedResources);
-
- // when
- final List extends Resource> fetchedDistributedResources = manager.getResourcesCaps(ORG_ID);
-
- // then
- assertEquals(fetchedDistributedResources, distributedResources.getResourcesCap());
- verify(distributedResourcesDao).get(ORG_ID);
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void shouldThrowNpeOnGettingResourcesCapByNullOrganizationId() throws Exception {
- // when
- manager.getResourcesCaps(null);
- }
-
- @Test
- public void shouldResourceAvailabilityCappingResourcesWhenResourceCapIsLessThanUsedOne()
- throws Exception {
- // given
- doCallRealMethod().when(manager).checkResourcesAvailability(anyString(), any());
-
- ResourceImpl used = createTestResource(500);
- doReturn(singletonList(used)).when(resourceManager).getUsedResources(any());
-
- ResourceImpl toCap = createTestResource(700);
- doReturn(createTestResource(200)).when(resourceAggregator).deduct((Resource) any(), any());
-
- // when
- manager.checkResourcesAvailability(ORG_ID, singletonList(toCap));
-
- // then
- verify(resourceManager).getUsedResources(ORG_ID);
- verify(resourceAggregator).deduct(toCap, used);
- }
-
- @Test(
- expectedExceptions = ConflictException.class,
- expectedExceptionsMessageRegExp = "Resources are currently in use. Denied.")
- public void shouldResourceAvailabilityCappingResourcesWhenResourceCapIsGreaterThanUsedOne()
- throws Exception {
- // given
- doCallRealMethod().when(manager).checkResourcesAvailability(anyString(), any());
- doReturn("Denied.").when(manager).getMessage(anyString());
-
- ResourceImpl used = createTestResource(1000);
- doReturn(singletonList(used)).when(resourceManager).getUsedResources(any());
-
- ResourceImpl toCap = createTestResource(700);
- doThrow(new NoEnoughResourcesException(emptyList(), emptyList(), singletonList(toCap)))
- .when(resourceAggregator)
- .deduct((Resource) any(), any());
-
- // when
- manager.checkResourcesAvailability(ORG_ID, singletonList(toCap));
-
- // then
- verify(resourceManager).getUsedResources(ORG_ID);
- verify(resourceAggregator).deduct(toCap, used);
- }
-
- private ResourceImpl createTestResource(long amount) {
- return new ResourceImpl("test", amount, "init");
- }
-
- private OrganizationDistributedResourcesImpl createDistributedResources(long resourceAmount) {
- return new OrganizationDistributedResourcesImpl(
- ORG_ID, singletonList(createTestResource(resourceAmount)));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProviderTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProviderTest.java
deleted file mode 100644
index 79e2d2e0c7a..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/OrganizationalAccountAvailableResourcesProviderTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import javax.inject.Provider;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Spy;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/** Test for {@link OrganizationalAccountAvailableResourcesProvider} */
-@Listeners(MockitoTestNGListener.class)
-public class OrganizationalAccountAvailableResourcesProviderTest {
- private static final String ROOT_ORG_NAME = "root";
- private static final String ROOT_ORG_ID = "organization123";
- private static final String SUBORG_ID = "organization321";
- private static final String SUBSUBORG_ID = "organization231";
-
- @Mock private Provider resourceManagerProvider;
- @Mock private ResourceManager resourceManager;
- @Mock private ResourceAggregator resourceAggregator;
- @Mock private OrganizationManager organizationManager;
-
- @InjectMocks @Spy
- private OrganizationalAccountAvailableResourcesProvider availableResourcesProvider;
-
- private Organization rootOrganization;
- private Organization suborganization;
- private Organization subsuborganization;
-
- @BeforeMethod
- public void setUp() throws Exception {
- lenient().when(resourceManagerProvider.get()).thenReturn(resourceManager);
-
- rootOrganization = new OrganizationImpl(ROOT_ORG_ID, ROOT_ORG_NAME, null);
- suborganization = new OrganizationImpl(SUBORG_ID, "root/suborg", ROOT_ORG_ID);
- subsuborganization = new OrganizationImpl(SUBSUBORG_ID, "root/suborg/subsuborg", SUBORG_ID);
-
- lenient().when(organizationManager.getById(ROOT_ORG_ID)).thenReturn(rootOrganization);
- lenient().when(organizationManager.getById(SUBORG_ID)).thenReturn(suborganization);
- lenient().when(organizationManager.getById(SUBSUBORG_ID)).thenReturn(subsuborganization);
- }
-
- @Test
- public void shouldReturnAvailableResourcesForRootOrganization() throws Exception {
- // given
- ResourceImpl availableResource = new ResourceImpl("test", 5000, "unit");
- doReturn(singletonList(availableResource))
- .when(availableResourcesProvider)
- .getAvailableOrganizationResources(any());
-
- // when
- List extends Resource> availableResources =
- availableResourcesProvider.getAvailableResources(ROOT_ORG_ID);
-
- // then
- assertEquals(availableResources.size(), 1);
- assertEquals(availableResources.get(0), availableResource);
- verify(availableResourcesProvider).getAvailableResources(ROOT_ORG_ID);
- }
-
- @Test
- public void shouldReturnAvailableResourcesForSuborganization() throws Exception {
- // given
- ResourceImpl parentAvailableResource = new ResourceImpl("test", 3000, "unit");
- prepareAvailableResource(ROOT_ORG_ID, parentAvailableResource);
- ResourceImpl suborgAvailableResource = new ResourceImpl("test", 5000, "unit");
- prepareAvailableResource(SUBORG_ID, suborgAvailableResource);
- doReturn(asList(parentAvailableResource, suborgAvailableResource))
- .when(resourceAggregator)
- .intersection(anyList(), anyList());
- doReturn(singletonList(parentAvailableResource)).when(resourceAggregator).min(anyList());
-
- // when
- List extends Resource> availableResources =
- availableResourcesProvider.getAvailableResources(SUBORG_ID);
-
- // then
- assertEquals(availableResources.size(), 1);
- assertEquals(availableResources.get(0), parentAvailableResource);
- verify(availableResourcesProvider).getAvailableOrganizationResources(rootOrganization);
- verify(availableResourcesProvider).getAvailableOrganizationResources(suborganization);
- verify(resourceAggregator)
- .intersection(
- singletonList(parentAvailableResource), singletonList(suborgAvailableResource));
- verify(resourceAggregator).min(asList(parentAvailableResource, suborgAvailableResource));
- }
-
- @Test
- public void shouldReturnAvailableResourcesAsTotalMinusUsedByItselfAndItsSuborganizations()
- throws Exception {
- // given
- ResourceImpl totalResource = new ResourceImpl("test", 9000, "unit");
- doReturn(singletonList(totalResource)).when(resourceManager).getTotalResources(anyString());
-
- ResourceImpl usedResource = new ResourceImpl("test", 3000, "unit");
- doReturn(singletonList(usedResource)).when(resourceManager).getUsedResources(anyString());
-
- ResourceImpl usedBySuborgResource = new ResourceImpl("test", 1500, "unit");
- ResourceImpl usedBySubsuborgResource = new ResourceImpl("test", 2000, "unit");
- doReturn(asList(usedBySuborgResource, usedBySubsuborgResource))
- .when(availableResourcesProvider)
- .getUsedResourcesBySuborganizations(anyString());
-
- ResourceImpl availableResource = new ResourceImpl("test", 2500, "unit");
- doReturn(singletonList(availableResource))
- .when(resourceAggregator)
- .deduct(anyList(), anyList());
-
- // when
- List extends Resource> availableResources =
- availableResourcesProvider.getAvailableOrganizationResources(rootOrganization);
-
- // then
- assertEquals(availableResources.size(), 1);
- assertEquals(availableResources.get(0), availableResource);
- verify(resourceManager).getTotalResources(ROOT_ORG_ID);
- verify(resourceManager).getUsedResources(ROOT_ORG_ID);
- verify(availableResourcesProvider).getUsedResourcesBySuborganizations(ROOT_ORG_NAME);
- verify(resourceAggregator)
- .deduct(
- singletonList(totalResource),
- asList(usedResource, usedBySuborgResource, usedBySubsuborgResource));
- }
-
- @Test
- public void shouldReturnExcessiveResourcesWhenUsedResourceAreGreaterThanTotal() throws Exception {
- // given
- ResourceImpl totalResource = new ResourceImpl("test", 9000, "unit");
- ResourceImpl excessiveTotalResource = new ResourceImpl("test1", 1000, "unit");
- doReturn(asList(totalResource, excessiveTotalResource))
- .when(resourceManager)
- .getTotalResources(anyString());
-
- ResourceImpl usedResource = new ResourceImpl("test", 10000, "unit");
- doReturn(singletonList(usedResource)).when(resourceManager).getUsedResources(anyString());
-
- doReturn(emptyList())
- .when(availableResourcesProvider)
- .getUsedResourcesBySuborganizations(anyString());
-
- doThrow(new NoEnoughResourcesException(emptyList(), emptyList(), emptyList()))
- .when(resourceAggregator)
- .deduct(anyList(), anyList());
- doReturn(singletonList(excessiveTotalResource))
- .when(resourceAggregator)
- .excess(anyList(), anyList());
-
- // when
- List extends Resource> availableResources =
- availableResourcesProvider.getAvailableOrganizationResources(rootOrganization);
-
- // then
- assertEquals(availableResources.size(), 1);
- assertEquals(availableResources.get(0), excessiveTotalResource);
- verify(resourceManager).getTotalResources(ROOT_ORG_ID);
- verify(resourceManager).getUsedResources(ROOT_ORG_ID);
- verify(availableResourcesProvider).getUsedResourcesBySuborganizations(ROOT_ORG_NAME);
- verify(resourceAggregator)
- .deduct(asList(totalResource, excessiveTotalResource), singletonList(usedResource));
- verify(resourceAggregator)
- .excess(asList(totalResource, excessiveTotalResource), singletonList(usedResource));
- }
-
- @Test
- public void shouldCalculateUsedResourceBySuborganizations() throws Exception {
- // given
- doReturn(new Page<>(singletonList(suborganization), 0, 1, 2))
- .doReturn(new Page<>(singletonList(subsuborganization), 1, 1, 2))
- .when(organizationManager)
- .getSuborganizations(anyString(), anyInt(), anyLong());
- ResourceImpl usedBySuborgResource = new ResourceImpl("test", 1500, "unit");
- doReturn(singletonList(usedBySuborgResource)).when(resourceManager).getUsedResources(SUBORG_ID);
- ResourceImpl usedBySubsuborgResource = new ResourceImpl("test", 2000, "unit");
- doReturn(singletonList(usedBySubsuborgResource))
- .when(resourceManager)
- .getUsedResources(SUBSUBORG_ID);
-
- // when
- List extends Resource> usedResources =
- availableResourcesProvider.getUsedResourcesBySuborganizations(ROOT_ORG_NAME);
-
- // then
- assertEquals(usedResources.size(), 2);
- assertTrue(usedResources.contains(usedBySuborgResource));
- assertTrue(usedResources.contains(usedBySubsuborgResource));
- verify(organizationManager, times(2))
- .getSuborganizations(eq(ROOT_ORG_NAME), anyInt(), anyLong());
- verify(resourceManager).getUsedResources(SUBORG_ID);
- verify(resourceManager).getUsedResources(SUBSUBORG_ID);
- }
-
- private void prepareAvailableResource(String organizationId, ResourceImpl availableResource)
- throws NotFoundException, ServerException {
- doReturn(singletonList(availableResource))
- .when(availableResourcesProvider)
- .getAvailableOrganizationResources(
- argThat(argument -> organizationId.equals(((Organization) argument).getId())));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProviderTest.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProviderTest.java
deleted file mode 100644
index 7e3281f1695..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/api/resource/SuborganizationResourcesProviderTest.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.api.resource;
-
-import static java.util.Arrays.asList;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.lenient;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import javax.inject.Provider;
-import org.eclipse.che.account.api.AccountManager;
-import org.eclipse.che.account.shared.model.Account;
-import org.eclipse.che.multiuser.organization.api.OrganizationManager;
-import org.eclipse.che.multiuser.organization.shared.model.Organization;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-import org.eclipse.che.multiuser.resource.api.usage.ResourceManager;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.spi.impl.ProvidedResourcesImpl;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-import org.mockito.Mock;
-import org.mockito.testng.MockitoTestNGListener;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Listeners;
-import org.testng.annotations.Test;
-
-/**
- * Tests for {@link
- * org.eclipse.che.multiuser.organization.api.resource.SuborganizationResourcesProvider}
- *
- * @author Sergii Leschenko
- */
-@Listeners(MockitoTestNGListener.class)
-public class SuborganizationResourcesProviderTest {
- @Mock private Account account;
- @Mock private Organization organization;
-
- @Mock private AccountManager accountManager;
- @Mock private OrganizationManager organizationManager;
- @Mock private OrganizationResourcesDistributor resourcesDistributor;
- @Mock private Provider distributorProvider;
- @Mock private Provider resourceManagerProvider;
- @Mock private ResourceManager resourceManager;
-
- private SuborganizationResourcesProvider suborganizationResourcesProvider;
-
- @BeforeMethod
- public void setUp() throws Exception {
- when(accountManager.getById(any())).thenReturn(account);
- lenient().when(organizationManager.getById(any())).thenReturn(organization);
-
- lenient().when(distributorProvider.get()).thenReturn(resourcesDistributor);
-
- lenient().when(resourceManagerProvider.get()).thenReturn(resourceManager);
-
- suborganizationResourcesProvider =
- new SuborganizationResourcesProvider(
- accountManager, organizationManager, distributorProvider, resourceManagerProvider);
- }
-
- @Test
- public void shouldNotProvideResourcesForNonOrganizationalAccounts() throws Exception {
- // given
- when(account.getType()).thenReturn("test");
-
- // when
- final List providedResources =
- suborganizationResourcesProvider.getResources("account123");
-
- // then
- assertTrue(providedResources.isEmpty());
- verify(accountManager).getById("account123");
- }
-
- @Test
- public void shouldNotProvideResourcesForRootOrganizationalAccount() throws Exception {
- // given
- when(account.getType()).thenReturn(OrganizationImpl.ORGANIZATIONAL_ACCOUNT);
- when(organization.getParent()).thenReturn(null);
-
- // when
- final List providedResources =
- suborganizationResourcesProvider.getResources("organization123");
-
- // then
- assertTrue(providedResources.isEmpty());
- verify(accountManager).getById("organization123");
- verify(organizationManager).getById("organization123");
- }
-
- @Test
- public void shouldProvideResourcesForSuborganizationalAccount() throws Exception {
- // given
- when(account.getType()).thenReturn(OrganizationImpl.ORGANIZATIONAL_ACCOUNT);
- when(organization.getParent()).thenReturn("parentOrg");
- final ResourceImpl parentNotCapedResource = new ResourceImpl("test", 1234, "unit");
- final ResourceImpl parentCapedResource = new ResourceImpl("caped", 20, "unit");
- final ResourceImpl parentUnlimitedCapedResource = new ResourceImpl("unlimited", -1, "unit");
- doReturn(asList(parentNotCapedResource, parentCapedResource, parentUnlimitedCapedResource))
- .when(resourceManager)
- .getTotalResources(anyString());
-
- final ResourceImpl capedResourceCap = new ResourceImpl("caped", 10, "unit");
- final ResourceImpl unlimitedCapedResourceCap = new ResourceImpl("unlimited", 40, "unit");
- doReturn(asList(capedResourceCap, unlimitedCapedResourceCap))
- .when(resourcesDistributor)
- .getResourcesCaps(any());
-
- // when
- final List providedResources =
- suborganizationResourcesProvider.getResources("organization123");
-
- // then
- assertEquals(providedResources.size(), 1);
- assertEquals(
- providedResources.get(0),
- new ProvidedResourcesImpl(
- SuborganizationResourcesProvider.PARENT_RESOURCES_PROVIDER,
- null,
- "organization123",
- -1L,
- -1L,
- asList(parentNotCapedResource, capedResourceCap, unlimitedCapedResourceCap)));
- verify(accountManager).getById("organization123");
- verify(organizationManager).getById("organization123");
- verify(resourcesDistributor).getResourcesCaps("organization123");
- verify(resourceManager).getTotalResources("parentOrg");
- }
-
- @Test
- public void shouldNotProvideResourcesForOrganizationalAccountIfItDoesNotHaveDistributedResources()
- throws Exception {
- // given
- when(account.getType()).thenReturn(OrganizationImpl.ORGANIZATIONAL_ACCOUNT);
- when(organization.getParent()).thenReturn("parentOrg");
-
- // when
- final List providedResources =
- suborganizationResourcesProvider.getResources("organization123");
-
- // then
- assertTrue(providedResources.isEmpty());
- verify(accountManager).getById("organization123");
- verify(organizationManager).getById("organization123");
- verify(resourcesDistributor, never()).getResourcesCaps("organization123");
- verify(resourceManager).getTotalResources("parentOrg");
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/spi/jpa/JpaOrganizationImplTckRepository.java b/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/spi/jpa/JpaOrganizationImplTckRepository.java
deleted file mode 100644
index e6c73a061b5..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/java/org/eclipse/che/multiuser/organization/spi/jpa/JpaOrganizationImplTckRepository.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.organization.spi.jpa;
-
-import com.google.inject.Inject;
-import com.google.inject.persist.UnitOfWork;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import javax.inject.Provider;
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
-import org.eclipse.che.commons.test.tck.repository.JpaTckRepository;
-import org.eclipse.che.commons.test.tck.repository.TckRepositoryException;
-import org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl;
-
-/**
- * Organizations require to have own repository because it is important to delete organization in
- * reverse order that they were stored. It allows to resolve problems with removing suborganization
- * before parent organization removing.
- *
- * @author Sergii Leschenko
- */
-public class JpaOrganizationImplTckRepository extends JpaTckRepository {
- @Inject protected Provider managerProvider;
-
- @Inject protected UnitOfWork uow;
-
- private final List createdOrganizations = new ArrayList<>();
-
- public JpaOrganizationImplTckRepository() {
- super(OrganizationImpl.class);
- }
-
- @Override
- public void createAll(Collection extends OrganizationImpl> entities)
- throws TckRepositoryException {
- super.createAll(entities);
- // It's important to save organization to remove them in the reverse order
- createdOrganizations.addAll(entities);
- }
-
- @Override
- public void removeAll() throws TckRepositoryException {
- uow.begin();
- final EntityManager manager = managerProvider.get();
- try {
- manager.getTransaction().begin();
-
- for (int i = createdOrganizations.size() - 1; i > -1; i--) {
- // The query 'DELETE FROM ....' won't be correct as it will ignore orphanRemoval
- // and may also ignore some configuration options, while EntityManager#remove won't
- try {
- final OrganizationImpl organizationToRemove =
- manager
- .createQuery(
- "SELECT o FROM Organization o " + "WHERE o.id = :id", OrganizationImpl.class)
- .setParameter("id", createdOrganizations.get(i).getId())
- .getSingleResult();
- manager.remove(organizationToRemove);
- } catch (NoResultException ignored) {
- // it is already removed
- }
- }
- createdOrganizations.clear();
-
- manager.getTransaction().commit();
- } catch (RuntimeException x) {
- if (manager.getTransaction().isActive()) {
- manager.getTransaction().rollback();
- }
- throw new TckRepositoryException(x.getLocalizedMessage(), x);
- } finally {
- uow.end();
- }
-
- // remove all objects that was created in tests
- super.removeAll();
- }
-}
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/persistence.xml b/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/persistence.xml
deleted file mode 100644
index c9409c32cad..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/persistence.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
- org.eclipse.persistence.jpa.PersistenceProvider
- org.eclipse.che.account.spi.AccountImpl
- org.eclipse.che.api.user.server.model.impl.UserImpl
- org.eclipse.che.multiuser.organization.spi.impl.OrganizationImpl
- org.eclipse.che.multiuser.organization.spi.impl.MemberImpl
- org.eclipse.che.multiuser.organization.spi.impl.OrganizationDistributedResourcesImpl
- org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/services/org.eclipse.che.commons.test.tck.TckModule b/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/services/org.eclipse.che.commons.test.tck.TckModule
deleted file mode 100644
index ad7b8c2b406..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/resources/META-INF/services/org.eclipse.che.commons.test.tck.TckModule
+++ /dev/null
@@ -1 +0,0 @@
-org.eclipse.che.multiuser.organization.spi.tck.jpa.OrganizationJpaTckModule
diff --git a/multiuser/api/che-multiuser-api-organization/src/test/resources/logback-test.xml b/multiuser/api/che-multiuser-api-organization/src/test/resources/logback-test.xml
deleted file mode 100644
index 3d4d10adab1..00000000000
--- a/multiuser/api/che-multiuser-api-organization/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
- %-41(%date[%.15thread]) %-45([%-5level] [%.30logger{30} %L]) - %msg%n
-
-
-
-
-
-
-
diff --git a/multiuser/api/che-multiuser-api-permission/pom.xml b/multiuser/api/che-multiuser-api-permission/pom.xml
index 7934b3ae473..676caa680ea 100644
--- a/multiuser/api/che-multiuser-api-permission/pom.xml
+++ b/multiuser/api/che-multiuser-api-permission/pom.xml
@@ -108,16 +108,6 @@
che-core-api-accounttest
-
- org.eclipse.che.core
- che-core-sql-schema
- test
-
-
- org.eclipse.che.multiuser
- che-multiuser-sql-schema
- test
- org.eclipse.persistenceorg.eclipse.persistence.core
@@ -261,11 +251,6 @@
unpack-dependencies
-
- che-core-sql-schema, che-multiuser-sql-schema
- che-schema/
- ${project.build.directory}
-
diff --git a/multiuser/api/che-multiuser-api-resource-shared/pom.xml b/multiuser/api/che-multiuser-api-resource-shared/pom.xml
deleted file mode 100644
index 1cf4b7cfcbc..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/pom.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- 4.0.0
-
- che-multiuser-api
- org.eclipse.che.multiuser
- 7.117.0-SNAPSHOT
-
- che-multiuser-api-resource-shared
- jar
- Che Multiuser :: Resource :: Shared
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-commons-annotations
-
-
-
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/FreeResourcesLimit.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/FreeResourcesLimit.java
deleted file mode 100644
index a33d2b911a4..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/FreeResourcesLimit.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.model;
-
-import java.util.List;
-
-/**
- * Represents limit of resources which are available for free usage by some account.
- *
- * @author Sergii Leschenko
- */
-public interface FreeResourcesLimit {
- /** Returns id of account that can use free resources. */
- String getAccountId();
-
- /** Returns resources which are available for free usage. */
- List extends Resource> getResources();
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ProvidedResources.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ProvidedResources.java
deleted file mode 100644
index 3833ab5b5ff..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ProvidedResources.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.model;
-
-import java.util.List;
-import org.eclipse.che.commons.annotation.Nullable;
-
-/**
- * Resources that are provided for using by account by some resource providing mechanism.
- *
- * @author Sergii Leschenko
- */
-public interface ProvidedResources {
-
- /** Returns id of resource provider. */
- String getProviderId();
-
- /**
- * Returns id of granted resource entity. Can be null when provider provides static single entry.
- */
- @Nullable
- String getId();
-
- /** Returns owner of resources. */
- String getOwner();
-
- /** Returns time when resources became active. */
- Long getStartTime();
-
- /** Returns time when resources will be/became inactive. */
- Long getEndTime();
-
- /** Returns list of resources which can be used by owner. */
- List extends Resource> getResources();
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/Resource.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/Resource.java
deleted file mode 100644
index 552337b871d..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/Resource.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.model;
-
-/**
- * Represents some number of resources that can be used by account.
- *
- * @author gazarenkov
- * @author Sergii Leschenko
- */
-public interface Resource {
- /** Returns type of resources, e.g. RAM. */
- String getType();
-
- /**
- * Returns amount of resources.
- *
- *
Applicable values here are from -1 to {@link Long#MAX_VALUE} inclusively. -1 value represent
- * infinity.
- */
- long getAmount();
-
- /** Returns unit of resources. */
- String getUnit();
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ResourcesDetails.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ResourcesDetails.java
deleted file mode 100644
index d51ea27b063..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/model/ResourcesDetails.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.model;
-
-import java.util.List;
-
-/**
- * Permits account to use some resources.
- *
- * @author gazarenkov
- * @author Sergii Leschenko
- */
-public interface ResourcesDetails {
- /** Returns id of account that is owner of these resources. */
- String getAccountId();
-
- /** Returns detailed list of resources which can be used by owner. */
- List extends ProvidedResources> getProvidedResources();
-
- /** Returns list of resources which can be used by owner. */
- List extends Resource> getTotalResources();
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/FreeResourcesLimitDto.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/FreeResourcesLimitDto.java
deleted file mode 100644
index 743e541396f..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/FreeResourcesLimitDto.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface FreeResourcesLimitDto extends FreeResourcesLimit {
- @Override
- String getAccountId();
-
- void setAccountId(String accountId);
-
- FreeResourcesLimitDto withAccountId(String accountId);
-
- @Override
- List getResources();
-
- void setResources(List resources);
-
- FreeResourcesLimitDto withResources(List resources);
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ProvidedResourcesDto.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ProvidedResourcesDto.java
deleted file mode 100644
index a7e240edc61..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ProvidedResourcesDto.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface ProvidedResourcesDto extends ProvidedResources {
- @Override
- String getProviderId();
-
- void setProviderId(String providerId);
-
- ProvidedResourcesDto withProviderId(String providerId);
-
- @Override
- String getId();
-
- void setId(String id);
-
- ProvidedResourcesDto withId(String id);
-
- @Override
- String getOwner();
-
- void setOwner(String owner);
-
- ProvidedResourcesDto withOwner(String owner);
-
- @Override
- Long getStartTime();
-
- void setStartTime(Long startTime);
-
- ProvidedResourcesDto withStartTime(Long startTime);
-
- @Override
- Long getEndTime();
-
- void setEndTime(Long endTime);
-
- ProvidedResourcesDto withEndTime(Long endTime);
-
- @Override
- List getResources();
-
- void setResources(List resources);
-
- ProvidedResourcesDto withResources(List resources);
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourceDto.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourceDto.java
deleted file mode 100644
index 71d9276b339..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourceDto.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.shared.dto;
-
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface ResourceDto extends Resource {
- @Override
- String getType();
-
- void setType(String type);
-
- ResourceDto withType(String type);
-
- @Override
- long getAmount();
-
- void setAmount(long amount);
-
- ResourceDto withAmount(long amount);
-
- @Override
- String getUnit();
-
- void setUnit(String unit);
-
- ResourceDto withUnit(String unit);
-}
diff --git a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourcesDetailsDto.java b/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourcesDetailsDto.java
deleted file mode 100644
index daa0df2cd2d..00000000000
--- a/multiuser/api/che-multiuser-api-resource-shared/src/main/java/org/eclipse/che/multiuser/resource/shared/dto/ResourcesDetailsDto.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.shared.dto;
-
-import java.util.List;
-import org.eclipse.che.dto.shared.DTO;
-import org.eclipse.che.multiuser.resource.model.ResourcesDetails;
-
-/**
- * @author Sergii Leschenko
- */
-@DTO
-public interface ResourcesDetailsDto extends ResourcesDetails {
- @Override
- String getAccountId();
-
- void setAccountId(String accountId);
-
- ResourcesDetailsDto withAccountId(String accountId);
-
- @Override
- List getProvidedResources();
-
- void setProvidedResources(List providedResources);
-
- ResourcesDetailsDto withProvidedResources(List providedResources);
-
- @Override
- List getTotalResources();
-
- void setTotalResources(List totalResources);
-
- ResourcesDetailsDto withTotalResources(List totalResources);
-}
diff --git a/multiuser/api/che-multiuser-api-resource/pom.xml b/multiuser/api/che-multiuser-api-resource/pom.xml
deleted file mode 100644
index 9d309e4f423..00000000000
--- a/multiuser/api/che-multiuser-api-resource/pom.xml
+++ /dev/null
@@ -1,197 +0,0 @@
-
-
-
- 4.0.0
-
- che-multiuser-api
- org.eclipse.che.multiuser
- 7.117.0-SNAPSHOT
-
- che-multiuser-api-resource
- jar
- Che Multiuser :: Resource
-
- ${project.build.directory}/generated-sources/dto/
-
-
-
- com.google.code.gson
- gson
-
-
- com.google.guava
- guava
-
-
- com.google.inject
- guice
-
-
- jakarta.inject
- jakarta.inject-api
-
-
- org.eclipse.che.core
- che-core-api-account
-
-
- org.eclipse.che.core
- che-core-api-core
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-api-model
-
-
- org.eclipse.che.core
- che-core-api-workspace
-
-
- org.eclipse.che.core
- che-core-commons-annotations
-
-
- org.eclipse.che.core
- che-core-commons-lang
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-permission
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-resource-shared
-
-
- org.eclipse.persistence
- jakarta.persistence
-
-
- org.slf4j
- slf4j-api
-
-
- org.eclipse.persistence
- org.eclipse.persistence.core
- provided
-
-
- org.eclipse.persistence
- org.eclipse.persistence.jpa
- provided
-
-
-
-
-
-
- org.eclipse.che.core
- che-core-api-dto-maven-plugin
- ${project.version}
-
-
- process-sources
-
- generate
-
-
-
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-resource-shared
- ${project.version}
-
-
-
-
- org.eclipse.che.multiuser.resource.shared.dto
-
- ${dto-generator-out-directory}
- org.eclipse.che.multiuser.resource.api.dto.DtoServerImpls
- server
-
-
-
- maven-compiler-plugin
-
-
- pre-compile
- generate-sources
-
- compile
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
-
-
- add-domain
- process-sources
-
- add-resource
-
-
-
-
- ${dto-generator-out-directory}/META-INF
- META-INF
-
-
-
-
-
- add-source
- process-sources
-
- add-source
-
-
-
- ${dto-generator-out-directory}
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- resource-dependencies
- process-test-resources
-
- unpack-dependencies
-
-
- che-core-sql-schema,
- che-multiuser-sql-schema
- che-schema/
- ${project.build.directory}
-
-
-
-
-
-
-
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/AvailableResourcesProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/AvailableResourcesProvider.java
deleted file mode 100644
index dc075ce30a6..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/AvailableResourcesProvider.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import java.util.List;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Provides resources which are available for usage by account.
- *
- *
It can be used for example for implementing resources sharing between accounts or resources
- * usage limitation when limit should be less than resources provided to account.
- *
- * @author Sergii Leschenko
- */
-public interface AvailableResourcesProvider {
- /**
- * Returns resources that are available for usage by account with specified id.
- *
- * @param accountId account identifier
- * @return resources that are available for usage by account with specified id.
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurs
- */
- List extends Resource> getAvailableResources(String accountId)
- throws NotFoundException, ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/DtoConverter.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/DtoConverter.java
deleted file mode 100644
index 0f345f559e0..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/DtoConverter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import java.util.stream.Collectors;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.model.ResourcesDetails;
-import org.eclipse.che.multiuser.resource.shared.dto.FreeResourcesLimitDto;
-import org.eclipse.che.multiuser.resource.shared.dto.ProvidedResourcesDto;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourcesDetailsDto;
-
-/**
- * Helps to convert objects related to resource to DTOs.
- *
- * @author Sergii Leschenko
- */
-public final class DtoConverter {
- private DtoConverter() {}
-
- public static ResourceDto asDto(Resource resource) {
- return DtoFactory.newDto(ResourceDto.class)
- .withAmount(resource.getAmount())
- .withType(resource.getType())
- .withUnit(resource.getUnit());
- }
-
- public static FreeResourcesLimitDto asDto(FreeResourcesLimit limit) {
- return DtoFactory.newDto(FreeResourcesLimitDto.class)
- .withResources(
- limit.getResources().stream().map(DtoConverter::asDto).collect(Collectors.toList()))
- .withAccountId(limit.getAccountId());
- }
-
- public static ResourcesDetailsDto asDto(ResourcesDetails resourcesDetails) {
- return DtoFactory.newDto(ResourcesDetailsDto.class)
- .withAccountId(resourcesDetails.getAccountId())
- .withTotalResources(
- resourcesDetails.getTotalResources().stream()
- .map(DtoConverter::asDto)
- .collect(Collectors.toList()))
- .withProvidedResources(
- resourcesDetails.getProvidedResources().stream()
- .map(DtoConverter::asDto)
- .collect(Collectors.toList()));
- }
-
- private static ProvidedResourcesDto asDto(ProvidedResources providedResources) {
- return DtoFactory.newDto(ProvidedResourcesDto.class)
- .withId(providedResources.getId())
- .withOwner(providedResources.getOwner())
- .withStartTime(providedResources.getStartTime())
- .withEndTime(providedResources.getEndTime())
- .withProviderId(providedResources.getProviderId())
- .withResources(
- providedResources.getResources().stream()
- .map(DtoConverter::asDto)
- .collect(Collectors.toList()));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceAggregator.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceAggregator.java
deleted file mode 100644
index 9f8eb215ea2..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceAggregator.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import static java.util.stream.Collectors.toSet;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.api.type.ResourceType;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Helps aggregate resources by theirs type.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class ResourceAggregator {
- private final Map resourcesTypes;
-
- @Inject
- public ResourceAggregator(Set resourcesTypes) {
- this.resourcesTypes =
- resourcesTypes.stream().collect(Collectors.toMap(ResourceType::getId, Function.identity()));
- }
-
- /**
- * Aggregates resources of the same type.
- *
- * @param resources resources list which can contain more that one instance for some type
- * @return map where key is resources type and value is aggregated resource
- * @throws IllegalArgumentException when resources list contains resource with not supported type
- */
- public Map aggregateByType(List extends Resource> resources) {
- checkSupporting(resources);
-
- Map type2Resource = new HashMap<>();
- for (Resource resource : resources) {
- final Resource resource1 = type2Resource.get(resource.getType());
- if (resource1 != null) {
- type2Resource.put(resource.getType(), aggregate(resource1, resource));
- } else {
- type2Resource.put(resource.getType(), resource);
- }
- }
- return type2Resource;
- }
-
- /**
- * Returns list which is result of deduction {@code resourceToDeduct} from {@code
- * sourceResources}.
- *
- * @param sourceResources the source resources
- * @param resourcesToDeduct the resources which should be deducted from {@code sourceResources}
- * @throws NoEnoughResourcesException when {@code sourceResources} list doesn't contain enough
- * resources
- * @throws IllegalArgumentException when {@code sourceResources} or {@code resourcesToDeduct}
- * contain resource with not supported type
- */
- public List extends Resource> deduct(
- List extends Resource> sourceResources, List extends Resource> resourcesToDeduct)
- throws NoEnoughResourcesException {
- checkSupporting(sourceResources);
- checkSupporting(resourcesToDeduct);
-
- final Map result =
- sourceResources.stream().collect(Collectors.toMap(Resource::getType, Function.identity()));
- final List missingResources = new ArrayList<>();
-
- for (Resource toDeduct : resourcesToDeduct) {
- final Resource sourceResource = result.get(toDeduct.getType());
- if (sourceResource != null) {
- try {
- result.put(toDeduct.getType(), deduct(sourceResource, toDeduct));
- } catch (NoEnoughResourcesException e) {
- result.remove(toDeduct.getType());
- missingResources.addAll(e.getMissingResources());
- }
- } else {
- missingResources.add(toDeduct);
- }
- }
-
- if (!missingResources.isEmpty()) {
- throw new NoEnoughResourcesException(sourceResources, resourcesToDeduct, missingResources);
- }
-
- return new ArrayList<>(result.values());
- }
-
- /**
- * Returns list which contains resources from specified {@code sourceResources} which have
- * excessive amount in compare to specified {@code resourcesToCompare}.
- *
- *
- *
- * @param sourceResources the source resources
- * @param resourcesToCompare the resources which should be compared to {@code sourceResources}
- * @throws IllegalArgumentException when {@code sourceResources} or {@code resourcesToCompare}
- * contain resource with not supported type
- */
- public List extends Resource> excess(
- List extends Resource> sourceResources, List extends Resource> resourcesToCompare) {
- checkSupporting(sourceResources);
- checkSupporting(resourcesToCompare);
-
- final Map result =
- sourceResources.stream().collect(Collectors.toMap(Resource::getType, Function.identity()));
- for (Resource toCompare : resourcesToCompare) {
- String resourceType = toCompare.getType();
- final Resource sourceResource = result.get(resourceType);
- if (sourceResource != null) {
- if (sourceResource.getAmount() == toCompare.getAmount()) {
- // source resource doesn't have excessive amount
- result.remove(resourceType);
- continue;
- }
- try {
- Resource excess = deduct(sourceResource, toCompare);
- if (excess.getAmount() == 0) {
- // source resource doesn't have excessive amount
- result.remove(resourceType);
- } else {
- result.put(resourceType, excess);
- }
- } catch (NoEnoughResourcesException e) {
- // source resource doesn't have excessive amount
- result.remove(resourceType);
- }
- }
- }
-
- return new ArrayList<>(result.values());
- }
-
- /**
- * Aggregates two resources which have the same type.
- *
- * @param resourceA resources A
- * @param resourceB resource B
- * @return one resources with type {@code T} that is result of aggregating {@code resourceA} and
- * {@code resourceB}
- * @throws IllegalArgumentException when {@code T} is not supported type
- */
- public Resource aggregate(Resource resourceA, Resource resourceB) {
- final String typeId = resourceA.getType();
- final ResourceType resourceType = getResourceType(typeId);
- return resourceType.aggregate(resourceA, resourceB);
- }
-
- /**
- * Deducts two resources which have the same type.
- *
- * @param totalResource total resource
- * @param deduction resources which should be deducted from {@code totalResource}
- * @return one resources with type {@code T} that is result of subtraction {@code totalResource}
- * and {@code deduction}
- * @throws NoEnoughResourcesException when {@code totalResource}'s amount is less than {@code
- * deduction}'s amount
- * @throws IllegalArgumentException when {@code T} is not supported type
- */
- public Resource deduct(Resource totalResource, Resource deduction)
- throws NoEnoughResourcesException {
- final String typeId = totalResource.getType();
- final ResourceType resourceType = getResourceType(typeId);
- return resourceType.deduct(totalResource, deduction);
- }
-
- /**
- * Returns resources list that contains resources with types that are contained by both input
- * lists.
- *
- * @throws IllegalArgumentException when {@code resources} list contains resource with not
- * supported type
- */
- public List extends Resource> intersection(
- List extends Resource> resourcesA, List extends Resource> resourcesB) {
- checkSupporting(resourcesA);
- checkSupporting(resourcesB);
-
- final Set keysA = resourcesA.stream().map(Resource::getType).collect(toSet());
- final Set keysB = resourcesB.stream().map(Resource::getType).collect(toSet());
- final Set commonKeys = ImmutableSet.copyOf(Sets.intersection(keysA, keysB));
- return Stream.concat(resourcesA.stream(), resourcesB.stream())
- .filter(res -> commonKeys.contains(res.getType()))
- .collect(Collectors.toList());
- }
-
- /**
- * Returns list that contains one resource with minimum amount for each resource type.
- *
- * @throws IllegalArgumentException when {@code resources} list contains resource with not
- * supported type
- */
- public List extends Resource> min(Collection extends Resource> resources) {
- checkSupporting(resources);
- Map result = new HashMap<>();
- for (Resource resource : resources) {
- String type = resource.getType();
- Resource min = result.get(type);
- if (min == null) {
- result.put(type, resource);
- } else if (resource.getAmount() != -1) {
- if (min.getAmount() == -1 || min.getAmount() > resource.getAmount()) {
- result.put(type, resource);
- }
- }
- }
- return new ArrayList<>(result.values());
- }
-
- /**
- * Check supporting of all given resources.
- *
- * @param resources resources to check types
- * @throws IllegalArgumentException when {@code resources} list contains resource with not
- * supported type
- */
- private void checkSupporting(Collection extends Resource> resources) {
- final Set resourcesTypes =
- resources.stream().map(Resource::getType).collect(Collectors.toSet());
- for (String resourcesType : resourcesTypes) {
- if (!this.resourcesTypes.containsKey(resourcesType)) {
- throw new IllegalArgumentException(
- String.format("'%s' resource type is not supported", resourcesType));
- }
- }
- }
-
- /**
- * Returns resources type by given id.
- *
- * @param typeId id of resources type
- * @return resources type by given id
- * @throws IllegalArgumentException when type by given id is not supported type
- */
- private ResourceType getResourceType(String typeId) {
- final ResourceType resourceType = resourcesTypes.get(typeId);
- if (resourceType == null) {
- throw new IllegalArgumentException(
- String.format("'%s' resource type is not supported", typeId));
- }
- return resourceType;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceLockKeyProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceLockKeyProvider.java
deleted file mode 100644
index 09de29423d0..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceLockKeyProvider.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import org.eclipse.che.api.core.ServerException;
-
-/**
- * Returns key for fetching lock which will be used for locking resources during resources
- * operations for account with some type.
- *
- * @author Sergii Leschenko
- */
-public interface ResourceLockKeyProvider {
- /**
- * Returns lock key by which resources should be lock during resources operations
- *
- * @param accountId account id
- * @return lock key by which resources should be lock during resources operations
- * @throws ServerException when any other exception occurs
- */
- String getLockKey(String accountId) throws ServerException;
-
- /** Returns account type for which this class provides locks' ids */
- String getAccountType();
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceModule.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceModule.java
deleted file mode 100644
index 810322ea6fd..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceModule.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012-2026 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.multibindings.MapBinder;
-import com.google.inject.multibindings.Multibinder;
-import org.eclipse.che.multiuser.api.permission.server.account.AccountPermissionsChecker;
-import org.eclipse.che.multiuser.resource.api.free.DefaultResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.free.FreeResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.type.RamResourceType;
-import org.eclipse.che.multiuser.resource.api.type.ResourceType;
-import org.eclipse.che.multiuser.resource.api.type.RuntimeResourceType;
-import org.eclipse.che.multiuser.resource.api.type.TimeoutResourceType;
-import org.eclipse.che.multiuser.resource.api.type.WorkspaceResourceType;
-
-/**
- * @author Sergii Leschenko
- */
-public class ResourceModule extends AbstractModule {
- @Override
- protected void configure() {
- MapBinder.newMapBinder(binder(), String.class, AvailableResourcesProvider.class);
- Multibinder.newSetBinder(binder(), DefaultResourcesProvider.class);
- Multibinder.newSetBinder(binder(), ResourceLockKeyProvider.class);
- Multibinder.newSetBinder(binder(), AccountPermissionsChecker.class);
-
- Multibinder.newSetBinder(binder(), ResourcesProvider.class)
- .addBinding()
- .to(FreeResourcesProvider.class);
-
- MapBinder.newMapBinder(binder(), String.class, AvailableResourcesProvider.class);
-
- Multibinder resourcesTypesBinder =
- Multibinder.newSetBinder(binder(), ResourceType.class);
- resourcesTypesBinder.addBinding().to(RamResourceType.class);
- resourcesTypesBinder.addBinding().to(WorkspaceResourceType.class);
- resourcesTypesBinder.addBinding().to(RuntimeResourceType.class);
- resourcesTypesBinder.addBinding().to(TimeoutResourceType.class);
-
- Multibinder usageTrackersBinder =
- Multibinder.newSetBinder(binder(), ResourceUsageTracker.class);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceUsageTracker.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceUsageTracker.java
deleted file mode 100644
index 9c883d5f5a7..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourceUsageTracker.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import java.util.Optional;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Tracks usage of resources of specified type.
- *
- * @author Sergii Leschenko
- */
-public interface ResourceUsageTracker {
- /**
- * Returns used resource by given account.
- *
- * @param accountId account id to fetch used resource
- * @return used resource by given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurs on used resources fetching
- */
- Optional getUsedResource(String accountId) throws NotFoundException, ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourcesProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourcesProvider.java
deleted file mode 100644
index 232e0e55798..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/ResourcesProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api;
-
-import java.util.List;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-
-/**
- * Bridge class that link resources details and resources granting mechanisms.
- *
- * @author Sergii Leschenko
- */
-public interface ResourcesProvider {
- /**
- * Returns list of provided resources for given account.
- *
- * @param accountId account id
- * @return list of provided resources for given account or empty list if there are not any
- * resources for given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurs
- */
- List getResources(String accountId) throws ServerException, NotFoundException;
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/exception/NoEnoughResourcesException.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/exception/NoEnoughResourcesException.java
deleted file mode 100644
index 0e8664a9d49..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/exception/NoEnoughResourcesException.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.exception;
-
-import static java.util.Collections.singletonList;
-
-import java.util.List;
-import java.util.stream.Collectors;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Thrown in case when account doesn't have enough resources to perform some operation.
- *
- *
It contains detailed information about resources so required, available, missing amounts to
- * provide ability to construct user friendly message.
- *
- * @author Sergii Leschenko
- */
-public class NoEnoughResourcesException extends Exception {
- private static final String MESSAGE =
- "Account has %s resources to use, but operation requires %s. It requires more %s.";
-
- private String message;
- private List extends Resource> availableResources;
- private List extends Resource> requiredResources;
- private List extends Resource> missedResources;
-
- public NoEnoughResourcesException(
- Resource availableResource, Resource requiredResource, Resource missedResource) {
- this(
- singletonList(availableResource),
- singletonList(requiredResource),
- singletonList(missedResource));
- }
-
- public NoEnoughResourcesException(
- List extends Resource> availableResources,
- List extends Resource> requiredResources,
- List extends Resource> missedResources) {
- this.availableResources = availableResources;
- this.requiredResources = requiredResources;
- this.missedResources = missedResources;
- }
-
- @Override
- public String getMessage() {
- if (message == null) {
- message =
- String.format(
- MESSAGE,
- resourcesToString(availableResources),
- resourcesToString(requiredResources),
- resourcesToString(missedResources));
- }
- return message;
- }
-
- public List extends Resource> getRequiredResources() {
- return requiredResources;
- }
-
- public List extends Resource> getAvailableResources() {
- return availableResources;
- }
-
- public List extends Resource> getMissingResources() {
- return missedResources;
- }
-
- private String resourcesToString(List extends Resource> resources) {
- return '['
- + resources.stream()
- .map(resource -> resource.getAmount() + resource.getUnit() + " " + resource.getType())
- .collect(Collectors.joining(", "))
- + ']';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/DefaultResourcesProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/DefaultResourcesProvider.java
deleted file mode 100644
index eca6a86bf51..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/DefaultResourcesProvider.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.free;
-
-import java.util.List;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Provides default resources which should be are available for usage by account when admin doesn't
- * override limit by {@link FreeResourcesLimitService}.
- *
- * @author Sergii Leschenko
- */
-public interface DefaultResourcesProvider {
- /** Provides default resources are available for usage by account */
- List getResources(String accountId) throws ServerException, NotFoundException;
-
- /** Returns account type for which this class provides default resources. */
- String getAccountType();
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitManager.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitManager.java
deleted file mode 100644
index bb669c42cc9..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitManager.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.free;
-
-import static java.util.Objects.requireNonNull;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-import org.eclipse.che.multiuser.resource.spi.FreeResourcesLimitDao;
-import org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl;
-
-/**
- * Facade for free resources limit related operations.
- *
- * @author Sergii Leschenko
- */
-// TODO Add checking resources availability before limit changing and removing
-@Singleton
-public class FreeResourcesLimitManager {
- private final FreeResourcesLimitDao freeResourcesLimitDao;
-
- @Inject
- public FreeResourcesLimitManager(FreeResourcesLimitDao freeResourcesLimitDao) {
- this.freeResourcesLimitDao = freeResourcesLimitDao;
- }
-
- /**
- * Stores (creates new one or updates existed) free resource limit.
- *
- * @param freeResourcesLimit resources limit to store
- * @return stored resources limit
- * @throws NullPointerException when {@code freeResourcesLimit} is null
- * @throws NotFoundException when resources limit contains resource with non supported type
- * @throws ConflictException when the specified account doesn't exist
- * @throws ServerException when any other error occurs
- */
- public FreeResourcesLimit store(FreeResourcesLimit freeResourcesLimit)
- throws NotFoundException, ConflictException, ServerException {
- requireNonNull(freeResourcesLimit, "Required non-null free resources limit");
- final FreeResourcesLimitImpl toStore = new FreeResourcesLimitImpl(freeResourcesLimit);
- freeResourcesLimitDao.store(toStore);
- return toStore;
- }
-
- /**
- * Returns free resources limit for account with specified id.
- *
- * @param accountId account id to fetch resources limit
- * @return free resources limit for account with specified id
- * @throws NullPointerException when {@code accountId} is null
- * @throws NotFoundException when free resources limit for specifies id was not found
- * @throws ServerException when any other error occurs
- */
- public FreeResourcesLimit get(String accountId) throws NotFoundException, ServerException {
- requireNonNull(accountId, "Required non-null account id");
- return freeResourcesLimitDao.get(accountId);
- }
-
- /**
- * Removes free resources limit for account with specified id.
- *
- *
After removing resources limit account will be able to use default resources
- *
- *
Doesn't throw an exception when resources limit for specified {@code accountId} does not
- * exist
- *
- * @param accountId account id to remove resources limit
- * @throws NullPointerException when {@code accountId} is null
- * @throws ServerException when any other error occurs
- */
- public void remove(String accountId) throws ServerException {
- requireNonNull(accountId, "Required non-null account id");
- freeResourcesLimitDao.remove(accountId);
- }
-
- /**
- * Gets all free resources limits.
- *
- * @param maxItems the maximum number of limits to return
- * @param skipCount the number of limits to skip
- * @return list of limits POJO or empty list if no limits were found
- * @throws ServerException when any other error occurs
- */
- public Page extends FreeResourcesLimit> getAll(int maxItems, int skipCount)
- throws ServerException {
- return freeResourcesLimitDao.getAll(maxItems, skipCount);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitValidator.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitValidator.java
deleted file mode 100644
index 31bf222ff99..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesLimitValidator.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.free;
-
-import static java.lang.String.format;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-import org.eclipse.che.multiuser.resource.shared.dto.FreeResourcesLimitDto;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-
-/**
- * Utils for validation of {@link FreeResourcesLimit}
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class FreeResourcesLimitValidator {
- private final ResourceValidator resourceValidator;
-
- @Inject
- public FreeResourcesLimitValidator(ResourceValidator resourceValidator) {
- this.resourceValidator = resourceValidator;
- }
-
- /**
- * Validates given {@code freeResourcesLimit}
- *
- * @param freeResourcesLimit resources limit to validate
- * @throws BadRequestException when {@code freeResourcesLimit} is null
- * @throws BadRequestException when any of {@code freeResourcesLimit.getResources} is not valid
- * @see ResourceValidator#validate(ResourceDto)
- */
- public void check(FreeResourcesLimitDto freeResourcesLimit) throws BadRequestException {
- if (freeResourcesLimit == null) {
- throw new BadRequestException("Missed free resources limit description.");
- }
- if (freeResourcesLimit.getAccountId() == null) {
- throw new BadRequestException("Missed account id.");
- }
-
- Set resourcesToSet = new HashSet<>();
- for (ResourceDto resource : freeResourcesLimit.getResources()) {
- if (!resourcesToSet.add(resource.getType())) {
- throw new BadRequestException(
- format(
- "Free resources limit should contain only one resources with type '%s'.",
- resource.getType()));
- }
- resourceValidator.validate(resource);
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesProvider.java
deleted file mode 100644
index 74326447e08..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/FreeResourcesProvider.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.free;
-
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static java.util.stream.Collectors.toMap;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.account.api.AccountManager;
-import org.eclipse.che.account.shared.model.Account;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.api.ResourcesProvider;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ProvidedResourcesImpl;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Provides free resources for account usage.
- *
- *
Returns free resources limits if it is specified for given account or default free resources
- * limit in other case
- *
- *
Default resources should be provided by {@link DefaultResourcesProvider} for different account
- * types
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class FreeResourcesProvider implements ResourcesProvider {
- public static final String FREE_RESOURCES_PROVIDER = "free";
-
- private final FreeResourcesLimitManager freeResourcesLimitManager;
- private final AccountManager accountManager;
- private final Map defaultResourcesProviders;
-
- @Inject
- public FreeResourcesProvider(
- FreeResourcesLimitManager freeResourcesLimitManager,
- AccountManager accountManager,
- Set defaultResourcesProviders) {
- this.freeResourcesLimitManager = freeResourcesLimitManager;
- this.accountManager = accountManager;
- this.defaultResourcesProviders =
- defaultResourcesProviders.stream()
- .collect(toMap(DefaultResourcesProvider::getAccountType, Function.identity()));
- }
-
- @Override
- public List getResources(String accountId)
- throws ServerException, NotFoundException {
- Map freeResources = new HashMap<>();
- String limitId = null;
- try {
- FreeResourcesLimit resourcesLimit = freeResourcesLimitManager.get(accountId);
- for (Resource resource : resourcesLimit.getResources()) {
- freeResources.put(resource.getType(), new ResourceImpl(resource));
- }
- limitId = resourcesLimit.getAccountId();
- } catch (NotFoundException ignored) {
- // there is no resources limit for given account
- }
-
- // add default resources which are not specified by limit
- for (ResourceImpl resource : getDefaultResources(accountId)) {
- freeResources.putIfAbsent(resource.getType(), resource);
- }
-
- if (!freeResources.isEmpty()) {
- return singletonList(
- new ProvidedResourcesImpl(
- FREE_RESOURCES_PROVIDER, limitId, accountId, -1L, -1L, freeResources.values()));
- } else {
- return emptyList();
- }
- }
-
- private List getDefaultResources(String accountId)
- throws NotFoundException, ServerException {
- List defaultResources = new ArrayList<>();
- final Account account = accountManager.getById(accountId);
-
- final DefaultResourcesProvider defaultResourcesProvider =
- defaultResourcesProviders.get(account.getType());
- if (defaultResourcesProvider != null) {
- defaultResources.addAll(defaultResourcesProvider.getResources(accountId));
- }
-
- return defaultResources;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/ResourceValidator.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/ResourceValidator.java
deleted file mode 100644
index 05dd3b0d491..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/free/ResourceValidator.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.free;
-
-import static java.util.stream.Collectors.toMap;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.multiuser.resource.api.type.ResourceType;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.shared.dto.ResourceDto;
-
-/**
- * Utils for validation of {@link Resource}.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class ResourceValidator {
- private final Map> resourcesTypesToUnits;
- private final Map resourcesTypesToDefaultUnit;
-
- @Inject
- public ResourceValidator(Set supportedResources) {
- this.resourcesTypesToUnits =
- supportedResources.stream()
- .collect(toMap(ResourceType::getId, ResourceType::getSupportedUnits));
- this.resourcesTypesToDefaultUnit =
- supportedResources.stream()
- .collect(toMap(ResourceType::getId, ResourceType::getDefaultUnit));
- }
-
- /**
- * Validates given {@code resource}
- *
- *
{@link ResourceDto#getUnit()} can be null then {@link ResourceType#getDefaultUnit() default
- * unit} of {@link ResourceDto#getType() specified type} will be set.
- *
- * @param resource resource to validate
- * @throws BadRequestException when {@code resource} is null
- * @throws BadRequestException when {@code resource} has non supported type
- * @throws BadRequestException when {@code resource} has non supported unit
- */
- public void validate(ResourceDto resource) throws BadRequestException {
- if (resource == null) {
- throw new BadRequestException("Missed resource");
- }
-
- final Set units = resourcesTypesToUnits.get(resource.getType());
-
- if (units == null) {
- throw new BadRequestException(
- "Specified resources type '" + resource.getType() + "' is not supported");
- }
-
- if (resource.getUnit() == null) {
- resource.setUnit(resourcesTypesToDefaultUnit.get(resource.getType()));
- } else {
- if (!units.contains(resource.getUnit())) {
- throw new BadRequestException(
- "Specified resources type '"
- + resource.getType()
- + "' support only following units: "
- + units.stream().collect(Collectors.joining(", ")));
- }
- }
-
- if (resource.getAmount() < -1) {
- throw new BadRequestException(
- "Resources with type '" + resource.getType() + "' has negative amount");
- }
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/AbstractExhaustibleResource.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/AbstractExhaustibleResource.java
deleted file mode 100644
index 31372025e09..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/AbstractExhaustibleResource.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourceImpl;
-
-/**
- * Abstract resource that contains logic for aggregating and deduction for exhaustible resources.
- *
- * @author Sergii Leschenko
- */
-public abstract class AbstractExhaustibleResource implements ResourceType {
- @Override
- public Resource aggregate(Resource resourceA, Resource resourceB) {
- checkResource(resourceA);
- checkResource(resourceB);
-
- if (resourceA.getAmount() == -1 || resourceB.getAmount() == -1) {
- return new ResourceImpl(getId(), -1, getDefaultUnit());
- }
-
- return new ResourceImpl(
- getId(), resourceA.getAmount() + resourceB.getAmount(), getDefaultUnit());
- }
-
- @Override
- public Resource deduct(Resource total, Resource deduction) throws NoEnoughResourcesException {
- checkResource(total);
- checkResource(deduction);
-
- if (total.getAmount() == -1) {
- return total;
- }
-
- if (deduction.getAmount() == -1) {
- throw new NoEnoughResourcesException(total, deduction, deduction);
- }
-
- final long resultAmount = total.getAmount() - deduction.getAmount();
- if (resultAmount < 0) {
- throw new NoEnoughResourcesException(
- total, deduction, new ResourceImpl(getId(), -resultAmount, getDefaultUnit()));
- }
- return new ResourceImpl(getId(), resultAmount, getDefaultUnit());
- }
-
- /**
- * Checks that given resources can be processed by this resource type
- *
- * @param resource resource to check
- * @throws IllegalArgumentException if given resources has unsupported type or unit
- */
- private void checkResource(Resource resource) {
- checkArgument(
- getId().equals(resource.getType()), "Resource should have '" + getId() + "' type");
- checkArgument(
- getSupportedUnits().contains(resource.getUnit()),
- "Resource has unsupported unit '" + resource.getUnit() + "'");
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RamResourceType.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RamResourceType.java
deleted file mode 100644
index 0648b129360..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RamResourceType.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-
-/**
- * Describes resource type that control number of RAM which can be used by running workspaces at the
- * same time.
- *
- * @author Sergii Leschenko
- */
-public class RamResourceType extends AbstractExhaustibleResource {
- public static final String ID = "RAM";
- public static final String UNIT = "mb";
-
- private static final Set SUPPORTED_UNITS = ImmutableSet.of(UNIT);
-
- @Override
- public String getId() {
- return ID;
- }
-
- @Override
- public String getDescription() {
- return "Number of RAM which can be used by running workspaces at the same time";
- }
-
- @Override
- public Set getSupportedUnits() {
- return SUPPORTED_UNITS;
- }
-
- @Override
- public String getDefaultUnit() {
- return UNIT;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/ResourceType.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/ResourceType.java
deleted file mode 100644
index 049a514fb81..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/ResourceType.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import java.util.Set;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Represents some kind of resources which can be used by account.
- *
- * @author Sergii Leschenko
- */
-public interface ResourceType {
- /** Returns id of resource type. */
- String getId();
-
- /** Returns description of resource type. */
- String getDescription();
-
- /** Returns supported units. */
- Set getSupportedUnits();
-
- /** Returns default unit. */
- String getDefaultUnit();
-
- /**
- * Defines function for aggregating two resources of this type.
- *
- * @param resourceA resources A
- * @param resourceB resource B
- * @throws IllegalArgumentException if one of resources has unsupported type or unit
- */
- Resource aggregate(Resource resourceA, Resource resourceB);
-
- /**
- * Defines function for subtraction two resources of this type.
- *
- * @param total total resource
- * @param deduction resource that should be deducted from {@code total}
- * @throws IllegalArgumentException if one of resources has unsupported type or unit
- * @throws NoEnoughResourcesException when {@code total}'s amount is less than {@code deduction}'s
- * amount
- */
- Resource deduct(Resource total, Resource deduction) throws NoEnoughResourcesException;
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RuntimeResourceType.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RuntimeResourceType.java
deleted file mode 100644
index 1f96501f887..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/RuntimeResourceType.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-
-/**
- * Describes resource type that control number of workspaces which user can run at the same time.
- *
- * @author Sergii Leshchenko
- */
-public class RuntimeResourceType extends AbstractExhaustibleResource {
- public static final String ID = "runtime";
- public static final String UNIT = "item";
-
- private static final Set SUPPORTED_UNITS = ImmutableSet.of(UNIT);
-
- @Override
- public String getId() {
- return ID;
- }
-
- @Override
- public String getDescription() {
- return "Number of workspaces which user can run at the same time";
- }
-
- @Override
- public Set getSupportedUnits() {
- return SUPPORTED_UNITS;
- }
-
- @Override
- public String getDefaultUnit() {
- return UNIT;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/TimeoutResourceType.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/TimeoutResourceType.java
deleted file mode 100644
index 140148c4298..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/TimeoutResourceType.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Describes resource type that control the length of time that a user is idle with their workspace
- * when the system will suspend the workspace by snapshotting it and then stopping it.
- *
- * @author Sergii Leschenko
- */
-public class TimeoutResourceType implements ResourceType {
- public static final String ID = "timeout";
- public static final String UNIT = "minute";
-
- private static final Set SUPPORTED_UNITS = ImmutableSet.of(UNIT);
-
- @Override
- public String getId() {
- return ID;
- }
-
- @Override
- public String getDescription() {
- return "Timeout";
- }
-
- @Override
- public Set getSupportedUnits() {
- return SUPPORTED_UNITS;
- }
-
- @Override
- public String getDefaultUnit() {
- return UNIT;
- }
-
- @Override
- public Resource aggregate(Resource resourceA, Resource resourceB) {
- return resourceA.getAmount() > resourceB.getAmount() ? resourceA : resourceB;
- }
-
- @Override
- public Resource deduct(Resource total, Resource deduction) throws NoEnoughResourcesException {
- return total;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/WorkspaceResourceType.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/WorkspaceResourceType.java
deleted file mode 100644
index 818919a01d9..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/type/WorkspaceResourceType.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.type;
-
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
-
-/**
- * Describes resource type that control number of workspaces which user can have at the same time.
- *
- * @author Sergii Leshchenko
- */
-public class WorkspaceResourceType extends AbstractExhaustibleResource {
- public static final String ID = "workspace";
- public static final String UNIT = "item";
-
- private static final Set SUPPORTED_UNITS = ImmutableSet.of(UNIT);
-
- @Override
- public String getId() {
- return ID;
- }
-
- @Override
- public String getDescription() {
- return "Number of workspaces which user can have at the same time";
- }
-
- @Override
- public Set getSupportedUnits() {
- return SUPPORTED_UNITS;
- }
-
- @Override
- public String getDefaultUnit() {
- return UNIT;
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/DefaultAvailableResourcesProvider.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/DefaultAvailableResourcesProvider.java
deleted file mode 100644
index 809b319e9be..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/DefaultAvailableResourcesProvider.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.usage;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Default implementation of providing available resources for accounts.
- *
- *
By default account can use resources only by itself, so available resources equals to total
- * resources minus resources which are already used by account.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class DefaultAvailableResourcesProvider implements AvailableResourcesProvider {
- private static final Logger LOG =
- LoggerFactory.getLogger(DefaultAvailableResourcesProvider.class);
-
- private final Provider resourceManagerProvider;
- private final ResourceAggregator resourceAggregator;
-
- @Inject
- public DefaultAvailableResourcesProvider(
- Provider resourceManagerProvider, ResourceAggregator resourceAggregator) {
- this.resourceManagerProvider = resourceManagerProvider;
- this.resourceAggregator = resourceAggregator;
- }
-
- @Override
- public List extends Resource> getAvailableResources(String accountId)
- throws NotFoundException, ServerException {
- ResourceManager resourceManager = resourceManagerProvider.get();
- List extends Resource> totalResources = null;
- List usedResources = null;
- try {
- totalResources = resourceManager.getTotalResources(accountId);
- usedResources = new ArrayList<>(resourceManager.getUsedResources(accountId));
- return resourceAggregator.deduct(totalResources, usedResources);
- } catch (NoEnoughResourcesException e) {
- LOG.warn(
- "Account with id {} uses more resources {} than he has {}.",
- accountId,
- format(usedResources),
- format(totalResources));
- return resourceAggregator.excess(totalResources, usedResources);
- }
- }
-
- /** Returns formatted string for list of resources. */
- private static String format(Collection extends Resource> resources) {
- return '['
- + resources.stream()
- .map(
- resource -> resource.getAmount() + resource.getUnit() + " of " + resource.getType())
- .collect(Collectors.joining(", "))
- + ']';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourceManager.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourceManager.java
deleted file mode 100644
index efc75cd7f0f..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourceManager.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.usage;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.account.api.AccountManager;
-import org.eclipse.che.account.shared.model.Account;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.api.AvailableResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.ResourceAggregator;
-import org.eclipse.che.multiuser.resource.api.ResourceUsageTracker;
-import org.eclipse.che.multiuser.resource.api.ResourcesProvider;
-import org.eclipse.che.multiuser.resource.api.exception.NoEnoughResourcesException;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.model.ResourcesDetails;
-import org.eclipse.che.multiuser.resource.spi.impl.ResourcesDetailsImpl;
-
-/**
- * Facade for resources related operations.
- *
- * @author Sergii Leschenko
- */
-@Singleton
-public class ResourceManager {
- private final ResourceAggregator resourceAggregator;
- private final Set resourcesProviders;
- private final Set usageTrackers;
- private final AccountManager accountManager;
- private final Map accountTypeToAvailableResourcesProvider;
- private final DefaultAvailableResourcesProvider defaultAvailableResourcesProvider;
-
- @Inject
- public ResourceManager(
- ResourceAggregator resourceAggregator,
- Set resourcesProviders,
- Set usageTrackers,
- AccountManager accountManager,
- Map accountTypeToAvailableResourcesProvider,
- DefaultAvailableResourcesProvider defaultAvailableResourcesProvider) {
- this.resourceAggregator = resourceAggregator;
- this.resourcesProviders = resourcesProviders;
- this.usageTrackers = usageTrackers;
- this.accountManager = accountManager;
- this.accountTypeToAvailableResourcesProvider = accountTypeToAvailableResourcesProvider;
- this.defaultAvailableResourcesProvider = defaultAvailableResourcesProvider;
- }
-
- /**
- * Returns list of resources which are available for usage by given account.
- *
- * @param accountId id of account
- * @return list of resources which are available for usage by given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurred while resources fetching
- */
- public List extends Resource> getTotalResources(String accountId)
- throws NotFoundException, ServerException {
- return getResourceDetails(accountId).getTotalResources();
- }
-
- /**
- * Returns list of resources which are available for usage by given account.
- *
- * @param accountId id of account
- * @return list of resources which are available for usage by given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurred while resources fetching
- */
- public List extends Resource> getAvailableResources(String accountId)
- throws NotFoundException, ServerException {
- final Account account = accountManager.getById(accountId);
- final AvailableResourcesProvider availableResourcesProvider =
- accountTypeToAvailableResourcesProvider.get(account.getType());
-
- if (availableResourcesProvider == null) {
- return defaultAvailableResourcesProvider.getAvailableResources(accountId);
- }
-
- return availableResourcesProvider.getAvailableResources(accountId);
- }
-
- /**
- * Returns list of resources which are used by given account.
- *
- * @param accountId id of account
- * @return list of resources which are used by given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurred while resources fetching
- */
- public List extends Resource> getUsedResources(String accountId)
- throws NotFoundException, ServerException {
- List usedResources = new ArrayList<>();
- for (ResourceUsageTracker usageTracker : usageTrackers) {
- Optional usedResource = usageTracker.getUsedResource(accountId);
- usedResource.ifPresent(usedResources::add);
- }
- return usedResources;
- }
-
- /**
- * Checks that specified account has available resources to use
- *
- * @param accountId account id
- * @param resources resources to check availability
- * @throws NotFoundException when account with specified id was not found
- * @throws NoEnoughResourcesException when account doesn't have specified available resources
- * @throws ServerException when any other error occurs
- */
- public void checkResourcesAvailability(String accountId, List extends Resource> resources)
- throws NotFoundException, NoEnoughResourcesException, ServerException {
- List extends Resource> availableResources = getAvailableResources(accountId);
- // check resources availability
- resourceAggregator.deduct(availableResources, resources);
- }
-
- /**
- * Returns detailed information about resources which given account can use.
- *
- * @param accountId account id
- * @return detailed information about resources which can be used by given account
- * @throws NotFoundException when account with specified id was not found
- * @throws ServerException when some exception occurs
- */
- public ResourcesDetails getResourceDetails(String accountId)
- throws NotFoundException, ServerException {
- final List resources = new ArrayList<>();
- for (ResourcesProvider resourcesProvider : resourcesProviders) {
- resources.addAll(resourcesProvider.getResources(accountId));
- }
-
- final List allResources =
- resources.stream()
- .flatMap(providedResources -> providedResources.getResources().stream())
- .collect(Collectors.toList());
-
- return new ResourcesDetailsImpl(
- accountId,
- resources,
- new ArrayList<>(resourceAggregator.aggregateByType(allResources).values()));
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourcesLocks.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourcesLocks.java
deleted file mode 100644
index be224279eee..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/ResourcesLocks.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.usage;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import org.eclipse.che.account.api.AccountManager;
-import org.eclipse.che.account.shared.model.Account;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.commons.lang.concurrent.StripedLocks;
-import org.eclipse.che.commons.lang.concurrent.Unlocker;
-import org.eclipse.che.multiuser.resource.api.ResourceLockKeyProvider;
-
-/**
- * Helps to lock resources while performing operations related to them.
- *
- *
Resources will be locked not by account id but by key which will be provided by {@link
- * ResourceLockKeyProvider} for specified account's type
- *
- *
It based on {@link StripedLocks} so it can be used in try-with-resources construction.
- *
- *
- * try (Unlocker u = resourceLocks.lock("account123")) {
- * // check resources availability and perform operation here
- * }
- *
- *
- * @author Sergii Leschenko
- */
-public class ResourcesLocks {
-
- private final AccountManager accountManager;
- private final Map accountTypeToLockProvider;
- private final StripedLocks stripedLocks;
-
- @Inject
- public ResourcesLocks(
- Set resourceLockKeyProviders, AccountManager accountManager) {
- this.accountManager = accountManager;
- this.stripedLocks = new StripedLocks(16);
- this.accountTypeToLockProvider =
- resourceLockKeyProviders.stream()
- .collect(
- Collectors.toMap(ResourceLockKeyProvider::getAccountType, Function.identity()));
- }
-
- /**
- * Acquire resources lock for specified account.
- *
- * @param accountId account id to lock resources
- * @return lock for unlocking resources when resources operation finishes
- * @throws NotFoundException when account with specified {@code account id} was not found
- * @throws ServerException when any other error occurs
- */
- public Unlocker lock(String accountId) throws NotFoundException, ServerException {
- final Account account = accountManager.getById(accountId);
- final ResourceLockKeyProvider resourceLockKeyProvider =
- accountTypeToLockProvider.get(account.getType());
- String lockKey;
- if (resourceLockKeyProvider == null) {
- // this account type doesn't have custom lock provider.
- // Lock resources by current account
- lockKey = accountId;
- } else {
- lockKey = resourceLockKeyProvider.getLockKey(accountId);
- }
-
- return stripedLocks.writeLock(lockKey);
- }
-
- public Unlocker lock(String... accountIds) throws NotFoundException, ServerException {
- // TODO It should be implemented for making possible lock resources by two or more accounts in
- // case of resources redistribution
- throw new UnsupportedOperationException("Not implemented.");
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/tracker/EnvironmentRamCalculator.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/tracker/EnvironmentRamCalculator.java
deleted file mode 100644
index c4244bb5c1b..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/api/usage/tracker/EnvironmentRamCalculator.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.api.usage.tracker;
-
-import static java.lang.String.format;
-import static org.eclipse.che.api.core.model.workspace.config.MachineConfig.MEMORY_LIMIT_ATTRIBUTE;
-
-import java.util.Map;
-import javax.inject.Inject;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.ValidationException;
-import org.eclipse.che.api.core.model.workspace.Runtime;
-import org.eclipse.che.api.core.model.workspace.config.Environment;
-import org.eclipse.che.api.core.model.workspace.config.MachineConfig;
-import org.eclipse.che.api.workspace.server.spi.InfrastructureException;
-import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironment;
-import org.eclipse.che.api.workspace.server.spi.environment.InternalEnvironmentFactory;
-import org.eclipse.che.commons.annotation.Nullable;
-
-/**
- * Helps to calculate amount of RAM defined in {@link Environment environment}
- *
- * @author Sergii Leschenko
- * @author Anton Korneta
- */
-public class EnvironmentRamCalculator {
- private static final long BYTES_TO_MEGABYTES_DIVIDER = 1024L * 1024L;
-
- private final Map environmentFactories;
-
- @Inject
- public EnvironmentRamCalculator(Map environmentFactories) {
- this.environmentFactories = environmentFactories;
- }
-
- /**
- * Parses (and fetches if needed) recipe of environment and sums RAM size of all machines in
- * environment in megabytes.
- */
- public long calculate(@Nullable Environment environment) throws ServerException {
- if (environment == null) {
- return 0;
- }
- try {
- return getInternalEnvironment(environment).getMachines().values().stream()
- .mapToLong(
- m -> parseMemoryAttributeValue(m.getAttributes().get(MEMORY_LIMIT_ATTRIBUTE)))
- .sum()
- / BYTES_TO_MEGABYTES_DIVIDER;
- } catch (InfrastructureException | ValidationException | NotFoundException ex) {
- throw new ServerException(ex.getMessage(), ex);
- }
- }
-
- /**
- * Calculates summary RAM of given {@link Runtime}.
- *
- * @return summary RAM of all machines in runtime in megabytes
- */
- public long calculate(Runtime runtime) {
- return runtime.getMachines().values().stream()
- .mapToLong(
- m -> parseMemoryAttributeValue(m.getAttributes().get(MEMORY_LIMIT_ATTRIBUTE)))
- .sum()
- / BYTES_TO_MEGABYTES_DIVIDER;
- }
-
- /**
- * Parse {@link MachineConfig#MEMORY_LIMIT_ATTRIBUTE} value to {@code Long}.
- *
- * @param attributeValue value of {@link MachineConfig#MEMORY_LIMIT_ATTRIBUTE} attribute from
- * machine config or runtime
- * @return long value parsed from provided string attribute value or {@code 0} if {@code null} is
- * provided
- * @throws NumberFormatException if provided value is neither {@code null} nor valid stringified
- * long
- * @see Long#parseLong(String)
- */
- private long parseMemoryAttributeValue(String attributeValue) {
- if (attributeValue == null) {
- return 0;
- } else {
- return Long.parseLong(attributeValue);
- }
- }
-
- private InternalEnvironment getInternalEnvironment(Environment environment)
- throws InfrastructureException, ValidationException, NotFoundException {
- final String recipeType = environment.getRecipe().getType();
- final InternalEnvironmentFactory factory = environmentFactories.get(recipeType);
- if (factory == null) {
- throw new NotFoundException(
- format("InternalEnvironmentFactory is not configured for recipe type: '%s'", recipeType));
- }
- return factory.create(environment);
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/FreeResourcesLimitDao.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/FreeResourcesLimitDao.java
deleted file mode 100644
index 4acd7107fb9..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/FreeResourcesLimitDao.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.spi;
-
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.Page;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.multiuser.resource.spi.impl.FreeResourcesLimitImpl;
-
-/**
- * Defines data access object contract for {@link FreeResourcesLimitImpl}.
- *
- * @author Sergii Leschenko
- */
-public interface FreeResourcesLimitDao {
- /**
- * Stores (creates new one or updates existed) free resource limit.
- *
- * @param resourcesLimit resources limit to store
- * @throws NullPointerException when {@code resourcesLimit} is null
- * @throws ConflictException when the specified account doesn't exist
- * @throws ServerException when any other error occurs
- */
- void store(FreeResourcesLimitImpl resourcesLimit) throws ConflictException, ServerException;
-
- /**
- * Returns free resources limit for account with specified id.
- *
- * @param accountId account id to fetch resources limit
- * @return free resources limit for account with specified id
- * @throws NullPointerException when {@code accountId} is null
- * @throws NotFoundException when free resources limit for specifies id was not found
- * @throws ServerException when any other error occurs
- */
- FreeResourcesLimitImpl get(String accountId) throws NotFoundException, ServerException;
-
- /**
- * Gets all free resources limits.
- *
- * @param maxItems the maximum number of limits to return
- * @param skipCount the number of limits to skip
- * @return list of limits POJO or empty list if no limits were found
- * @throws ServerException when any other error occurs
- */
- Page getAll(int maxItems, int skipCount) throws ServerException;
-
- /**
- * Removes free resources limit for account with specified id.
- *
- *
Doesn't throw an exception when resources limit for specified {@code accountId} does not
- * exist
- *
- * @param accountId account id to remove resources limit
- * @throws NullPointerException when {@code accountId} is null
- * @throws ServerException when any other error occurs
- */
- void remove(String accountId) throws ServerException;
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/FreeResourcesLimitImpl.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/FreeResourcesLimitImpl.java
deleted file mode 100644
index 7e70efffdc3..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/FreeResourcesLimitImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.spi.impl;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.NamedQueries;
-import javax.persistence.NamedQuery;
-import javax.persistence.OneToMany;
-import javax.persistence.PrimaryKeyJoinColumn;
-import javax.persistence.Table;
-import org.eclipse.che.account.spi.AccountImpl;
-import org.eclipse.che.multiuser.resource.model.FreeResourcesLimit;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * Data object for {@link FreeResourcesLimit}.
- *
- * @author Sergii Leschenko
- */
-@Entity(name = "FreeResourcesLimit")
-@NamedQueries({
- @NamedQuery(
- name = "FreeResourcesLimit.get",
- query = "SELECT limit FROM FreeResourcesLimit limit WHERE limit.accountId= :accountId"),
- @NamedQuery(
- name = "FreeResourcesLimit.getAll",
- query = "SELECT limit FROM FreeResourcesLimit limit"),
- @NamedQuery(
- name = "FreeResourcesLimit.getTotalCount",
- query = "SELECT COUNT(limit) FROM FreeResourcesLimit limit")
-})
-@Table(name = "che_free_resources_limit")
-public class FreeResourcesLimitImpl implements FreeResourcesLimit {
- @Id
- @Column(name = "account_id")
- private String accountId;
-
- @PrimaryKeyJoinColumn private AccountImpl account;
-
- @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
- @JoinTable(
- name = "che_free_resources_limit_resource",
- joinColumns = @JoinColumn(name = "free_resources_limit_account_id"),
- inverseJoinColumns = @JoinColumn(name = "resources_id"))
- private List resources;
-
- public FreeResourcesLimitImpl() {}
-
- public FreeResourcesLimitImpl(FreeResourcesLimit freeResourcesLimit) {
- this(freeResourcesLimit.getAccountId(), freeResourcesLimit.getResources());
- }
-
- public FreeResourcesLimitImpl(String accountId, List extends Resource> resources) {
- this.accountId = accountId;
- if (resources != null) {
- this.resources = resources.stream().map(ResourceImpl::new).collect(Collectors.toList());
- }
- }
-
- @Override
- public String getAccountId() {
- return accountId;
- }
-
- @Override
- public List getResources() {
- if (resources == null) {
- resources = new ArrayList<>();
- }
- return resources;
- }
-
- public void setResources(List resources) {
- this.resources = resources;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof FreeResourcesLimitImpl)) return false;
- FreeResourcesLimitImpl that = (FreeResourcesLimitImpl) o;
- return Objects.equals(accountId, that.accountId)
- && Objects.equals(getResources(), that.getResources());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(accountId, getResources());
- }
-
- @Override
- public String toString() {
- return "FreeResourcesLimitImpl{"
- + "accountId='"
- + accountId
- + '\''
- + ", resources="
- + getResources()
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ProvidedResourcesImpl.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ProvidedResourcesImpl.java
deleted file mode 100644
index 41328ad6c38..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ProvidedResourcesImpl.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.spi.impl;
-
-import com.google.common.base.Objects;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * @author Sergii Leschenko
- */
-public class ProvidedResourcesImpl implements ProvidedResources {
- private String provider;
- private String id;
- private String owner;
- private Long startTime;
- private Long endTime;
- private List resources;
-
- public ProvidedResourcesImpl(ProvidedResources providedResources) {
- this(
- providedResources.getProviderId(),
- providedResources.getId(),
- providedResources.getOwner(),
- providedResources.getStartTime(),
- providedResources.getEndTime(),
- providedResources.getResources());
- }
-
- public ProvidedResourcesImpl(
- String provider,
- String id,
- String owner,
- Long startTime,
- Long endTime,
- Collection extends Resource> resources) {
- this.provider = provider;
- this.id = id;
- this.owner = owner;
- this.startTime = startTime;
- this.endTime = endTime;
- if (resources != null) {
- this.resources = resources.stream().map(ResourceImpl::new).collect(Collectors.toList());
- }
- }
-
- @Override
- public String getProviderId() {
- return provider;
- }
-
- @Override
- public String getId() {
- return id;
- }
-
- @Override
- public String getOwner() {
- return owner;
- }
-
- @Override
- public Long getStartTime() {
- return startTime;
- }
-
- @Override
- public Long getEndTime() {
- return endTime;
- }
-
- @Override
- public List getResources() {
- if (resources == null) {
- resources = new ArrayList<>();
- }
- return resources;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ProvidedResourcesImpl)) return false;
- ProvidedResourcesImpl that = (ProvidedResourcesImpl) o;
- return Objects.equal(provider, that.provider)
- && Objects.equal(id, that.id)
- && Objects.equal(owner, that.owner)
- && Objects.equal(startTime, that.startTime)
- && Objects.equal(endTime, that.endTime)
- && Objects.equal(getResources(), that.getResources());
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(provider, id, owner, startTime, endTime, getResources());
- }
-
- @Override
- public String toString() {
- return "GrantedResourceImpl{"
- + "provider='"
- + provider
- + '\''
- + ", id='"
- + id
- + '\''
- + ", owner='"
- + owner
- + '\''
- + ", startTime="
- + startTime
- + ", endTime="
- + endTime
- + ", resources="
- + getResources()
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourceImpl.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourceImpl.java
deleted file mode 100644
index 597655040f3..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourceImpl.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.spi.impl;
-
-import java.util.Objects;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import org.eclipse.che.multiuser.resource.model.Resource;
-
-/**
- * @author Sergii Leschenko
- */
-@Entity(name = "Resource")
-@Table(name = "che_resource")
-public class ResourceImpl implements Resource {
- @Id
- @GeneratedValue
- @Column(name = "id")
- private Long id;
-
- @Column(name = "type", nullable = false)
- private String type;
-
- @Column(name = "amount", nullable = false)
- private long amount;
-
- @Column(name = "unit", nullable = false)
- private String unit;
-
- public ResourceImpl() {}
-
- public ResourceImpl(String type, long amount, String unit) {
- this.amount = amount;
- this.type = type;
- this.unit = unit;
- }
-
- public ResourceImpl(Resource resource) {
- this(resource.getType(), resource.getAmount(), resource.getUnit());
- }
-
- @Override
- public String getType() {
- return type;
- }
-
- @Override
- public long getAmount() {
- return amount;
- }
-
- @Override
- public String getUnit() {
- return unit;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!(obj instanceof ResourceImpl)) {
- return false;
- }
- final ResourceImpl that = (ResourceImpl) obj;
- return amount == that.amount
- && Objects.equals(id, that.id)
- && Objects.equals(type, that.type)
- && Objects.equals(unit, that.unit);
- }
-
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 31 * hash + Objects.hashCode(id);
- hash = 31 * hash + Objects.hashCode(type);
- hash = 31 * hash + Long.hashCode(amount);
- hash = 31 * hash + Objects.hashCode(unit);
- return hash;
- }
-
- @Override
- public String toString() {
- return "ResourceImpl{"
- + "id="
- + id
- + ", type='"
- + type
- + '\''
- + ", amount="
- + amount
- + ", unit='"
- + unit
- + '\''
- + '}';
- }
-}
diff --git a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourcesDetailsImpl.java b/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourcesDetailsImpl.java
deleted file mode 100644
index 25c94b57b9d..00000000000
--- a/multiuser/api/che-multiuser-api-resource/src/main/java/org/eclipse/che/multiuser/resource/spi/impl/ResourcesDetailsImpl.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.resource.spi.impl;
-
-import com.google.common.base.Objects;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.eclipse.che.multiuser.resource.model.ProvidedResources;
-import org.eclipse.che.multiuser.resource.model.Resource;
-import org.eclipse.che.multiuser.resource.model.ResourcesDetails;
-
-/**
- * @author Sergii Leschenko
- */
-public class ResourcesDetailsImpl implements ResourcesDetails {
- private String accountId;
- private List providedResources;
- private List totalResources;
-
- public ResourcesDetailsImpl(ResourcesDetails resourcesDetails) {
- this(
- resourcesDetails.getAccountId(),
- resourcesDetails.getProvidedResources(),
- resourcesDetails.getTotalResources());
- }
-
- public ResourcesDetailsImpl(
- String owner,
- List extends ProvidedResources> providedResources,
- List extends Resource> totalResources) {
- this.accountId = owner;
- if (providedResources != null) {
- this.providedResources =
- providedResources.stream().map(ProvidedResourcesImpl::new).collect(Collectors.toList());
- }
- if (totalResources != null) {
- this.totalResources =
- totalResources.stream().map(ResourceImpl::new).collect(Collectors.toList());
- }
- }
-
- @Override
- public String getAccountId() {
- return accountId;
- }
-
- @Override
- public List getProvidedResources() {
- if (providedResources == null) {
- providedResources = new ArrayList<>();
- }
- return providedResources;
- }
-
- @Override
- public List getTotalResources() {
- if (totalResources == null) {
- totalResources = new ArrayList<>();
- }
- return totalResources;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ResourcesDetailsImpl)) return false;
- ResourcesDetailsImpl resourceDetails = (ResourcesDetailsImpl) o;
- return Objects.equal(accountId, resourceDetails.accountId)
- && Objects.equal(providedResources, resourceDetails.providedResources)
- && Objects.equal(totalResources, resourceDetails.totalResources);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(accountId, providedResources, totalResources);
- }
-
- @Override
- public String toString() {
- return "ResourcesDetailsImpl{"
- + "accountId='"
- + accountId
- + '\''
- + ", providedResources="
- + providedResources
- + ", totalResources="
- + totalResources
- + '}';
- }
-}
diff --git a/multiuser/api/pom.xml b/multiuser/api/pom.xml
index 94f22ad63e1..87554dbabf7 100644
--- a/multiuser/api/pom.xml
+++ b/multiuser/api/pom.xml
@@ -29,9 +29,5 @@
che-multiuser-api-permissionche-multiuser-api-authorizationche-multiuser-api-authorization-impl
- che-multiuser-api-resource-shared
- che-multiuser-api-resource
- che-multiuser-api-organization-shared
- che-multiuser-api-organization
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/authenticating-to-the-che-server-using-openid.adoc b/multiuser/keycloak/che-multiuser-keycloak-server/authenticating-to-the-che-server-using-openid.adoc
deleted file mode 100644
index 5cfd947c873..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/authenticating-to-the-che-server-using-openid.adoc
+++ /dev/null
@@ -1,109 +0,0 @@
-// authenticating-to-the-che-server
-
-[id="authenticating-to-the-che-server-using-openid_che"]
-= Authenticating to the Che server using OpenID
-
-OpenID authentication on the Che server implies the presence of an external OpenID Connect provider and has the following main steps:
-
-* Authenticate the user through a JWT token that is retrieved from an HTTP request or, in case of a missing or invalid token, redirect the user to the Keycloak login page.
-
-* Send authentication tokens in an *Authorization* header. In limited cases, when it is impossible to use the *Authorization* header, the token can be sent in the token query parameter. Example: OAuth authentication initialization.
-
-* Compose an internal `subject` object that represents the current user inside the Che server code.
-
-NOTE: The only supported and tested OpenID provider is Keycloak.
-
-.Procedure
-
-To authenticate to the Che server using OpenID authentication:
-
-. Request the OpenID settings service where clients can find all the necessary URLs and properties of the OpenId provider, such as `jwks.endpoint`, `token.endpoint`, `logout.endpoint`, `realm.name`, or `client_id` returned in the JSON format.
-
-. The service URL is `pass:c,a,q[https://che-host:che-port/api/keycloak/settings]`, and it is only available in the Che multiuser mode. The presence of the service in the URL confirms that the authentication is enabled in the current deployment.
-+
-Example output:
-+
-[source,json]
-----
-{
- "che.keycloak.token.endpoint": "http://172.19.20.9:5050/auth/realms/che/protocol/openid-connect/token",
- "che.keycloak.profile.endpoint": "http://172.19.20.9:5050/auth/realms/che/account",
- "che.keycloak.client_id": "che-public",
- "che.keycloak.auth_server_url": "http://172.19.20.9:5050/auth",
- "che.keycloak.password.endpoint": "http://172.19.20.9:5050/auth/realms/che/account/password",
- "che.keycloak.logout.endpoint": "http://172.19.20.9:5050/auth/realms/che/protocol/openid-connect/logout",
- "che.keycloak.realm": "che"
-}
-----
-+
-The service allows downloading the JavaScript client library to interact with the provider using the `pass:c,a,q[https://che-host:che-port/api/keycloak/OIDCKeycloak.js]` URL.
-
-. Redirect the user to the appropriate provider's login page with all the necessary parameters, including `client_id` and the return redirection path. This can be done with any client library (JS or Java).
-
-. When the user is logged in to the provider, the client side-code is obtained, and the JWT token has validated the token, the creation of the `subject` begins.
-
-The verification of the token signature occurs in two main steps:
-
-. Authentication: The token is extracted from the *Authorization* header or from the `token` query parameter and is parsed using the public key retrieved from the provider. In case of expired, invalid, or malformed tokens, a `403` error is sent to the user. The minimal use of the query parameter is recommended, due to its support limitations or complete removal in upcoming versions.
-+
-If the validation is successful, the parsed form of the token is passed to the environment initialization step:
-
-. Environment initialization: The filter extracts data from the JWT token claims, creates the user in the local database if it is not yet available, and constructs the `subject` object and sets it into the per-request *EnvironmentContext* object, which is statically accessible everywhere.
-+
-If the request was made using only a JWT token, the following single authentication filter is used:
-+
-*org.eclipse.che.multiuser.machine.authentication.server.MachineLoginFilter*: The filter finds the user that the `userId` token belongs to, retrieves the user instance, and sets the principal to the session. The Che server-to-server requests are performed using a dedicated request factory that signs every request with the current subject token obtained from the `EnvironmentContext` object.
-
-[NOTE]
-====
-.Providing user-specific data
-
-Since Keycloak may store user-specific information (first and last name, phone number, job title), there is a special implementation of the *ProfileDao* that can provide this data to consumers. The implementation is read-only, so users cannot perform create and update operations.
-====
-
-
-[id="obtaining-the-token-from-keycloak_che"]
-== Obtaining the token from credentials through Keycloak
-
-Clients that cannot run JavaScript or other clients (such as command-line clients or Selenium tests) must request the authorization token directly from Keycloak.
-
-To obtain the token, send a request to the token endpoint with the username and password credentials. This request can be schematically described as the following cURL request:
-
-[subs="+quotes,+attributes"]
-----
-$ curl --insecure --data "grant_type=password&client_id=che-public&username=____&password=____" \ <1> <2>
-https:///auth/realms/che/protocol/openid-connect/token <3>
-----
-<1> Eclipse Che username
-<2> Eclipse Che user's password
-<3> Keycloak host
-
-The Che dashboard uses a customized Keycloak login page and an authentication mechanism based on `grant_type=authorization_code`. It is a two-step authentication process:
-
-. Logging in and obtaining the authorization code.
-. Obtaining the token using this authorization code.
-
-[id="obtaining-the-token-from-openshift-token-through-keycloak_che"]
-== Obtaining the token from the OpenShift token through Keycloak
-
-When Che was installed on OpenShift using the Operator, and the OpenShift OAuth integration is enabled, as it is by default,
-the user's Che authentication token can be retrieved from the user's OpenShift token.
-
-To retrieve the authentication token from the OpenShift token, send a schematically described cURL request to the OpenShift token endpoint:
-
-[subs="+quotes,+attributes"]
-----
-$ curl --insecure -X POST \
--d "client_id=che-public" \
--d "subject_token=____" \ <1>
--d "subject_issuer=____" \ <2>
---data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
---data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
-https://____/auth/realms/che/protocol/openid-connect/token <3>
-----
-<1> The token retrieved by the end-user with the command `oc whoami --show-token`
-<2> `openshift-v4` for OpenShift 4.x and `openshift-v3` for OpenShift 3.11
-<3> Keycloak host
-
-
-WARNING: Before using this token exchange feature, it is required for an end user to be interactively logged in at least once to the Che Dashboard using the OpenShift login page. This step is needed to link the OpenShift and Keycloak user accounts properly and set the required user profile information.
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml b/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml
deleted file mode 100644
index 2aed4bcab13..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/pom.xml
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
- 4.0.0
-
- che-multiuser-keycloak
- org.eclipse.che.multiuser
- 7.117.0-SNAPSHOT
-
- che-multiuser-keycloak-server
- jar
- Che Multiuser :: Keycloak Server
-
- ${project.build.directory}/generated-sources/dto/
-
-
-
- com.auth0
- jwks-rsa
-
-
- com.google.code.gson
- gson
-
-
- com.google.guava
- guava
-
-
- com.google.inject
- guice
-
-
- com.google.inject.extensions
- guice-persist
-
-
- io.jsonwebtoken
- jjwt-api
-
-
- jakarta.inject
- jakarta.inject-api
-
-
- jakarta.validation
- jakarta.validation-api
-
-
- jakarta.ws.rs
- jakarta.ws.rs-api
-
-
- org.eclipse.che.core
- che-core-api-account
-
-
- org.eclipse.che.core
- che-core-api-auth
-
-
- org.eclipse.che.core
- che-core-api-auth-shared
-
-
- org.eclipse.che.core
- che-core-api-core
-
-
- org.eclipse.che.core
- che-core-api-dto
-
-
- org.eclipse.che.core
- che-core-api-model
-
-
- org.eclipse.che.core
- che-core-api-user
-
-
- org.eclipse.che.core
- che-core-commons-annotations
-
-
- org.eclipse.che.core
- che-core-commons-lang
-
-
- org.eclipse.che.core
- che-core-logback
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-authentication-commons
-
-
- org.eclipse.che.multiuser
- che-multiuser-api-authorization
-
-
- org.eclipse.che.multiuser
- che-multiuser-keycloak-shared
-
-
- org.eclipse.che.multiuser
- che-multiuser-machine-authentication-shared
-
-
- org.eclipse.che.multiuser
- che-multiuser-oidc
-
-
- org.eclipse.che.multiuser
- che-multiuser-personal-account
-
-
- org.everrest
- everrest-guice-servlet
-
-
- org.slf4j
- slf4j-api
-
-
- jakarta.servlet
- jakarta.servlet-api
- provided
-
-
- com.github.tomakehurst
- wiremock-jre8-standalone
- test
-
-
- commons-fileupload
- commons-fileupload
- test
-
-
- io.jsonwebtoken
- jjwt-impl
- test
-
-
- io.jsonwebtoken
- jjwt-jackson
- test
-
-
- io.rest-assured
- rest-assured
- test
-
-
- org.eclipse.che.multiuser
- che-multiuser-machine-authentication
- test
-
-
- org.everrest
- everrest-assured
- test
-
-
- org.hamcrest
- hamcrest
- test
-
-
- org.mockito
- mockito-core
- test
-
-
- org.mockito
- mockito-testng
- test
-
-
- org.testng
- testng
- test
-
-
- org.wiremock
- wiremock-standalone
- test
-
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
-
-
- add-resource
- process-sources
-
- add-resource
-
-
-
-
- ${dto-generator-out-directory}/META-INF
- META-INF
-
-
-
-
-
- add-source
- process-sources
-
- add-source
-
-
-
- ${dto-generator-out-directory}
-
-
-
-
-
-
- maven-compiler-plugin
-
-
- pre-compile
- generate-sources
-
- compile
-
-
-
-
-
- org.eclipse.che.core
- che-core-api-dto-maven-plugin
- ${project.version}
-
-
- server
- process-sources
-
- generate
-
-
-
- org.eclipse.che.multiuser.keycloak.shared.dto
-
- ${dto-generator-out-directory}
- org.eclipse.che.multiuser.keycloak.server.DtoServerImpls
- server
-
-
-
-
-
- org.eclipse.che.multiuser
- che-multiuser-keycloak-shared
- ${project.version}
-
-
-
-
-
-
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakConfigurationService.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakConfigurationService.java
deleted file mode 100644
index b2973f67388..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakConfigurationService.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.rest.Service;
-
-/**
- * Endpoint which provides keycloak public client authentication information (such as URL, realm,
- * client_id).
- *
- * @author Max Shaposhnik (mshaposh@redhat.com)
- */
-@Singleton
-@Path("/keycloak")
-public class KeycloakConfigurationService extends Service {
-
- private final KeycloakSettings keycloakSettings;
-
- @Inject
- public KeycloakConfigurationService(KeycloakSettings keycloakSettings) {
- this.keycloakSettings = keycloakSettings;
- }
-
- @GET
- @Path("/settings")
- @Produces(APPLICATION_JSON)
- public Map settings() {
- return keycloakSettings.get();
- }
-
- private String getKeycloakResource(String fileName) throws IOException {
- URL resource =
- Thread.currentThread().getContextClassLoader().getResource("keycloak/" + fileName);
- if (resource != null) {
- URLConnection conn = resource.openConnection();
- try (InputStream is = conn.getInputStream();
- ByteArrayOutputStream os = new ByteArrayOutputStream()) {
- byte[] buffer = new byte[1024];
- int length;
- while ((length = is.read(buffer)) != -1) {
- os.write(buffer, 0, length);
- }
- return os.toString("UTF-8");
- }
- }
- return "";
- }
-
- @GET
- @Path("/OIDCKeycloak.js")
- @Produces("text/javascript")
- public String javascriptAdapter() throws IOException {
- return getKeycloakResource("OIDCKeycloak.js");
- }
-
- @GET
- @Path("/oidcCallback.js")
- @Produces("text/javascript")
- public String callbackScript() throws IOException {
- return getKeycloakResource("oidcCallback.js");
- }
-
- @GET
- @Path("/oidcCallbackIde.html")
- @Produces("text/html")
- public String ideCallback() throws IOException {
- return getKeycloakResource("oidcCallbackIde.html");
- }
-
- @GET
- @Path("/oidcCallbackDashboard.html")
- @Produces("text/html")
- public String dashboardCallback() throws IOException {
- return getKeycloakResource("oidcCallbackDashboard.html");
- }
-}
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitializationFilter.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitializationFilter.java
deleted file mode 100644
index bbc548abf8e..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakEnvironmentInitializationFilter.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 2012-2026 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static jakarta.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
-import static org.eclipse.che.multiuser.oidc.OIDCInfoProvider.OIDC_USERNAME_CLAIM_SETTING;
-
-import com.google.common.base.Splitter;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jws;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.JwtParser;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.FilterConfig;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.ServletRequest;
-import jakarta.servlet.ServletResponse;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Optional;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ConflictException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.model.user.User;
-import org.eclipse.che.commons.annotation.Nullable;
-import org.eclipse.che.commons.subject.Subject;
-import org.eclipse.che.commons.subject.SubjectImpl;
-import org.eclipse.che.multiuser.api.authentication.commons.SessionStore;
-import org.eclipse.che.multiuser.api.authentication.commons.filter.MultiUserEnvironmentInitializationFilter;
-import org.eclipse.che.multiuser.api.authentication.commons.token.RequestTokenExtractor;
-import org.eclipse.che.multiuser.api.permission.server.AuthorizedSubject;
-import org.eclipse.che.multiuser.api.permission.server.PermissionChecker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Sets subject attribute into session based on keycloak authentication data.
- *
- * @author Max Shaposhnik (mshaposhnik@redhat.com)
- */
-@Singleton
-public class KeycloakEnvironmentInitializationFilter
- extends MultiUserEnvironmentInitializationFilter> {
-
- private static final Logger LOG =
- LoggerFactory.getLogger(KeycloakEnvironmentInitializationFilter.class);
-
- private final KeycloakUserManager userManager;
- private final KeycloakProfileRetriever keycloakProfileRetriever;
- private final PermissionChecker permissionChecker;
- private final KeycloakSettings keycloakSettings;
- private final JwtParser jwtParser;
- private final Map userNameReplacementPatterns;
-
- @Inject
- public KeycloakEnvironmentInitializationFilter(
- SessionStore sessionStore,
- JwtParser jwtParser,
- KeycloakUserManager userManager,
- KeycloakProfileRetriever keycloakProfileRetriever,
- RequestTokenExtractor tokenExtractor,
- PermissionChecker permissionChecker,
- KeycloakSettings settings,
- @Nullable @Named("che.keycloak.username.replacement_patterns")
- String userNameReplacementPatterns) {
- super(sessionStore, tokenExtractor);
- this.jwtParser = jwtParser;
- this.userManager = userManager;
- this.keycloakProfileRetriever = keycloakProfileRetriever;
- this.permissionChecker = permissionChecker;
- this.keycloakSettings = settings;
- this.userNameReplacementPatterns =
- isNullOrEmpty(userNameReplacementPatterns)
- ? Collections.emptyMap()
- : Splitter.on(",").withKeyValueSeparator("=").split(userNameReplacementPatterns);
- }
-
- @Override
- public void init(FilterConfig filterConfig) {}
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
- throws IOException, ServletException {
- try {
- super.doFilter(request, response, filterChain);
- } catch (MachineTokenJwtException mte) {
- filterChain.doFilter(request, response);
- } catch (JwtException e) {
- sendError(response, SC_UNAUTHORIZED, e.getMessage());
- return;
- }
- }
-
- @Override
- protected Optional> processToken(String token) {
- return Optional.ofNullable(jwtParser.parseClaimsJws(token));
- }
-
- @Override
- protected String getUserId(Jws processedToken) {
- return processedToken.getBody().getSubject();
- }
-
- @Override
- public Subject extractSubject(String token, Jws processedToken) throws ServletException {
- Claims claims = processedToken.getBody();
- LOG.debug("JWT = {}", processedToken);
- // OK, we can trust this JWT
-
- try {
- String username =
- claims.get(keycloakSettings.get().get(OIDC_USERNAME_CLAIM_SETTING), String.class);
- if (username == null) { // fallback to unique id promised by spec
- // https://openid.net/specs/openid-connect-basic-1_0.html#ClaimStability
- username = claims.getIssuer() + ":" + claims.getSubject();
- }
- if (!userNameReplacementPatterns.isEmpty()) {
- for (Map.Entry entry : userNameReplacementPatterns.entrySet()) {
- username = username.replaceAll(entry.getKey(), entry.getValue());
- }
- }
- String id = claims.getSubject();
-
- String email =
- retrieveEmail(token, claims, id)
- .orElseThrow(
- () ->
- new JwtException(
- "Unable to authenticate user because email address is not set in keycloak profile"));
- User user = userManager.getOrCreateUser(id, email, username);
- // #KeycloakEnvironmentInitializationFilter is not used anymore, so we can ignore obtaining
- // the list of groups user belongs to
- return new AuthorizedSubject(
- new SubjectImpl(user.getName(), Collections.emptyList(), user.getId(), token, false),
- permissionChecker);
- } catch (ServerException | ConflictException e) {
- throw new ServletException(
- "Unable to identify user " + claims.getSubject() + " in Che database", e);
- }
- }
-
- @Override
- protected void handleMissingToken(
- ServletRequest request, ServletResponse response, FilterChain chain) throws IOException {
- sendError(response, 401, "Authorization token is missing");
- }
-
- private Optional retrieveEmail(String token, Claims claims, String id)
- throws ServerException {
- String email = claims.get("email", String.class);
-
- if (isNullOrEmpty(email)) {
- try {
- userManager.getById(id);
- } catch (NotFoundException e) {
- Map profileAttributes =
- keycloakProfileRetriever.retrieveKeycloakAttributes("Bearer " + token);
- email = profileAttributes.get("email");
- }
- }
- return Optional.ofNullable(email);
- }
-
- @Override
- public void destroy() {}
-}
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakHttpJsonRequestFactory.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakHttpJsonRequestFactory.java
deleted file mode 100644
index 8dee719df99..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakHttpJsonRequestFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import jakarta.validation.constraints.NotNull;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.rest.DefaultHttpJsonRequestFactory;
-import org.eclipse.che.api.core.rest.HttpJsonRequest;
-import org.eclipse.che.api.core.rest.shared.dto.Link;
-import org.eclipse.che.commons.env.EnvironmentContext;
-
-@Singleton
-public class KeycloakHttpJsonRequestFactory extends DefaultHttpJsonRequestFactory {
-
- @Inject
- public KeycloakHttpJsonRequestFactory() {}
-
- @Override
- public HttpJsonRequest fromUrl(@NotNull String url) {
- return super.fromUrl(url)
- .setAuthorizationHeader(
- "Bearer " + EnvironmentContext.getCurrent().getSubject().getToken());
- }
-
- @Override
- public HttpJsonRequest fromLink(@NotNull Link link) {
- return super.fromLink(link)
- .setAuthorizationHeader(
- "Bearer " + EnvironmentContext.getCurrent().getSubject().getToken());
- }
-}
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakOIDCInfoProvider.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakOIDCInfoProvider.java
deleted file mode 100644
index 207353d9e58..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakOIDCInfoProvider.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.eclipse.che.commons.annotation.Nullable;
-import org.eclipse.che.multiuser.oidc.OIDCInfoProvider;
-
-/**
- * KeycloakOIDCInfoProvider retrieves OpenID Connect (OIDC) configuration for well-known endpoint.
- * These information is useful to provide access to the Keycloak api.
- */
-public class KeycloakOIDCInfoProvider extends OIDCInfoProvider {
- public final String realm;
-
- @Inject
- public KeycloakOIDCInfoProvider(
- @Nullable @Named(AUTH_SERVER_URL_SETTING) String serverURL,
- @Nullable @Named(AUTH_SERVER_URL_INTERNAL_SETTING) String serverInternalURL,
- @Nullable @Named(OIDC_PROVIDER_SETTING) String oidcProviderUrl,
- @Nullable @Named(REALM_SETTING) String realm) {
- super(serverURL, serverInternalURL, oidcProviderUrl);
- this.realm = realm;
- }
-
- @Override
- protected String constructServerAuthUrl(String serverAuthUrl) {
- return serverAuthUrl + "/realms/" + realm;
- }
-
- protected void validate() {
- if (oidcProviderUrl == null && realm == null) {
- throw new RuntimeException("The '" + REALM_SETTING + "' property must be set");
- }
- super.validate();
- }
-}
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakProfileRetriever.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakProfileRetriever.java
deleted file mode 100644
index f7c3b47c8c4..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakProfileRetriever.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-
-import jakarta.validation.constraints.NotNull;
-import java.io.IOException;
-import java.util.Map;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.ApiException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.rest.HttpJsonRequestFactory;
-import org.eclipse.che.multiuser.oidc.OIDCInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Fetches user profile from Keycloack server.
- *
- * @author David Festal
- */
-@Singleton
-public class KeycloakProfileRetriever {
- private static final Logger LOG = LoggerFactory.getLogger(KeycloakProfileRetriever.class);
-
- private final String keyclockCurrentUserInfoUrl;
- private final HttpJsonRequestFactory requestFactory;
-
- @Inject
- public KeycloakProfileRetriever(OIDCInfo oidcInfo, HttpJsonRequestFactory requestFactory) {
- this.requestFactory = requestFactory;
- this.keyclockCurrentUserInfoUrl =
- isNullOrEmpty(oidcInfo.getUserInfoInternalEndpoint())
- ? oidcInfo.getUserInfoPublicEndpoint()
- : oidcInfo.getUserInfoInternalEndpoint();
- }
-
- /**
- * Retrieves attributes from keycloak using default request factory assuming that there is an
- * {@code Subject} with authorization token present in {@code EnvironmentContext}
- *
- * @return map of user attributes from keycloak
- * @throws ServerException in an error happened
- */
- public Map retrieveKeycloakAttributes() throws ServerException {
- try {
- return requestFactory.fromUrl(keyclockCurrentUserInfoUrl).request().asProperties();
- } catch (IOException | ApiException e) {
- LOG.warn("Exception during retrieval of the Keycloak user profile", e);
- throw new ServerException("Exception during retrieval of the Keycloak user profile", e);
- }
- }
-
- /**
- * Retrieves attributes from keycloak using default request factory and provided authorization
- * header for cases when no {@code Subject} set in {@code EnvironmentContext}
- *
- * @return map of user attributes from keycloak
- * @throws ServerException in an error happened
- */
- public Map retrieveKeycloakAttributes(@NotNull String authorizationHeader)
- throws ServerException {
- try {
- return requestFactory
- .fromUrl(keyclockCurrentUserInfoUrl)
- .setAuthorizationHeader(authorizationHeader)
- .request()
- .asProperties();
- } catch (IOException | ApiException e) {
- LOG.warn("Exception during retrieval of the Keycloak user profile", e);
- throw new ServerException("Exception during retrieval of the Keycloak user profile", e);
- }
- }
-}
diff --git a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakServiceClient.java b/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakServiceClient.java
deleted file mode 100644
index 1542b5c409b..00000000000
--- a/multiuser/keycloak/che-multiuser-keycloak-server/src/main/java/org/eclipse/che/multiuser/keycloak/server/KeycloakServiceClient.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (c) 2012-2025 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.multiuser.keycloak.server;
-
-import static org.eclipse.che.multiuser.keycloak.shared.KeycloakConstants.REALM_SETTING;
-
-import com.google.common.io.CharStreams;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.JwtParser;
-import jakarta.ws.rs.HttpMethod;
-import jakarta.ws.rs.core.HttpHeaders;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.UriBuilder;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import org.eclipse.che.api.core.BadRequestException;
-import org.eclipse.che.api.core.ForbiddenException;
-import org.eclipse.che.api.core.NotFoundException;
-import org.eclipse.che.api.core.ServerException;
-import org.eclipse.che.api.core.UnauthorizedException;
-import org.eclipse.che.commons.env.EnvironmentContext;
-import org.eclipse.che.commons.lang.Pair;
-import org.eclipse.che.dto.server.DtoFactory;
-import org.eclipse.che.multiuser.keycloak.shared.dto.KeycloakErrorResponse;
-import org.eclipse.che.multiuser.keycloak.shared.dto.KeycloakTokenResponse;
-import org.eclipse.che.multiuser.oidc.OIDCInfo;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Helps to perform keycloak operations and provide correct errors handling.
- *
- * @author Max Shaposhnik (mshaposh@redhat.com)
- */
-@Singleton
-public class KeycloakServiceClient {
-
- private final KeycloakSettings keycloakSettings;
- private final OIDCInfo oidcInfo;
-
- private static final Logger LOG = LoggerFactory.getLogger(KeycloakServiceClient.class);
-
- private static final Pattern assotiateUserPattern =
- Pattern.compile("User (.+) is not associated with identity provider (.+)");
-
- private static final Pattern errorPageMessagePattern =
- Pattern.compile("
(\\s*)
(.+?)
");
-
- private static final Gson gson = new Gson();
- private final JwtParser jwtParser;
-
- @Inject
- public KeycloakServiceClient(
- KeycloakSettings keycloakSettings, OIDCInfo oidcInfo, JwtParser jwtParser) {
- this.keycloakSettings = keycloakSettings;
- this.oidcInfo = oidcInfo;
- this.jwtParser = jwtParser;
- }
-
- /**
- * Generates URL for account linking redirect
- *
- * @param token client jwt token
- * @param oauthProvider provider name
- * @param redirectAfterLogin URL to return after login
- * @return URL to redirect client to perform account linking
- */
- public String getAccountLinkingURL(
- String token, String oauthProvider, String redirectAfterLogin) {
-
- Claims claims = jwtParser.parseClaimsJws(token).getBody();
- final String clientId = claims.get("azp", String.class);
- final String sessionState = claims.get("session_state", String.class);
- MessageDigest md;
- try {
- md = MessageDigest.getInstance("SHA-256");
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException(e);
- }
-
- final String nonce = UUID.randomUUID().toString();
- final String input = nonce + sessionState + clientId + oauthProvider;
- byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
- final String hash = Base64.getUrlEncoder().encodeToString(check);
-
- return UriBuilder.fromUri(oidcInfo.getAuthServerPublicURL())
- .path("/realms/{realm}/broker/{provider}/link")
- .queryParam("nonce", nonce)
- .queryParam("hash", hash)
- .queryParam("client_id", clientId)
- .queryParam("redirect_uri", redirectAfterLogin)
- .build(keycloakSettings.get().get(REALM_SETTING), oauthProvider)
- .toString();
- }
-
- /**
- * Gets auth token from given identity provider.
- *
- * @param oauthProvider provider name
- * @return KeycloakTokenResponse token response
- * @throws ForbiddenException when HTTP request was forbidden
- * @throws BadRequestException when HTTP request considered as bad
- * @throws IOException when unable to parse error response
- * @throws NotFoundException when requested URL not found
- * @throws ServerException when other error occurs
- * @throws UnauthorizedException when no token present for user or user not linked to provider
- */
- public KeycloakTokenResponse getIdentityProviderToken(String oauthProvider)
- throws ForbiddenException,
- BadRequestException,
- IOException,
- NotFoundException,
- ServerException,
- UnauthorizedException {
- String url =
- UriBuilder.fromUri(oidcInfo.getAuthServerURL())
- .path("/realms/{realm}/broker/{provider}/token")
- .build(keycloakSettings.get().get(REALM_SETTING), oauthProvider)
- .toString();
- try {
- String response = doRequest(url, HttpMethod.GET, null);
- // Successful answer is not a json, but key=value&foo=bar format pairs
- return DtoFactory.getInstance()
- .createDtoFromJson(toJson(response), KeycloakTokenResponse.class);
- } catch (BadRequestException e) {
- if (assotiateUserPattern.matcher(e.getMessage()).matches()) {
- // If user has no link with identity provider yet,
- // we should threat this as unauthorized and send to OAuth login page.
- throw new UnauthorizedException(e.getMessage());
- }
- throw e;
- }
- }
-
- private String doRequest(String url, String method, List> parameters)
- throws IOException,
- ServerException,
- ForbiddenException,
- NotFoundException,
- UnauthorizedException,
- BadRequestException {
- final String authToken = EnvironmentContext.getCurrent().getSubject().getToken();
- final boolean hasQueryParams = parameters != null && !parameters.isEmpty();
- if (hasQueryParams) {
- final UriBuilder ub = UriBuilder.fromUri(url);
- for (Pair parameter : parameters) {
- ub.queryParam(parameter.first, parameter.second);
- }
- url = ub.build().toString();
- }
- final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
- conn.setConnectTimeout(60000);
- conn.setReadTimeout(60000);
-
- try {
- conn.setRequestMethod(method);
- // drop a hint for server side that we want to receive application/json
- conn.addRequestProperty(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
- if (authToken != null) {
- conn.setRequestProperty(HttpHeaders.AUTHORIZATION, "bearer " + authToken);
- }
- final int responseCode = conn.getResponseCode();
- if ((responseCode / 100) != 2) {
- InputStream in = conn.getErrorStream();
- if (in == null) {
- in = conn.getInputStream();
- }
- final String output;
- try (Reader reader = new InputStreamReader(in)) {
- String read = CharStreams.toString(reader);
- // Unspecific errors always returned from Keycloak as 502 + HTML error page.
- // So try to handle that case separately
- if (responseCode == 502) {
- Matcher matcher = errorPageMessagePattern.matcher(read);
- output = matcher.find() ? matcher.group(2) : read;
- } else {
- output = read;
- }
- }
- final String contentType = conn.getContentType();
- if (contentType != null
- && (contentType.startsWith(MediaType.APPLICATION_JSON)
- || contentType.startsWith("application/vnd.api+json"))) {
- final KeycloakErrorResponse serviceError =
- DtoFactory.getInstance().createDtoFromJson(output, KeycloakErrorResponse.class);
- if (responseCode == Response.Status.FORBIDDEN.getStatusCode()) {
- throw new ForbiddenException(serviceError.getErrorMessage());
- } else if (responseCode == Response.Status.NOT_FOUND.getStatusCode()) {
- throw new NotFoundException(serviceError.getErrorMessage());
- } else if (responseCode == Response.Status.UNAUTHORIZED.getStatusCode()) {
- throw new UnauthorizedException(serviceError.getErrorMessage());
- } else if (responseCode == Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()) {
- throw new ServerException(serviceError.getErrorMessage());
- } else if (responseCode == Response.Status.BAD_REQUEST.getStatusCode()) {
- throw new BadRequestException(serviceError.getErrorMessage());
- }
- throw new ServerException(serviceError.getErrorMessage());
- }
- // Can't parse content as json or content has format other we expect for error.
- LOG.warn(
- String.format(
- "Failed access: %s, method: %s, response code: %d, message: %s",
- UriBuilder.fromUri(url).replaceQuery("token").build(),
- method,
- responseCode,
- output));
- throw new IOException(output);
- }
- try (Reader reader = new InputStreamReader(conn.getInputStream())) {
- return CharStreams.toString(reader);
- }
- } finally {
- conn.disconnect();
- }
- }
-
- /** Converts key=value&foo=bar string into json if necessary */
- private static String toJson(String source) {
- if (source == null) {
- return null;
- }
- try {
- // Check that the source is valid Json Object (can be returned as a Map)
- Map unused = gson.