Skip to content

Commit

Permalink
楽観ロックエラーと権限エラーを共通エラーハンドラでキャッチするように変更
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjiyoshid-a committed Nov 13, 2024
1 parent 4d76ce4 commit eb3ab3e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import com.dressca.applicationcore.applicationservice.CatalogManagementApplicationService;
import com.dressca.applicationcore.applicationservice.CatalogApplicationService;
import com.dressca.applicationcore.authorization.PermissionDeniedException;
import com.dressca.applicationcore.catalog.CatalogBrandNotFoundException;
import com.dressca.applicationcore.catalog.CatalogCategoryNotFoundException;
Expand All @@ -23,7 +23,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand Down Expand Up @@ -54,7 +53,7 @@
public class CatalogItemsController {

@Autowired
private CatalogManagementApplicationService service;
private CatalogApplicationService service;

private static final Logger apLog = LoggerFactory.getLogger(SystemPropertyConstants.APPLICATION_LOG_LOGGER);

Expand Down Expand Up @@ -104,7 +103,7 @@ public ResponseEntity<PagedListOfCatalogItemResponse> getByQuery(
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "pageSize", defaultValue = "20") int pageSize) {

List<CatalogItemResponse> items = this.service.getCatalogItems(brandId, categoryId, page, pageSize).stream()
List<CatalogItemResponse> items = this.service.getCatalogItemsByAdmin(brandId, categoryId, page, pageSize).stream()
.map(CatalogItemMapper::convert).collect(Collectors.toList());
int totalCount = this.service.countCatalogItems(brandId, categoryId);

Expand All @@ -117,24 +116,22 @@ public ResponseEntity<PagedListOfCatalogItemResponse> getByQuery(
*
* @param postCatalogItemRequest 追加するカタログアイテム
* @return 追加したカタログアイテム
* @throws PermissionDeniedException 認可エラー
*/
@Operation(summary = "カタログにアイテムを追加します。", description = "カタログにアイテムを追加します。")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "成功。", content = @Content),
@ApiResponse(responseCode = "401", description = "", content = @Content)
})
@PostMapping
@PreAuthorize(value = "hasRole('ADMIN')")
public ResponseEntity<CatalogItem> postCatalogItem(@RequestBody PostCatalogItemRequest postCatalogItemRequest) {
try {
this.service.addItemToCatalog(postCatalogItemRequest.getName(), postCatalogItemRequest.getDescription(),
new BigDecimal(postCatalogItemRequest.getPrice()), postCatalogItemRequest.getProductCode(),
postCatalogItemRequest.getCatalogCategoryId(), postCatalogItemRequest.getCatalogBrandId());
} catch (PermissionDeniedException e) {
apLog.info(e.getMessage());
apLog.debug(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
}
@PreAuthorize(value = "hasAuthority('ROLE_ADMIN')")
public ResponseEntity<CatalogItem> postCatalogItem(@RequestBody PostCatalogItemRequest postCatalogItemRequest)
throws PermissionDeniedException {

this.service.addItemToCatalog(postCatalogItemRequest.getName(), postCatalogItemRequest.getDescription(),
new BigDecimal(postCatalogItemRequest.getPrice()), postCatalogItemRequest.getProductCode(),
postCatalogItemRequest.getCatalogCategoryId(), postCatalogItemRequest.getCatalogBrandId());

return ResponseEntity.created(URI.create("catalog-items")).build();
}

Expand All @@ -143,6 +140,7 @@ public ResponseEntity<CatalogItem> postCatalogItem(@RequestBody PostCatalogItemR
*
* @param catalogItemId カタログアイテムID。
* @return なし。
* @throws PermissionDeniedException 認可エラー
*/
@Operation(summary = "カタログから指定したカタログアイテム ID のアイテムを削除します。", description = "カタログから指定したカタログアイテム ID のアイテムを削除します。")
@ApiResponses(value = {
Expand All @@ -151,14 +149,11 @@ public ResponseEntity<CatalogItem> postCatalogItem(@RequestBody PostCatalogItemR
@ApiResponse(responseCode = "404", description = "", content = @Content)
})
@DeleteMapping("{catalogItemId}")
@PreAuthorize(value = "hasRole('ADMIN')")
public ResponseEntity<CatalogItem> deleteCatalogItem(@PathVariable("catalogItemId") long catalogItemId) {
@PreAuthorize(value = "hasAuthority('ROLE_ADMIN')")
public ResponseEntity<CatalogItem> deleteCatalogItem(@PathVariable("catalogItemId") long catalogItemId)
throws PermissionDeniedException {
try {
this.service.deleteItemFromCatalog(catalogItemId);
} catch (PermissionDeniedException e) {
apLog.info(e.getMessage());
apLog.debug(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
} catch (CatalogNotFoundException e) {
apLog.info(e.getMessage());
apLog.debug(ExceptionUtils.getStackTrace(e));
Expand All @@ -173,6 +168,8 @@ public ResponseEntity<CatalogItem> deleteCatalogItem(@PathVariable("catalogItemI
* @param catalogItemId カタログアイテムID。
* @param putCatalogItemRequest 更新するカタログアイテムの情報。
* @return なし。
* @throws OptimisticLockingFailureException 楽観ロックエラー
* @throws PermissionDeniedException 認可エラー
*/
@Operation(summary = "指定したIDのカタログアイテムの情報を更新します。", description = "指定したIDのカタログアイテムの情報を更新します。")
@ApiResponses(value = {
Expand All @@ -182,19 +179,15 @@ public ResponseEntity<CatalogItem> deleteCatalogItem(@PathVariable("catalogItemI
@ApiResponse(responseCode = "409", description = "更新の競合が発生。", content = @Content),
})
@PutMapping("{catalogItemId}")
@PreAuthorize(value = "hasRole('ADMIN')")
@PreAuthorize(value = "hasAuthority('ROLE_ADMIN')")
public ResponseEntity<CatalogItem> putCatalogItem(@PathVariable("catalogItemId") long catalogItemId,
@RequestBody PutCatalogItemRequest putCatalogItemRequest) {

@RequestBody PutCatalogItemRequest putCatalogItemRequest)
throws PermissionDeniedException, OptimisticLockingFailureException {
try {
this.service.updateCatalogItem(catalogItemId, putCatalogItemRequest.getName(),
putCatalogItemRequest.getDescription(), new BigDecimal(putCatalogItemRequest.getPrice()),
putCatalogItemRequest.getProductCode(), putCatalogItemRequest.getCatalogCategoryId(),
putCatalogItemRequest.getCatalogBrandId());
} catch (PermissionDeniedException e) {
apLog.info(e.getMessage());
apLog.debug(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
} catch (CatalogNotFoundException e) {
apLog.info(e.getMessage());
apLog.debug(ExceptionUtils.getStackTrace(e));
Expand All @@ -203,8 +196,6 @@ public ResponseEntity<CatalogItem> putCatalogItem(@PathVariable("catalogItemId")
apLog.error(ExceptionUtils.getStackTrace(e));
// ここでは発生を想定していないので、システムエラーとする。
throw new SystemException(e, ExceptionIdConstant.E_SHARE0000, null, null);
} catch (OptimisticLockingFailureException e) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(null);
}
return ResponseEntity.noContent().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public ResponseEntity<PagedListOfCatalogItemResponse> getByQuery(
@RequestParam(name = "categoryId", defaultValue = "0") long categoryId,
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "pageSize", defaultValue = "20") int pageSize) {
List<CatalogItemResponse> items = service.getCatalogItems(brandId, categoryId, page, pageSize).stream()
List<CatalogItemResponse> items = service.getCatalogItemsByConsumer(brandId, categoryId, page, pageSize).stream()
.map(CatalogItemMapper::convert)
.collect(Collectors.toList());
int totalCount = service.countCatalogItems(brandId, categoryId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.dressca.web.controller.advice;

import jakarta.servlet.http.HttpServletRequest;
import com.dressca.applicationcore.authorization.PermissionDeniedException;
import com.dressca.systemcommon.constant.ExceptionIdConstant;
import com.dressca.systemcommon.constant.SystemPropertyConstants;
import com.dressca.systemcommon.exception.LogicException;
import com.dressca.systemcommon.exception.OptimisticLockingFailureException;
import com.dressca.systemcommon.exception.SystemException;
import com.dressca.web.constant.ProblemDetailsConstant;
import com.dressca.web.log.ErrorMessageBuilder;
Expand Down Expand Up @@ -41,7 +43,7 @@ public class ExceptionHandlerControllerAdvice extends ResponseEntityExceptionHan
@ExceptionHandler(AuthenticationCredentialsNotFoundException.class)
public ResponseEntity<String> handleAuthenticationCredentialsNotFoundException(
AuthenticationCredentialsNotFoundException e, HttpServletRequest req) {
apLog.error(ExceptionUtils.getStackTrace(e));
apLog.warn(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

Expand All @@ -52,13 +54,27 @@ public ResponseEntity<String> handleAuthenticationCredentialsNotFoundException(
* @param req リクエスト
* @return ステータースコード404のレスポンス
*/
@ExceptionHandler(AuthorizationDeniedException.class)
@ExceptionHandler({ AuthorizationDeniedException.class, PermissionDeniedException.class })
public ResponseEntity<String> handleAuthorizationDeniedException(
AuthorizationDeniedException e, HttpServletRequest req) {
apLog.error(ExceptionUtils.getStackTrace(e));
apLog.warn(ExceptionUtils.getStackTrace(e));
return ResponseEntity.notFound().build();
}

/**
* 楽観ロックエラーをステータスコード409で返却する。
*
* @param e 楽観ロックエラー
* @param req リクエスト
* @return ステータスコード409のレスポンス
*/
@ExceptionHandler(OptimisticLockingFailureException.class)
public ResponseEntity<String> handleOptimisticLockingFailureException(
OptimisticLockingFailureException e, HttpServletRequest req) {
apLog.warn(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.CONFLICT).body(null);
}

/**
* その他の業務エラーをステータースコード500で返却する(本番環境、テスト環境用)。
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.dressca.applicationcore.authorization.PermissionDeniedException;
import com.dressca.systemcommon.constant.ExceptionIdConstant;
import com.dressca.systemcommon.constant.SystemPropertyConstants;
import com.dressca.systemcommon.exception.LogicException;
import com.dressca.systemcommon.exception.OptimisticLockingFailureException;
import com.dressca.systemcommon.exception.SystemException;
import com.dressca.web.constant.ProblemDetailsConstant;
import com.dressca.web.log.ErrorMessageBuilder;
Expand Down Expand Up @@ -52,13 +54,27 @@ public ResponseEntity<String> handleAuthenticationCredentialsNotFoundException(
* @param req リクエスト
* @return ステータースコード404のレスポンス
*/
@ExceptionHandler(AuthorizationDeniedException.class)
@ExceptionHandler({ AuthorizationDeniedException.class, PermissionDeniedException.class })
public ResponseEntity<String> handleAuthorizationDeniedException(
AuthorizationDeniedException e, HttpServletRequest req) {
apLog.warn(ExceptionUtils.getStackTrace(e));
return ResponseEntity.notFound().build();
}

/**
* 楽観ロックエラーをステータスコード409で返却する。
*
* @param e 楽観ロックエラー
* @param req リクエスト
* @return ステータスコード409のレスポンス
*/
@ExceptionHandler(OptimisticLockingFailureException.class)
public ResponseEntity<String> handleOptimisticLockingFailureException(
OptimisticLockingFailureException e, HttpServletRequest req) {
apLog.warn(ExceptionUtils.getStackTrace(e));
return ResponseEntity.status(HttpStatus.CONFLICT).body(null);
}

/**
* その他の業務エラーをステータースコード500で返却する(開発環境用)。
*
Expand Down

0 comments on commit eb3ab3e

Please sign in to comment.