diff --git a/.gitignore b/.gitignore index 4c3475e..34da23e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -**/target/ -/config/ +/target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### diff --git a/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt b/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt new file mode 100644 index 0000000..5db32a9 --- /dev/null +++ b/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt @@ -0,0 +1 @@ +eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.rf8bViJPb5bRJHFamVoCftE0TLA1Gz7JyGnfcjtKEx3KiUL4SSbgYSUQlsKhCt8VJMWE--UpgbkM0Bv3pFVsMF_uh693MhFstEy_A6S3MODjoUV_bMLa_Zr1yH2Jwzud4LSyw-ctJ7G-vO8S_I6YML0HV5kNbobdFmMfXFLGKssVmM_Km0m57ZgSjj3zRii0cKpmdwwSbWoJC2y519TpKhIja0OZAoN1oB3IVKvERlFYCQYUpQmcRkzULGrlSoLIm9iqbRX4qMGhGISwVS6JdVtn9WjpSjF3xkUxN_QsVuYKYFL_kEKWSNepIcfoip7Ag9Qw_S1RZA_KO908MgrzGRbs2UIpxY9sAM8yZ-k1NTk0swV836s5pdDIP3PHovcd6iR8mqWBPt7mq7ES98vNeCZxqPLB_b1JuNfKsbLPdRIvEk2DTjZHeEi-yA1yl5uMi_1f4la6mgy65u_jLL_Ow28uZtj-8yQ3dR4lF3K7tkxQaB4LQiH5nl6lXEndpoPe.Cpu6VoHf2ptCue_L.uH-Pq1WZN-x_c71Iyx8X1QJa1JZRp9sYta9iUOmQ4W8x4Qh2wYm-_tpr8FEw56MLvIb8IH_gHVVLAJgXTmCZhyo26vJlPCtnMMPYFDrPRzTJv9Ewg7RMpsAh_kXFFK4UJ6Tgt_r7Tg_bnVOTKXodUjl3wVdMowZRX_ua-gKwLU-2LDWdqIRmuFDSOkMb1sFBZLPyjWHg_rThs-RwVa4YJdDi74s-L0WX0xRPXzeovu1-xvOgZ0xYf0ScbsFQgvK-JwAxOWsB1WKeHRqnnx5-apK6qtzhpiJ30c7ukPlrg2nieuJvkXOVuKBKXLVRLSViOH4HU76DD96btDUA0Cg2kEURpepucX0VWPyB7K3xb9v1AT42TUkW9wZzdmIs9saRo-ItuWzlCezvapLIsbqmYCs_rW2J3KgqXrUyy2mptn32sqaqQZnlNVu4wwboPCCrbl2MG5CYlYKrwaOHNg611j8sCDkIptm_UmPFnOnzvQYwURuDSgzswTIV5bTd_58yxag2yWwiMdGLMDbxxSUPQ6a4EbuDkqwmGBTSLiG7SaSFchSg6o9EflqK6k-u_rlixCxmfg1A6sa7nloW17dOxDzGKtmn9lBoaskL97nNrhP6ptftak7j4TIZulz1FUOSVoR8kXK8RNQMj-b6rg_MdSO9Ecq5hZsza1SzjkzKZvV-tpP6Wl6-rszCH6g3DIQAWN5aWdUkwuya1HqDDyVPbUOVQPsp4nhVC24QmnlbcqFwQdoCrikYKyX3Snc0H6_K4z9c6nURAdj6THwHmA9BfHtJniI_rEIvkmBk3yndi-H5eAjtxIoYSFQrSTWEFhgvk6bAKoR_xb_cHgzKOxYLBiO_FifkjkFDOlkVBuYnZEp3oRePDKgMDfL5Oxjuie4u-8yrH52Cd32yQzbvGplaXLLeEDf3i71dcz4LkO5DknScWG3G_SbKBpjlse-GKe3XYqRXeRIYLpyiX1MXph0b-Q.dvHU75ZR8wJFxoSacfkthw \ No newline at end of file diff --git a/config/clients/matrix/matrix-signing-private.pem b/config/clients/matrix/matrix-signing-private.pem new file mode 100644 index 0000000..226e9df --- /dev/null +++ b/config/clients/matrix/matrix-signing-private.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +M/D4ZjXsfrW//BMF6+w2Bh4= +-----END PRIVATE KEY----- diff --git a/config/clients/matrix/matrix-signing-public.pem b/config/clients/matrix/matrix-signing-public.pem new file mode 100644 index 0000000..880c04c --- /dev/null +++ b/config/clients/matrix/matrix-signing-public.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAloJtGMOLcTNWe1IgdrT8 +uYucI1Vs02WjyUPZ7Po51iC67QmGdG0InzlBJYdkYtTz8eda+qArZMNGB0ChFs/7 +xKPKASkMvVcrm4IYbth0DEIkXWAL7YXsWd8qdS+KsnxuC6TqvuA9Xq/PX4RmtAq4 +bl0/1T2HZjJs53/b73l5NehcseZU129w+5lBqDwW5xh+1VnXNbc96za7BFfQSnfg +9WwaWSpo8Y57XATnV7s46yT8gNKM29INHJXs4aIrQ9tcLnTbDz9nhGceNgec3AhO +zc4TyCPugUiG9WD4ehsQr+7Cp30RqT5l9ZPvoBTpAdHLZ1r/jB+qY6+WkY6EsOJW +2xg9bUYoHXjMiFdi8OLXC4NTAPUquFOaIMfjxGaYQc8NoDMFiq3qdTWi2ndCOoxX +yFxYRP5pYs/oA46UAHZsCHaspjvl9jfR/abCALBtsFLwpLA9qqBws5ojXFH//UoX +E7dXnJziCFQNyJOhXtIhbQhtb3wJc6WSLtDrRpFtaJudAgMBAAE= +-----END PUBLIC KEY----- diff --git a/config/keys/access-token-private.pem b/config/keys/access-token-private.pem new file mode 100644 index 0000000..c2f0831 --- /dev/null +++ b/config/keys/access-token-private.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +m/lDtrY4EpMy9FSQD1zb+qE= +-----END PRIVATE KEY----- diff --git a/config/keys/access-token-public.pem b/config/keys/access-token-public.pem new file mode 100644 index 0000000..a696ef2 --- /dev/null +++ b/config/keys/access-token-public.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyfuM67QxEonEvC2Vf21 +P+fxo406Z4C+zNzxH/8tCPhMH94Sklt10WXqSfQFfZbhJPVYoZL8m0NDI7ozI7lI +MPAhAVfcFOzO6VqpFGrzMgMqmnWLrxRsL3y1rjB3LnE84W+ATcS/mlk6rwbCfrSo +RRlY3i79ol8h36jhhaHT2/iGGO3uvqAQK334lQEOlqr+YL4Kkr/GMOm86bE4PcZS +JgCTAnlCQC7TUu6jGWuocmI1nNwLXPjQvXgc+HKtJEqFGf+a0fty9fLgaR2yIzlM +9i31r3kjeKzqVe2DeLTbttd8bVWU4/KmGg8rEchtwC8wR4inuDUjwJ3FwmdBrvDp +Ga1AM8yofdbs73Lv2EgkvRLvlgaWiX2P6KdlKGHeaDj9v0YWJbiFM4rc9y5hD3lG +2unhpvP/49OFXVBT2/pm86LmxSlwsun3G2LKNOXI646jhdVHQkIVcBiHTHYQOe9/ +xLqx3ZiEM7witbzuJnxIkbj/8OFgH+WDUmTQVXtbz7vdAgMBAAE= +-----END PUBLIC KEY----- diff --git a/config/keys/assertion-decryption-private.pem b/config/keys/assertion-decryption-private.pem new file mode 100644 index 0000000..3facc8a --- /dev/null +++ b/config/keys/assertion-decryption-private.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +RqsZZ1cLu0TCOoNBkcSr79a6 +-----END PRIVATE KEY----- diff --git a/config/keys/assertion-decryption-public.pem b/config/keys/assertion-decryption-public.pem new file mode 100644 index 0000000..2e72887 --- /dev/null +++ b/config/keys/assertion-decryption-public.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtZc750+cxwDcG/lvpEHm +3fxFgp5X5df90s51R4ShKpV6dmDRYXnVil9GmXrJf/aGAqrsf6ZUvZWJrAJ2OO2X +Wt8tcqajnaWdM33BrH/QztTJkoGHZM1xLY5EpRaWo1LaG2gNGsaxG0ON9T1emKi7 +XDEcI9Lmc/mhP6SuuUnvGwq1Z433vqGodorkU+T2jCfflhwfenvBcOk4GJZoJFlY +sjy9Dtlha70MJpdVFWffxs4UBhhkjckb7GbDTVxa3xvz1NEbkY2+oh/tJmuIuupA +7A6TnfYP1YPXPMRQFtSPaKMOeKW5J5IorvgQKr4C74HR9iBojJN2oJ6/BjfAaz7P +8kywLj2uo9gJemOm1wz8HZyZsz482GHa0wqpUcFfOIr0oTMiJtvLn/FSYVb5xvNg +3xWiGPMju32Z49XTX7VxTDsIjGx5wtDd4G8ILS3yUlKw0yufHacmy8Fn+Plk+Xtz +Bbz6rq4frV93/3mfVMPGgBDx8mLjVJovPBnXKBSX+SdbAgMBAAE= +-----END PUBLIC KEY----- diff --git a/config/keys/case-save-private.pem b/config/keys/case-save-private.pem new file mode 100644 index 0000000..b840faf --- /dev/null +++ b/config/keys/case-save-private.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +5PO2cnRk24OsUqAswTBT2qjd +-----END PRIVATE KEY----- diff --git a/config/keys/case-save-public.pem b/config/keys/case-save-public.pem new file mode 100644 index 0000000..8443e1b --- /dev/null +++ b/config/keys/case-save-public.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzpOwECKVW0KdZwlVJtW7 +tkqqa1wY1J+HhuFf/kbjmJv8fwFcGj+uyy2s5cXzgckNHz3Cv4Ki8VnQakbn83KR +TNIuMvYgwnaNY35KvVKU5R8KPJ7wV8yEUyhRyjtauaY9TaVUH0MStD3izcZ7Pfej +XJvxRtLjQ9SX/K+joHs3mkWyWDNYm9u6ecLBoPxW6BpAXiUOWnSpc0IO2njGbvnY +I7zs5tYdFjVtDTf4TOSIDXeCXc7nNUhf/yQVAEKvGmr64SihZc+11T5AXJy1eVEj +Fwj7hWqcZxhgukacOoU8oUORO0O0H1HIS8ICXHBgKL17Jq+furEInlU4Pfp1tkA7 +dYh9nXQ91+hmRtTSXA1BpzWdIzC3fQqnwTsD6cyIDsPdRB9iSJTywFPbGywMIbh4 +wIpUOS3s83DBtpxj2qHw7zc5Q99BP4Dd38kl9ejfdYuFYRmbzrq+BZR7ic5/LM7+ +8iExYGpz3sFCr6qJAlCDK4th6TCl2ZjzgpTOF3pnC1I7AgMBAAE= +-----END PUBLIC KEY----- diff --git a/config/keys/login-private.pem b/config/keys/login-private.pem new file mode 100644 index 0000000..bbe99c8 --- /dev/null +++ b/config/keys/login-private.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +VkpSw8QqBfhHSViEh12BQZa2 +-----END PRIVATE KEY----- diff --git a/config/keys/login-public.pem b/config/keys/login-public.pem new file mode 100644 index 0000000..e6c9488 --- /dev/null +++ b/config/keys/login-public.pem @@ -0,0 +1,11 @@ +-----BEGIN PUBLIC KEY----- +MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2g0IbNxsNIZ6fKaGTHTQ +pUFfgJVq3x0SZ458xAQDL0l1PZ+lnMtvS3/ZZpbF99bLuqyzUuHwi+1BJ/Nled61 +oK8RdJKfUPiQUshXfvWT4/sLsYO6H+v2qw2jBv6kx3h+teDiuHMbw6ikUECr5u1k +qkjb+ls3aijtWplmN25HRhwFB/l6/0xAhEQNA36EoNb+ufsDR/2aRQYGQ6qegynp +8bUt7JDf3hW1y76UCKlKteFfIOkp4zwY0YYq/NewgKlze08LBrX+zy5xr5Vn8nE0 +ZtWY8vbNC33Sf6g5D1ZlA+HvquplAWS/rPymj+IN79FeXNegmyCxF/ZafsneaUBn +GpSgXYbyASpA+OkqUqJcBEeTI4rfRZPiyx3ztaibg+rgOEM/DUV5le2WyujnsQ75 +IG4SrVu/XTmF08MN8/hD1+ydBVnhVa7bE4WctqgA1T/5BP7ivAB03a1BJHpKFRh/ +Q/pO5ONIK8lNGG6aImLPmtJijEvOL0VsUdp+oO87VnTFAgMBAAE= +-----END PUBLIC KEY----- diff --git a/cygnus-cloud-client/src/main/java/com/cygnus/client/CloudIdentityClient.java b/cygnus-cloud-client/src/main/java/com/cygnus/client/CloudIdentityClient.java index f21dd8b..8f2076a 100644 --- a/cygnus-cloud-client/src/main/java/com/cygnus/client/CloudIdentityClient.java +++ b/cygnus-cloud-client/src/main/java/com/cygnus/client/CloudIdentityClient.java @@ -1,11 +1,15 @@ package com.cygnus.client; import com.cygnus.client.model.CloudIdentitySession; +import com.cygnus.client.model.CloudDataItem; +import com.cygnus.client.model.CloudDataRequest; import com.cygnus.client.model.CloudQueryResponse; import com.cygnus.client.model.LoginPayload; import com.cygnus.client.security.LoginEnvelopeEncryptor; import com.cygnus.client.security.MachineTokenProvider; import java.time.Clock; +import java.util.List; +import java.util.Map; import java.util.UUID; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -73,4 +77,18 @@ public class CloudIdentityClient { .bodyToMono(CloudQueryResponse.class)) .timeout(properties.requestTimeout()); } + + public Mono> fetchData(String scope, Map data) { + return tokenProvider.accessToken() + .flatMap(token -> webClient.post() + .uri(properties.baseUri().resolve("/api/v1/platform/data")) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .bodyValue(new CloudDataRequest(scope, Map.copyOf(data))) + .retrieve() + .bodyToFlux(CloudDataItem.class) + .collectList()) + .timeout(properties.requestTimeout()); + } } diff --git a/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataItem.java b/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataItem.java new file mode 100644 index 0000000..67821d1 --- /dev/null +++ b/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataItem.java @@ -0,0 +1,4 @@ +package com.cygnus.client.model; + +public record CloudDataItem(Object value, String label, String group) { +} diff --git a/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataRequest.java b/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataRequest.java new file mode 100644 index 0000000..4f189bc --- /dev/null +++ b/cygnus-cloud-client/src/main/java/com/cygnus/client/model/CloudDataRequest.java @@ -0,0 +1,6 @@ +package com.cygnus.client.model; + +import java.util.Map; + +public record CloudDataRequest(String scope, Map data) { +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataController.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataController.java new file mode 100644 index 0000000..0309581 --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataController.java @@ -0,0 +1,49 @@ +package com.cygnus.cloud.platform.api; + +import com.cygnus.cloud.platform.service.ScopedDataException; +import com.cygnus.cloud.platform.service.ScopedDataService; +import jakarta.validation.Valid; +import java.util.Map; +import java.util.UUID; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.web.bind.annotation.ExceptionHandler; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +@RestController +@RequestMapping("/api/v1/platform/data") +public class ScopedDataController { + private static final Logger LOGGER = LoggerFactory.getLogger(ScopedDataController.class); + private final ScopedDataService service; + + public ScopedDataController(ScopedDataService service) { + this.service = service; + } + + @PostMapping + public Flux data( + @AuthenticationPrincipal Jwt machineJwt, + @Valid @RequestBody ScopedDataRequest request) { + if (machineJwt == null) throw new ScopedDataException("Machine authentication required"); + try { + return service.fetch(UUID.fromString(machineJwt.getClaimAsString("tenant_id")), request); + } catch (IllegalArgumentException exception) { + throw new ScopedDataException("Machine tenant is invalid"); + } + } + + @ExceptionHandler(ScopedDataException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + Map invalidRequest(ScopedDataException exception) { + LOGGER.warn("Scoped platform-data request rejected: {}", exception.getMessage()); + return Map.of("code", "PLATFORM_DATA_INVALID", "message", exception.getMessage()); + } +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataItem.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataItem.java new file mode 100644 index 0000000..d6a0296 --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataItem.java @@ -0,0 +1,7 @@ +package com.cygnus.cloud.platform.api; + +public record ScopedDataItem( + Object value, + String label, + String group) { +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataRequest.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataRequest.java new file mode 100644 index 0000000..8905e90 --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/api/ScopedDataRequest.java @@ -0,0 +1,10 @@ +package com.cygnus.cloud.platform.api; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.util.Map; + +public record ScopedDataRequest( + @NotBlank String scope, + @NotNull Map data) { +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/repository/ScopedDataRepository.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/repository/ScopedDataRepository.java new file mode 100644 index 0000000..8b49942 --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/repository/ScopedDataRepository.java @@ -0,0 +1,79 @@ +package com.cygnus.cloud.platform.repository; + +import com.cygnus.cloud.database.ReactiveDatabaseClient; +import com.cygnus.cloud.platform.api.ScopedDataItem; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.Tuple; +import java.util.List; +import java.util.UUID; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; + +@Repository +public class ScopedDataRepository { + private static final String COMPANY_OPTIONS = """ + SELECT ov.opt_value AS value, + ov.val_description AS label, + lower(o.description) || '.' AS group_name + FROM platform.company_options_mapping m + JOIN platform.options o ON o.option_id = m.option_id + JOIN platform.options_values ov ON ov.opt_value_id = m.opt_value_id + JOIN identity.company c ON c.company_id = m.company_id + WHERE c.tenant_id = $1 + AND m.company_id = $2 + AND o.isactive = 1 + AND ov.isactive = 1 + AND o.description = ANY($3::text[]) + ORDER BY o.description, ov.val_description + """; + private static final String PORTFOLIO_OPTIONS = """ + SELECT ov.opt_value AS value, + ov.val_description AS label, + lower(o.description) || '.' AS group_name + FROM platform.options_mapping m + JOIN platform.options o ON o.option_id = m.option_id + JOIN platform.options_values ov ON ov.opt_value_id = m.opt_value_id + JOIN identity.company c ON c.company_id = m.company_id + JOIN platform.company_branch_portfolios cbp + ON cbp.company_id = m.company_id + AND cbp.portfolio_reference = m.portfolio_reference + WHERE c.tenant_id = $1 + AND m.company_id = $2 + AND cbp.company_branch_id = $3 + AND m.portfolio_reference = $4 + AND o.isactive = 1 + AND ov.isactive = 1 + AND o.description = ANY($5::text[]) + ORDER BY o.description, ov.val_description + """; + + private final ReactiveDatabaseClient database; + + public ScopedDataRepository(ReactiveDatabaseClient database) { + this.database = database; + } + + public Flux companyOptions( + UUID tenantId, short companyId, List descriptions) { + return rows(COMPANY_OPTIONS, Tuple.of(tenantId, companyId, descriptions.toArray(String[]::new))); + } + + public Flux portfolioOptions( + UUID tenantId, short companyId, short branchId, UUID portfolioReference, + List descriptions) { + return rows(PORTFOLIO_OPTIONS, + Tuple.of(tenantId, companyId, branchId, portfolioReference, + descriptions.toArray(String[]::new))); + } + + private Flux rows(String sql, Tuple parameters) { + return database.preparedQuery(sql, parameters) + .flatMapMany(result -> Flux.fromIterable(result)) + .map(this::item); + } + + private ScopedDataItem item(Row row) { + return new ScopedDataItem( + row.getValue("value"), row.getString("label"), row.getString("group_name")); + } +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataException.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataException.java new file mode 100644 index 0000000..132d71c --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataException.java @@ -0,0 +1,7 @@ +package com.cygnus.cloud.platform.service; + +public class ScopedDataException extends RuntimeException { + public ScopedDataException(String message) { + super(message); + } +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataService.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataService.java new file mode 100644 index 0000000..df542cc --- /dev/null +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/platform/service/ScopedDataService.java @@ -0,0 +1,74 @@ +package com.cygnus.cloud.platform.service; + +import com.cygnus.cloud.platform.api.ScopedDataItem; +import com.cygnus.cloud.platform.api.ScopedDataRequest; +import com.cygnus.cloud.platform.repository.ScopedDataRepository; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Flux; + +@Service +public class ScopedDataService { + public static final String COMPANY_OPTIONS = "company-options"; + public static final String PORTFOLIO_OPTIONS = "portfolio-options"; + + private final ScopedDataRepository repository; + + public ScopedDataService(ScopedDataRepository repository) { + this.repository = repository; + } + + public Flux fetch(UUID tenantId, ScopedDataRequest request) { + Map data = request.data(); + short companyId = shortValue(data, "companyId"); + List descriptions = descriptions(data); + return switch (request.scope().trim().toLowerCase(Locale.ROOT)) { + case COMPANY_OPTIONS -> repository.companyOptions(tenantId, companyId, descriptions); + case PORTFOLIO_OPTIONS -> repository.portfolioOptions( + tenantId, companyId, shortValue(data, "branchId"), + uuidValue(data, "portfolioReference"), descriptions); + default -> Flux.error(new ScopedDataException("Unsupported data scope")); + }; + } + + private UUID uuidValue(Map data, String name) { + try { + return UUID.fromString(String.valueOf(data.get(name))); + } catch (RuntimeException exception) { + throw new ScopedDataException(name + " must be a valid UUID"); + } + } + + private short shortValue(Map data, String name) { + Object value = data.get(name); + try { + short result = value instanceof Number number + ? number.shortValue() : Short.parseShort(String.valueOf(value)); + if (result <= 0) throw new NumberFormatException(); + return result; + } catch (RuntimeException exception) { + throw new ScopedDataException(name + " must be a positive number"); + } + } + + private List descriptions(Map data) { + Object value = data.get("descriptions"); + if (!(value instanceof List values)) { + throw new ScopedDataException("descriptions must be a non-empty list"); + } + List result = values.stream() + .map(String::valueOf) + .map(String::trim) + .filter(text -> !text.isEmpty()) + .map(text -> text.toUpperCase(Locale.ROOT)) + .distinct() + .toList(); + if (result.isEmpty() || result.size() > 20) { + throw new ScopedDataException("descriptions must contain between 1 and 20 values"); + } + return result; + } +} diff --git a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CloudSecurityConfiguration.java b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CloudSecurityConfiguration.java index db90c1e..3622ecf 100644 --- a/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CloudSecurityConfiguration.java +++ b/cygnus-cloud-service/src/main/java/com/cygnus/cloud/security/CloudSecurityConfiguration.java @@ -38,6 +38,8 @@ public class CloudSecurityConfiguration { .hasAuthority("SCOPE_identity.login") .pathMatchers("/api/v1/queries/**") .hasAuthority("SCOPE_identity.login") + .pathMatchers("/api/v1/platform/data") + .hasAuthority("SCOPE_identity.login") .pathMatchers("/api/v1/admin/**") .hasAuthority("SCOPE_cygnus.admin") .anyExchange().authenticated()) diff --git a/cygnus-installer/.DS_Store b/cygnus-installer/.DS_Store index ee77193..c69d7bc 100644 Binary files a/cygnus-installer/.DS_Store and b/cygnus-installer/.DS_Store differ diff --git a/cygnus-installer/src/main/java/com/cygnus/installer/SwingInstallationWizard.java b/cygnus-installer/src/main/java/com/cygnus/installer/SwingInstallationWizard.java index fbfa5cb..0574438 100644 --- a/cygnus-installer/src/main/java/com/cygnus/installer/SwingInstallationWizard.java +++ b/cygnus-installer/src/main/java/com/cygnus/installer/SwingInstallationWizard.java @@ -42,8 +42,9 @@ import org.springframework.stereotype.Service; public class SwingInstallationWizard { private static final String WELCOME = "welcome"; + private static final String DATABASE = "database"; + private static final String DEPLOYMENT = "deployment"; private static final String DETAILS = "details"; - private static final String RUNTIME = "runtime"; private static final String INSTALLING = "installing"; private static final Color ACCENT = new Color(35, 97, 146); private static final Color BACKGROUND = new Color(236, 243, 247); @@ -68,7 +69,9 @@ public class SwingInstallationWizard { private JPasswordField dockerPassword; private JTextField outputDirectory; private JTextField containerCloudServiceUrl; - private JTextField databaseUrl; + private JTextField databaseHost; + private JTextField databasePort; + private JTextField databaseName; private JTextField databaseUsername; private JPasswordField databasePassword; private JTextField redisHost; @@ -139,8 +142,9 @@ public class SwingInstallationWizard { cardPanel = new JPanel(cards); cardPanel.setBackground(BACKGROUND); cardPanel.add(welcomePanel(), WELCOME); + cardPanel.add(databasePanel(), DATABASE); + cardPanel.add(deploymentPanel(), DEPLOYMENT); cardPanel.add(detailsPanel(), DETAILS); - cardPanel.add(runtimePanel(), RUNTIME); cardPanel.add(installingPanel(), INSTALLING); root.add(cardPanel, BorderLayout.CENTER); return root; @@ -197,7 +201,8 @@ public class SwingInstallationWizard { JPanel top = new JPanel(new BorderLayout()); top.setOpaque(false); top.add(heading("Installation details"), BorderLayout.NORTH); - top.add(text("Enter the activation details supplied by Technobee."), BorderLayout.SOUTH); + top.add(text("Review and enter the activation details supplied by Technobee."), + BorderLayout.SOUTH); panel.add(top, BorderLayout.NORTH); JPanel form = new JPanel(new GridBagLayout()); @@ -209,6 +214,32 @@ public class SwingInstallationWizard { licenseKey = new JPasswordField(); installationCode = new JTextField(); installationName = new JTextField(); + int row = 0; + row = addField(form, row, "Client code", clientCode, null); + row = addField(form, row, "License key", licenseKey, null); + row = addField(form, row, "Installation code", installationCode, null); + addField(form, row, "Installation name", installationName, null); + panel.add(form, BorderLayout.CENTER); + + JButton back = secondaryButton("Back"); + back.addActionListener(event -> cards.show(cardPanel, DEPLOYMENT)); + JButton install = primaryButton("Install"); + install.addActionListener(event -> startInstallation()); + panel.add(actions(back, install), BorderLayout.SOUTH); + return panel; + } + + private JPanel deploymentPanel() { + JPanel panel = contentPanel(); + panel.setLayout(new BorderLayout(0, 12)); + JPanel top = new JPanel(new BorderLayout()); + top.setOpaque(false); + top.add(heading("Docker and deployment"), BorderLayout.NORTH); + top.add(text("Configure the container image, registry and deployment location."), + BorderLayout.SOUTH); + panel.add(top, BorderLayout.NORTH); + + JPanel form = formPanel(); containerCloudServiceUrl = new JTextField(settings.containerCloudServiceUrl().toString()); containerCloudServiceUrl.setEditable(true); @@ -220,10 +251,6 @@ public class SwingInstallationWizard { outputDirectory = new JTextField( settings.defaultOutputDirectory().toAbsolutePath().normalize().toString()); int row = 0; - row = addField(form, row, "Client code", clientCode, null); - row = addField(form, row, "License key", licenseKey, null); - row = addField(form, row, "Installation code", installationCode, null); - row = addField(form, row, "Installation name", installationName, null); row = addField( form, row, @@ -237,8 +264,11 @@ public class SwingInstallationWizard { dockerImage, null); row = addField(form, row, "Docker registry", dockerRegistry, null); - row = addField(form, row, "Docker username", dockerUsername, null); - row = addField(form, row, "Docker password", dockerPassword, null); + row = addComponentField( + form, + row, + "Docker credentials", + credentialFields(dockerUsername, dockerPassword)); for (String field : profile.optionalInstallationFields()) { JTextField input = new JTextField(); optionalFields.put(field, input); @@ -254,31 +284,28 @@ public class SwingInstallationWizard { panel.add(scroll, BorderLayout.CENTER); JButton back = secondaryButton("Back"); - back.addActionListener(event -> cards.show(cardPanel, WELCOME)); + back.addActionListener(event -> cards.show(cardPanel, DATABASE)); JButton next = primaryButton("Next"); - next.addActionListener(event -> cards.show(cardPanel, RUNTIME)); + next.addActionListener(event -> cards.show(cardPanel, DETAILS)); panel.add(actions(back, next), BorderLayout.SOUTH); return panel; } - private JPanel runtimePanel() { + private JPanel databasePanel() { JPanel panel = contentPanel(); panel.setLayout(new BorderLayout(0, 12)); JPanel top = new JPanel(new BorderLayout()); top.setOpaque(false); - top.add(heading("Runtime configuration"), BorderLayout.NORTH); + top.add(heading("Database and Redis"), BorderLayout.NORTH); top.add(text("Configure the database and Redis services used by the " + profile.displayName() + " on-premises container."), BorderLayout.SOUTH); panel.add(top, BorderLayout.NORTH); - JPanel form = new JPanel(new GridBagLayout()); - form.setBackground(PANEL); - form.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createLineBorder(new Color(205, 217, 225)), - BorderFactory.createEmptyBorder(14, 16, 14, 16))); - - databaseUrl = new JTextField("jdbc:postgresql://localhost:5432/matrix"); + JPanel form = formPanel(); + databaseHost = new JTextField("localhost"); + databasePort = new JTextField("5432"); + databaseName = new JTextField("matrix"); databaseUsername = new JTextField("postgres"); databasePassword = new JPasswordField(); redisHost = new JTextField("localhost"); @@ -287,9 +314,16 @@ public class SwingInstallationWizard { cloudRequestTimeout = new JTextField("PT10S"); tokenRefreshSkew = new JTextField("PT30S"); int row = 0; - row = addField(form, row, "Database URL", databaseUrl, null); - row = addField(form, row, "Database username", databaseUsername, null); - row = addField(form, row, "Database password", databasePassword, null); + row = addComponentField( + form, + row, + "Database", + databaseConnectionFields()); + row = addComponentField( + form, + row, + "Database credentials", + credentialFields(databaseUsername, databasePassword)); row = addField(form, row, "Redis host", redisHost, null); row = addField(form, row, "Redis port", redisPort, null); row = addField(form, row, "Redis password", redisPassword, null); @@ -304,10 +338,10 @@ public class SwingInstallationWizard { panel.add(form, BorderLayout.CENTER); JButton back = secondaryButton("Back"); - back.addActionListener(event -> cards.show(cardPanel, DETAILS)); - JButton install = primaryButton("Install"); - install.addActionListener(event -> startInstallation()); - panel.add(actions(back, install), BorderLayout.SOUTH); + back.addActionListener(event -> cards.show(cardPanel, WELCOME)); + JButton next = primaryButton("Next"); + next.addActionListener(event -> cards.show(cardPanel, DEPLOYMENT)); + panel.add(actions(back, next), BorderLayout.SOUTH); return panel; } @@ -373,7 +407,7 @@ public class SwingInstallationWizard { progressBar.setValue(0); progressPercentage.setText("0%"); progressMessage.setText("Preparing installation"); - cards.show(cardPanel, RUNTIME); + cards.show(cardPanel, DEPLOYMENT); containerCloudServiceUrl.requestFocusInWindow(); }); @@ -415,8 +449,8 @@ public class SwingInstallationWizard { button.setText("Check Docker and continue"); try { get(); - cards.show(cardPanel, DETAILS); - clientCode.requestFocusInWindow(); + cards.show(cardPanel, DATABASE); + databaseHost.requestFocusInWindow(); } catch (Exception exception) { showError(message(exception)); } @@ -445,7 +479,12 @@ public class SwingInstallationWizard { optionalValues(), new RuntimeConfiguration( containerCloudServiceUrl.getText(), - databaseUrl.getText(), + "jdbc:postgresql://" + + databaseHost.getText().trim() + + ":" + + databasePort.getText().trim() + + "/" + + databaseName.getText().trim(), databaseUsername.getText(), new String(databaseSecret), redisHost.getText(), @@ -559,7 +598,9 @@ public class SwingInstallationWizard { validateAbsoluteHttpUrl( runtime.containerCloudServiceUrl(), "Container cloud service URL"); - if (runtime.databaseUrl().isBlank() + if (databaseHost.getText().isBlank() + || databasePort.getText().isBlank() + || databaseName.getText().isBlank() || runtime.databaseUsername().isBlank() || runtime.databasePassword().isBlank()) { throw new IllegalArgumentException( @@ -632,6 +673,95 @@ public class SwingInstallationWizard { return row + 1; } + private int addComponentField( + JPanel form, + int row, + String label, + Component input) { + GridBagConstraints labelConstraints = constraints(0, row); + labelConstraints.weightx = 0; + labelConstraints.fill = GridBagConstraints.NONE; + labelConstraints.anchor = GridBagConstraints.LINE_START; + JLabel fieldLabel = new JLabel(label); + fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD, 12f)); + form.add(fieldLabel, labelConstraints); + + GridBagConstraints inputConstraints = constraints(1, row); + inputConstraints.weightx = 1; + inputConstraints.fill = GridBagConstraints.HORIZONTAL; + form.add(input, inputConstraints); + return row + 1; + } + + private JPanel formPanel() { + JPanel form = new JPanel(new GridBagLayout()); + form.setBackground(PANEL); + form.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(205, 217, 225)), + BorderFactory.createEmptyBorder(14, 16, 14, 16))); + return form; + } + + private JPanel databaseConnectionFields() { + JPanel fields = inlineFieldsPanel(); + addInlineField(fields, databaseHost, 0, 0.50); + addInlineSeparator(fields, ":", 1); + addInlineField(fields, databasePort, 2, 0.15); + addInlineSeparator(fields, "/", 3); + addInlineField(fields, databaseName, 4, 0.35); + databaseHost.setToolTipText("Database host"); + databasePort.setToolTipText("Database port"); + databaseName.setToolTipText("Database name"); + return fields; + } + + private JPanel credentialFields(JTextField username, JTextField password) { + JPanel fields = inlineFieldsPanel(); + addInlineLabel(fields, "Username", 0); + addInlineField(fields, username, 1, 0.5); + addInlineLabel(fields, "Password", 2); + addInlineField(fields, password, 3, 0.5); + return fields; + } + + private JPanel inlineFieldsPanel() { + JPanel fields = new JPanel(new GridBagLayout()); + fields.setOpaque(false); + return fields; + } + + private void addInlineField( + JPanel panel, + JTextField field, + int column, + double weight) { + GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = column; + constraints.weightx = weight; + constraints.fill = GridBagConstraints.HORIZONTAL; + constraints.insets = new Insets(0, column == 0 ? 0 : 5, 0, 0); + field.setPreferredSize(new Dimension(120, 29)); + panel.add(field, constraints); + } + + private void addInlineLabel(JPanel panel, String text, int column) { + GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = column; + constraints.weightx = 0; + constraints.insets = new Insets(0, column == 0 ? 0 : 12, 0, 5); + JLabel label = new JLabel(text); + label.setForeground(new Color(75, 88, 99)); + panel.add(label, constraints); + } + + private void addInlineSeparator(JPanel panel, String text, int column) { + GridBagConstraints constraints = new GridBagConstraints(); + constraints.gridx = column; + constraints.weightx = 0; + constraints.insets = new Insets(0, 5, 0, 0); + panel.add(new JLabel(text), constraints); + } + private GridBagConstraints constraints(int column, int row) { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = column; @@ -664,6 +794,7 @@ public class SwingInstallationWizard { JLabel label = new JLabel(value); label.setFont(label.getFont().deriveFont(Font.BOLD, 19f)); label.setForeground(new Color(35, 48, 58)); + label.setAlignmentX(Component.LEFT_ALIGNMENT); return label; } @@ -677,6 +808,7 @@ public class SwingInstallationWizard { private JPanel summaryRow(String label, String value) { JPanel row = new JPanel(new BorderLayout(18, 0)); row.setOpaque(false); + row.setAlignmentX(Component.LEFT_ALIGNMENT); row.setBorder(BorderFactory.createEmptyBorder(7, 0, 7, 0)); JLabel name = new JLabel(label); name.setPreferredSize(new Dimension(130, 20)); @@ -691,7 +823,8 @@ public class SwingInstallationWizard { JPanel row = new JPanel(new BorderLayout(18, 0)); row.setOpaque(false); row.setAlignmentX(Component.LEFT_ALIGNMENT); - row.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34)); + row.setBorder(BorderFactory.createEmptyBorder(7, 0, 7, 0)); + row.setMaximumSize(new Dimension(Integer.MAX_VALUE, 42)); JLabel name = new JLabel(label); name.setFont(name.getFont().deriveFont(Font.BOLD)); name.setPreferredSize(new Dimension(130, 28)); diff --git a/cygnus-installer/src/main/java/com/cygnus/installer/TechnobeeServiceInstallerApplication.java b/cygnus-installer/src/main/java/com/cygnus/installer/TechnobeeServiceInstallerApplication.java index 2c9c8ca..80dfec6 100644 --- a/cygnus-installer/src/main/java/com/cygnus/installer/TechnobeeServiceInstallerApplication.java +++ b/cygnus-installer/src/main/java/com/cygnus/installer/TechnobeeServiceInstallerApplication.java @@ -23,6 +23,7 @@ public class TechnobeeServiceInstallerApplication implements CommandLineRunner { } public static void main(String[] args) { + disableAccidentalSpringDebug(args); SpringApplication application = new SpringApplication(TechnobeeServiceInstallerApplication.class); application.setWebApplicationType(WebApplicationType.NONE); @@ -39,6 +40,18 @@ public class TechnobeeServiceInstallerApplication implements CommandLineRunner { } } + static void disableAccidentalSpringDebug(String[] args) { + boolean debugRequested = Arrays.stream(args) + .anyMatch(argument -> "--debug".equals(argument) + || "--debug=true".equalsIgnoreCase(argument)); + if (!debugRequested && System.getProperty("debug") == null) { + // DEBUG is commonly exported by developer tools with non-boolean + // values. Spring maps it to its own debug switch unless a more + // specific system property is present. + System.setProperty("debug", "false"); + } + } + @Override public void run(String... args) { boolean cli = Arrays.asList(args).contains("--cli"); diff --git a/cygnus-installer/src/test/java/com/cygnus/installer/TechnobeeServiceInstallerApplicationTest.java b/cygnus-installer/src/test/java/com/cygnus/installer/TechnobeeServiceInstallerApplicationTest.java new file mode 100644 index 0000000..52aa658 --- /dev/null +++ b/cygnus-installer/src/test/java/com/cygnus/installer/TechnobeeServiceInstallerApplicationTest.java @@ -0,0 +1,29 @@ +package com.cygnus.installer; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +class TechnobeeServiceInstallerApplicationTest { + + @AfterEach + void clearDebugProperty() { + System.clearProperty("debug"); + } + + @Test + void disablesDebugUnlessExplicitlyRequested() { + TechnobeeServiceInstallerApplication.disableAccidentalSpringDebug(new String[0]); + + assertThat(System.getProperty("debug")).isEqualTo("false"); + } + + @Test + void preservesExplicitDebugRequest() { + TechnobeeServiceInstallerApplication.disableAccidentalSpringDebug( + new String[] {"--debug"}); + + assertThat(System.getProperty("debug")).isNull(); + } +} diff --git a/cygnus-lib/src/main/java/lib/constants/ApplicationMessage.java b/cygnus-lib/src/main/java/lib/constants/ApplicationMessage.java index 6c5c11f..341bd86 100644 --- a/cygnus-lib/src/main/java/lib/constants/ApplicationMessage.java +++ b/cygnus-lib/src/main/java/lib/constants/ApplicationMessage.java @@ -42,6 +42,15 @@ public enum ApplicationMessage { "The application details were saved successfully.", ""), APPLICATIONS_LOADED(200, "APP-2002", "Applications loaded", "The application records were loaded successfully.", ""), + DEDUPE_CHECK_COMPLETED(200, "DDP-2001", "Dedupe check completed", + "The dedupe check completed successfully.", ""), + DEDUPE_CHECK_FAILED(500, "DDP-5001", "Dedupe check failed", + "Cygnus could not complete the dedupe check.", + "Try again. If the issue continues, contact support."), + DEDUPE_DETAILS_LOADED(200, "DDP-2002", "Dedupe details loaded", + "Matching records were loaded successfully.", ""), + DEDUPE_DETAILS_SAVED(200, "DDP-2003", "Dedupe details saved", + "Dedupe remarks were saved successfully.", ""), APPLICATION_LOAD_FAILED(500, "APP-5002", "Applications could not be loaded", "Cygnus could not load the application details.", "Try again. If the issue continues, share the reference ID with support."), diff --git a/cygnus-lib/src/main/java/lib/models/Allocation.java b/cygnus-lib/src/main/java/lib/models/Allocation.java new file mode 100644 index 0000000..ddab486 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/Allocation.java @@ -0,0 +1,16 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +@Data +public class Allocation { + private List allocationlist = new ArrayList<>(); + private String allocTime; + private String errMsg; + private String errDesc; + private String errCode; + private String sessUUID; + private boolean processFlag; +} diff --git a/cygnus-lib/src/main/java/lib/models/CaseGrid.java b/cygnus-lib/src/main/java/lib/models/CaseGrid.java new file mode 100644 index 0000000..9f7d230 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/CaseGrid.java @@ -0,0 +1,13 @@ +package lib.models; + +import lombok.Data; + +@Data +public class CaseGrid { + private String errMsg; + private String errDesc; + private String errCode; + private boolean processFlag; + private String portfolioId; + private String caseID; +} diff --git a/cygnus-lib/src/main/java/lib/models/CutOffList.java b/cygnus-lib/src/main/java/lib/models/CutOffList.java new file mode 100644 index 0000000..3b1566c --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/CutOffList.java @@ -0,0 +1,17 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +@Data +public class CutOffList { + private List cofflist = new ArrayList<>(); + private String cutoffTime; + private String batch; + private String errMsg; + private String errDesc; + private String errCode; + private String sessUUID; + private boolean processFlag; +} diff --git a/cygnus-lib/src/main/java/lib/models/CutOffRecord.java b/cygnus-lib/src/main/java/lib/models/CutOffRecord.java new file mode 100644 index 0000000..7778eb9 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/CutOffRecord.java @@ -0,0 +1,41 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Data; + +@Data +public class CutOffRecord { + private List sublist = new ArrayList<>(); + private String portfolioid; + private String portname; + private String customername; + private String apptype; + private String mvcode; + private String applno; + private boolean allocation; + private boolean sms; + private boolean telesheet; + private boolean earlier; + private boolean negative; + private int islocked; + private String lockedby; + private boolean docut; + private int ischanged; + private int totrv; + private int totov; + private int totpv; + private int totrtv; + private int tototv; + private int totref; + private boolean tv; + private boolean oprsend; + private String resiloc; + private String offloc; + private String proploc; + private String uuid; + private String repformat; + private String repfunction; + private String message; + private String portgroup; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeBatch.java b/cygnus-lib/src/main/java/lib/models/DedupeBatch.java new file mode 100644 index 0000000..1a8fa11 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeBatch.java @@ -0,0 +1,21 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class DedupeBatch { + private List cases = new ArrayList<>(); + private String cutoffKey; + private String cutoffon; + private int totalAddresses; + private int totalCases; + private int islocked; + private String lockedby; + private Integer lockOwnerId; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeCase.java b/cygnus-lib/src/main/java/lib/models/DedupeCase.java new file mode 100644 index 0000000..d5ea6f1 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeCase.java @@ -0,0 +1,22 @@ +package lib.models; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class DedupeCase { + private String mvcode; + private String applno; + private String customername; + private String apptype; + private String uuid; + private int totrv; + private int totov; + private int totpv; + private String earlier; + private String negative; + private String lockedby; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeCaseSummary.java b/cygnus-lib/src/main/java/lib/models/DedupeCaseSummary.java new file mode 100644 index 0000000..7bbd558 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeCaseSummary.java @@ -0,0 +1,20 @@ +package lib.models; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class DedupeCaseSummary { + private String documentCaseId; + private Integer portfolioId; + private String mvCode; + private String fileNumber; + private String customerName; + private String applicationType; + private int residenceVisits; + private int officeVisits; + private int propertyVisits; + private String receivedOn; + private String done; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeCheckData.java b/cygnus-lib/src/main/java/lib/models/DedupeCheckData.java new file mode 100644 index 0000000..d2dc190 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeCheckData.java @@ -0,0 +1,3 @@ +package lib.models; + +public record DedupeCheckData(String documentCaseId, int operation) { } diff --git a/cygnus-lib/src/main/java/lib/models/DedupeCheckRequest.java b/cygnus-lib/src/main/java/lib/models/DedupeCheckRequest.java new file mode 100644 index 0000000..0681579 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeCheckRequest.java @@ -0,0 +1,3 @@ +package lib.models; + +public record DedupeCheckRequest(String documentCaseId, int operation) { } diff --git a/cygnus-lib/src/main/java/lib/models/DedupeDetails.java b/cygnus-lib/src/main/java/lib/models/DedupeDetails.java new file mode 100644 index 0000000..c30fa76 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeDetails.java @@ -0,0 +1,20 @@ +package lib.models; + +import lombok.Data; + +@Data +public class DedupeDetails { + private String sessuuid; + private String uuid; + private String mvcode; + private String customername; + private String dob; + private String mobile; + private String resiaddress; + private String offaddress; + private String resiphone; + private String offphone; + private String earremarks; + private String negremarks; + private String category; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeMatchRecord.java b/cygnus-lib/src/main/java/lib/models/DedupeMatchRecord.java new file mode 100644 index 0000000..7726a88 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeMatchRecord.java @@ -0,0 +1,17 @@ +package lib.models; + +import lombok.Data; + +@Data +public class DedupeMatchRecord { + private String dedupeType; + private String foundOn; + private String remarks; + private String customerName; + private String dob; + private String residenceAddress; + private String officeAddress; + private String residencePhone; + private String officePhone; + private String mobile; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeRun.java b/cygnus-lib/src/main/java/lib/models/DedupeRun.java new file mode 100644 index 0000000..4ae803a --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeRun.java @@ -0,0 +1,17 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class DedupeRun { + private List batches = new ArrayList<>(); + private String dedcutTime; + private String errMsg; + private String csrfToken; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeSendCase.java b/cygnus-lib/src/main/java/lib/models/DedupeSendCase.java new file mode 100644 index 0000000..9420ea6 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeSendCase.java @@ -0,0 +1,21 @@ +package lib.models; + +import lombok.Data; + +@Data +public class DedupeSendCase { + private String uuid; + private String mvcode; + private String applno; + private String customername; + private String apptype; + private String product; + private String earlier; + private String negative; + private String deduperunon; + private String bkbranchname; + private String fid; + private int dqid; + private String portname; + private String supervisor; +} diff --git a/cygnus-lib/src/main/java/lib/models/DedupeWorkspace.java b/cygnus-lib/src/main/java/lib/models/DedupeWorkspace.java new file mode 100644 index 0000000..76f2e90 --- /dev/null +++ b/cygnus-lib/src/main/java/lib/models/DedupeWorkspace.java @@ -0,0 +1,16 @@ +package lib.models; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class DedupeWorkspace { + private Integer portfolioId; + private List