Skip to content

Commit

Permalink
fix(rest): Create a new endpoint for dataBaseSanitation.
Browse files Browse the repository at this point in the history
Signed-off-by: Nikesh kumar <[email protected]>
  • Loading branch information
Nikesh kumar committed Feb 5, 2024
1 parent e6dc931 commit a387789
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 0 deletions.
1 change: 1 addition & 0 deletions rest/resource-server/src/docs/asciidoc/api-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,4 @@ include::obligations.adoc[]
include::moderationRequests.adoc[]
include::fossology.adoc[]
include::schedule.adoc[]
include::databaseSanitation.adoc[]
25 changes: 25 additions & 0 deletions rest/resource-server/src/docs/asciidoc/databaseSanitation.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Copyright Siemens AG, 2023. Part of the SW360 Portal Project.
//
// 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
//

[[resources-databaseSanitation]]
=== DatabaseSanitation

The Database sanitation is used to get the duplicate releases and components.

[[search-duplicate]]
==== search duplicate identifiers

A `GET` request will fetch the duplicate project and components.

===== Example request
include::{snippets}/should_document_search_duplicate/curl-request.adoc[]

===== Example response
include::{snippets}/should_document_search_duplicate/http-response.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright Siemens AG, 2023-2024.
* Part of the SW360 Portal Project.
*
* 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
*/

package org.eclipse.sw360.rest.resourceserver.databasesanitation;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;

import java.util.HashMap;
import java.util.Map;

import org.apache.thrift.TException;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.BasePathAwareController;
import org.springframework.data.rest.webmvc.RepositoryLinksResource;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.server.RepresentationModelProcessor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@BasePathAwareController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RestController
@SecurityRequirement(name = "tokenAuth")
public class DatabaseSanitationController implements RepresentationModelProcessor<RepositoryLinksResource> {

public static final String DATABASESANITATION_URL = "/databaseSanitation";

@NonNull
Sw360DatabaseSanitationService dataSanitationService;

@NonNull
private final RestControllerHelper restControllerHelper;

@Override
public RepositoryLinksResource process(RepositoryLinksResource resource) {
resource.add(linkTo(DatabaseSanitationController.class).slash("api" + DATABASESANITATION_URL).withRel("databaseSanitation"));
return resource;
}
@RequestMapping(value = DATABASESANITATION_URL + "/searchDuplicate", method = RequestMethod.GET)
public ResponseEntity searchDuplicateIdentifiers()throws TException {
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
Map<String, Object> resource = new HashMap<>();
resource = dataSanitationService.duplicateIdentifiers(sw360User);
if (!resource.isEmpty()) {
return new ResponseEntity<>(resource, HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright Siemens AG, 2023-2024.
* Part of the SW360 Portal Project.
*
* 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
*/

package org.eclipse.sw360.rest.resourceserver.databasesanitation;

import static org.eclipse.sw360.datahandler.common.CommonUtils.allAreEmptyOrNull;
import static org.eclipse.sw360.datahandler.common.CommonUtils.oneIsNull;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransportException;
import org.eclipse.sw360.datahandler.permissions.PermissionUtils;
import org.eclipse.sw360.datahandler.thrift.SW360Exception;
import org.eclipse.sw360.datahandler.thrift.components.ComponentService;
import org.eclipse.sw360.datahandler.thrift.projects.ProjectService;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.datahandler.thrift.users.UserGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class Sw360DatabaseSanitationService {

@Value("${sw360.thrift-server-url:http://localhost:8080}")
private String thriftServerUrl;

public Map<String, Object> duplicateIdentifiers(User sw360User) throws TException {
Map<String, Object> responseMap = new HashMap<>();

Map<String, List<String>> duplicateComponents=null;
Map<String, List<String>> duplicateReleases=null;
Map<String, List<String>> duplicateReleaseSources=null;
Map<String, List<String>> duplicateProjects=null;
try {
if (PermissionUtils.isUserAtLeast(UserGroup.ADMIN, sw360User)) {
ComponentService.Iface componentClient = getThriftComponentClient();
ProjectService.Iface projectClient = getThriftProjectClient();
duplicateComponents = componentClient.getDuplicateComponents();
duplicateReleases = componentClient.getDuplicateReleases();
duplicateReleaseSources = componentClient.getDuplicateReleaseSources();
duplicateProjects = projectClient.getDuplicateProjects();
} else {
throw new RuntimeException("User is not admin");
}
} catch (SW360Exception exp) {
if (exp.getErrorCode() == 404) {
throw new ResourceNotFoundException(exp.getWhy());
} else {
throw new RuntimeException(exp.getWhy());
}
}
if (oneIsNull(duplicateComponents, duplicateReleases, duplicateProjects, duplicateReleaseSources)) {
throw new RuntimeException("Some duplicates are null");
} else if (allAreEmptyOrNull(duplicateComponents, duplicateReleases, duplicateProjects, duplicateReleaseSources)) {
throw new RuntimeException("No duplicates found");
} else {
responseMap.put("duplicateReleases", duplicateReleases);
responseMap.put("duplicateReleaseSources", duplicateReleaseSources);
responseMap.put("duplicateComponents", duplicateComponents);
responseMap.put("duplicateProjects", duplicateProjects);
}
return responseMap;
}
public ComponentService.Iface getThriftComponentClient() throws TTransportException {
THttpClient thriftClient = new THttpClient(thriftServerUrl + "/components/thrift");
TProtocol protocol = new TCompactProtocol(thriftClient);
return new ComponentService.Client(protocol);
}

public ProjectService.Iface getThriftProjectClient() throws TTransportException {
THttpClient thriftClient = new THttpClient(thriftServerUrl + "/projects/thrift");
TProtocol protocol = new TCompactProtocol(thriftClient);
return new ProjectService.Client(protocol);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public void should_document_index() throws Exception {
linkWithRel("sw360:changeLogs").description("The <<resources-changelog,Changelog resource>>"),
linkWithRel("sw360:clearingRequests").description("The <<resources-clearingRequest,ClearingRequest resource>>"),
linkWithRel("sw360:obligations").description("The <<resources-obligations,Obligation resource>>"),
linkWithRel("sw360:databaseSanitation").description("The <<resources-databaseSanitation,DatabaseSanitation resource>>"),
linkWithRel("sw360:moderationRequests").description("The <<resources-moderationRequest,ModerationRequest resource>>"),
linkWithRel("sw360:fossology").description("The <<resources-fossology,Fossology resource>>"),
linkWithRel("sw360:schedule").description("The <<resources-schedule,Schedule resource>>"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright Siemens AG, 2023-2024.
* Part of the SW360 Portal Project.
*
* 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
*/

package org.eclipse.sw360.rest.resourceserver.restdocs;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.thrift.TException;
import org.eclipse.sw360.datahandler.thrift.components.Component;
import org.eclipse.sw360.datahandler.thrift.components.Release;
import org.eclipse.sw360.datahandler.thrift.projects.Project;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.rest.resourceserver.TestHelper;
import org.eclipse.sw360.rest.resourceserver.databasesanitation.Sw360DatabaseSanitationService;
import org.eclipse.sw360.rest.resourceserver.user.Sw360UserService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.hateoas.MediaTypes;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.cloudant.client.api.model.Attachment;

@RunWith(SpringJUnit4ClassRunner.class)
public class DatabaseSanitationSpecTest extends TestRestDocsSpecBase {
@Value("${sw360.test-user-id}")
private String testUserId;

@Value("${sw360.test-user-password}")
private String testUserPassword;

@MockBean
private Sw360UserService userServiceMock;

@MockBean
private Sw360DatabaseSanitationService sanitationService;

private Component component;
private Release release;
private Project project;
private Attachment attachment,attachment1 ;

@Before
public void before() throws TException, IOException {
Map<String, Object> responseMap = new HashMap<>();

List<Attachment> attachmentList = new ArrayList<Attachment>();
attachment = new Attachment();
attachment.setContentType("12345");
attachment1 = new Attachment();
attachment.setContentType("1234");
attachmentList.add(attachment);
attachmentList.add(attachment1);
attachment.setContentType("12345");

List<Component> componentList = new ArrayList<>();
component = new Component();
component.setName("Angular");
component.unsetType();
component.unsetVisbility();
componentList.add(component);

List<Release> releaseList = new ArrayList<>();
release = new Release();
release.setId("123456");
release.unsetType();
releaseList.add(release);

List<Project> projectList = new ArrayList<>();
project = new Project();
project.setName("Emerald Web");
project.unsetState();
project.unsetSecurityResponsibles();
project.unsetEnableSvm();
project.unsetConsiderReleasesFromExternalList();
project.unsetEnableVulnerabilitiesDisplay();
project.unsetProjectType();
project.unsetVisbility();
projectList.add(project);

User sw360User = new User();
sw360User.setId("123456789");
sw360User.setEmail("[email protected]");
sw360User.setFullname("John Doe");
given(this.userServiceMock.getUserByEmailOrExternalId("[email protected]")).willReturn(
new User("[email protected]", "sw360").setId("123456789"));
Map<String, List<Component>> componentResponse = new HashMap<>();
componentResponse.put("component", componentList);

Map<String, List<Release>> releaseResponse = new HashMap<>();
releaseResponse.put("release", releaseList);

Map<String, List<Attachment>> releaseSourcesResponse = new HashMap<>();
releaseSourcesResponse.put("attachment", attachmentList);

Map<String, List<Project>> projectResponse = new HashMap<>();
projectResponse.put("project", projectList);

responseMap.put("duplicateReleases", releaseResponse);
responseMap.put("duplicateReleaseSources", releaseSourcesResponse);
responseMap.put("duplicateComponents", componentResponse);
responseMap.put("duplicateProjects", projectResponse);
given(this.sanitationService.duplicateIdentifiers(any())).willReturn(responseMap);
}

@Test
public void should_document_search_duplicate() throws Exception {
String accessToken = TestHelper.getAccessToken(mockMvc, testUserId, testUserPassword);
mockMvc.perform(get("/api/databaseSanitation/searchDuplicate")
.header("Authorization", "Bearer " + accessToken)
.accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk()).andDo(this.documentationHandler.document());
}
}

0 comments on commit a387789

Please sign in to comment.