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

docs(openapi): add docs for vendor, user, search #2102

Merged
merged 1 commit into from
Aug 30, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.swagger.v3.oas.annotations.media.Schema;
import org.eclipse.sw360.datahandler.thrift.*;
import org.eclipse.sw360.datahandler.thrift.attachments.Attachment;
import org.eclipse.sw360.datahandler.thrift.attachments.AttachmentDTO;
Expand Down Expand Up @@ -267,7 +268,66 @@ static abstract class MultiStatusMixin extends MultiStatus {
"packageIdsIterator",
"packageIds",
"setReleaseRelationNetwork",
"releaseRelationNetwork"
"releaseRelationNetwork",
"projectTypeIsSet",
"tagIsSet",
"projectResponsibleIsSet",
"leadArchitectIsSet",
"securityResponsiblesIsSet",
"projectOwnerIsSet",
"linkedProjectsIsSet",
"releaseIdToUsageIsSet",
"clearingTeamIsSet",
"preevaluationDeadlineIsSet",
"systemTestStartIsSet",
"systemTestEndIsSet",
"deliveryStartIsSet",
"phaseOutSinceIsSet",
"enableSvmIsSet",
"considerReleasesFromExternalListIsSet",
"licenseInfoHeaderTextIsSet",
"enableVulnerabilitiesDisplayIsSet",
"obligationsTextIsSet",
"clearingSummaryIsSet",
"specialRisksOSSIsSet",
"generalRisks3rdPartyIsSet",
"specialRisks3rdPartyIsSet",
"deliveryChannelsIsSet",
"remarksAdditionalRequirementsIsSet",
"clearingRequestIdIsSet",
"releaseClearingStateSummaryIsSet",
"linkedObligationIdIsSet",
"externalUrlsIsSet",
"releaseRelationNetworkIsSet",
"domainIsSet",
"stateIsSet",
"createdByIsSet",
"createdOnIsSet",
"packageIdsIsSet",
"modifiedByIsSet",
"modifiedOnIsSet",
"versionIsSet",
"externalIdsIsSet",
"additionalDataIsSet",
"attachmentsIsSet",
"clearingStateIsSet",
"contributorsIsSet",
"rolesIsSet",
"vendorIsSet",
"vendorIdIsSet",
"ownerAccountingUnitIsSet",
"ownerGroupIsSet",
"ownerCountryIsSet",
"visbilityIsSet",
"businessUnitIsSet",
"idIsSet",
"revisionIsSet",
"typeIsSet",
"nameIsSet",
"descriptionIsSet",
"documentStateIsSet",
"permissionsIsSet",
"moderatorsIsSet"
})
static abstract class ProjectMixin extends Project {

Expand Down Expand Up @@ -360,7 +420,30 @@ static abstract class EmbeddedProjectMixin extends ProjectMixin {
"setPrimaryRoles",
"setDeactivated",
"oidcClientInfosSize",
"setOidcClientInfos"
"setOidcClientInfos",
"commentMadeDuringModerationRequest",
"oidcClientInfosIsSet",
"passwordIsSet",
"idIsSet",
"revisionIsSet",
"typeIsSet",
"emailIsSet",
"userGroupIsSet",
"externalidIsSet",
"fullnameIsSet",
"givennameIsSet",
"lastnameIsSet",
"departmentIsSet",
"wantsMailNotificationIsSet",
"commentMadeDuringModerationRequestIsSet",
"notificationPreferencesIsSet",
"formerEmailAddressesIsSet",
"restApiTokensIsSet",
"myProjectsPreferenceSelectionIsSet",
"secondaryDepartmentsAndRolesIsSet",
"primaryRolesIterator",
"primaryRolesIsSet",
"deactivatedIsSet"
})
static abstract class UserMixin extends User {
@Override
Expand Down Expand Up @@ -815,15 +898,24 @@ static abstract class ProjectUsageMixin {
"setPermissions",
"setFullname",
"setShortname",
"setUrl"
"setUrl",
"fullnameIsSet",
"permissionsIsSet",
"typeIsSet",
"revisionIsSet",
"idIsSet",
"shortnameIsSet",
"urlIsSet"
})
static abstract class VendorMixin extends Vendor {
@Override
@JsonProperty("fullName")
@Schema(description = "The full name of the vendor")
abstract public String getFullname();

@Override
@JsonProperty("shortName")
@Schema(description = "The Short Name of the vendor")
abstract public String getShortname();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

import javax.servlet.http.HttpServletRequest;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.thrift.TException;
Expand Down Expand Up @@ -45,26 +49,46 @@

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RestController;

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

private static final Logger log = LogManager.getLogger(SearchController.class);

public static final String SEARCH_URL = "/search";

@Autowired
private Sw360SearchService sw360SearchService;

@NonNull
private final RestControllerHelper restControllerHelper;



@Operation(
summary = "List all the search results based on the search text and type.",
description = "List all the search results based on the search text and type.",
tags = {"Search"}
)
@RequestMapping(value = SEARCH_URL, method = RequestMethod.GET)
public ResponseEntity<CollectionModel<EntityModel<SearchResult>>> getSearchResult(Pageable pageable,
@RequestParam(value = "searchText") String searchText, @RequestParam Optional<List<String>> typeMasks,
HttpServletRequest request) throws TException, URISyntaxException, PaginationParameterException, ResourceClassNotFoundException {
public ResponseEntity<CollectionModel<EntityModel<SearchResult>>> getSearchResult(
Pageable pageable,
@Parameter(description = "The search text.")
@RequestParam(value = "searchText") String searchText,
@Parameter(
description = "The type of resource.",
schema = @Schema(
allowableValues = {"project", "component", "license", "release", "obligation", "user",
"vendor"},
type = "array"
)
)
@RequestParam Optional<List<String>> typeMasks,
HttpServletRequest request
) throws TException, URISyntaxException, PaginationParameterException, ResourceClassNotFoundException {
log.debug("SearchText = {} typeMasks = {}", searchText, typeMasks);
User sw360User = restControllerHelper.getSw360UserFromAuthentication();
List<SearchResult> searchResults = sw360SearchService.search(searchText, sw360User, typeMasks);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
*/
package org.eclipse.sw360.rest.resourceserver.user;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.Operation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -29,11 +32,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.UnsupportedEncodingException;
Expand All @@ -47,6 +46,8 @@
@BasePathAwareController
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RestController
@SecurityRequirement(name = "tokenAuth")
public class UserController implements RepresentationModelProcessor<RepositoryLinksResource> {

protected final EntityLinks entityLinks;
Expand All @@ -62,6 +63,11 @@ public class UserController implements RepresentationModelProcessor<RepositoryLi
@NonNull
private final RestControllerHelper restControllerHelper;

@Operation(
summary = "List all of the service's users.",
description = "List all of the service's users.",
tags = {"Users"}
)
@RequestMapping(value = USERS_URL, method = RequestMethod.GET)
public ResponseEntity<CollectionModel<EntityModel<User>>> getUsers() {
List<User> sw360Users = userService.getAllUsers();
Expand All @@ -79,10 +85,16 @@ public ResponseEntity<CollectionModel<EntityModel<User>>> getUsers() {

// '/users/{xyz}' searches by email, as opposed to by id, as is customary,
// for compatibility with older version of the REST API
@Operation(
summary = "Get a single user.",
description = "Get a single user by email.",
tags = {"Users"}
)
@RequestMapping(value = USERS_URL + "/{email:.+}", method = RequestMethod.GET)
public ResponseEntity<EntityModel<User>> getUserByEmail(
@PathVariable("email") String email) {

@Parameter(description = "The email of the user to be retrieved.")
@PathVariable("email") String email
) {
String decodedEmail;
try {
decodedEmail = URLDecoder.decode(email, "UTF-8");
Expand All @@ -96,16 +108,31 @@ public ResponseEntity<EntityModel<User>> getUserByEmail(
}

// unusual URL mapping for compatibility with older version of the REST API (see getUserByEmail())
@Operation(
summary = "Get a single user.",
description = "Get a single user by id.",
tags = {"Users"}
)
@RequestMapping(value = USERS_URL + "/byid/{id:.+}", method = RequestMethod.GET)
public ResponseEntity<EntityModel<User>> getUser(
@PathVariable("id") String id) {
@Parameter(description = "The id of the user to be retrieved.")
@PathVariable("id") String id
) {
User sw360User = userService.getUser(id);
HalResource<User> halResource = createHalUser(sw360User);
return new ResponseEntity<>(halResource, HttpStatus.OK);
}

@Operation(
summary = "Create a new user.",
description = "Create a user (not in Liferay).",
tags = {"Users"}
)
@PostMapping(value = USERS_URL)
public ResponseEntity<EntityModel<User>> createUser(@RequestBody User user) throws TException {
public ResponseEntity<EntityModel<User>> createUser(
@Parameter(description = "The user to be created.")
@RequestBody User user
) throws TException {
if(CommonUtils.isNullEmptyOrWhitespace(user.getPassword())) {
throw new HttpMessageNotReadableException("Password can not be null or empty or whitespace!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
*/
package org.eclipse.sw360.rest.resourceserver.vendor;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.eclipse.sw360.datahandler.thrift.vendors.Vendor;
Expand All @@ -23,10 +26,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
Expand All @@ -37,6 +37,8 @@

@BasePathAwareController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@RestController
@SecurityRequirement(name = "tokenAuth")
public class VendorController implements RepresentationModelProcessor<RepositoryLinksResource> {
public static final String VENDORS_URL = "/vendors";

Expand All @@ -46,6 +48,11 @@ public class VendorController implements RepresentationModelProcessor<Repository
@NonNull
private final RestControllerHelper<?> restControllerHelper;

@Operation(
summary = "List all of the service's vendors.",
description = "List all of the service's vendors.",
tags = {"Vendor"}
)
@RequestMapping(value = VENDORS_URL, method = RequestMethod.GET)
public ResponseEntity<CollectionModel<EntityModel<Vendor>>> getVendors() {
List<Vendor> vendors = vendorService.getVendors();
Expand All @@ -60,18 +67,32 @@ public ResponseEntity<CollectionModel<EntityModel<Vendor>>> getVendors() {
return new ResponseEntity<>(resources, HttpStatus.OK);
}

@Operation(
summary = "Get a single vendor.",
description = "Get a single vendor by id.",
tags = {"Vendor"}
)
@RequestMapping(value = VENDORS_URL + "/{id}", method = RequestMethod.GET)
public ResponseEntity<EntityModel<Vendor>> getVendor(
@PathVariable("id") String id) {
@Parameter(description = "The id of the vendor to get.")
@PathVariable("id") String id
) {
Vendor sw360Vendor = vendorService.getVendorById(id);
HalResource<Vendor> halResource = createHalVendor(sw360Vendor);
return new ResponseEntity<>(halResource, HttpStatus.OK);
}

@Operation(
summary = "Create a new vendor.",
description = "Create a new vendor.",
tags = {"Vendor"}
)
@PreAuthorize("hasAuthority('WRITE')")
@RequestMapping(value = VENDORS_URL, method = RequestMethod.POST)
public ResponseEntity<?> createVendor(
@RequestBody Vendor vendor) {
@Parameter(description = "The vendor to be created.")
@RequestBody Vendor vendor
) {
vendor = vendorService.createVendor(vendor);
HalResource<Vendor> halResource = createHalVendor(vendor);

Expand Down