Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

EPMRPP-89699 implement OrganizationInfo endpoint #1942

Merged
merged 5 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ dependencies {
implementation 'com.epam.reportportal:plugin-api'
} else {
implementation 'com.github.reportportal:commons-events:e337f8b7be'
implementation 'com.github.reportportal:commons-dao:f6c9669'
implementation 'com.github.reportportal:commons-dao:c274f1d'
implementation 'com.github.reportportal:commons-rules:1f6bfed'
implementation 'com.github.reportportal:commons-model:38a52fb'
implementation 'com.github.reportportal:commons-reporting:5c74bb2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@

import com.epam.ta.reportportal.commons.ReportPortalUser;
import com.epam.ta.reportportal.commons.querygen.Queryable;
import com.epam.ta.reportportal.model.OrganizationResource;
import com.epam.ta.reportportal.model.organization.OrganizationInfoResource;
import com.epam.ta.reportportal.model.organization.OrganizationResource;
import org.springframework.data.domain.Pageable;

/**
Expand All @@ -44,4 +45,15 @@ public interface GetOrganizationHandler {
* projects
*/
Iterable<OrganizationResource> getOrganizations(Queryable filter, Pageable pageable);

/**
grabsefx marked this conversation as resolved.
Show resolved Hide resolved
* Get Organizations aggregated info by query parameters
*
* @param filter Queryable filter to apply on organizations
* @param pageable Pagination information for the results
* @return An {@link Iterable} of {@link OrganizationInfoResource} containing information about
* all projects
grabsefx marked this conversation as resolved.
Show resolved Hide resolved
*/
Iterable<OrganizationInfoResource> getOrganizationsInfo(Queryable filter, Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
import com.epam.ta.reportportal.dao.organization.OrganizationRepositoryCustom;
import com.epam.ta.reportportal.entity.organization.Organization;
import com.epam.ta.reportportal.exception.ReportPortalException;
import com.epam.ta.reportportal.model.OrganizationResource;
import com.epam.ta.reportportal.model.organization.OrganizationInfoResource;
import com.epam.ta.reportportal.model.organization.OrganizationResource;
import com.epam.ta.reportportal.ws.converter.PagedResourcesAssembler;
import com.epam.ta.reportportal.ws.converter.converters.OrganizationConverter;
import com.epam.ta.reportportal.ws.reporting.ErrorType;
Expand Down Expand Up @@ -58,4 +59,12 @@ public Iterable<OrganizationResource> getOrganizations(Queryable filter, Pageabl
.apply(organizationRepositoryCustom.findByFilter(filter, pageable));
}

@Override
public Iterable<OrganizationInfoResource> getOrganizationsInfo(Queryable filter,
Pageable pageable) {
return PagedResourcesAssembler
.pageConverter(OrganizationConverter.TO_ORGANIZATION_INFO_RESOURCE)
.apply(organizationRepositoryCustom.findOrganizationInfoByFilter(filter, pageable));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.epam.ta.reportportal.model.organization;

/*
* Copyright 2024 EPAM Systems
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


import com.epam.ta.reportportal.entity.enums.OrganizationType;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDateTime;
import java.util.Date;
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
* Basic JSON representation of Organization.
*
* @author Andrei Piankouski
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@Getter
@Setter
@ToString
public class OrganizationInfoResource {

@NotNull
@JsonProperty(value = "id", required = true)
private Long id;

@NotNull
@JsonProperty(value = "name", required = true)
private String name;

@NotNull
@JsonProperty(value = "slug", required = true)
private String slug;

@NotNull
@JsonProperty(value = "type", required = true)
private OrganizationType type;

@NotNull
@JsonProperty(value = "creationDate", required = true)
private Date creationDate;

@JsonProperty(value = "usersQuantity", required = true)
private int usersQuantity;

@JsonProperty(value = "projectsQuantity", required = true)
private int projectsQuantity;

@JsonProperty(value = "launchesQuantity", required = true)
private int launchesQuantity;

@JsonProperty(value = "lastRun", required = true)
private LocalDateTime lastRun;

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.epam.ta.reportportal.model;
package com.epam.ta.reportportal.model.organization;

/*
* Copyright 2024 EPAM Systems
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
* @author Konstantin Antipin
*/
@RestController
@RequestMapping("/v2/{projectName}/launch")
@RequestMapping("/v2/{projectKey}/launch")
@Tag(name = "launch-async-controller", description = "Launch Async Controller")
public class LaunchAsyncController {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@

package com.epam.ta.reportportal.ws.controller;

import static com.epam.ta.reportportal.core.widget.content.constant.ContentLoaderConstants.USER;

import com.epam.ta.reportportal.commons.ReportPortalUser;
import com.epam.ta.reportportal.commons.querygen.CompositeFilter;
import com.epam.ta.reportportal.commons.querygen.Condition;
import com.epam.ta.reportportal.commons.querygen.Filter;
import com.epam.ta.reportportal.commons.querygen.FilterCondition;
import com.epam.ta.reportportal.commons.querygen.Queryable;
import com.epam.ta.reportportal.core.organization.GetOrganizationHandler;
import com.epam.ta.reportportal.entity.organization.Organization;
import com.epam.ta.reportportal.model.OrganizationResource;
import com.epam.ta.reportportal.entity.organization.OrganizationInfo;
import com.epam.ta.reportportal.entity.user.UserRole;
import com.epam.ta.reportportal.model.organization.OrganizationInfoResource;
grabsefx marked this conversation as resolved.
Show resolved Hide resolved
import com.epam.ta.reportportal.model.organization.OrganizationResource;
import com.epam.ta.reportportal.ws.resolver.FilterFor;
import com.epam.ta.reportportal.ws.resolver.SortFor;
import io.swagger.v3.oas.annotations.Operation;
Expand All @@ -41,7 +48,7 @@
* @author Andrei Piankouski
*/
@RestController
@RequestMapping("/v1/organization")
@RequestMapping("/v1")
@Tag(name = "organizations-controller", description = "Organizations Controller")
public class OrganizationController {

Expand All @@ -53,24 +60,59 @@ public OrganizationController(GetOrganizationHandler getOrganizationHandler) {
}

@Transactional
@GetMapping("/{organizationId}")
@GetMapping("/organizations/{organizationId}")
@Operation(summary = "Get information about organization")
public OrganizationResource getOrganization(@PathVariable Long organizationId,
@AuthenticationPrincipal ReportPortalUser user) {
return getOrganizationHandler.getResource(organizationId, user);
}

@Transactional
@GetMapping("/list")
@Operation(summary = "Get list of all organizations")
@GetMapping("/organizations")
@Operation(summary = "Get list of organizations associated with the user")
public Iterable<OrganizationResource> getAllOrganizations(
@AuthenticationPrincipal ReportPortalUser user,
@FilterFor(Organization.class) Filter filter,
@FilterFor(Organization.class) Queryable predefinedFilter,
@SortFor(Organization.class) Pageable pageable
) {
@SortFor(Organization.class) Pageable pageable) {

modifyFilterWithUserCriteria(filter, user);

return getOrganizationHandler.getOrganizations(
new CompositeFilter(Operator.AND, filter, predefinedFilter),
pageable);
}


@Transactional
grabsefx marked this conversation as resolved.
Show resolved Hide resolved
@GetMapping("/organizations-info")
@Operation(summary = "Get list of organizations aggregated info associated with the user")
public Iterable<OrganizationInfoResource> getOrganizationsInfo(
@AuthenticationPrincipal ReportPortalUser user,
@FilterFor(OrganizationInfo.class) Filter filter,
@FilterFor(OrganizationInfo.class) Queryable predefinedFilter,
@SortFor(OrganizationInfo.class) Pageable pageable) {

modifyFilterWithUserCriteria(filter, user);

return getOrganizationHandler.getOrganizationsInfo(
new CompositeFilter(Operator.AND, filter, predefinedFilter),
pageable);
}

/**
* By security reasons "filter.*.user" should always be replaced with filter by current user.
* Only Admin users can retrieve all organizations regardless organization membership
*/
private void modifyFilterWithUserCriteria(Filter filter, ReportPortalUser user) {
// always remove user filter
filter.getFilterConditions()
.removeIf(cc -> cc.getAllConditions().stream()
.anyMatch(fc -> fc.getSearchCriteria().equalsIgnoreCase(USER)));

if (UserRole.ADMINISTRATOR != user.getUserRole()) {
filter.withCondition(
new FilterCondition(Condition.EQUALS, false, user.getUsername(), USER));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
* @author Konstantin Antipin
*/
@RestController
@RequestMapping("/v2/{projectName}/item")
@RequestMapping("/v2/{projectKey}/item")
@PreAuthorize(ASSIGNED_TO_PROJECT)
@Tag(name = "test-item-async-controller", description = "Test Item Async Controller")
public class TestItemAsyncController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import static com.epam.ta.reportportal.commons.EntityUtils.TO_DATE;

import com.epam.ta.reportportal.entity.organization.Organization;
import com.epam.ta.reportportal.model.OrganizationResource;
import com.epam.ta.reportportal.entity.organization.OrganizationInfo;
import com.epam.ta.reportportal.model.organization.OrganizationInfoResource;
import com.epam.ta.reportportal.model.organization.OrganizationResource;
import java.util.function.Function;

/**
Expand All @@ -43,4 +45,19 @@ private OrganizationConverter() {

return orgResource;
};

public static final Function<OrganizationInfo, OrganizationInfoResource> TO_ORGANIZATION_INFO_RESOURCE = org -> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [reviewdog] <com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck> reported by reviewdog 🐶
Line is longer than 100 characters (found 115).

OrganizationInfoResource orgInfoResource = new OrganizationInfoResource();
orgInfoResource.setId(org.getId());
orgInfoResource.setName(org.getName());
orgInfoResource.setSlug(org.getSlug());
orgInfoResource.setType(org.getOrganizationType());
orgInfoResource.setCreationDate(TO_DATE.apply(org.getCreationDate()));
orgInfoResource.setLastRun(org.getLastRun());
orgInfoResource.setLaunchesQuantity(org.getLaunchesQuantity());
orgInfoResource.setProjectsQuantity(org.getProjectsQuantity());
orgInfoResource.setUsersQuantity(org.getUsersQuantity());

return orgInfoResource;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package com.epam.ta.reportportal.ws.converter.converters;

import com.epam.ta.reportportal.commons.MoreCollectors;
import com.epam.ta.reportportal.entity.organization.OrganizationUser;
import com.epam.ta.reportportal.entity.user.OrganizationUser;
import com.epam.ta.reportportal.entity.user.ProjectUser;
import com.epam.ta.reportportal.entity.user.User;
import com.epam.ta.reportportal.entity.user.UserType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,36 @@ class OrganizationControllerTest extends BaseMvcTest {

@Test
void getOrganization() throws Exception {
mockMvc.perform(get("/v1/organization/1").with(token(oAuthHelper.getSuperadminToken())))
mockMvc.perform(get("/v1/organizations/1")
.with(token(oAuthHelper.getSuperadminToken())))
.andExpect(status().isOk());
}

@Test
void getAllOrganizations() throws Exception {
mockMvc.perform(get("/v1/organization/list").with(token(oAuthHelper.getSuperadminToken())))
mockMvc.perform(get("/v1/organizations")
.with(token(oAuthHelper.getSuperadminToken())))
.andExpect(status().isOk());
}

@Test
void getAllOrganizationsInfo() throws Exception {
mockMvc.perform(get("/v1/organizations-info")
.with(token(oAuthHelper.getSuperadminToken())))
.andExpect(status().isOk());
}

@Test
void getAllOrganizationsInfoFilterByDifferentUser() throws Exception {
mockMvc.perform(get("/v1/organizations-info?filter.eq.user=default")
.with(token(oAuthHelper.getSuperadminToken())))
.andExpect(status().isOk());
}

@Test
void getAllOrganizationsInfoFilterByAdminUser() throws Exception {
mockMvc.perform(get("/v1/organizations-info?filter.eq.user=superadmin")
.with(token(oAuthHelper.getDefaultToken())))
.andExpect(status().isOk());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import com.epam.ta.reportportal.entity.enums.OrganizationType;
import com.epam.ta.reportportal.entity.organization.Organization;
import com.epam.ta.reportportal.model.OrganizationResource;
import com.epam.ta.reportportal.model.organization.OrganizationResource;
import java.time.LocalDateTime;
import org.junit.jupiter.api.Test;

Expand Down
5 changes: 5 additions & 0 deletions src/test/resources/db/project/project-fill.sql
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ values (3, 3, 'MEMBER');
insert into project_user(user_id, project_id, project_role)
values (1, 3, 'PROJECT_MANAGER');

insert into organization_user (user_id, organization_id, organization_role)
values (1, 101, (select 'MANAGER'::public."organization_role_enum"));
insert into organization_user (user_id, organization_id, organization_role)
values (3, 101, (select 'MEMBER'::public."organization_role_enum"));

insert into owned_entity(id, owner, project_id)
values (1, 'superadmin', 3);
insert into filter(id, name, target, description)
Expand Down
Loading