package com.dalab.policyengine.web.rest; import java.net.URI; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import com.dalab.common.security.SecurityUtils; import com.dalab.policyengine.dto.PolicyImpactRequestDTO; import com.dalab.policyengine.dto.PolicyImpactResponseDTO; import com.dalab.policyengine.dto.PolicyInputDTO; import com.dalab.policyengine.dto.PolicyOutputDTO; import com.dalab.policyengine.dto.PolicySummaryDTO; import com.dalab.policyengine.service.IPolicyService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; @RestController @RequestMapping("/api/v1/policyengine/policies") @Tag(name = "Policy Management", description = "Endpoints for managing data governance policies") public class PolicyController { private static final Logger log = LoggerFactory.getLogger(PolicyController.class); private final IPolicyService policyService; @Autowired public PolicyController(IPolicyService policyService) { this.policyService = policyService; } @GetMapping @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER', 'ROLE_USER')") public ResponseEntity> getAllPolicies( @PageableDefault(size = 20, sort = "name") Pageable pageable, @RequestParam(required = false) String status, @RequestParam(required = false) String nameContains) { log.info("REST request to get all Policies with filters: status={}, nameContains={}", status, nameContains); Page policyPage = policyService.getAllPolicies(pageable, status, nameContains); return ResponseEntity.ok(policyPage); } @GetMapping("/{policyId}") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER', 'ROLE_USER')") public ResponseEntity getPolicyById(@PathVariable UUID policyId) { log.info("REST request to get Policy by id: {}", policyId); PolicyOutputDTO policyDTO = policyService.getPolicyById(policyId); return ResponseEntity.ok(policyDTO); } @PostMapping @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER')") public ResponseEntity createPolicy(@Valid @RequestBody PolicyInputDTO policyInputDTO) { log.info("REST request to create Policy: {}", policyInputDTO.getName()); UUID creatorUserId = SecurityUtils.getAuthenticatedUserId(); PolicyOutputDTO createdPolicy = policyService.createPolicy(policyInputDTO, creatorUserId); URI location = ServletUriComponentsBuilder.fromCurrentRequest() .path("/{id}") .buildAndExpand(createdPolicy.getId()) .toUri(); return ResponseEntity.created(location).body(createdPolicy); } @PutMapping("/{policyId}") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER')") public ResponseEntity updatePolicy( @PathVariable UUID policyId, @Valid @RequestBody PolicyInputDTO policyInputDTO) { log.info("REST request to update Policy: {}", policyId); UUID updaterUserId = SecurityUtils.getAuthenticatedUserId(); PolicyOutputDTO updatedPolicy = policyService.updatePolicy(policyId, policyInputDTO, updaterUserId); return ResponseEntity.ok(updatedPolicy); } @DeleteMapping("/{policyId}") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER')") public ResponseEntity deletePolicy(@PathVariable UUID policyId) { log.info("REST request to delete Policy by id: {}", policyId); policyService.deletePolicy(policyId); return ResponseEntity.noContent().build(); } @PostMapping("/analyze-impact") @PreAuthorize("hasAnyAuthority('ROLE_ADMIN', 'ROLE_POLICY_MANAGER', 'ROLE_DATA_STEWARD')") @Operation( summary = "Analyze policy impact before implementation", description = "Provides comprehensive analysis of potential policy impacts including affected assets, performance estimates, cost implications, and compliance analysis. Supports FULL, QUICK, and TARGETED analysis types." ) @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "Policy impact analysis completed successfully" ), @ApiResponse( responseCode = "400", description = "Invalid analysis request parameters" ), @ApiResponse( responseCode = "403", description = "Insufficient permissions to perform policy analysis" ) }) public ResponseEntity analyzePolicyImpact( @Parameter(description = "Policy impact analysis request with rules content and analysis parameters") @Valid @RequestBody PolicyImpactRequestDTO request) { log.info("REST request to analyze policy impact with analysis type: {}", request.getAnalysisType()); PolicyImpactResponseDTO response = policyService.analyzePolicy(request); log.info("Policy impact analysis completed for analysis ID: {}", response.getAnalysisId()); return ResponseEntity.ok(response); } }