Skip to content

Commit

Permalink
Merge pull request #2102 from siemens/doc/api/openapi
Browse files Browse the repository at this point in the history
docs(openapi): add docs for vendor, user, search

Reviewed by: hoang2.nguyenthai@toshiba.co.jp
  • Loading branch information
ag4ums authored Aug 30, 2023
2 parents 05a2760 + 98e10d4 commit 5192e85
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 26 deletions.
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

0 comments on commit 5192e85

Please sign in to comment.