From 9a0abfdc8bb5d6ad10248460d0098b8f96aae658 Mon Sep 17 00:00:00 2001 From: Skippy Williams Date: Thu, 19 Jun 2025 18:32:38 -0700 Subject: [PATCH] Remove submit and status apps Simplify onboarding by removing the submit and status apps. We won't use those in this project. --- ONBOARDING.md | 13 - direct-file/status/.dockerignore | 4 - direct-file/status/.gitignore | 43 - direct-file/status/.liquibase.properties | 5 - .../.mvn/wrapper/maven-wrapper.properties | 19 - direct-file/status/Dockerfile-local | 56 -- direct-file/status/README.md | 86 -- direct-file/status/localrun.sh | 2 - direct-file/status/mvnw | 259 ------ direct-file/status/mvnw.cmd | 149 --- direct-file/status/pom.xml | 174 ---- .../directfile/status/StatusApplication.java | 37 - .../AcknowledgementController.java | 212 ----- .../AcknowledgementService.java | 593 ------------ .../CompletedAcknowledgementRepository.java | 14 - .../PendingAcknowledgementRepository.java | 18 - .../TaxReturnSubmissionRepository.java | 48 - .../domain/AcknowledgementStatus.java | 24 - .../status/acknowledgement/domain/Status.java | 8 - .../status/config/AWSClientConfiguration.java | 13 - .../config/AWSCredentialsConfiguration.java | 34 - .../config/EncryptionClientConfiguration.java | 46 - .../config/EncryptionConfiguration.java | 20 - .../config/MessageQueueConfiguration.java | 42 - .../status/config/SnsClientConfiguration.java | 29 - .../status/config/SnsConfiguration.java | 32 - .../status/config/SqsClientConfiguration.java | 27 - .../status/config/StatusProperties.java | 39 - .../status/domain/AcknowledgementWrapper.java | 51 -- .../domain/AcknowledgementsListWrapper.java | 23 - .../directfile/status/domain/Completed.java | 48 - .../irs/directfile/status/domain/Error.java | 45 - .../status/domain/GetAcksResultWrapper.java | 18 - .../irs/directfile/status/domain/Pending.java | 43 - .../status/domain/PodIdentifier.java | 30 - .../status/domain/TaxReturnSubmission.java | 40 - .../status/domain/ToolkitError.java | 30 - .../domain/ValidationErrorGrpWrapper.java | 22 - .../status/error/ErrorRepository.java | 7 - .../status/error/ToolkitErrorRepository.java | 9 - .../mef/client/ServiceContextWrapper.java | 18 - .../repository/PodIdentifierRepository.java | 14 - .../services/MessageQueueListenerService.java | 71 -- .../PendingSubmissionMessageRouter.java | 60 -- .../services/SqsConnectionSetupService.java | 67 -- .../services/StatusChangeMessageService.java | 70 -- .../services/StatusChangePublisher.java | 7 - .../services/StatusChangeSnsPublisher.java | 18 - .../services/StatusChangeSqsPublisher.java | 18 - .../SubmissionConfirmationMessageRouter.java | 63 -- .../SubmissionConfirmationHandler.java | 9 - .../SubmissionConfirmationV1Handler.java | 65 -- .../SubmissionConfirmationV2Handler.java | 68 -- .../UnsupportedMessageVersionHandler.java | 17 - .../pending/PendingSubmissionHandler.java | 8 - .../pending/PendingSubmissionV1Handler.java | 64 -- .../UnsupportedMessageVersionHandler.java | 17 - .../resources/application-development.yaml | 11 - .../main/resources/application-docker.yaml | 19 - .../src/main/resources/application.yaml | 98 -- .../status/src/main/resources/banner.txt | 32 - .../src/main/resources/db/changelog.yaml | 7 - .../migrations/000-initial-schema-status.yaml | 196 ---- .../20240102154200-add-created_at.yaml | 77 -- .../20240108152400-add-error-message.yaml | 18 - ...240108153300-delete-lob-error-message.yaml | 18 - ...100800-add-taxreturn-submission-table.yaml | 31 - .../20240401154901-add-indices.yaml | 40 - .../20240726130000-fk-completed-errror.yaml | 36 - ...-and-drop-tax-return-identifier-table.yaml | 63 -- ...411151117000-add-pod-identifier-table.yaml | 29 - ...50104094800-add-pod-id-column-pending.yaml | 18 - .../status/src/main/resources/logback.xml | 22 - .../AcknowledgementControllerTest.java | 423 --------- .../AcknowledgementServiceTest.java | 859 ------------------ .../AcknowledgementServiceWithMocksTest.java | 130 --- ...ompletedAcknowledgementRepositoryTest.java | 156 ---- .../PendingAcknowledgementRepositoryTest.java | 143 --- .../TaxReturnSubmissionRepositoryTest.java | 42 - .../AWSCredentialsConfigurationTest.java | 51 -- .../EncryptionClientConfigurationTest.java | 32 - .../config/SnsClientConfigurationTest.java | 51 -- .../config/SnsClientTestConfiguration.java | 34 - .../config/SqsClientConfigurationTest.java | 54 -- .../status/error/ErrorRepositoryTest.java | 122 --- .../error/ToolkitErrorRepositoryTest.java | 78 -- .../status/extension/BatchUtil.java | 17 - .../status/extension/LoggerExtension.java | 105 --- .../MessageQueueListenerServiceTest.java | 133 --- .../PendingSubmissionMessageRouterTest.java | 84 -- .../StatusChangeMessageServiceTest.java | 108 --- ...bmissionConfirmationMessageRouterTest.java | 112 --- .../SubmissionConfirmationV1HandlerTest.java | 84 -- .../SubmissionConfirmationV2HandlerTest.java | 117 --- .../PendingSubmissionV1HandlerTest.java | 82 -- .../test/resources/application-default.yaml | 38 - .../test/resources/config/logging.properties | 2 - direct-file/submit/.dockerignore | 5 - direct-file/submit/.gitignore | 45 - direct-file/submit/.liquibase.properties | 5 - .../.mvn/wrapper/maven-wrapper.properties | 19 - direct-file/submit/Dockerfile-local | 54 -- direct-file/submit/README.md | 186 ---- direct-file/submit/mvnw | 259 ------ direct-file/submit/mvnw.cmd | 149 --- direct-file/submit/pom.xml | 194 ---- .../directfile/submit/BatchingProperties.java | 23 - .../gov/irs/directfile/submit/Runner.java | 63 -- .../directfile/submit/SubmitApplication.java | 19 - .../irs/directfile/submit/SubmitService.java | 60 -- .../submit/actions/ActionContext.java | 36 - .../submit/actions/ActionException.java | 16 - .../actions/BundleArchivesActionHandler.java | 67 -- .../submit/actions/CleanupActionHandler.java | 95 -- .../actions/CreateArchiveActionHandler.java | 107 --- .../directfile/submit/actions/IAction.java | 5 - .../BundleArchiveActionException.java | 28 - .../CreateArchiveActionException.java | 13 - .../exception/SubmissionFailureException.java | 19 - .../results/BundleArchivesActionResult.java | 14 - .../actions/results/CleanupActionResult.java | 3 - .../results/CreateArchiveActionResult.java | 20 - .../SubmissionFailureActionResult.java | 14 - .../irs/directfile/submit/command/Action.java | 6 - .../directfile/submit/command/ActionType.java | 9 - .../submit/command/BundleArchiveAction.java | 18 - .../submit/command/CleanupAction.java | 17 - .../submit/command/CreateArchiveAction.java | 17 - .../command/SubmissionFailureAction.java | 17 - .../submit/command/SubmitBundleAction.java | 18 - .../submit/config/AWSClientConfig.java | 13 - .../submit/config/AWSCredentialsConfig.java | 35 - .../submit/config/ActionContextConfig.java | 21 - .../submit/config/ActionQueueConfig.java | 24 - .../submit/config/BatchingConfiguration.java | 36 - .../irs/directfile/submit/config/Config.java | 32 - .../submit/config/DirectoriesConfig.java | 15 - .../submit/config/DocumentStoreConfig.java | 21 - .../submit/config/EncryptionClientConfig.java | 46 - .../submit/config/EncryptionConfig.java | 20 - .../submit/config/IntervalsConfig.java | 10 - .../submit/config/KeystoreConfig.java | 12 - .../submit/config/MessageQueueConfig.java | 28 - .../submit/config/S3StorageClientConfig.java | 170 ---- .../submit/config/SnsClientConfiguration.java | 30 - .../directfile/submit/config/SnsConfig.java | 23 - .../submit/config/SqsClientConfiguration.java | 28 - .../directfile/submit/domain/ActionQueue.java | 20 - .../submit/domain/BundledArchives.java | 26 - .../submit/domain/DocumentStoreResource.java | 14 - .../domain/SendSubmissionsResultWrapper.java | 43 - .../domain/SubmissionArchiveContainer.java | 18 - .../submit/domain/SubmissionBatch.java | 18 - .../submit/domain/SubmissionData.java | 29 - .../domain/SubmissionReceiptGrpWrapper.java | 30 - .../submit/domain/SubmittedDataContainer.java | 72 -- .../submit/domain/UserContextData.java | 48 - .../submit/domain/UserSubmission.java | 21 - .../submit/domain/model/PodIdentifier.java | 30 - .../StorageLocationBuilder.java | 31 - .../exception/LoginFailureException.java | 15 - .../exception/LogoutFailureException.java | 15 - .../DocumentStorageBatchRepository.java | 185 ---- .../repository/PodIdentifierRepository.java | 14 - .../interfaces/IBatchRepository.java | 18 - .../submit/service/ActionHandler.java | 322 ------- .../submit/service/DirectoryCreator.java | 38 - .../submit/service/DispatchMessageRouter.java | 59 -- ...cumentStorageSubmissionFailureService.java | 140 --- .../submit/service/ErrorBatchPoller.java | 104 --- .../service/LocalWriteUtilityService.java | 62 -- .../submit/service/OfflineModeService.java | 35 - ...eTestingBundleSubmissionActionHandler.java | 99 -- .../service/SqsConnectionSetupService.java | 122 --- .../SubmissionConfirmationMessageService.java | 73 -- .../SubmissionConfirmationPublisher.java | 7 - .../SubmissionConfirmationSnsPublisher.java | 18 - .../SubmissionConfirmationSqsPublisher.java | 18 - .../service/SynchronousS3StorageService.java | 198 ---- .../service/UserSubmissionBatchAssembler.java | 89 -- .../service/UserSubmissionBatchProcessor.java | 78 -- .../service/UserSubmissionConsumer.java | 54 -- .../handlers/dispatch/DispatchHandler.java | 9 - .../handlers/dispatch/DispatchV1Handler.java | 28 - .../UnsupportedMessageVersionHandler.java | 16 - .../IBundleSubmissionActionHandler.java | 21 - .../submit/service/interfaces/IService.java | 7 - .../interfaces/ISubmissionFailureService.java | 11 - .../ISynchronousDocumentStoreService.java | 28 - ...BatchProcessingApplicationStartRunner.java | 37 - ...MefConnectivityApplicationStartRunner.java | 29 - .../resources/application-development.yaml | 7 - .../main/resources/application-docker.yaml | 31 - .../src/main/resources/application.yaml | 112 --- .../submit/src/main/resources/banner.txt | 32 - .../src/main/resources/db/changelog.yaml | 7 - .../db/migrations/000-initial-schema.yaml | 19 - .../migrations/20240119123900-app-id-add.yaml | 26 - .../2024012395500-sub-app-table.yaml | 26 - ...411151120000-add-pod-identifier-table.yaml | 29 - .../submit/src/main/resources/logback.xml | 22 - .../submit/ApplicationContextTest.java | 31 - .../submit/LibsProofOfConceptTest.java | 20 - .../BundleArchivesActionHandlerTest.java | 240 ----- ...undleArchiveActionActionExceptionTest.java | 27 - .../config/AWSCredentialsConfigTest.java | 52 -- .../config/EncryptionClientConfigTest.java | 29 - .../config/S3StorageClientConfigTest.java | 73 -- .../config/SnsClientConfigurationTest.java | 45 - .../config/SnsClientTestConfiguration.java | 34 - .../config/SqsClientConfigurationTest.java | 44 - .../SynchronousS3TestConfiguration.java | 23 - .../domain/SubmittedDataContainerTest.java | 152 ---- .../submit/domain/UserSubmissionTest.java | 31 - .../StorageLocationBuilderTest.java | 37 - .../submit/extension/LoggerExtension.java | 96 -- ...FakeSynchronousDocumentStorageService.java | 153 ---- .../submit/mocks/MutableTestClock.java | 65 -- ...ThrowingBundleSubmissionActionHandler.java | 56 -- .../mocks/ThrowingInformerException.java | 7 - .../submit/service/ActionHandlerTest.java | 588 ------------ .../service/DispatchMessageRouterTest.java | 79 -- .../DocumentStorageBatchRepositoryTest.java | 349 ------- ...ntStorageSubmissionFailureServiceTest.java | 109 --- .../ErrorBatchPollerIntegrationTest.java | 174 ---- .../submit/service/ErrorBatchPollerTest.java | 141 --- .../service/ErrorHandlingIntegrationTest.java | 343 ------- .../MefBundleSubmissionServiceTest.java | 188 ---- .../SqsConnectionSetupServiceTest.java | 114 --- ...missionConfirmationMessageServiceTest.java | 123 --- .../SynchronousS3StorageServiceTest.java | 89 -- .../UserSubmissionBatchAssemblerTest.java | 83 -- .../UserSubmissionBatchProcessorTest.java | 98 -- .../service/UserSubmissionConsumerTest.java | 76 -- .../dispatch/DispatchV1HandlerTest.java | 51 -- ...onnectivityApplicationStartRunnerTest.java | 32 - .../test/resources/application-default.yml | 56 -- .../test/resources/config/logging.properties | 2 - 238 files changed, 15592 deletions(-) delete mode 100644 direct-file/status/.dockerignore delete mode 100644 direct-file/status/.gitignore delete mode 100644 direct-file/status/.liquibase.properties delete mode 100644 direct-file/status/.mvn/wrapper/maven-wrapper.properties delete mode 100644 direct-file/status/Dockerfile-local delete mode 100644 direct-file/status/README.md delete mode 100755 direct-file/status/localrun.sh delete mode 100755 direct-file/status/mvnw delete mode 100644 direct-file/status/mvnw.cmd delete mode 100644 direct-file/status/pom.xml delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/StatusApplication.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementController.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementService.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/AcknowledgementStatus.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/Status.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSClientConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSCredentialsConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionClientConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/MessageQueueConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsClientConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/SqsClientConfiguration.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/config/StatusProperties.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementWrapper.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementsListWrapper.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/Completed.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/Error.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/GetAcksResultWrapper.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/Pending.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/PodIdentifier.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/TaxReturnSubmission.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/ToolkitError.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/domain/ValidationErrorGrpWrapper.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/error/ErrorRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/error/ToolkitErrorRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/mef/client/ServiceContextWrapper.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/repository/PodIdentifierRepository.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/MessageQueueListenerService.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouter.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/SqsConnectionSetupService.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeMessageService.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangePublisher.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSnsPublisher.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSqsPublisher.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouter.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationHandler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1Handler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2Handler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/UnsupportedMessageVersionHandler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionHandler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1Handler.java delete mode 100644 direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/UnsupportedMessageVersionHandler.java delete mode 100644 direct-file/status/src/main/resources/application-development.yaml delete mode 100644 direct-file/status/src/main/resources/application-docker.yaml delete mode 100644 direct-file/status/src/main/resources/application.yaml delete mode 100644 direct-file/status/src/main/resources/banner.txt delete mode 100644 direct-file/status/src/main/resources/db/changelog.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/000-initial-schema-status.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240102154200-add-created_at.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240108152400-add-error-message.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240108153300-delete-lob-error-message.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240112100800-add-taxreturn-submission-table.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240401154901-add-indices.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20240726130000-fk-completed-errror.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20241107100000-drop-unused-columns-from-completed-and-pending-tables-and-drop-tax-return-identifier-table.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/202411151117000-add-pod-identifier-table.yaml delete mode 100644 direct-file/status/src/main/resources/db/migrations/20250104094800-add-pod-id-column-pending.yaml delete mode 100644 direct-file/status/src/main/resources/logback.xml delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementControllerTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceWithMocksTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepositoryTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepositoryTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepositoryTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/config/AWSCredentialsConfigurationTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/config/EncryptionClientConfigurationTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientConfigurationTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientTestConfiguration.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/config/SqsClientConfigurationTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/error/ErrorRepositoryTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/error/ToolkitErrorRepositoryTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/extension/BatchUtil.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/extension/LoggerExtension.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/MessageQueueListenerServiceTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouterTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/StatusChangeMessageServiceTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouterTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1HandlerTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2HandlerTest.java delete mode 100644 direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1HandlerTest.java delete mode 100644 direct-file/status/src/test/resources/application-default.yaml delete mode 100644 direct-file/status/src/test/resources/config/logging.properties delete mode 100644 direct-file/submit/.dockerignore delete mode 100644 direct-file/submit/.gitignore delete mode 100644 direct-file/submit/.liquibase.properties delete mode 100644 direct-file/submit/.mvn/wrapper/maven-wrapper.properties delete mode 100644 direct-file/submit/Dockerfile-local delete mode 100644 direct-file/submit/README.md delete mode 100755 direct-file/submit/mvnw delete mode 100644 direct-file/submit/mvnw.cmd delete mode 100644 direct-file/submit/pom.xml delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/BatchingProperties.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/Runner.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitApplication.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionContext.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CleanupActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CreateArchiveActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/IAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/CreateArchiveActionException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/SubmissionFailureException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/BundleArchivesActionResult.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CleanupActionResult.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CreateArchiveActionResult.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/SubmissionFailureActionResult.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/Action.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/ActionType.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/BundleArchiveAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CleanupAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CreateArchiveAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmissionFailureAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmitBundleAction.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSClientConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSCredentialsConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionContextConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionQueueConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/BatchingConfiguration.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/Config.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DirectoriesConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DocumentStoreConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionClientConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/IntervalsConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/KeystoreConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/MessageQueueConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/S3StorageClientConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsClientConfiguration.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsConfig.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SqsClientConfiguration.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/ActionQueue.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/BundledArchives.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/DocumentStoreResource.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SendSubmissionsResultWrapper.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionArchiveContainer.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionBatch.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionData.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionReceiptGrpWrapper.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmittedDataContainer.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserContextData.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserSubmission.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/model/PodIdentifier.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilder.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LoginFailureException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LogoutFailureException.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/DocumentStorageBatchRepository.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/PodIdentifierRepository.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/interfaces/IBatchRepository.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DirectoryCreator.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DispatchMessageRouter.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ErrorBatchPoller.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/LocalWriteUtilityService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/OfflineModeService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/PerformanceTestingBundleSubmissionActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SqsConnectionSetupService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationPublisher.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSnsPublisher.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSqsPublisher.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SynchronousS3StorageService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssembler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessor.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionConsumer.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1Handler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/UnsupportedMessageVersionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IBundleSubmissionActionHandler.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISubmissionFailureService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISynchronousDocumentStoreService.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/BatchProcessingApplicationStartRunner.java delete mode 100644 direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunner.java delete mode 100644 direct-file/submit/src/main/resources/application-development.yaml delete mode 100644 direct-file/submit/src/main/resources/application-docker.yaml delete mode 100644 direct-file/submit/src/main/resources/application.yaml delete mode 100644 direct-file/submit/src/main/resources/banner.txt delete mode 100644 direct-file/submit/src/main/resources/db/changelog.yaml delete mode 100644 direct-file/submit/src/main/resources/db/migrations/000-initial-schema.yaml delete mode 100644 direct-file/submit/src/main/resources/db/migrations/20240119123900-app-id-add.yaml delete mode 100644 direct-file/submit/src/main/resources/db/migrations/2024012395500-sub-app-table.yaml delete mode 100644 direct-file/submit/src/main/resources/db/migrations/202411151120000-add-pod-identifier-table.yaml delete mode 100644 direct-file/submit/src/main/resources/logback.xml delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/ApplicationContextTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/LibsProofOfConceptTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandlerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionActionExceptionTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/AWSCredentialsConfigTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/EncryptionClientConfigTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/S3StorageClientConfigTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientConfigurationTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientTestConfiguration.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SqsClientConfigurationTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SynchronousS3TestConfiguration.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/SubmittedDataContainerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/UserSubmissionTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilderTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/extension/LoggerExtension.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/FakeSynchronousDocumentStorageService.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/MutableTestClock.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingBundleSubmissionActionHandler.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingInformerException.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ActionHandlerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DispatchMessageRouterTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageBatchRepositoryTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureServiceTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerIntegrationTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorHandlingIntegrationTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/MefBundleSubmissionServiceTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SqsConnectionSetupServiceTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageServiceTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SynchronousS3StorageServiceTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssemblerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessorTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionConsumerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1HandlerTest.java delete mode 100644 direct-file/submit/src/test/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunnerTest.java delete mode 100644 direct-file/submit/src/test/resources/application-default.yml delete mode 100644 direct-file/submit/src/test/resources/config/logging.properties diff --git a/ONBOARDING.md b/ONBOARDING.md index c0d9a4c..10361ef 100644 --- a/ONBOARDING.md +++ b/ONBOARDING.md @@ -313,21 +313,8 @@ Most of the project dependencies can be installed using [SDKMAN!](https://sdkman export LOCAL_WRAPPING_KEY="9mteZFY+gIVfMFywgvpLpyVl+8UIcNoIWpGaHX4jDFU=" export MEF_SOFTWARE_ID="[mef-software-id]" export MEF_SOFTWARE_VERSION_NUM="2023.0.1" - export STATUS_ASID="[status-asid]" - export STATUS_EFIN="[status-efin]" - export STATUS_ETIN="[status-etin]" - export SUBMIT_ASID=$STATUS_ASID - export SUBMIT_EFIN=$STATUS_EFIN - export SUBMIT_ETIN=$STATUS_ETIN export DF_TIN_VALIDATION_ENABLED=false export DF_EMAIL_VALIDATION_ENABLED=false - export STATUS_KEYSTOREALIAS="[keystore-alias]" - export STATUS_KEYSTOREBASE64="[base64-encoded-keystore]" - export STATUS_KEYSTOREPASSWORD="[keystore-password]" - export SUBMIT_KEYSTORE_KEYSTOREALIAS=$STATUS_KEYSTOREALIAS - export SUBMIT_KEYSTORE_KEYSTOREBASE64=$STATUS_KEYSTOREBASE64 - export SUBMIT_KEYSTORE_KEYSTOREPASSWORD=$STATUS_KEYSTOREPASSWORD - export SUBMIT_ID_VAR_CHARS="zz" export GIT_COMMIT_HASH="$(cd /path/to/direct-file && git rev-parse --short main)" ``` diff --git a/direct-file/status/.dockerignore b/direct-file/status/.dockerignore deleted file mode 100644 index 0e421fd..0000000 --- a/direct-file/status/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -**/application-local.* -.env* -.git/ -Dockerfile* diff --git a/direct-file/status/.gitignore b/direct-file/status/.gitignore deleted file mode 100644 index e57ef53..0000000 --- a/direct-file/status/.gitignore +++ /dev/null @@ -1,43 +0,0 @@ -HELP.md -target/ -!**/src/main/**/target/ -!**/src/test/**/target/ -*.jar -/src/main/resources/spotbugs/output/spotbugs.xml - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ - -### Special ### -/src/main/resources/application-local.* -src/test/resources/private.p12 -src/test/resources/private.p12 - -### Gradle ### -/.gradle/ -/build/ diff --git a/direct-file/status/.liquibase.properties b/direct-file/status/.liquibase.properties deleted file mode 100644 index eb1cc2b..0000000 --- a/direct-file/status/.liquibase.properties +++ /dev/null @@ -1,5 +0,0 @@ -changeLogFile=db/changelog.yaml -url=jdbc:postgresql://localhost:32768/directfile-status -username=postgres -password=postgres -changesetAuthor=directfile \ No newline at end of file diff --git a/direct-file/status/.mvn/wrapper/maven-wrapper.properties b/direct-file/status/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 23c7e59..0000000 --- a/direct-file/status/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -wrapperVersion=3.3.2 -distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip diff --git a/direct-file/status/Dockerfile-local b/direct-file/status/Dockerfile-local deleted file mode 100644 index fc301d5..0000000 --- a/direct-file/status/Dockerfile-local +++ /dev/null @@ -1,56 +0,0 @@ -#syntax=docker/dockerfile:1.7-labs -# build factgraph since it will be a dependency in share-libs-builder -FROM sbtscala/scala-sbt:eclipse-temurin-alpine-21.0.2_13_1.9.9_3.3.3 AS factgraph-builder -WORKDIR /build/ -COPY --from=factgraph-repo js/src/ js/src/ -COPY --from=factgraph-repo jvm/src/ jvm/src/ -COPY --from=factgraph-repo project/build.properties project/plugins.sbt project/ -COPY --from=factgraph-repo shared/ shared/ -COPY --from=factgraph-repo build.sbt . -RUN sbt compile package publishM2 - -# build shared dependencies -FROM eclipse-temurin:21-jdk-alpine AS shared-dependencies-builder -COPY --from=factgraph-builder /root/.m2/repository/gov/irs/factgraph/fact-graph_3/ /root/.m2/repository/gov/irs/factgraph/fact-graph_3/ -ARG MAVEN_OPTS="" -WORKDIR /build/ -COPY --from=config . ./config/ -COPY --from=boms . ./boms/ -WORKDIR /build/libs/ -COPY --from=shared-libs .mvn/wrapper/maven-wrapper.properties .mvn/wrapper/ -COPY --from=shared-libs mvnw ./ -COPY --from=shared-libs --parents **/pom.xml ./ -RUN ./mvnw dependency:resolve -P resolve -COPY --from=shared-libs starters/ ./starters/ -COPY --from=shared-libs data-models/ ./data-models/ -RUN ./mvnw install - - -# build mef-status -FROM shared-dependencies-builder AS mef-status-builder -ARG MAVEN_OPTS="" -ENV MEF_REPO /mef-client-sdk -ENV A2A_TOOLKIT_HOME /${MEF_REPO}/MeF_Client_SDK/Java/source/ -ENV LOCALSTACK_INTEGRATION_TESTS_ENABLED false -COPY --from=mef-sdk-repo MeF_Client_SDK/ /${MEF_REPO}/MeF_Client_SDK/ -COPY --from=config . /config/ -WORKDIR /build/ -COPY --from=scripts install-mef-sdk.sh ./ -COPY mvnw pom.xml ./ -COPY .mvn/wrapper/maven-wrapper.properties .mvn/wrapper/ -RUN ./install-mef-sdk.sh -RUN ./mvnw dependency:resolve -COPY src/ src/ -RUN ./mvnw package - -FROM eclipse-temurin:21-jre-alpine -ENV LOCAL_WRAPPING_KEY "${LOCAL_WRAPPING_KEY:-oE3Pm+fr1I+YbX2ZxEe/n9INqJjy00KSl7oXXW4p5Xw=}" -COPY --from=mef-status-builder /build/target/mef-status-0.0.1-SNAPSHOT.jar /app.jar -COPY --from=mef-sdk-repo MeF_Client_SDK/Java/source/ /mef-client-sdk-src/ -# Run from dir that allows mef-sdk to write it's files to the working directory (next iteration: configure mef-sdk) -RUN adduser --system --no-create-home jar-runner && \ - mkdir -p /jar-run && \ - chown jar-runner /jar-run -WORKDIR /jar-run -USER jar-runner -CMD ["java", "-jar", "/app.jar"] diff --git a/direct-file/status/README.md b/direct-file/status/README.md deleted file mode 100644 index d5a6c90..0000000 --- a/direct-file/status/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# MEF Status - -## About MeF Status -The MeF Status application's job is to: -- Regularly poll MeF to learn about the status of each submitted tax return, until we recieve a final status. A final status is one that will not change: Accepted, Rejected, or an error that will not get resolved without intervention. -- Save the final status for each tax return where it can be accessed by the backend application - -### How it works - -- At the time a tax return is submitted, the mef-submit app creates a submission ID and notifies the status application via message queue that there is a new tax return to begin polling for. -- MeF status periodically queries the status database to find a list of pending tax returns. -- MeF status (this application) then queries MeF (the external API) for batches of those returns. When it receives a final response from MeF (generally "accepted" or "rejected") for any one of those returns, it saves the results to the status database. Returns that remain in pending status will be polled for at the next interval. - -## Setup - -> [!NOTE] -> For setup please see the most up-to-date instructions which are found in the [Onboarding docs](../../ONBOARDING.md). - -### MeF SDK - -2. Once you have that variable set, run the -build-project.sh script from the -`submit` folder of the direct_file project. - - -### Proxy -If you use a proxy, first see `MAVEN_OPTS` in [the project readme](../README.md#important-configuration-variables) and [the OMB Connect readme](../README-omb-connect.md) for information about ensuring your proxy settings are passed to all build steps. - -## Docker - -Ensure you have the environment variables set (see [Environment](#environment) below). -You may be able to run with only `STATUS_ETIN` set, using the test value from the [submit README](../backend/README.md). - -Build the application: - -```bash -docker compose build -``` - -Then run it: - -```bash -docker compose up -d mef-status -``` - -The app probably failed for you due to lack of configuration. You can look at the reason why it failed to start with: - -```bash -docker compose logs mef-status -``` - - -## Running locally - -### Environment - -Set the following environment variables in your local environment which will facilitate running both the applications as well as the docker containers. On macbooks, placing the export statements below in the `.zshrc` (gets run and evaluated everytime a shell instance is started) or `.zprofile` (gets run and evaluated when a user logs in) file will accomplish this. If using the bash shell, placing them in `.bashrc` should do (and effectively behave similar to `.zshrc`). - -``` -# Get the keystore alias from a fellow developer and replace the value in between quotes with the actual value -export STATUS_KEYSTOREALIAS="[keystore-alias]" - -# Get the base64 encoded keystore from a fellow developer and replace the value in between quotes with the actual value -export STATUS_KEYSTOREBASE64="[base64-encoded-keystore]" - -# Get the keystore password from a fellow developer and replace the value in between quotes with the actual value -export STATUS_KEYSTOREPASSWORD="[keystore-password]" - -# Get the ASID value for the status application from a fellow developer and replace the value in between quotes with the actual value -export STATUS_ASID="[status-asid]" - -# Get the EFIN value for the status application from a fellow developer and replace the value in between quotes with the actual value -export STATUS_EFIN="[status-efin]" - -# Get the ETIN value for the status application from a fellow developer and replace the value in between quotes with the actual value -export STATUS_ETIN="[status-etin]" -``` - -You'll also need to set up the `LOCAL_WRAPPING_KEY` following the instructions in the [backend README](../backend/README.md#initial-setup) -``` -export LOCAL_WRAPPING_KEY="[local-wrapping-key]" -``` - -### Static Analysis: Spot Bugs and PMD -For notes and usage on spotbugs see the [Backend API README Spot Bugs section](../submit/README.md#static-analysis) - diff --git a/direct-file/status/localrun.sh b/direct-file/status/localrun.sh deleted file mode 100755 index 924f122..0000000 --- a/direct-file/status/localrun.sh +++ /dev/null @@ -1,2 +0,0 @@ -cd target -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001 -jar mef-status-0.0.1-SNAPSHOT.jar diff --git a/direct-file/status/mvnw b/direct-file/status/mvnw deleted file mode 100755 index 19529dd..0000000 --- a/direct-file/status/mvnw +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.2 -# -# Optional ENV vars -# ----------------- -# JAVA_HOME - location of a JDK home dir, required when download maven via java source -# MVNW_REPOURL - repo url base for downloading maven distribution -# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output -# ---------------------------------------------------------------------------- - -set -euf -[ "${MVNW_VERBOSE-}" != debug ] || set -x - -# OS specific support. -native_path() { printf %s\\n "$1"; } -case "$(uname)" in -CYGWIN* | MINGW*) - [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" - native_path() { cygpath --path --windows "$1"; } - ;; -esac - -# set JAVACMD and JAVACCMD -set_java_home() { - # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched - if [ -n "${JAVA_HOME-}" ]; then - if [ -x "$JAVA_HOME/jre/sh/java" ]; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - JAVACCMD="$JAVA_HOME/jre/sh/javac" - else - JAVACMD="$JAVA_HOME/bin/java" - JAVACCMD="$JAVA_HOME/bin/javac" - - if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then - echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 - echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 - return 1 - fi - fi - else - JAVACMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v java - )" || : - JAVACCMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v javac - )" || : - - if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then - echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 - return 1 - fi - fi -} - -# hash string like Java String::hashCode -hash_string() { - str="${1:-}" h=0 - while [ -n "$str" ]; do - char="${str%"${str#?}"}" - h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) - str="${str#?}" - done - printf %x\\n $h -} - -verbose() { :; } -[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - -die() { - printf %s\\n "$1" >&2 - exit 1 -} - -trim() { - # MWRAPPER-139: - # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. - # Needed for removing poorly interpreted newline sequences when running in more - # exotic environments such as mingw bash on Windows. - printf "%s" "${1}" | tr -d '[:space:]' -} - -# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties -while IFS="=" read -r key value; do - case "${key-}" in - distributionUrl) distributionUrl=$(trim "${value-}") ;; - distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; - esac -done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" - -case "${distributionUrl##*/}" in -maven-mvnd-*bin.*) - MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ - case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in - *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; - :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; - :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; - :Linux*x86_64*) distributionPlatform=linux-amd64 ;; - *) - echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 - distributionPlatform=linux-amd64 - ;; - esac - distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" - ;; -maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; -esac - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" -distributionUrlName="${distributionUrl##*/}" -distributionUrlNameMain="${distributionUrlName%.*}" -distributionUrlNameMain="${distributionUrlNameMain%-bin}" -MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" -MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" - -exec_maven() { - unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : - exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" -} - -if [ -d "$MAVEN_HOME" ]; then - verbose "found existing MAVEN_HOME at $MAVEN_HOME" - exec_maven "$@" -fi - -case "${distributionUrl-}" in -*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; -*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; -esac - -# prepare tmp dir -if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then - clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } - trap clean HUP INT TERM EXIT -else - die "cannot create temp dir" -fi - -mkdir -p -- "${MAVEN_HOME%/*}" - -# Download and Install Apache Maven -verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -verbose "Downloading from: $distributionUrl" -verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -# select .zip or .tar.gz -if ! command -v unzip >/dev/null; then - distributionUrl="${distributionUrl%.zip}.tar.gz" - distributionUrlName="${distributionUrl##*/}" -fi - -# verbose opt -__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' -[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v - -# normalize http auth -case "${MVNW_PASSWORD:+has-password}" in -'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; -has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; -esac - -if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then - verbose "Found wget ... using wget" - wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" -elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then - verbose "Found curl ... using curl" - curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" -elif set_java_home; then - verbose "Falling back to use Java to download" - javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" - targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" - cat >"$javaSource" <<-END - public class Downloader extends java.net.Authenticator - { - protected java.net.PasswordAuthentication getPasswordAuthentication() - { - return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); - } - public static void main( String[] args ) throws Exception - { - setDefault( new Downloader() ); - java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); - } - } - END - # For Cygwin/MinGW, switch paths to Windows format before running javac and java - verbose " - Compiling Downloader.java ..." - "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" - verbose " - Running Downloader.java ..." - "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" -fi - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -if [ -n "${distributionSha256Sum-}" ]; then - distributionSha256Result=false - if [ "$MVN_CMD" = mvnd.sh ]; then - echo "Checksum validation is not supported for maven-mvnd." >&2 - echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - elif command -v shasum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 - echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - fi - if [ $distributionSha256Result = false ]; then - echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 - echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 - exit 1 - fi -fi - -# unzip and move -if command -v unzip >/dev/null; then - unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" -else - tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" -fi -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" - -clean || : -exec_maven "$@" diff --git a/direct-file/status/mvnw.cmd b/direct-file/status/mvnw.cmd deleted file mode 100644 index b150b91..0000000 --- a/direct-file/status/mvnw.cmd +++ /dev/null @@ -1,149 +0,0 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/direct-file/status/pom.xml b/direct-file/status/pom.xml deleted file mode 100644 index 0e097a6..0000000 --- a/direct-file/status/pom.xml +++ /dev/null @@ -1,174 +0,0 @@ - - - 4.0.0 - - gov.irs.directfile.boot - irs-spring-boot-starter-parent - 0.0.1-SNAPSHOT - ../boms/irs-spring-boot-starter-parent - - gov.irs.directfile.status - mef-status - 0.0.1-SNAPSHOT - MeF status - Status checking system for MeF - - - ${project.basedir}/../config - - - - org.springframework.boot - spring-boot-starter-actuator - - - com.google.guava - guava - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - true - - - org.postgresql - postgresql - runtime - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-starter-test - test - - - jakarta.xml.ws - jakarta.xml.ws-api - - - com.sun.xml.bind - jaxb-impl - - - com.sun.xml.ws - jaxws-rt - - - com.h2database - h2 - test - - - software.amazon.awssdk - sns - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - sqs - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - s3 - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - sts - - - commons-logging - commons-logging - - - - - gov.irs.directfile - data-models - - - org.liquibase - liquibase-core - - - com.amazonaws - amazon-sqs-java-messaging-lib - - - org.slf4j - slf4j-api - - - - - software.amazon.encryption.s3 - amazon-s3-encryption-client-java - - - net.logstash.logback - logstash-logback-encoder - runtime - - - com.github.spotbugs - spotbugs-annotations - - - - - - org.apache.maven.plugins - maven-site-plugin - - - 9898 - ${basedir}/target/site/tempdir - - - - org.apache.maven.plugins - maven-surefire-plugin - - -XX:+EnableDynamicAgentLoading ${argLine} - - - SPRING_PROFILES_ACTIVE - - - - - - - diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/StatusApplication.java b/direct-file/status/src/main/java/gov/irs/directfile/status/StatusApplication.java deleted file mode 100644 index 6145670..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/StatusApplication.java +++ /dev/null @@ -1,37 +0,0 @@ -package gov.irs.directfile.status; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.ConfigurationPropertiesScan; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Scope; - -import gov.irs.mef.services.msi.LoginClient; -import gov.irs.mef.services.msi.LogoutClient; -import gov.irs.mef.services.transmitter.mtom.GetAcksMTOMClient; - -@SpringBootApplication -@ConfigurationPropertiesScan -public class StatusApplication { - @Bean - @Scope("prototype") - public LoginClient loginClient() { - return new LoginClient(); - } - - @Bean - @Scope("prototype") - public GetAcksMTOMClient ackClient() { - return new GetAcksMTOMClient(); - } - - @Bean - @Scope("prototype") - public LogoutClient logoutClient() { - return new LogoutClient(); - } - - public static void main(String[] args) { - SpringApplication.run(StatusApplication.class, args); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementController.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementController.java deleted file mode 100644 index 00f8d12..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementController.java +++ /dev/null @@ -1,212 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.List; -import java.util.UUID; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.EntityNotFoundException; -import jakarta.servlet.http.HttpServletRequest; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.MDC; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import gov.irs.directfile.audit.AuditEventData; -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.AuditService; -import gov.irs.directfile.audit.events.Event; -import gov.irs.directfile.audit.events.EventId; -import gov.irs.directfile.audit.events.EventStatus; -import gov.irs.directfile.audit.events.SystemEventPrincipal; -import gov.irs.directfile.models.RejectedStatus; -import gov.irs.directfile.status.acknowledgement.domain.AcknowledgementStatus; - -@SuppressFBWarnings( - value = {"CRLF_INJECTION_LOGS"}, - justification = "Initial SpotBugs Setup") -@RestController -@Validated -@Slf4j -@RequestMapping("/status") -public class AcknowledgementController { - - private static String X_FORWARDED_FOR = "X-Forwarded-For"; - - @SuppressFBWarnings( - value = {"EI_EXPOSE_REP2"}, - justification = "constructor injection") - public AcknowledgementController(AcknowledgementService acknowledgementService) { - this.acknowledgementService = acknowledgementService; - } - - private final AcknowledgementService acknowledgementService; - private static final AuditService auditService = new AuditService(); - - @GetMapping() - public ResponseEntity get( - @RequestParam(name = "id") UUID taxReturnId, HttpServletRequest request) { - AuditEventData eventData = new AuditEventData(); - String submissionId = null; - try { - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - log.info(String.format("Request for taxReturnId %s", taxReturnId)); - MDC.clear(); - - submissionId = - acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(taxReturnId); - AcknowledgementStatus acknowledgementStatus = - acknowledgementService.GetAcknowledgement(taxReturnId, submissionId); - - submissionId = setSubmissionIdToUnknownStringIfItIsNullSoThatLogMessagesWillBeMoreClear(submissionId); - - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - log.info(String.format("Retrieved submissionId %s", submissionId)); - MDC.clear(); - - if (acknowledgementStatus == null) { - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData(eventData, AuditLogElement.taxReturnId, taxReturnId.toString()); - addValuesToEventData( - eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.NOT_FOUND.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - return new ResponseEntity(HttpStatus.NOT_FOUND); - } - // this will get logged everytime /status is hit, regardless of whether submissionId is found - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData(eventData, AuditLogElement.taxReturnId, taxReturnId.toString()); - addValuesToEventData(eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.OK.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.SUCCESS) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - return new ResponseEntity<>(acknowledgementStatus, HttpStatus.OK); - - } catch (Exception ex) { - eventData.put(AuditLogElement.eventErrorMessage, ex.getClass().getName()); - eventData.putDetail("errorMessage", ex.getMessage()); - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData(eventData, AuditLogElement.taxReturnId, taxReturnId.toString()); - addValuesToEventData( - eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.BAD_REQUEST.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - log.error(String.format("Error handling submission id %s", taxReturnId), ex); - MDC.clear(); - return new ResponseEntity(HttpStatus.BAD_REQUEST); - } finally { - MDC.clear(); - } - } - - @GetMapping("/rejection-codes") - public ResponseEntity> getRejectionCodes( - @RequestParam(name = "submissionId") String submissionId, HttpServletRequest request) { - AuditEventData eventData = new AuditEventData(); - try { - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.clear(); - - List rejectionCodes; - try { - rejectionCodes = acknowledgementService.getRejectionCodesForSubmissionId(submissionId); - } catch (EntityNotFoundException e) { - log.error(String.format("Could not find record for submission ID %s", submissionId), e); - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData( - eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.NOT_FOUND.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.clear(); - - // this will get logged everytime /status is hit, regardless of whether submissionId is found - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData(eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.OK.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.SUCCESS) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - return new ResponseEntity<>(rejectionCodes, HttpStatus.OK); - - } catch (Exception ex) { - eventData.put(AuditLogElement.eventErrorMessage, ex.getClass().getName()); - eventData.putDetail("errorMessage", ex.getMessage()); - addValuesToEventData(eventData, AuditLogElement.mefSubmissionId, submissionId); - addValuesToEventData( - eventData, AuditLogElement.responseStatusCode, String.valueOf(HttpStatus.BAD_REQUEST.value())); - - auditService.performLogFromEvent( - Event.builder() - .eventId(EventId.CHECK) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .build(), - eventData); - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - log.error(String.format("Error handling submission id %s", submissionId), ex); - MDC.clear(); - return new ResponseEntity<>(HttpStatus.BAD_REQUEST); - } finally { - MDC.clear(); - } - } - - private void addValuesToEventData(AuditEventData auditEventData, AuditLogElement key, String value) { - if (value != null) { - auditEventData.put(key, value); - } - } - - // This is a bit of workaround to make our log messages more clear. - // If submissionId is null, that means the status app could not find a submission associated with the given - // taxreturn in the TaxReturnSubmission table. - // If no submission was found in the TaxReturnSubmission, that likely means that the status app is still waiting for - // a message from the pending submission queue. - // There is currently some logic based on a config property in getAcknowledgementStatus. This logic causes - // GetAcknowledgement to return PENDING if submissionId is null, - // and the statusEndpointReturnsPendingByDefaultEnabled property is true (which it currently is in PROD). - // Without this workaround, submissionId will not appear in our logs, which was causing confusion. - // I am setting submissionId to NOT_YET_KNOWN so that we can have a more clear understanding of what is happening - // when we see our logs. - private String setSubmissionIdToUnknownStringIfItIsNullSoThatLogMessagesWillBeMoreClear(String submissionId) { - if (submissionId == null) { - return "NOT_YET_KNOWN"; - } else { - return submissionId; - } - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementService.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementService.java deleted file mode 100644 index ac74859..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/AcknowledgementService.java +++ /dev/null @@ -1,593 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.math.RoundingMode; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; - -import com.google.common.collect.Iterables; -import com.google.common.math.IntMath; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.EntityNotFoundException; -import jakarta.transaction.Transactional; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.MDC; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import gov.irs.mef.exception.ServiceException; -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.services.ServiceContext; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.models.RejectedStatus; -import gov.irs.directfile.status.acknowledgement.domain.AcknowledgementStatus; -import gov.irs.directfile.status.acknowledgement.domain.Status; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.*; -import gov.irs.directfile.status.domain.Error; -import gov.irs.directfile.status.error.ErrorRepository; -import gov.irs.directfile.status.error.ToolkitErrorRepository; -import gov.irs.directfile.status.mef.client.MeFAcksMTOMClientService; -import gov.irs.directfile.status.mef.client.MeFLoginClientService; -import gov.irs.directfile.status.mef.client.MeFLogoutClientService; -import gov.irs.directfile.status.repository.PodIdentifierRepository; -import gov.irs.directfile.status.services.StatusChangeMessageService; - -@SuppressFBWarnings( - value = {"CRLF_INJECTION_LOGS", "NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@Service -@EnableScheduling -@Transactional -@Slf4j -@SuppressWarnings({ - "PMD.SimpleDateFormatNeedsLocale", - "PMD.ExcessiveParameterList", - "PMD.AvoidDuplicateLiterals", - "PMD.LiteralsFirstInComparisons", - "PMD.UselessParentheses" -}) -public class AcknowledgementService { - private final CompletedAcknowledgementRepository completedRepo; - private final PendingAcknowledgementRepository pendingRepo; - private final TaxReturnSubmissionRepository taxReturnSubmissionRepository; - private final ErrorRepository errorRepo; - private final PodIdentifierRepository podIdentifierRepository; - - private final ToolkitErrorRepository toolkitErrorRepo; - private final StatusProperties statusProperties; - private ServiceContext serviceContext; - - private final StatusChangeMessageService statusChangeMessageService; - - private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss"); - - @SuppressFBWarnings( - value = {"EI_EXPOSE_REP2"}, - justification = "constructor injection") - public AcknowledgementService( - CompletedAcknowledgementRepository completedRepo, - PendingAcknowledgementRepository pendingRepo, - TaxReturnSubmissionRepository taxReturnSubmissionRepository, - ErrorRepository errorRepo, - ToolkitErrorRepository toolkitErrorRepo, - StatusProperties statusProperties, - StatusChangeMessageService statusChangeMessageService, - MeFAcksMTOMClientService getAcksClientService, - MeFLoginClientService loginClientService, - MeFLogoutClientService logoutClientService, - PodIdentifierRepository podIdentifierRepository) { - this.completedRepo = completedRepo; - this.pendingRepo = pendingRepo; - this.taxReturnSubmissionRepository = taxReturnSubmissionRepository; - this.errorRepo = errorRepo; - this.toolkitErrorRepo = toolkitErrorRepo; - this.statusProperties = statusProperties; - this.statusChangeMessageService = statusChangeMessageService; - this.getAcksClientService = getAcksClientService; - this.loginClientService = loginClientService; - this.logoutClientService = logoutClientService; - this.podIdentifierRepository = podIdentifierRepository; - } - - // changed from protected to public, called by TaxReturnXmlServiceImpl (which would be separated into its own - // microservice later) - public String getLatestSubmissionIdByTaxReturnId(UUID taxReturnId) { - log.info("getLatestSubmissionIdByTaxReturnId for tax-return-id {}", taxReturnId); - Optional submissionId = taxReturnSubmissionRepository.getLatestSubmissionIdByTaxReturnId(taxReturnId); - return submissionId.orElse(null); - } - - public String getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(UUID taxReturnId) { - log.info("Getting most relevant submission Id for taxReturnId {}", taxReturnId); - - Optional latestAcceptedSubmissionId = - taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId); - - if (latestAcceptedSubmissionId.isPresent()) { - String submissionId = latestAcceptedSubmissionId.get(); - log.info("Using {} as the most relevant submissionId for taxReturnId {}", submissionId, taxReturnId); - return submissionId; - } - - log.info( - "Falling back to retrieving the latest submissionId, regardless of status, for tax return {}", - taxReturnId); - return getLatestSubmissionIdByTaxReturnId(taxReturnId); - } - - /** - * Useful for navigating race conditions where a non-accepted submission that is more recent than an accepted - * submission exists, where the accepted submission should be the - * - * @param requestedSubmissionId a submission that (ideally) belongs to a tax return submission - * @return the latest accepted submissionId, if present - */ - public Optional getLatestAcceptedSubmissionIdOfParentTaxReturn(String requestedSubmissionId) { - // Note: Cannot log method name alongside submissionId as it implies status - log.info("checking for more relevant submissionId of tax return with submissionId {}", requestedSubmissionId); - return taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId); - } - - public Optional getCompletedBySubmissionId(String submissionId) { - return completedRepo.GetCompletedSubmission(submissionId); - } - - public List getRejectionCodesForSubmissionId(String submissionId) { - Optional optCompleted = getCompletedBySubmissionId(submissionId); - - // If submission ID does not have a completed record, throw an exception. - if (optCompleted.isEmpty()) { - throw new EntityNotFoundException("Could not find completed record for submission ID: " + submissionId); - } - - // We have a completed submission. Convert to a List and return the list (if it's - // not a rejected submission, the returned list should be empty). - Completed completed = optCompleted.get(); - return createRejectedReasonList(completed); - } - - public AcknowledgementStatus GetAcknowledgement(UUID taxReturnId) { - String submissionId = getLatestSubmissionIdByTaxReturnId(taxReturnId); - - return getAcknowledgementStatus(taxReturnId, submissionId); - } - - public AcknowledgementStatus GetAcknowledgement(UUID taxReturnId, String submissionId) { - return getAcknowledgementStatus(taxReturnId, submissionId); - } - - private AcknowledgementStatus getAcknowledgementStatus(UUID taxReturnId, String submissionId) { - if (submissionId == null && statusProperties.statusEndpointReturnsPendingByDefaultEnabled) { - // if statusProperties.createPendingUponGetStatus is true, return Pending status as we previously did - // The difference is, we are no longer saving a Pending object in the DB. - log.atInfo() - .setMessage("Unable to find a submission associated with taxReturnId in TaxReturnSubmission table") - .addKeyValue(AuditLogElement.taxReturnId.toString(), taxReturnId) - .log(); - - return new AcknowledgementStatus( - Status.Pending, CreateTranslationKey("status", "pending"), List.of(), new Date()); - } - - if (submissionId == null && !statusProperties.statusEndpointReturnsPendingByDefaultEnabled) { - // tax return was likely not submitted to MeF - return null; - } - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - log.info(String.format("Attempting to find submission id %s in completed database", submissionId)); - MDC.clear(); - - Optional completed = completedRepo.GetCompletedSubmission(submissionId); - // this is a completed return - if (completed.isPresent()) { - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - log.info("Completed record found"); - MDC.clear(); - - return getCompletedStatus(completed.get()); - } - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - log.info(String.format("Did not find %s in completed, checking pending", submissionId)); - MDC.clear(); - - Optional pending = pendingRepo.GetPendingSubmission(submissionId); - if (pending.isPresent()) { - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId.toString()); - log.info(String.format("Found %s in pending, will recheck status on next pass", submissionId)); - MDC.clear(); - - return new AcknowledgementStatus( - Status.Pending, - CreateTranslationKey("status", "pending"), - List.of(), - pending.get().getCreatedAt()); - } - - return null; - } - - @Scheduled(fixedRateString = "${status.ack-poll-in-milliseconds}", initialDelay = 1000) - public void ProcessPendingTable() { - if (!statusProperties.isStatusPollingEnabled()) { - log.info("Status polling is disabled in this environment"); - return; - } - log.info("Timer called: performing ack check"); - LookupSubmissions(); - } - - protected Iterable getAllPending() { - return pendingRepo.findAll(); - } - - protected Iterable getAllError() { - return errorRepo.findAll(); - } - - protected Iterable getAllCompleted() { - return completedRepo.findAll(); - } - - private List> batchPendings(Iterable pendings) { - List> batches = new ArrayList<>(); - Set current = new HashSet<>(); - log.info(String.format("Estimated count: %s", pendings.spliterator().estimateSize())); - // This surprised me, but if you access it from pending every time - // the iterator will never move to next. - Iterator iterator = pendings.iterator(); - while (iterator.hasNext()) { - Pending pending = iterator.next(); - if (current.size() < 100) { - current.add(pending); - } else { - log.info("100 Pendings in current batch, creating new batch"); - batches.add(current); - current = new HashSet<>(); - current.add(pending); - } - } - batches.add(current); - log.info(String.format("%s batches created", batches.size())); - return batches; - } - - protected void LookupSubmissions() { - String podId = statusProperties.getApplicationId(); - log.info("Getting all pending submission ids for podId {}", podId); - Iterable pendings = pendingRepo.findAllByPodId(podId); - // we will either get the exact size or a 0 here. - if (pendings.spliterator().getExactSizeIfKnown() == 0) { - log.info("No pending submission ids for podId {}", podId); - return; - } - // The MeF system has a limit of 100 submission ids checked per attempt - List> batchedPendings = batchPendings(pendings); - - log.info("Creating ack client for podId {}", podId); - long startTime = System.currentTimeMillis(); - Date date = new Date(startTime); - log.info("Logging in at {} for podId {}", simpleDateFormat.format(date), podId); - batchedPendings.forEach(batch -> { - try { - log.info("Getting acks from MeF for batch for podId {}", podId); - getGetAcksResult(batch); - // It might one day be necessary to purge submissionIds - // It shouldn't be necessary with this service being only available - // to our internal system. - } catch (ToolkitException e) { - // TODO: if a batch fails, find the bad one and report the problem to some other system - log.error("Toolkit error getting ack on poll: {}", e.getMessage(), e); - - if (batch.size() == 1) { - createToolkitError(batch.iterator().next(), e); - } else { - partitionBatch(batch); - } - } catch (ServiceException e) { - log.error("Service error getting ack on poll: {}", e.getMessage(), e); - } - }); - - long endTime = System.currentTimeMillis(); - date = new Date(endTime); - log.info( - "Logging out at {}, elapsed time in milliseconds: {}", - simpleDateFormat.format(date), - (endTime - startTime)); - } - - private void getGetAcksResult(Set pendings) throws ToolkitException, ServiceException { - Set submissionIds = - pendings.stream().map(Pending::getSubmissionId).collect(Collectors.toSet()); - GetAcksResultWrapper acknowledgements = getAcksClientService.getAcks(serviceContext, submissionIds); - // to enable parallel processing of each batch of 100 submissions, we handle each batch of acknowledgements in a - // separate thread - // once we have fetched them from MeF - new Thread(() -> bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages(acknowledgements, pendings)) - .start(); - } - - void bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages( - GetAcksResultWrapper acksResult, Iterable pendings) { - /* - * We start with a list of ackResults and the original Pending records in the database - * All batching logic is handle as a map of a mefSubmissionId key to an arbitrary value - * This allows us to make O(1) look ups between the various batching functions when creating new maps - * There are several steps for map and transform steps before we are ready to save/write database records - * and enqueue the SQS message back to the Backend service - * - * 1. createStatusSubmissionIdMap() - * - initializes a Map of ackStatus (accepted, rejected, pending) to an empty list - * - returns: {"accepted":[],"rejected":[],"pending":[]} - * 2. Loop through the acks and: - * a) populate the submissionIdToValidationErrorMap map submission Id to a list of lists of strings representing each part of the validationErrorGroup - * - returns {"sub_id_1" :[["R0000-904-03","Reject and Stop","Software ID in the Return Header must have passed testing for the form family and ‘TaxYr’."], - * ["F1040-525-03","Reject and Stop","If 'PINTypeCd' in the Return Header has ..."]],"sub_id_2":[[...],[...]]} - * b) populate the statusSubmissionIdMap - * - returns: {"accepted":["sub_id_3"],"rejected":["sub_id_2",],"pending":["sub_id_1"]} - * - * 3. createNewCompleteds() - * - Prepare the new Completed entities *but do not save them yet* - * - * 4. Map the Completed and Pending entities to respective maps of submissionId:Completed and submissionId:Pending - * - * 5. bulkUpdateEntities() - * - bulkGetOrCreateErrorsToRejectedAcknowledgements() - * - Create the Error entities based on the submissionIdToValidationErrorMap and save them to the database - * - at this point, the Error entities are *not* related to the Completed entities, because - * - Completed entities haven't been saved - * - returns submissionIdToError(), which is a map of submission Ids to Errors (newly created) - * - addErrorsToRejectedAcknowledgementsAndDeletePendingRecords() - * - pass the three maps (submissionIdToError,submissionIdToCompleted,submissionIdToPending) as args - * - iterate through the submissionIdToCompleted and: - * - if Errors exist, relate them to the completed - * - if the Pending exists, add it to the batch of Pendings to delete - * - in all cases, add the Completed to a batch of Completeds to persist - * - Save all Completeds in the batch to create - * - Delete all Pendings in the batch to delete - * 6. Remove pending submissions from the map of statusSubmissionIds to produce finalStatusSubmissionIds - * 7. Enqueue the finalStatusSubmissionIds to SQS and call statusChangeMessageService.publishStatusChangePayloadV1(finalStatusSubmissionIds) - * */ - Map> statusSubmissionIdMap = createStatusSubmissionIdMap(); - Map>> submissionIdToValidationErrorMap = new HashMap<>(); - Map submissionIdToCompletedMap = new HashMap<>(); - Map submissionIdToPendingdMap = new HashMap<>(); - - acksResult.getAcknowledgementsListWrapper().getAcknowledgements().forEach(acknowledgement -> { - String status = acknowledgement.getAcceptanceStatusTxt().toLowerCase(); - String submissionId = acknowledgement.getSubmissionId(); - submissionIdToValidationErrorMap.put(submissionId, new ArrayList<>()); - if (status.equals("rejected")) { - acknowledgement.getValidationErrorList().forEach(validationErrorGrp -> { - List errorMap = new ArrayList<>(); - errorMap.add(validationErrorGrp.getRuleNum()); - errorMap.add(validationErrorGrp.getSeverityCd()); - errorMap.add(validationErrorGrp.getErrorMessageTxt()); - submissionIdToValidationErrorMap.get(submissionId).add(errorMap); - }); - } - addToSubmissionIdMap(status, submissionId, statusSubmissionIdMap); - }); - - Iterable completeds = createNewCompleteds(statusSubmissionIdMap); - completeds.forEach(completed -> submissionIdToCompletedMap.put(completed.getSubmissionId(), completed)); - pendings.forEach(pending -> submissionIdToPendingdMap.put(pending.getSubmissionId(), pending)); - - bulkUpdateEntities(submissionIdToValidationErrorMap, submissionIdToCompletedMap, submissionIdToPendingdMap); - Map> finalStatusSubmissionIdMap = - stripPendingAcknowledgementsFromStatusSubmissionIdMap(statusSubmissionIdMap); - - if (!finalStatusSubmissionIdMap.get("rejected").isEmpty() - || !finalStatusSubmissionIdMap.get("accepted").isEmpty()) { - statusChangeMessageService.publishStatusChangePayloadV1(finalStatusSubmissionIdMap); - } - } - - protected Map> stripPendingAcknowledgementsFromStatusSubmissionIdMap( - Map> statusSubmssionIdMap) { - statusSubmssionIdMap.remove("pending"); - return statusSubmssionIdMap; - } - - protected Map> createStatusSubmissionIdMap() { - Map> statusSubmissionIdMap = new HashMap<>(); - - statusSubmissionIdMap.put("accepted", new ArrayList<>()); - statusSubmissionIdMap.put("rejected", new ArrayList<>()); - statusSubmissionIdMap.put("pending", new ArrayList<>()); - return statusSubmissionIdMap; - } - - protected Iterable createNewCompleteds(Map> statusSubmissionIdMap) { - List completedsToCreate = new ArrayList<>(); - statusSubmissionIdMap.forEach((status, submissionIdSet) -> { - if (status.equals("pending")) { - log.info("The following subIds are still pending {}", submissionIdSet.toString()); - } else { - submissionIdSet.forEach(submissionId -> { - Completed completed = new Completed(); - completed.setSubmissionId(submissionId); - completed.setStatus(status); - completedsToCreate.add(completed); - log.info("{} acknowledgement received from MeF", status); - }); - } - }); - return completedsToCreate; - } - - protected void addToSubmissionIdMap( - String status, String submissionId, Map> statusSubmissionIdMap) { - MDC.put(AuditLogElement.mefSubmissionId.toString(), submissionId); - if (statusSubmissionIdMap.containsKey(status)) { - log.info( - "Acknowledgement with submissionId {} has status changed, adding to statusSubmissionIdMap", - submissionId); - statusSubmissionIdMap.get(status).add(submissionId); - } else { - // default case where the status is not present or not one we expect - // TODO: handle the exception status case when/if necessary - log.error("Missing a status type: {}", status); - } - MDC.clear(); - } - - public void bulkUpdateEntities( - Map>> validationErrorMap, - Map submissionIdToCompleted, - Map submissionIdToPending) { - Map> submissionIdToError = - bulkGetOrCreateErrorsToRejectedAcknowledgements(validationErrorMap); - addErrorsToRejectedAcknowledgementsAndDeletePendingRecords( - submissionIdToError, submissionIdToCompleted, submissionIdToPending); - } - - protected Map> bulkGetOrCreateErrorsToRejectedAcknowledgements( - Map>> validationErrorMap) { - - List errorList = new ArrayList<>(); - Map> submissionIdToError = new HashMap<>(); - - validationErrorMap.forEach((submissionId, validationErrorGrp) -> { - submissionIdToError.put(submissionId, new ArrayList<>()); - validationErrorGrp.forEach(validationError -> { - String ruleNum = validationError.get(0); - String severityCd = validationError.get(1); - String errorMessageTxt = validationError.get(2); - var databaseError = errorRepo.findById(ruleNum); - if (databaseError.isPresent()) { - log.info(String.format("Found reject reason %s", ruleNum)); - Error existingError = databaseError.get(); - errorList.add(existingError); - submissionIdToError.get(submissionId).add(existingError); - - } else { - log.warn(String.format("New reject reason found: %s. New translation required", ruleNum)); - Error newError = new Error(); - newError.setMefErrorCode(ruleNum); - newError.setErrorCodeTranslationKey(CreateTranslationKey("reject", ruleNum)); - newError.setMefErrorCategory(severityCd); - newError.setErrorMessage(errorMessageTxt); - log.info(String.format("Saving new reject reason %s", ruleNum)); - errorList.add(newError); - submissionIdToError.get(submissionId).add(newError); - } - }); - }); - errorRepo.saveAll(errorList); - return submissionIdToError; - } - - protected void addErrorsToRejectedAcknowledgementsAndDeletePendingRecords( - Map> submissionIdToError, - Map submissionIdToCompleted, - Map submissionIdToPending) { - List completedToSave = new ArrayList<>(); - List pendingToDelete = new ArrayList<>(); - submissionIdToCompleted.forEach((submissionId, completed) -> { - List errorsToPersist = submissionIdToError.get(submissionId); - Optional pending = Optional.ofNullable(submissionIdToPending.get(submissionId)); - if (errorsToPersist != null - && !errorsToPersist.isEmpty() - && completed.getStatus().toLowerCase().compareTo("rejected") == 0) { - completed.setErrors(errorsToPersist); - } - completedToSave.add(completed); - if (pending.isPresent()) { - Pending p = pending.get(); - pendingToDelete.add(p); - } - }); - log.info(String.format("Creating %s completed objects", completedToSave.size())); - completedRepo.saveAll(completedToSave); - log.info(String.format("Deleting %s pending objects", pendingToDelete.size())); - pendingRepo.deleteAll(pendingToDelete); - } - - protected void createToolkitError(Pending pending, Exception e) { - String submissionId = pending.getSubmissionId(); - ToolkitError tke = new ToolkitError(); - tke.setSubmissionId(submissionId); - tke.setErrorName(e.getClass().getName()); - tke.setErrorMessage(e.toString()); - - toolkitErrorRepo.save(tke); - - // delete the corresponding pending record - try { - deletePendingRecord(submissionId); - } catch (EntityNotFoundException notFoundException) { - log.error(notFoundException.getMessage()); - } - } - - private void deletePendingRecord(String submissionId) { - Pending p = pendingRepo - .findById(submissionId) - .orElseThrow(() -> new EntityNotFoundException( - String.format("Submission with id [%s] was not found in the database!", submissionId))); - pendingRepo.delete(p); - } - - private AcknowledgementStatus getCompletedStatus(Completed c) { - if (c.getStatus().toLowerCase().compareTo("accepted") == 0) { - return new AcknowledgementStatus( - Status.Accepted, CreateTranslationKey("status", "accepted"), List.of(), c.getCreatedAt()); - } else if (c.getStatus().toLowerCase().compareTo("rejected") == 0) { - return new AcknowledgementStatus( - Status.Rejected, - CreateTranslationKey("status", "rejected"), - createRejectedReasonList(c), - c.getCreatedAt()); - } else { - throw new RuntimeException("Missing status type"); - } - } - - private List createRejectedReasonList(Completed c) { - List statuses = new ArrayList<>(); - if (c.getErrors() != null) { - c.getErrors() - .forEach(x -> statuses.add(new RejectedStatus( - x.getMefErrorCode(), x.getErrorCodeTranslationKey(), x.getErrorMessage()))); - } - - return statuses; - } - - private String CreateTranslationKey(String type, String name) { - return String.join( - statusProperties.getTranslationKeySplitter(), statusProperties.getRootTranslationKey(), type, name); - } - - private void partitionBatch(Set pBatch) { - Iterable> partitions = - Iterables.partition(pBatch, IntMath.divide(pBatch.size(), 2, RoundingMode.CEILING)); - - partitions.forEach(partition -> { - try { - getGetAcksResult(new HashSet<>(partition)); - } catch (ToolkitException tke) { - if (partition.size() == 1) { - // report and flag bad data to db - createToolkitError(partition.get(0), tke); - } else { - partitionBatch(new HashSet<>(partition)); - } - } catch (ServiceException se) { - if (partition.size() == 1) { - log.warn("ServiceException - " + se); - } else { - partitionBatch(new HashSet<>(partition)); - } - } - }); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepository.java deleted file mode 100644 index 036b621..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.status.domain.Completed; - -public interface CompletedAcknowledgementRepository extends CrudRepository { - - @Query(value = "SELECT * FROM completed WHERE submission_id = :submissionId LIMIT 1", nativeQuery = true) - Optional GetCompletedSubmission(String submissionId); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepository.java deleted file mode 100644 index 4186221..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.List; -import java.util.Optional; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.status.domain.Pending; - -public interface PendingAcknowledgementRepository extends CrudRepository { - - @Query(value = "SELECT * FROM pending WHERE submission_id = :submissionId LIMIT 1", nativeQuery = true) - Optional GetPendingSubmission(String submissionId); - - @Query(value = "SELECT * FROM pending WHERE pod_id = :podId ORDER BY created_at asc", nativeQuery = true) - List findAllByPodId(String podId); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepository.java deleted file mode 100644 index 3327754..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepository.java +++ /dev/null @@ -1,48 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.Optional; -import java.util.UUID; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.status.domain.TaxReturnSubmission; - -public interface TaxReturnSubmissionRepository extends CrudRepository { - @Query( - value = - "SELECT submission_id FROM tax_return_submission WHERE tax_return_id = :taxReturnId ORDER BY CREATED_AT DESC LIMIT 1", - nativeQuery = true) - Optional getLatestSubmissionIdByTaxReturnId(UUID taxReturnId); - - @Query( - value = - """ - SELECT trs.submission_id - FROM tax_return_submission trs - JOIN completed c ON trs.submission_id = c.submission_id - WHERE trs.tax_return_id = :taxReturnId - AND LOWER(c.status) = 'accepted' - ORDER BY c.created_at DESC LIMIT 1 - """, - nativeQuery = true) - Optional getLatestAcceptedSubmissionIdForTaxReturnId(UUID taxReturnId); - - @Query( - value = - """ - SELECT trs.submission_id - FROM tax_return_submission trs - JOIN completed c ON trs.submission_id = c.submission_id - WHERE - trs.tax_return_id = ( - SELECT tax_return_id - FROM tax_return_submission - WHERE submission_id = :submissionId - ) - AND LOWER(c.status) = 'accepted' - ORDER BY c.created_at DESC LIMIT 1 - """, - nativeQuery = true) - Optional getLatestAcceptedSubmissionIdOfParentTaxReturn(String submissionId); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/AcknowledgementStatus.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/AcknowledgementStatus.java deleted file mode 100644 index 52c13fa..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/AcknowledgementStatus.java +++ /dev/null @@ -1,24 +0,0 @@ -package gov.irs.directfile.status.acknowledgement.domain; - -import java.util.Date; -import java.util.List; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -import gov.irs.directfile.models.RejectedStatus; - -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "Initial SpotBugs Setup") -@Getter -@Setter -@AllArgsConstructor -public class AcknowledgementStatus { - private Status status; - private String translationKey; - private List rejectionCodes; - private Date createdAt; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/Status.java b/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/Status.java deleted file mode 100644 index 5107f0c..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/acknowledgement/domain/Status.java +++ /dev/null @@ -1,8 +0,0 @@ -package gov.irs.directfile.status.acknowledgement.domain; - -public enum Status { - Pending, - Accepted, - Rejected, - Error, -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSClientConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSClientConfiguration.java deleted file mode 100644 index 094b2dd..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSClientConfiguration.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.irs.directfile.status.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(prefix = "aws") -@AllArgsConstructor -@Getter -public class AWSClientConfiguration { - private String accessKey; - private String secretKey; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSCredentialsConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSCredentialsConfiguration.java deleted file mode 100644 index c0032d6..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/AWSCredentialsConfiguration.java +++ /dev/null @@ -1,34 +0,0 @@ -package gov.irs.directfile.status.config; - -import lombok.AllArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -@Configuration -@AllArgsConstructor -@EnableConfigurationProperties(AWSClientConfiguration.class) -public class AWSCredentialsConfiguration { - private final AWSClientConfiguration awsClientConfiguration; - - @Bean - @ConditionalOnProperty( - name = "aws.default-credentials-provider-chain-enabled", - havingValue = "false", - matchIfMissing = true) - public AwsCredentialsProvider staticAWSCredentialsProvider() { - return StaticCredentialsProvider.create(AwsBasicCredentials.create( - awsClientConfiguration.getAccessKey(), awsClientConfiguration.getSecretKey())); - } - - @Bean - @ConditionalOnProperty(name = "aws.default-credentials-provider-chain-enabled", havingValue = "true") - public AwsCredentialsProvider defaultAWSCredentialsProvider() { - return DefaultCredentialsProvider.create(); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionClientConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionClientConfiguration.java deleted file mode 100644 index 5a2237b..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionClientConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -package gov.irs.directfile.status.config; - -import java.net.URI; -import java.util.Base64; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import lombok.AllArgsConstructor; -import lombok.NonNull; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.kms.KmsClient; -import software.amazon.encryption.s3.materials.CryptographicMaterialsManager; -import software.amazon.encryption.s3.materials.DefaultCryptoMaterialsManager; -import software.amazon.encryption.s3.materials.KmsKeyring; - -@Configuration -@AllArgsConstructor -@EnableConfigurationProperties(EncryptionConfiguration.class) -public class EncryptionClientConfiguration { - private final EncryptionConfiguration encryptionConfig; - private final AwsCredentialsProvider awsCredentialsProvider; - - public CryptographicMaterialsManager kmsCrypto(@NonNull String kmsWrappingKeyArn) { - return DefaultCryptoMaterialsManager.builder() - .keyring(KmsKeyring.builder() - .kmsClient(regionalKmsClient()) - .wrappingKeyId(kmsWrappingKeyArn) - .build()) - .build(); - } - - public SecretKey getLocalAesWrappingKey() { - return new SecretKeySpec(Base64.getDecoder().decode(encryptionConfig.getLocalWrappingKey()), "AES"); - } - - protected KmsClient regionalKmsClient() { - return KmsClient.builder() - .region(Region.of(encryptionConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(encryptionConfig.getKmsEndpoint())) - .build(); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionConfiguration.java deleted file mode 100644 index 3ad1dd3..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/EncryptionConfiguration.java +++ /dev/null @@ -1,20 +0,0 @@ -package gov.irs.directfile.status.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@AllArgsConstructor -@Getter -@ConfigurationProperties -public class EncryptionConfiguration { - @Value("${aws.kmsEndpoint:#{null}}") - private String kmsEndpoint; - - @Value("${aws.region:#{null}}") - private String region; - - @Value("${direct-file.local-encryption.local-wrapping-key:#{null}}") - private String localWrappingKey; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/MessageQueueConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/MessageQueueConfiguration.java deleted file mode 100644 index 0d2552f..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/MessageQueueConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -package gov.irs.directfile.status.config; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.hibernate.validator.constraints.URL; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -@Validated -@AllArgsConstructor -@Getter -// See https://stackoverflow.com/a/67994421 for why we use kebab case here (message-queue) -// when we're using camel case (messageQueue) in the source. -@ConfigurationProperties("status.message-queue") -public class MessageQueueConfiguration { - @NotBlank - @URL - private final String endpoint; - - @NotBlank - private final String statusChangeQueue; - - @NotBlank - private final String pendingSubmissionQueue; - - @NotBlank - private final String dlqPendingSubmissionQueue; - - @NotBlank - private final String region; - - @NotBlank - private final String accessKey; - - @NotBlank - private final String secretKey; - - private final boolean sqsMessageHandlingEnabled; - - private final boolean statusChangePublishEnabled; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsClientConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsClientConfiguration.java deleted file mode 100644 index 87eff51..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsClientConfiguration.java +++ /dev/null @@ -1,29 +0,0 @@ -package gov.irs.directfile.status.config; - -import java.net.URI; - -import lombok.AllArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.sns.SnsClient; - -@Configuration -@ConditionalOnProperty(value = "status.sns.status-change-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(SnsConfiguration.class) -@AllArgsConstructor -public class SnsClientConfiguration { - private final AwsCredentialsProvider awsCredentialsProvider; - - @Bean - public SnsClient snsClient(SnsConfiguration snsConfiguration) { - return SnsClient.builder() - .region(Region.of(snsConfiguration.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(snsConfiguration.getEndpoint())) - .build(); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsConfiguration.java deleted file mode 100644 index 782131f..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SnsConfiguration.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.irs.directfile.status.config; - -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.hibernate.validator.constraints.URL; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -@Validated -@AllArgsConstructor -@Getter -@ConfigurationProperties("status.sns") -public class SnsConfiguration { - @NotBlank - @URL - private final String endpoint; - - @NotBlank - private final String statusChangeTopicArn; - - @NotBlank - private final String region; - - @NotBlank - private final String accessKey; - - @NotBlank - private final String secretKey; - - private final boolean statusChangePublishEnabled; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SqsClientConfiguration.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/SqsClientConfiguration.java deleted file mode 100644 index 0c130ff..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/SqsClientConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -package gov.irs.directfile.status.config; - -import java.net.URI; - -import lombok.AllArgsConstructor; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.sqs.SqsClient; - -@Configuration -@EnableConfigurationProperties(MessageQueueConfiguration.class) -@AllArgsConstructor -public class SqsClientConfiguration { - private final AwsCredentialsProvider awsCredentialsProvider; - - @Bean - public SqsClient sqsClient(MessageQueueConfiguration messageQueueConfiguration) { - return SqsClient.builder() - .region(Region.of(messageQueueConfiguration.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(messageQueueConfiguration.getEndpoint())) - .build(); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/config/StatusProperties.java b/direct-file/status/src/main/java/gov/irs/directfile/status/config/StatusProperties.java deleted file mode 100644 index 06e97aa..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/config/StatusProperties.java +++ /dev/null @@ -1,39 +0,0 @@ -package gov.irs.directfile.status.config; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.validation.annotation.Validated; - -@SuppressFBWarnings( - value = {"NM_FIELD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@AllArgsConstructor -@Getter -@Validated -@ConfigurationProperties(prefix = "status") -public class StatusProperties { - @NotBlank - private String applicationId; - - private String keystoreBase64; - private String keystorePassword; - private String keystoreAlias; - private String etin; - - @Setter - private String asid; - - private String efin; - private boolean unitTesting; - private boolean prod; - private String rootTranslationKey; - private String translationKeySplitter; - public Long AckPollInMilliseconds; - public boolean statusEndpointReturnsPendingByDefaultEnabled; - private String toolkit; - private boolean statusPollingEnabled; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementWrapper.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementWrapper.java deleted file mode 100644 index 859ad9e..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementWrapper.java +++ /dev/null @@ -1,51 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Getter; - -import gov.irs.mef.AcknowledgementList; - -@Getter -public class AcknowledgementWrapper { - private final String submissionId; - private final String receiptId; - private final String acceptanceStatusTxt; - private final List validationErrorList; - - public AcknowledgementWrapper(String submissionId, String receiptId, String acceptanceStatusTxt) { - this(submissionId, receiptId, acceptanceStatusTxt, List.of()); - } - - public AcknowledgementWrapper( - String submissionId, - String receiptId, - String acceptanceStatusTxt, - List validationErrorList) { - this.submissionId = submissionId; - this.receiptId = receiptId; - this.acceptanceStatusTxt = acceptanceStatusTxt; - this.validationErrorList = List.copyOf(validationErrorList); - } - - public static AcknowledgementWrapper fromMefAcknowledgement(AcknowledgementList.Acknowledgement acknowledgement) { - if (acknowledgement.getValidationErrorList() == null) { - return new AcknowledgementWrapper( - acknowledgement.getSubmissionId(), - acknowledgement.getReceiptId(), - acknowledgement.getAcceptanceStatusTxt(), - new ArrayList<>()); - } else { - List validationErrors = - acknowledgement.getValidationErrorList().getValidationErrorGrp().stream() - .map(ValidationErrorGrpWrapper::fromMefValidationErrorGrp) - .toList(); - return new AcknowledgementWrapper( - acknowledgement.getSubmissionId(), - acknowledgement.getReceiptId(), - acknowledgement.getAcceptanceStatusTxt(), - validationErrors); - } - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementsListWrapper.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementsListWrapper.java deleted file mode 100644 index 045cbce..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/AcknowledgementsListWrapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.List; -import java.util.stream.Collectors; - -import lombok.Getter; - -import gov.irs.mef.AcknowledgementList; - -@Getter -public class AcknowledgementsListWrapper { - private final List acknowledgements; - - public AcknowledgementsListWrapper(AcknowledgementList acknowledgementList) { - this.acknowledgements = List.copyOf(acknowledgementList.getAcknowledgements().stream() - .map(AcknowledgementWrapper::fromMefAcknowledgement) - .collect(Collectors.toList())); - } - - public AcknowledgementsListWrapper(List acknowledgementWrappers) { - this.acknowledgements = List.copyOf(acknowledgementWrappers); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Completed.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Completed.java deleted file mode 100644 index 50921a9..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Completed.java +++ /dev/null @@ -1,48 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.Date; -import java.util.List; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.CreationTimestamp; - -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "Initial SpotBugs Setup") -@Entity(name = "Completed") -@Getter -@Setter -public class Completed { - @Id - @Column(length = 20) - private String submissionId; - - @Column(length = 20) - private String status; - - @Getter - @Column(name = "created_at", nullable = false, updatable = false, columnDefinition = "DEFAULT CURRENT_TIMESTAMP") - @CreationTimestamp - private Date createdAt; - - @Getter - @ManyToMany(fetch = FetchType.EAGER) - @JoinTable( - name = "completed-errors", - joinColumns = { - @JoinColumn( - name = "submissionId", - referencedColumnName = "submissionId", - foreignKey = @ForeignKey(name = "completed_error_submission_id_fk")) - }, - inverseJoinColumns = { - @JoinColumn( - name = "mefErrorCode", - referencedColumnName = "meferror_code", - foreignKey = @ForeignKey(name = "completed_error_mef_error_code_fk")) - }) - private List errors; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Error.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Error.java deleted file mode 100644 index 2740809..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Error.java +++ /dev/null @@ -1,45 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.time.LocalDate; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonBackReference; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; -import org.hibernate.annotations.CreationTimestamp; - -@Entity(name = "Error") -@Getter -@Setter -@ToString(doNotUseGetters = true) -public class Error { - @Id - @Column(name = "meferror_code", length = 25) - private String mefErrorCode; - - @Column(name = "error_message", columnDefinition = "TEXT") - private String errorMessage; - - @Column(name = "meferror_category") - private String mefErrorCategory; - - private String errorCodeTranslationKey; - - @Column(name = "created_at", nullable = false, updatable = false, columnDefinition = "DEFAULT CURRENT_TIMESTAMP") - @CreationTimestamp - private LocalDate createdAt; - - @ManyToMany(mappedBy = "errors") - @JsonBackReference - private List completed; - - public List getCompleted() { - return List.copyOf(completed); - } - - public void setCompleted(List completed) { - this.completed = List.copyOf(completed); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/GetAcksResultWrapper.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/GetAcksResultWrapper.java deleted file mode 100644 index c8078bb..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/GetAcksResultWrapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.status.domain; - -import lombok.Getter; - -import gov.irs.mef.services.transmitter.mtom.GetAcksResult; - -@Getter -public class GetAcksResultWrapper { - private AcknowledgementsListWrapper acknowledgementsListWrapper; - - public GetAcksResultWrapper(GetAcksResult getAcksResult) { - this.acknowledgementsListWrapper = new AcknowledgementsListWrapper(getAcksResult.getAcknowledgementList()); - } - - public GetAcksResultWrapper(AcknowledgementsListWrapper acknowledgementsListWrapper) { - this.acknowledgementsListWrapper = acknowledgementsListWrapper; - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Pending.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Pending.java deleted file mode 100644 index d910539..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/Pending.java +++ /dev/null @@ -1,43 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.Date; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2", "NM_FIELD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@Entity(name = "Pending") -@Getter -@Setter -public class Pending { - @Id - @Column(length = 20) - private String submissionId; - - @Getter - @Column(name = "created_at", nullable = false, updatable = false, columnDefinition = "DEFAULT CURRENT_TIMESTAMP") - @CreationTimestamp - private Date createdAt; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "pod_id", length = 255) - private String podId; - - public Pending() {} - - public Pending(final String submissionId) { - this.submissionId = submissionId; - } - - public Pending(String submissionId, String podId) { - this.submissionId = submissionId; - this.podId = podId; - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/PodIdentifier.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/PodIdentifier.java deleted file mode 100644 index 64ea61b..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/PodIdentifier.java +++ /dev/null @@ -1,30 +0,0 @@ -package gov.irs.directfile.status.domain; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - -@Getter -@Setter -@Entity(name = "PodIdentifier") -@Table(name = "pod_identifier") -public class PodIdentifier { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "asid", length = 50) - private String asid; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "region", length = 50) - private String region; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "pod_id", length = 255) - private String podId; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/TaxReturnSubmission.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/TaxReturnSubmission.java deleted file mode 100644 index 65df1a6..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/TaxReturnSubmission.java +++ /dev/null @@ -1,40 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.Date; -import java.util.UUID; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.CreationTimestamp; - -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "Initial SpotBugs Setup") -@Entity(name = "TaxReturnSubmission") -@Table(name = "tax_return_submission") -@Getter -@Setter -public class TaxReturnSubmission { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private UUID taxReturnId; - - @Column(length = 20) - private String submissionId; - - @Getter - @Column(name = "created_at", nullable = false, updatable = false, columnDefinition = "DEFAULT CURRENT_TIMESTAMP") - @CreationTimestamp - private Date createdAt; - - public TaxReturnSubmission(UUID taxReturnId, String submissionId) { - this.taxReturnId = taxReturnId; - this.submissionId = submissionId; - } - - public TaxReturnSubmission() {} -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ToolkitError.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ToolkitError.java deleted file mode 100644 index a55775f..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ToolkitError.java +++ /dev/null @@ -1,30 +0,0 @@ -package gov.irs.directfile.status.domain; - -import java.util.Date; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.persistence.*; -import jakarta.validation.constraints.NotNull; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.CreationTimestamp; - -@SuppressFBWarnings( - value = {"NM_FIELD_NAMING_CONVENTION", "EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "Initial SpotBugs Setup") -@Entity -@Getter -@Setter -public class ToolkitError { - @Id - private String submissionId; - - @NotNull private String errorMessage; - - @NotNull private String errorName; - - @Getter - @Column(name = "created_at", nullable = false, updatable = false, columnDefinition = "DEFAULT CURRENT_TIMESTAMP") - @CreationTimestamp - private Date createdAt; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ValidationErrorGrpWrapper.java b/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ValidationErrorGrpWrapper.java deleted file mode 100644 index 25bfa4f..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/domain/ValidationErrorGrpWrapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package gov.irs.directfile.status.domain; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.efile.ValidationErrorListType; - -@Getter -@AllArgsConstructor -public class ValidationErrorGrpWrapper { - private String ruleNum; - private String severityCd; - private String errorMessageTxt; - - public static ValidationErrorGrpWrapper fromMefValidationErrorGrp( - ValidationErrorListType.ValidationErrorGrp validationErrorGrp) { - return new ValidationErrorGrpWrapper( - validationErrorGrp.getRuleNum(), - validationErrorGrp.getSeverityCd(), - validationErrorGrp.getErrorMessageTxt()); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/error/ErrorRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/error/ErrorRepository.java deleted file mode 100644 index 1646419..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/error/ErrorRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.irs.directfile.status.error; - -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.status.domain.Error; - -public interface ErrorRepository extends CrudRepository {} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/error/ToolkitErrorRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/error/ToolkitErrorRepository.java deleted file mode 100644 index e823f2d..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/error/ToolkitErrorRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package gov.irs.directfile.status.error; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.stereotype.Repository; - -import gov.irs.directfile.status.domain.ToolkitError; - -@Repository -public interface ToolkitErrorRepository extends CrudRepository {} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/mef/client/ServiceContextWrapper.java b/direct-file/status/src/main/java/gov/irs/directfile/status/mef/client/ServiceContextWrapper.java deleted file mode 100644 index 1945952..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/mef/client/ServiceContextWrapper.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.status.mef.client; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -import gov.irs.mef.services.ServiceContext; - -@Getter -@Setter -@AllArgsConstructor -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "The Getter and Setter are auto-generated by Lombox.") -public class ServiceContextWrapper { - private final ServiceContext serviceContext; -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/repository/PodIdentifierRepository.java b/direct-file/status/src/main/java/gov/irs/directfile/status/repository/PodIdentifierRepository.java deleted file mode 100644 index 539091d..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/repository/PodIdentifierRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.status.repository; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.status.domain.PodIdentifier; - -public interface PodIdentifierRepository extends CrudRepository { - - @Query(value = "SELECT asid from pod_identifier WHERE pod_id = :pod_id", nativeQuery = true) - Optional findAsidByPodId(String pod_id); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/MessageQueueListenerService.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/MessageQueueListenerService.java deleted file mode 100644 index f273bfe..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/MessageQueueListenerService.java +++ /dev/null @@ -1,71 +0,0 @@ -package gov.irs.directfile.status.services; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.jms.Message; -import jakarta.jms.MessageListener; -import jakarta.jms.TextMessage; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.status.config.MessageQueueConfiguration; - -@Slf4j -@Service -@ConditionalOnProperty(value = "status.messageQueue.sqs-message-handling-enabled", havingValue = "true") -@EnableConfigurationProperties(MessageQueueConfiguration.class) -public class MessageQueueListenerService implements MessageListener { - private final String pendingSubmissionQueue; - private final PendingSubmissionMessageRouter pendingSubmissionMessageRouter; - private final SubmissionConfirmationMessageRouter submissionConfirmationMessageRouter; - private final ObjectMapper objectMapper = new ObjectMapper(); - - MessageQueueListenerService( - MessageQueueConfiguration messageQueueConfiguration, - PendingSubmissionMessageRouter pendingSubmissionMessageRouter, - SubmissionConfirmationMessageRouter submissionConfirmationMessageRouter) { - this.pendingSubmissionQueue = messageQueueConfiguration.getPendingSubmissionQueue(); - this.pendingSubmissionMessageRouter = pendingSubmissionMessageRouter; - this.submissionConfirmationMessageRouter = submissionConfirmationMessageRouter; - } - - @Override - public void onMessage(Message message) { - log.info("onMessage called ({})", pendingSubmissionQueue); - - String rawText = ""; - try { - rawText = ((TextMessage) message).getText(); - - try { - // First try to deserialize as a VersionedPendingSubmissionMessage (what SQS would send) - log.info("Trying to deserialize message to VersionedPendingSubmissionMessage"); - VersionedPendingSubmissionMessage versionedPendingSubmissionMessage = - objectMapper.readValue(rawText, new TypeReference<>() {}); - pendingSubmissionMessageRouter.handlePendingSubmissionMessage(versionedPendingSubmissionMessage); - } catch (JsonProcessingException e) { - // Otherwise, try to deserialize as a VersionedSubmissionConfirmationMessage (what SNS would send) - log.info("Trying to deserialize message to VersionedSubmissionConfirmationMessage"); - VersionedSubmissionConfirmationMessage - versionedSubmissionConfirmationMessage = - objectMapper.readValue(rawText, new TypeReference<>() {}); - submissionConfirmationMessageRouter.handleSubmissionConfirmationMessage( - versionedSubmissionConfirmationMessage); - } - - message.acknowledge(); - } catch (Exception e) { - log.error( - "Error saving Pending objects in database. Re-queueing list of submissionIds: {}. Error: {}", - rawText, - e.getMessage()); - } - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouter.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouter.java deleted file mode 100644 index c9c0e02..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouter.java +++ /dev/null @@ -1,60 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.models.message.pending.PendingSubmissionMessageVersion; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.status.services.handlers.pending.PendingSubmissionHandler; -import gov.irs.directfile.status.services.handlers.pending.PendingSubmissionV1Handler; -import gov.irs.directfile.status.services.handlers.pending.UnsupportedMessageVersionHandler; - -@Service -public class PendingSubmissionMessageRouter { - private final Map handlers = new HashMap<>(); - private final UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - public PendingSubmissionMessageRouter( - UnsupportedMessageVersionHandler unsupportedMessageVersionHandler, - PendingSubmissionV1Handler pendingSubmissionV1Handler) { - this.unsupportedMessageVersionHandler = unsupportedMessageVersionHandler; - this.handlers.put(PendingSubmissionMessageVersion.V1, pendingSubmissionV1Handler); - } - - public void handlePendingSubmissionMessage( - VersionedPendingSubmissionMessage message) { - QueueMessageHeaders headers = message.getHeaders(); - Optional versionOptional = headers.getAttribute(MessageHeaderAttribute.VERSION); - - // We can assume a version number is present here since a VersionedPendingSubmissionMessage - // mandates that on construction. - - // Get enum for this version (may throw UnsupportedVersionException which we should handle and - // rethrow to get message back on queue/DLQ). - PendingSubmissionMessageVersion version; - try { - version = PendingSubmissionMessageVersion.getEnum(versionOptional.get()); - } catch (UnsupportedVersionException e) { - unsupportedMessageVersionHandler.handlePendingSubmissionMessage(message); - throw e; - } - - // Get handler. If not found, we have an unsupported version so handle and throw exception. - PendingSubmissionHandler handler = handlers.get(version); - if (handler == null) { - unsupportedMessageVersionHandler.handlePendingSubmissionMessage(message); - throw new UnsupportedVersionException( - String.format("No handler found for PendingSubmissionMessageVersion (%s)", version.getVersion())); - } - - // We should have a good handler, so handle the message. - handler.handlePendingSubmissionMessage(message); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/SqsConnectionSetupService.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/SqsConnectionSetupService.java deleted file mode 100644 index 7a759c1..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/SqsConnectionSetupService.java +++ /dev/null @@ -1,67 +0,0 @@ -package gov.irs.directfile.status.services; - -import com.amazon.sqs.javamessaging.ProviderConfiguration; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSConnectionFactory; -import com.amazon.sqs.javamessaging.SQSSession; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import jakarta.annotation.PreDestroy; -import jakarta.jms.JMSException; -import jakarta.jms.MessageConsumer; -import jakarta.jms.Queue; -import jakarta.jms.Session; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sqs.SqsClient; - -import gov.irs.directfile.status.config.MessageQueueConfiguration; - -@Service -@ConditionalOnProperty(value = "status.messageQueue.sqs-message-handling-enabled", havingValue = "true") -@Slf4j -@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Java 21 update") -@SuppressWarnings({"PMD.CloseResource", "PMD.UnusedPrivateMethod"}) -@EnableConfigurationProperties(MessageQueueConfiguration.class) -public class SqsConnectionSetupService { - private final SqsClient sqsClient; - private final String pendingSubmissionQueue; - private final MessageQueueListenerService messageQueueListenerService; - private SQSConnection connection; - - SqsConnectionSetupService( - SqsClient sqsClient, - MessageQueueConfiguration messageQueueConfiguration, - MessageQueueListenerService messageQueueListenerService) - throws JMSException { - this.sqsClient = sqsClient; - this.pendingSubmissionQueue = messageQueueConfiguration.getPendingSubmissionQueue(); - this.messageQueueListenerService = messageQueueListenerService; - - initializeSQSConnection(); - } - - private void initializeSQSConnection() throws JMSException { - SQSConnectionFactory connectionFactory = new SQSConnectionFactory(new ProviderConfiguration(), sqsClient); - connection = connectionFactory.createConnection(); - - Session session = connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE); - Queue queue = session.createQueue(pendingSubmissionQueue); - MessageConsumer consumer = session.createConsumer(queue); - consumer.setMessageListener(messageQueueListenerService); - - connection.start(); - log.info("CONNECTED TO SQS"); - } - - @PreDestroy - private void cleanup() throws JMSException { - if (connection != null) { - connection.stop(); - log.info("SQS connection stopped"); - connection.close(); - log.info("SQS connection closed"); - } - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeMessageService.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeMessageService.java deleted file mode 100644 index 6bad9e7..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeMessageService.java +++ /dev/null @@ -1,70 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.PublisherException; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.status.StatusChangeMessageVersion; -import gov.irs.directfile.models.message.status.VersionedStatusChangeMessage; -import gov.irs.directfile.models.message.status.payload.AbstractStatusChangePayload; -import gov.irs.directfile.models.message.status.payload.StatusChangePayloadV1; - -@Service -@Slf4j -public class StatusChangeMessageService { - private final List publishers; - private final ObjectMapper mapper; - - public StatusChangeMessageService(List publishers, ObjectMapper mapper) { - this.publishers = publishers; - this.mapper = mapper; - } - - public void publishStatusChangePayloadV1(Map> statusSubmissionIdMap) { - AbstractStatusChangePayload payload = new StatusChangePayloadV1(statusSubmissionIdMap); - publishStatusChangePayload(payload, StatusChangeMessageVersion.V1); - } - - private void publishStatusChangePayload(AbstractStatusChangePayload payload, StatusChangeMessageVersion version) { - if (publishers == null || publishers.isEmpty()) { - return; - } - - VersionedStatusChangeMessage message = new VersionedStatusChangeMessage<>( - payload, new QueueMessageHeaders().addHeader(MessageHeaderAttribute.VERSION, version.getVersion())); - - String jsonString; - try { - jsonString = mapper.writeValueAsString(message); - } catch (JsonProcessingException e) { - String errorMessage = "Exception calling writeValueAsString"; - log.error(errorMessage, e); - throw new PublisherException(errorMessage, e); - } - - List errors = new ArrayList<>(); - for (StatusChangePublisher publisher : publishers) { - try { - publisher.publish(jsonString); - } catch (Exception e) { - log.error("Exception calling publish", e); - errors.add(e.getMessage() + " (" + publisher.getClass().getSimpleName() + ")"); - } - } - - if (!errors.isEmpty()) { - String errorMessage = StringUtils.join(errors, "; "); - log.error(errorMessage); - throw new PublisherException(errorMessage); - } - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangePublisher.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangePublisher.java deleted file mode 100644 index 411896e..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangePublisher.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.irs.directfile.status.services; - -import gov.irs.directfile.models.message.Publisher; - -public interface StatusChangePublisher extends Publisher { - // Just a marker interface to allow Spring to inject all the publishers for this message type -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSnsPublisher.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSnsPublisher.java deleted file mode 100644 index d2258f9..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSnsPublisher.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.status.services; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sns.SnsClient; - -import gov.irs.directfile.models.message.SnsPublisher; -import gov.irs.directfile.status.config.SnsConfiguration; - -@Service -@ConditionalOnProperty(value = "status.sns.status-change-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(SnsConfiguration.class) -public class StatusChangeSnsPublisher extends SnsPublisher implements StatusChangePublisher { - public StatusChangeSnsPublisher(SnsClient snsClient, SnsConfiguration snsConfiguration) { - super(snsClient, snsConfiguration.getStatusChangeTopicArn()); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSqsPublisher.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSqsPublisher.java deleted file mode 100644 index 7309ff5..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/StatusChangeSqsPublisher.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.status.services; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sqs.SqsClient; - -import gov.irs.directfile.models.message.SqsPublisher; -import gov.irs.directfile.status.config.MessageQueueConfiguration; - -@Service -@ConditionalOnProperty(value = "status.messageQueue.status-change-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(MessageQueueConfiguration.class) -public class StatusChangeSqsPublisher extends SqsPublisher implements StatusChangePublisher { - public StatusChangeSqsPublisher(SqsClient sqsClient, MessageQueueConfiguration messageQueueConfiguration) { - super(sqsClient, messageQueueConfiguration.getStatusChangeQueue()); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouter.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouter.java deleted file mode 100644 index f40692f..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouter.java +++ /dev/null @@ -1,63 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.status.services.handlers.confirmation.SubmissionConfirmationHandler; -import gov.irs.directfile.status.services.handlers.confirmation.SubmissionConfirmationV1Handler; -import gov.irs.directfile.status.services.handlers.confirmation.SubmissionConfirmationV2Handler; -import gov.irs.directfile.status.services.handlers.confirmation.UnsupportedMessageVersionHandler; - -@Service -public class SubmissionConfirmationMessageRouter { - private final Map handlers = new HashMap<>(); - private final UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - public SubmissionConfirmationMessageRouter( - UnsupportedMessageVersionHandler unsupportedMessageVersionHandler, - SubmissionConfirmationV1Handler submissionConfirmationV1Handler, - SubmissionConfirmationV2Handler submissionConfirmationV2Handler) { - this.unsupportedMessageVersionHandler = unsupportedMessageVersionHandler; - this.handlers.put(SubmissionConfirmationMessageVersion.V1, submissionConfirmationV1Handler); - this.handlers.put(SubmissionConfirmationMessageVersion.V2, submissionConfirmationV2Handler); - } - - public void handleSubmissionConfirmationMessage( - VersionedSubmissionConfirmationMessage message) { - QueueMessageHeaders headers = message.getHeaders(); - Optional versionOptional = headers.getAttribute(MessageHeaderAttribute.VERSION); - - // We can assume a version number is present here since a VersionedSubmissionConfirmationMessage - // mandates that on construction. - - // Get enum for this version (may throw UnsupportedVersionException which we should handle and - // rethrow to get message back on queue/DLQ). - SubmissionConfirmationMessageVersion version; - try { - version = SubmissionConfirmationMessageVersion.getEnum(versionOptional.get()); - } catch (UnsupportedVersionException e) { - unsupportedMessageVersionHandler.handleSubmissionConfirmationMessage(message); - throw e; - } - - // Get handler. If not found, we have an unsupported version so handle and throw exception. - SubmissionConfirmationHandler handler = handlers.get(version); - if (handler == null) { - unsupportedMessageVersionHandler.handleSubmissionConfirmationMessage(message); - throw new UnsupportedVersionException(String.format( - "No handler found for SubmissionConfirmationMessageVersion (%s)", version.getVersion())); - } - - // We should have a good handler, so handle the message. - handler.handleSubmissionConfirmationMessage(message); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationHandler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationHandler.java deleted file mode 100644 index c1d51e9..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; - -public interface SubmissionConfirmationHandler { - void handleSubmissionConfirmationMessage( - VersionedSubmissionConfirmationMessage message); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1Handler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1Handler.java deleted file mode 100644 index 44456f5..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1Handler.java +++ /dev/null @@ -1,65 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import java.util.List; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV1; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; -import gov.irs.directfile.status.domain.TaxReturnSubmission; - -/** - * @deprecated V1 messages are no longer sent, but keeping handlers until we are sure queues are V1-free - */ -@Deprecated -@Service -@Slf4j -public class SubmissionConfirmationV1Handler implements SubmissionConfirmationHandler { - private final PendingAcknowledgementRepository pendingRepo; - private final TaxReturnSubmissionRepository taxReturnSubmissionRepo; - private final StatusProperties statusProperties; - - public SubmissionConfirmationV1Handler( - PendingAcknowledgementRepository pendingRepo, - TaxReturnSubmissionRepository taxReturnSubmissionRepo, - StatusProperties statusProperties) { - - this.pendingRepo = pendingRepo; - this.taxReturnSubmissionRepo = taxReturnSubmissionRepo; - this.statusProperties = statusProperties; - } - - @Override - public void handleSubmissionConfirmationMessage( - VersionedSubmissionConfirmationMessage message) { - SubmissionConfirmationPayloadV1 payload = (SubmissionConfirmationPayloadV1) message.getPayload(); - List taxReturnSubmissionReceipts = payload.getReceipts(); - - StringBuilder sb = new StringBuilder(); - sb.append("Received submission confirmation V1 message for tax return ids:"); - taxReturnSubmissionReceipts.forEach( - taxReturnSubmissionReceipt -> sb.append(" ").append(taxReturnSubmissionReceipt.getTaxReturnId())); - log.info(sb.toString()); - - List pendings = taxReturnSubmissionReceipts.stream() - .map(taxReturnSubmissionReceipt -> - new Pending(taxReturnSubmissionReceipt.getSubmissionId(), statusProperties.getApplicationId())) - .toList(); - - List taxReturnSubmissions = taxReturnSubmissionReceipts.stream() - .map(taxReturnSubmissionReceipt -> new TaxReturnSubmission( - taxReturnSubmissionReceipt.getTaxReturnId(), taxReturnSubmissionReceipt.getSubmissionId())) - .toList(); - - log.info(String.format("Saving %s pendings", pendings.size())); - pendingRepo.saveAll(pendings); - taxReturnSubmissionRepo.saveAll(taxReturnSubmissions); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2Handler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2Handler.java deleted file mode 100644 index 7b3b6dd..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2Handler.java +++ /dev/null @@ -1,68 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import java.util.ArrayList; -import java.util.List; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; -import gov.irs.directfile.status.domain.TaxReturnSubmission; - -@Service -@Slf4j -@AllArgsConstructor -public class SubmissionConfirmationV2Handler implements SubmissionConfirmationHandler { - private final PendingAcknowledgementRepository pendingRepo; - private final TaxReturnSubmissionRepository taxReturnSubmissionRepo; - private final StatusProperties statusProperties; - - @Override - public void handleSubmissionConfirmationMessage( - VersionedSubmissionConfirmationMessage message) { - SubmissionConfirmationPayloadV2 payload = (SubmissionConfirmationPayloadV2) message.getPayload(); - - // Note that for the pending submission queue, we only need to process SUBMITTED tax return - // events. FAILED events are also sent via the submission confirmation SNS topic subscription, - // but can be ignored here since they aren't considered pending submissions. - List submittedTaxReturnSubmissionReceipts = new ArrayList<>(); - payload.getEntries().forEach(entry -> { - if (SubmissionEventTypeEnum.SUBMITTED.equals(entry.getEventType())) { - submittedTaxReturnSubmissionReceipts.add(entry.getTaxReturnSubmissionReceipt()); - } - }); - - // If we did not get any SUBMITTED returns, then we're done. - if (submittedTaxReturnSubmissionReceipts.isEmpty()) return; - - // Otherwise, save the database records for the SUBMITTED returns. - StringBuilder sb = new StringBuilder(); - sb.append("Received SUBMITTED submission confirmation V2 message for tax return ids:"); - submittedTaxReturnSubmissionReceipts.forEach( - taxReturnSubmissionReceipt -> sb.append(" ").append(taxReturnSubmissionReceipt.getTaxReturnId())); - log.info(sb.toString()); - - List pendings = submittedTaxReturnSubmissionReceipts.stream() - .map(taxReturnSubmissionReceipt -> - new Pending(taxReturnSubmissionReceipt.getSubmissionId(), statusProperties.getApplicationId())) - .toList(); - - List taxReturnSubmissions = submittedTaxReturnSubmissionReceipts.stream() - .map(taxReturnSubmissionReceipt -> new TaxReturnSubmission( - taxReturnSubmissionReceipt.getTaxReturnId(), taxReturnSubmissionReceipt.getSubmissionId())) - .toList(); - - log.info(String.format("Saving %s pendings", pendings.size())); - pendingRepo.saveAll(pendings); - taxReturnSubmissionRepo.saveAll(taxReturnSubmissions); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/UnsupportedMessageVersionHandler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/UnsupportedMessageVersionHandler.java deleted file mode 100644 index 2253e46..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/confirmation/UnsupportedMessageVersionHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; - -@Service("SubmissionConfirmationUnsupportedMessageVersionHandler") -@Slf4j -public class UnsupportedMessageVersionHandler implements SubmissionConfirmationHandler { - @Override - public void handleSubmissionConfirmationMessage( - VersionedSubmissionConfirmationMessage payload) { - log.error("Unable to process Submission Confirmation Message. Headers: {} ", payload.getHeaders()); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionHandler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionHandler.java deleted file mode 100644 index bfd0143..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionHandler.java +++ /dev/null @@ -1,8 +0,0 @@ -package gov.irs.directfile.status.services.handlers.pending; - -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; - -public interface PendingSubmissionHandler { - void handlePendingSubmissionMessage(VersionedPendingSubmissionMessage message); -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1Handler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1Handler.java deleted file mode 100644 index 74b7a99..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1Handler.java +++ /dev/null @@ -1,64 +0,0 @@ -package gov.irs.directfile.status.services.handlers.pending; - -import java.util.List; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.models.message.pending.payload.PendingSubmissionPayloadV1; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; -import gov.irs.directfile.status.domain.TaxReturnSubmission; - -@Service -@Slf4j -public class PendingSubmissionV1Handler implements PendingSubmissionHandler { - private final PendingAcknowledgementRepository pendingRepo; - private final TaxReturnSubmissionRepository taxReturnSubmissionRepo; - private final StatusProperties statusProperties; - - public PendingSubmissionV1Handler( - PendingAcknowledgementRepository pendingRepo, - TaxReturnSubmissionRepository taxReturnSubmissionRepo, - StatusProperties statusProperties) { - this.pendingRepo = pendingRepo; - this.taxReturnSubmissionRepo = taxReturnSubmissionRepo; - this.statusProperties = statusProperties; - } - - @Override - public void handlePendingSubmissionMessage( - VersionedPendingSubmissionMessage message) { - PendingSubmissionPayloadV1 payload = (PendingSubmissionPayloadV1) message.getPayload(); - List taxReturnIdAndSubmissionIds = payload.getPendings(); - - StringBuilder sb = new StringBuilder(); - sb.append("Received pending submission V1 message for tax return ids:"); - taxReturnIdAndSubmissionIds.forEach( - taxReturnIdAndSubmissionId -> sb.append(" ").append(taxReturnIdAndSubmissionId.getTaxReturnId())); - log.info(sb.toString()); - - List pendings = taxReturnIdAndSubmissionIds.stream() - .map(taxReturnIdAndSubmissionId -> { - Pending pending = new Pending(); - pending.setSubmissionId(taxReturnIdAndSubmissionId.getSubmissionId()); - pending.setPodId(statusProperties.getApplicationId()); - return pending; - }) - .toList(); - - List taxReturnSubmissions = taxReturnIdAndSubmissionIds.stream() - .map(taxReturnIdAndSubmissionId -> new TaxReturnSubmission( - taxReturnIdAndSubmissionId.getTaxReturnId(), taxReturnIdAndSubmissionId.getSubmissionId())) - .toList(); - - log.info(String.format("Saving %s pendings", pendings.size())); - pendingRepo.saveAll(pendings); - taxReturnSubmissionRepo.saveAll(taxReturnSubmissions); - } -} diff --git a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/UnsupportedMessageVersionHandler.java b/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/UnsupportedMessageVersionHandler.java deleted file mode 100644 index 9e8f3fc..0000000 --- a/direct-file/status/src/main/java/gov/irs/directfile/status/services/handlers/pending/UnsupportedMessageVersionHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.status.services.handlers.pending; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; - -@Service -@Slf4j -public class UnsupportedMessageVersionHandler implements PendingSubmissionHandler { - @Override - public void handlePendingSubmissionMessage( - VersionedPendingSubmissionMessage payload) { - log.error("Unable to process Pending Submission Message. Headers: {} ", payload.getHeaders()); - } -} diff --git a/direct-file/status/src/main/resources/application-development.yaml b/direct-file/status/src/main/resources/application-development.yaml deleted file mode 100644 index ef30766..0000000 --- a/direct-file/status/src/main/resources/application-development.yaml +++ /dev/null @@ -1,11 +0,0 @@ -status: - status-endpoint-returns-pending-by-default-enabled: false - messageQueue: - sqs-message-handling-enabled: true - -direct-file: - local-encryption: - local-wrapping-key: ${LOCAL_WRAPPING_KEY} - -server: - port: 8082 diff --git a/direct-file/status/src/main/resources/application-docker.yaml b/direct-file/status/src/main/resources/application-docker.yaml deleted file mode 100644 index ac61955..0000000 --- a/direct-file/status/src/main/resources/application-docker.yaml +++ /dev/null @@ -1,19 +0,0 @@ -spring: - datasource: - url: jdbc:postgresql://mef-apps-db:5432/directfile-status - -status: - toolkit: /mef-client-sdk-src - status-endpoint-returns-pending-by-default-enabled: false - messageQueue: - endpoint: http://localstack:4566 - sqs-message-handling-enabled: true - sns: - endpoint: http://localstack:4566 - documentstore: - endpoint: http://localstack:4566/ - -# these defaults are to match the backend (update/remove once we're fully onto sqs) -direct-file: - local-encryption: - local-wrapping-key: ${LOCAL_WRAPPING_KEY} diff --git a/direct-file/status/src/main/resources/application.yaml b/direct-file/status/src/main/resources/application.yaml deleted file mode 100644 index 9c6c84b..0000000 --- a/direct-file/status/src/main/resources/application.yaml +++ /dev/null @@ -1,98 +0,0 @@ -spring: - datasource: - username: postgres - password: postgres - url: jdbc:postgresql://localhost:${MEF_APPS_DB_PORT:32768}/directfile-status - jpa: - hibernate: - ddl-auto: none - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect - # Batching insert/update/delete - # https://docs.jboss.org/hibernate/orm/6.4/userguide/html_single/Hibernate_User_Guide.html#batch - jdbc: - batch_size: 30 # Hibernate docs recommend a value between 10 and 50 - # Not turning on order_inserts or order_updates since we already generally save as a group - # Hibernate disables batching for entities having an identity PK, so tax_return_submission won't batch - liquibase: - change-log: classpath:db/changelog.yaml - url: ${spring.datasource.url} - user: ${spring.datasource.username} - password: ${spring.datasource.password} - hikari: - maximum-pool-size: 50 - max-lifetime: 450000 - minimum-idle: 30 - connection-timeout: 15000 - -server: - shutdown: graceful - -status: - # base64-encode the DER-formatted keystore and pass as `keystore-base64` - keystore-base64: MISSING - keystore-password: MISSING - keystore-alias: MISSING - application-id: ${POD_NAME:dfsys-mef-status-deployment-0}-${DF_AWS_REGION:us-gov-east-1} - etin: ${STATUS_ETIN:99999} - asid: 000 - efin: 000 - prod: false - unit-testing: false - root-translation-key: status - translation-key-splitter: . - ack-poll-in-milliseconds: 60000 - # this field controls whether a Pending Response is returned from the /status endpoint when no submisionId is found. - # we will want to disable this in the future (likely when SQS communication is enabled). - status-endpoint-returns-pending-by-default-enabled: true - status-polling-enabled: true - messageQueue: - endpoint: http://localhost:4566 - status-change-queue: status-change-queue - pending-submission-queue: pending-submission-queue - dlq-pending-submission-queue: dlq-pending-submission-queue - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - sqs-message-handling-enabled: false - status-change-publish-enabled: false - sns: - endpoint: http://localhost:4566 - status-change-topic-arn: arn:aws:sns:us-west-2:000000000000:status-change-topic - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - status-change-publish-enabled: true - documentstore: - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - assume-role-arn: assume-role-arn-placeholder - assume-role-duration-seconds: 1800 - assume-role-session-name: "df-status" - endpoint: http://localhost:4566/ - bucket: direct-file-taxreturns - prefix: - -aws: - enabled: false - default-credentials-provider-chain-enabled: false - access-key: accessKey - secret-key: secretKey - -direct-file: - local-encryption: - local-wrapping-key: ${LOCAL_WRAPPING_KEY:-} - -management: - endpoint: - health: - enabled: true - endpoints: - enabled-by-default: false - web: - discovery: - enabled: false - exposure: - include: health diff --git a/direct-file/status/src/main/resources/banner.txt b/direct-file/status/src/main/resources/banner.txt deleted file mode 100644 index 71185a9..0000000 --- a/direct-file/status/src/main/resources/banner.txt +++ /dev/null @@ -1,32 +0,0 @@ - @@@@ - (..@ ( @ .@@@@ @@@@/*@#@@@. .@@(@&@@/&@ * * * . - . @ @@@@@@@@@ &@@@(@@@@@@ .@/@@@@@@./@@@*@(@@@. , - . @& &@&/@%@@@ ,&&@@&#@@@@ &%@@&. (@@@@(@@#@@(& - @@&@@#%& /@@@&@(@@% @@@@@@@@( @@@@@ @/&@@ #@@@@&&@ - @%@#%%@@@ @@@&&@@(&#%% . %&#(@& @@@@@( @@&@@ - @@&%@@#@@ @@%%@@ / # . %##@@@ @&&@@ %@@&@ &%@#@ - #&@%/@@%@ #&@ . @@@&@(#@&#@@@ @&@&#@@&&#(@&& #/@&@ ,@@@(# - @(@#(@@@ @& %@/*&( ,&%(@*@ #@%@@* @@@@(@*@@@( @@&@& - ((, @ @@&@ @@@@@@ @&(&/@&&@@@@/ , @&&% @&(@& @@@%@@@@%/ %@@(@ -,@@@ @@ #@@@@@#@@ @@&@. , .*@. @/@#@ .@@@@@@@@@ (#@*@ (/@@@ -@@(@&/ @@%@&/@%@@* #@@@%@@/*#@&@@ @@#@@, @@/@@ @/# @@@@@,@@@@@ -@*@(@@@% @@@(@@@@(@ . &@@@ @ @@(@@. @.&@&* *#@& &(@@@ #@@*@ - @@@/@/@@*@@@#@@@@ /@@@ &@@@* %@&@#. @@&@,,&@@@& @&(@ - @(@&@@@@@@@&@/ @ @ @@@@, * @@*/&%@@,@@( *@@/@@ @@@@@ @@@@ - &@@@@%@&%@ % . (@@# *@&*@(@&@@@ * @@@&@ &&#&@ &@@@ - @@@&@@@ &@@&@ ( &(@% * @#@#@@&%@ &@@@%, .@@@@@ #@@@ - *@@% ##@%@@ * @#@% ( / #@%&@&@ (#@#%@ #@&@@@ %@@@@ -@%& @ &@&@@@&@ @%@@&@@@&%@@%@&#@%@@%(&@ @@%@&@ (@@@@@% %#&&%# /#@@@@ - @#@@@ #@@&#(@@&( @&@#&#@(&&&@@@%%(#@@&&#%%@ @ ( &#%&% @@%@@@ %@@%@ - @@@(&&( @@&@@/@@@ @(@@@@@@ @@&@ @#@&@@@& &@%&/% &@@(@, @(*@* - (@#@@@@@@@@@@(@@ ,@&(@@.#@@&& &@@@ @#@@@@@@@& , @@@@( /@/@#( @@@@& - *@%@@@@@@&@&@@. @@#%@ @@@,@ ,@@#% @(%,@ . @@@@, @/,@(@ @@@@* - .(&&@/@%/@&@ @ @@@@@ @&@@@ (. @*@@ #@@@& ,(@@@, &@@@@# @@(@@ - &*@@@@@@@@# &@@@# . &@@%@ @*@@( .@@*@@ *@@@@@ @*@@( @#@@@ - /@@@&&@#& #@@&@%( @@@@* %@@@@# @@%@@ @@@@@& ,/@ - @@@@, /@@*@( /(&&@, &@@@@ @ @@&@( , @@@@@ . - . &(@%@@@@&@@&&&@@@&*@@@@@@*@@&&@@&#/@@@@@@ @&@/ . - ( &#@%#@#@%%# #@@@@#@&&#@ # - -${application.title} (${application.version}) -Spring Boot ${spring-boot.version} diff --git a/direct-file/status/src/main/resources/db/changelog.yaml b/direct-file/status/src/main/resources/db/changelog.yaml deleted file mode 100644 index 824a0e4..0000000 --- a/direct-file/status/src/main/resources/db/changelog.yaml +++ /dev/null @@ -1,7 +0,0 @@ -databaseChangeLog: - - preConditions: - onFail: HALT - onError: HALT - - includeAll: - path: migrations/ - relativeToChangelogFile: true diff --git a/direct-file/status/src/main/resources/db/migrations/000-initial-schema-status.yaml b/direct-file/status/src/main/resources/db/migrations/000-initial-schema-status.yaml deleted file mode 100644 index da770c4..0000000 --- a/direct-file/status/src/main/resources/db/migrations/000-initial-schema-status.yaml +++ /dev/null @@ -1,196 +0,0 @@ -databaseChangeLog: -- changeSet: - id: 1704409188607-1 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: completed - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: completed_pkey - name: submission_id - type: VARCHAR(20) - - column: - name: status - type: VARCHAR(20) - - column: - name: tax_return_id - type: VARCHAR(255) - tableName: completed -- changeSet: - id: 1704409188607-2 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: completed-errors - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - name: submission_id - type: VARCHAR(20) - - column: - constraints: - nullable: false - name: mef_error_code - type: VARCHAR(25) - tableName: completed-errors -- changeSet: - id: 1704409188607-3 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: error - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: error_pkey - name: meferror_code - type: VARCHAR(25) - - column: - name: error_code_translation_key - type: VARCHAR(255) - - column: - name: meferror_category - type: VARCHAR(255) - - column: - name: meferror_message - type: BLOB - tableName: error -- changeSet: - id: 1704409188607-4 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: pending - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: pending_pkey - name: submission_id - type: VARCHAR(20) - - column: - name: error_message - type: VARCHAR(255) - - column: - name: status - type: VARCHAR(20) - tableName: pending -- changeSet: - id: 1704409188607-5 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: tax_return_identifier - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: tax_return_identifier_pkey - name: tax_return_id - type: UUID - - column: - name: submission_id - type: VARCHAR(20) - tableName: tax_return_identifier -- changeSet: - id: 1704409188607-6 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: toolkit_error - changes: - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: toolkit_error_pkey - name: submission_id - type: VARCHAR(255) - - column: - constraints: - nullable: false - name: error_message - type: VARCHAR(255) - - column: - constraints: - nullable: false - name: error_name - type: VARCHAR(255) - tableName: toolkit_error -- changeSet: - id: 1704409188607-7 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: completed - - tableExists: - - tableName: completed-errors - changes: - - addForeignKeyConstraint: - baseColumnNames: submission_id - baseTableName: completed-errors - constraintName: fkd6wcrt7yp7rypmyf365wlrely - deferrable: false - initiallyDeferred: false - onDelete: NO ACTION - onUpdate: NO ACTION - referencedColumnNames: submission_id - referencedTableName: completed - validate: true -- changeSet: - id: 1704409188607-8 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: error - - tableExists: - - tableName: completed-errors - changes: - - addForeignKeyConstraint: - baseColumnNames: mef_error_code - baseTableName: completed-errors - constraintName: fkhq7kqsddr2k6uauh9gg47bfis - deferrable: false - initiallyDeferred: false - onDelete: NO ACTION - onUpdate: NO ACTION - referencedColumnNames: meferror_code - referencedTableName: error - validate: true diff --git a/direct-file/status/src/main/resources/db/migrations/20240102154200-add-created_at.yaml b/direct-file/status/src/main/resources/db/migrations/20240102154200-add-created_at.yaml deleted file mode 100644 index a112516..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240102154200-add-created_at.yaml +++ /dev/null @@ -1,77 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-created_at - author: irs-123 - comment: add createdAt columns for various tables - changes: - - addColumn: - tableName: pending - columns: - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - - addColumn: - tableName: completed - columns: - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - - addColumn: - tableName: toolkit_error - columns: - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - - addColumn: - tableName: error - columns: - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - - addColumn: - tableName: tax_return_identifier - columns: - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - rollback: - - dropColumn: - tableName: error - columns: - - column: - name: created_at - - dropColumn: - tableName: completed - columns: - - column: - name: created_at - - dropColumn: - tableName: pending - columns: - - column: - name: created_at - - dropColumn: - tableName: toolkit_error - columns: - - column: - name: created_at - - dropColumn: - tableName: tax_return_identifier - columns: - - column: - name: created_at diff --git a/direct-file/status/src/main/resources/db/migrations/20240108152400-add-error-message.yaml b/direct-file/status/src/main/resources/db/migrations/20240108152400-add-error-message.yaml deleted file mode 100644 index bf2492c..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240108152400-add-error-message.yaml +++ /dev/null @@ -1,18 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-error-message - author: irs-123 - comment: add error_message field to error table - changes: - - addColumn: - tableName: error - columns: - - column: - name: error_message - type: TEXT - rollback: - - dropColumn: - tableName: error - columns: - - column: - name: error_message diff --git a/direct-file/status/src/main/resources/db/migrations/20240108153300-delete-lob-error-message.yaml b/direct-file/status/src/main/resources/db/migrations/20240108153300-delete-lob-error-message.yaml deleted file mode 100644 index fee4682..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240108153300-delete-lob-error-message.yaml +++ /dev/null @@ -1,18 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-error-message - author: irs-123 - comment: delete meferror_message field from error table - changes: - - dropColumn: - tableName: error - columns: - - column: - name: meferror_message - rollback: - - addColumn: - tableName: error - columns: - - column: - name: meferror_message - type: BLOB diff --git a/direct-file/status/src/main/resources/db/migrations/20240112100800-add-taxreturn-submission-table.yaml b/direct-file/status/src/main/resources/db/migrations/20240112100800-add-taxreturn-submission-table.yaml deleted file mode 100644 index ea67b70..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240112100800-add-taxreturn-submission-table.yaml +++ /dev/null @@ -1,31 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-taxreturn-submission-table - author: irs-123 - comment: create tax_return_submission join table - changes: - - createTable: - columns: - - column: - name: id - type: serial - constraints: - nullable: false - primaryKey: true - primaryKeyName: tax_return_id_submission_id_pkey - - column: - name: tax_return_id - type: UUID - - column: - name: submission_id - type: VARCHAR(20) - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - tableName: tax_return_submission - rollback: - - dropTable: - tableName: tax_return_submission diff --git a/direct-file/status/src/main/resources/db/migrations/20240401154901-add-indices.yaml b/direct-file/status/src/main/resources/db/migrations/20240401154901-add-indices.yaml deleted file mode 100644 index d3ca3c7..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240401154901-add-indices.yaml +++ /dev/null @@ -1,40 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-indices-status-app - author: irs-123 - comment: add indices to status app - - changes: - - createIndex: - indexName: completed_tax_return_id_idx - tableName: completed - columns: - - column: - name: tax_return_id - - createIndex: - indexName: tax_return_submission_tax_return_id_idx - tableName: tax_return_submission - columns: - - column: - name: tax_return_id - - createIndex: - indexName: completed_errors_submission_id_idx - tableName: completed-errors - columns: - - column: - name: submission_id - - createIndex: - indexName: completed_errors_mef_error_code_idx - tableName: completed-errors - columns: - - column: - name: mef_error_code - rollback: - - dropIndex: - indexName: completed_tax_return_id_idx - - dropIndex: - indexName: tax_return_submission_tax_return_id_idx - - dropIndex: - indexName: completed_error_submission_id_idx - - dropIndex: - indexName: completed_error_mef_error_code_idx diff --git a/direct-file/status/src/main/resources/db/migrations/20240726130000-fk-completed-errror.yaml b/direct-file/status/src/main/resources/db/migrations/20240726130000-fk-completed-errror.yaml deleted file mode 100644 index f1bece3..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20240726130000-fk-completed-errror.yaml +++ /dev/null @@ -1,36 +0,0 @@ -databaseChangeLog: - - changeSet: - id: fk-completed-error - author: irs-123 - comment: add foreign key constraint on m2m join between completed and error tables - changes: - changes: - - addForeignKeyConstraint: - baseColumnNames: submission_id - baseTableName: completed-errors - constraintName: completed_error_submission_id_fk - deferrable: false - initiallyDeferred: false - onDelete: NO ACTION - onUpdate: NO ACTION - referencedColumnNames: submission_id - referencedTableName: completed - validate: true - - addForeignKeyConstraint: - baseColumnNames: mef_error_code - baseTableName: completed-errors - constraintName: completed_error_mef_error_code_fk - deferrable: false - initiallyDeferred: false - onDelete: NO ACTION - onUpdate: NO ACTION - referencedColumnNames: meferror_code - referencedTableName: error - validate: true - rollback: - - dropForeignKeyConstraint: - baseTableName: completed-errors - constraintName: completed_error_submission_id_fk - - dropForeignKeyConstraint: - baseTableName: completed-errors - constraintName: completed_error_mef_error_code_fk diff --git a/direct-file/status/src/main/resources/db/migrations/20241107100000-drop-unused-columns-from-completed-and-pending-tables-and-drop-tax-return-identifier-table.yaml b/direct-file/status/src/main/resources/db/migrations/20241107100000-drop-unused-columns-from-completed-and-pending-tables-and-drop-tax-return-identifier-table.yaml deleted file mode 100644 index 9e69da9..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20241107100000-drop-unused-columns-from-completed-and-pending-tables-and-drop-tax-return-identifier-table.yaml +++ /dev/null @@ -1,63 +0,0 @@ -databaseChangeLog: - - changeSet: - id: drop-unused-columns-from-completed-and-pending-tables-and-drop-tax-return-identifier-table - author: irs-123 - comment: drop tax_return_id column from completed, drop error_message and status columns from pending, drop tax_return_identifier table - changes: - - dropIndex: - indexName: completed_tax_return_id_idx - - dropColumn: - tableName: completed - columns: - - column: - name: tax_return_id - - dropColumn: - tableName: pending - columns: - - column: - name: error_message - - column: - name: status - - dropTable: - tableName: tax_return_identifier - rollback: - - addColumn: - tableName: completed - columns: - - column: - name: tax_return_id - type: VARCHAR(255) - - createIndex: - indexName: completed_tax_return_id_idx - tableName: completed - columns: - - column: - name: tax_return_id - - addColumn: - tableName: pending - columns: - - column: - name: error_message - type: TEXT - - column: - name: status - type: TEXT - - createTable: - columns: - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: tax_return_identifier_pkey - name: tax_return_id - type: UUID - - column: - name: submission_id - type: VARCHAR(20) - - column: - name: created_at - type: TIMESTAMP WITHOUT TIME ZONE - defaultValueComputed: CURRENT_TIMESTAMP - constraints: - nullable: false - tableName: tax_return_identifier diff --git a/direct-file/status/src/main/resources/db/migrations/202411151117000-add-pod-identifier-table.yaml b/direct-file/status/src/main/resources/db/migrations/202411151117000-add-pod-identifier-table.yaml deleted file mode 100644 index b07ab2e..0000000 --- a/direct-file/status/src/main/resources/db/migrations/202411151117000-add-pod-identifier-table.yaml +++ /dev/null @@ -1,29 +0,0 @@ -databaseChangeLog: - - changeSet: - id: pod-identifier-table - author: 123 (generated) - comment: create pod_identifier table - - changes: - - createTable: - columns: - - column: - name: id - type: serial - constraints: - nullable: false - primaryKey: true - primaryKeyName: pod_identifier_id_pkey - - column: - name: asid - type: VARCHAR(50) - - column: - name: region - type: VARCHAR(50) - - column: - name: pod_id - type: VARCHAR(255) - tableName: pod_identifier - rollback: - - dropTable: - tableName: pod_identifier diff --git a/direct-file/status/src/main/resources/db/migrations/20250104094800-add-pod-id-column-pending.yaml b/direct-file/status/src/main/resources/db/migrations/20250104094800-add-pod-id-column-pending.yaml deleted file mode 100644 index fbab888..0000000 --- a/direct-file/status/src/main/resources/db/migrations/20250104094800-add-pod-id-column-pending.yaml +++ /dev/null @@ -1,18 +0,0 @@ -databaseChangeLog: - - changeSet: - id: add-pod-id-column-pending - author: 123 (generated) - comment: add pod_id column to pending table - changes: - - addColumn: - tableName: pending - columns: - - column: - name: pod_id - type: VARCHAR(255) - rollback: - - dropColumn: - tableName: pending - columns: - - column: - name: pod_id diff --git a/direct-file/status/src/main/resources/logback.xml b/direct-file/status/src/main/resources/logback.xml deleted file mode 100644 index ffd0499..0000000 --- a/direct-file/status/src/main/resources/logback.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - timestamp - [ignore] - [ignore] - [ignore] - - yyyy-MM-dd'T'HH:mm:ss.SSS'Z' - UTC - {"system":"DIRECTFILE","eventType":"STATUS","version":"${GIT_COMMIT_HASH}"}} - - - - - - - - diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementControllerTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementControllerTest.java deleted file mode 100644 index 6c74dc1..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementControllerTest.java +++ /dev/null @@ -1,423 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Stream; - -import ch.qos.logback.classic.Level; -import jakarta.persistence.EntityNotFoundException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.http.HttpStatus; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.AuditService; -import gov.irs.directfile.audit.events.*; -import gov.irs.directfile.models.RejectedStatus; -import gov.irs.directfile.status.acknowledgement.domain.AcknowledgementStatus; -import gov.irs.directfile.status.acknowledgement.domain.Status; -import gov.irs.directfile.status.config.SnsClientTestConfiguration; -import gov.irs.directfile.status.extension.LoggerExtension; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@SpringBootTest -@AutoConfigureMockMvc -@TestPropertySource(properties = {"status.xml-headers-to-be-removed="}) -@Import(SnsClientTestConfiguration.class) -class AcknowledgementControllerTest { - @Autowired - private MockMvc mockMvc; - - @MockBean - private AcknowledgementService acknowledgementService; - - @RegisterExtension - public static LoggerExtension logVerifier = new LoggerExtension(Level.INFO, AuditService.class.getName()); - - private static String X_FORWARDED_FOR = "X-Forwarded-For"; - private static final String TEST_IP_ADDR1 = "10.1.2.1"; - private static final String TEST_IP_ADDR2 = "10.1.2.2"; - private static final String REMOTE_IP_ADDR = "10.1.2.3"; - - @Test - public void status_whenAcknowledgementServiceReturnsPendingStatus_endpointReturnsOkResponse() throws Exception { - AcknowledgementStatus acknowledgementStatus = - new AcknowledgementStatus(Status.Pending, "", List.of(), new Date()); - UUID taxReturnId = UUID.randomUUID(); - - when(acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(eq(taxReturnId))) - .thenReturn("1234567890"); - when(acknowledgementService.GetAcknowledgement(eq(taxReturnId), eq("1234567890"))) - .thenReturn(acknowledgementStatus); - - this.mockMvc - .perform(get("/status") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("id", taxReturnId.toString())) - .andExpect(status().isOk()); - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.SUCCESS) - .mefSubmissionId("1234567890") - .build(), - Map.of( - AuditLogElement.taxReturnId, - taxReturnId.toString(), - AuditLogElement.responseStatusCode, - HttpStatus.OK.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void status_whenAcknowledgementServiceReturnsNull_endpointReturnsNotFoundResponse() throws Exception { - UUID taxReturnId = UUID.randomUUID(); - - when(acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(eq(taxReturnId))) - .thenReturn("1234567890"); - when(acknowledgementService.GetAcknowledgement(eq(taxReturnId), eq("1234567890"))) - .thenReturn(null); - - this.mockMvc - .perform(get("/status") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("id", taxReturnId.toString())) - .andExpect(status().isNotFound()); - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.FAILURE) - .build(), - Map.of( - AuditLogElement.taxReturnId, - taxReturnId.toString(), - AuditLogElement.responseStatusCode, - HttpStatus.NOT_FOUND.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void status_whenAcknowledgementServiceThrowsException_endpointReturnsBadRequestResponse() throws Exception { - UUID taxReturnId = UUID.randomUUID(); - - when(acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(eq(taxReturnId))) - .thenReturn("1234567890"); - when(acknowledgementService.GetAcknowledgement(eq(taxReturnId), eq("1234567890"))) - .thenThrow(new NullPointerException("Error occurred")); - - this.mockMvc - .perform(get("/status") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("id", taxReturnId.toString())) - .andExpect(status().isBadRequest()); - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{errorMessage=Error occurred}") - .eventErrorMessage("java.lang.NullPointerException") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.FAILURE) - .build(), - Map.of( - AuditLogElement.taxReturnId, - taxReturnId.toString(), - AuditLogElement.responseStatusCode, - HttpStatus.BAD_REQUEST.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void status_endpointHitWithInvalidUUID_endpointReturnsBadRequestResponse() throws Exception { - String invalidUUIDString = "12323123231321"; - - this.mockMvc.perform(get("/status").param("id", invalidUUIDString)).andExpect(status().isBadRequest()); - } - - @Test - public void testRemoteIpAddress_OneIpInX_Forwarded_For() throws Exception { - AcknowledgementStatus acknowledgementStatus = - new AcknowledgementStatus(Status.Pending, "", List.of(), new Date()); - UUID taxReturnId = UUID.randomUUID(); - - when(acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(eq(taxReturnId))) - .thenReturn("1234567890"); - when(acknowledgementService.GetAcknowledgement(eq(taxReturnId), eq("1234567890"))) - .thenReturn(acknowledgementStatus); - - // 1 ip address in x-forwarded-for - this.mockMvc - .perform(get("/status") - .with(r -> { - r.addHeader(X_FORWARDED_FOR, TEST_IP_ADDR1); - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("id", taxReturnId.toString())) - .andExpect(status().isOk()); - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.SUCCESS) - .mefSubmissionId("1234567890") - .build(), - Map.of( - AuditLogElement.taxReturnId, - taxReturnId.toString(), - AuditLogElement.responseStatusCode, - HttpStatus.OK.value(), - AuditLogElement.remoteAddress, - TEST_IP_ADDR1, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void testRemoteIpAddress_TwoIpInX_Forwarded_For() throws Exception { - AcknowledgementStatus acknowledgementStatus = - new AcknowledgementStatus(Status.Pending, "", List.of(), new Date()); - UUID taxReturnId = UUID.randomUUID(); - - when(acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(eq(taxReturnId))) - .thenReturn("1234567890"); - when(acknowledgementService.GetAcknowledgement(eq(taxReturnId), eq("1234567890"))) - .thenReturn(acknowledgementStatus); - - // 2 ip addresses in x-forwarded-for - this.mockMvc - .perform(get("/status") - .with(r -> { - r.addHeader(X_FORWARDED_FOR, TEST_IP_ADDR2 + "," + TEST_IP_ADDR1); - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("id", taxReturnId.toString())) - .andExpect(status().isOk()); - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.SUCCESS) - .mefSubmissionId("1234567890") - .build(), - Map.of( - AuditLogElement.taxReturnId, - taxReturnId.toString(), - AuditLogElement.responseStatusCode, - HttpStatus.OK.value(), - AuditLogElement.remoteAddress, - TEST_IP_ADDR2, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void rejectionCodes_whenAcknowledgementServiceReturnsRejectionCodes_endpointReturnsOkResponse() - throws Exception { - List rejectionCodes = List.of( - new RejectedStatus("code1", "key1", "description1"), - new RejectedStatus("code2", "key2", "description2")); - - String submissionId = UUID.randomUUID().toString(); - - when(acknowledgementService.getRejectionCodesForSubmissionId(submissionId)) - .thenReturn(rejectionCodes); - - this.mockMvc - .perform(get("/status/rejection-codes") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("submissionId", submissionId)) - .andExpect(status().isOk()); - - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.SUCCESS) - .mefSubmissionId(submissionId) - .build(), - Map.of( - AuditLogElement.mefSubmissionId, - submissionId, - AuditLogElement.responseStatusCode, - HttpStatus.OK.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void rejectionCodes_whenAcknowledgementServiceThrowsNotFoundException_endpointReturnsNotFoundResponse() - throws Exception { - String submissionId = UUID.randomUUID().toString(); - - when(acknowledgementService.getRejectionCodesForSubmissionId(submissionId)) - .thenThrow(EntityNotFoundException.class); - - this.mockMvc - .perform(get("/status/rejection-codes") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("submissionId", submissionId)) - .andExpect(status().isNotFound()); - - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.FAILURE) - .mefSubmissionId(submissionId) - .build(), - Map.of( - AuditLogElement.mefSubmissionId, - submissionId, - AuditLogElement.responseStatusCode, - HttpStatus.NOT_FOUND.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - @Test - public void rejectionCodes_whenAcknowledgementServiceThrowsException_endpointReturnsBadRequestResponse() - throws Exception { - String submissionId = UUID.randomUUID().toString(); - - when(acknowledgementService.getRejectionCodesForSubmissionId(submissionId)) - .thenThrow(new NullPointerException("Error occurred")); - - this.mockMvc - .perform(get("/status/rejection-codes") - .with(r -> { - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("submissionId", submissionId)) - .andExpect(status().isBadRequest()); - - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{errorMessage=Error occurred}") - .eventErrorMessage("java.lang.NullPointerException") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.FAILURE) - .mefSubmissionId(submissionId) - .build(), - Map.of( - AuditLogElement.mefSubmissionId, - submissionId, - AuditLogElement.responseStatusCode, - HttpStatus.BAD_REQUEST.value(), - AuditLogElement.remoteAddress, - REMOTE_IP_ADDR, - AuditLogElement.cyberOnly, - true)); - } - - private static Stream getRejectionCodesXForwardedForParameters() { - return Stream.of( - Arguments.of(TEST_IP_ADDR1, TEST_IP_ADDR1), - Arguments.of(TEST_IP_ADDR2 + "," + TEST_IP_ADDR1, TEST_IP_ADDR2)); - } - - @ParameterizedTest - @MethodSource("getRejectionCodesXForwardedForParameters") - public void rejectionCodes_whenXForwardedFor_endpointReturnsOkResponse( - String xForwardedForValue, String expectedRemoteAddress) throws Exception { - List rejectionCodes = List.of( - new RejectedStatus("code1", "key1", "description1"), - new RejectedStatus("code2", "key2", "description2")); - - String submissionId = UUID.randomUUID().toString(); - - when(acknowledgementService.getRejectionCodesForSubmissionId(submissionId)) - .thenReturn(rejectionCodes); - - this.mockMvc - .perform(get("/status/rejection-codes") - .with(r -> { - r.addHeader(X_FORWARDED_FOR, xForwardedForValue); - r.setRemoteAddr(REMOTE_IP_ADDR); - return r; - }) - .param("submissionId", submissionId)) - .andExpect(status().isOk()); - - // verify audit log message - logVerifier.verifyLogEvent( - Event.builder() - .detail("{}") - .eventId(EventId.CHECK) - .eventPrincipal(new SystemEventPrincipal()) - .eventStatus(EventStatus.SUCCESS) - .mefSubmissionId(submissionId) - .build(), - Map.of( - AuditLogElement.mefSubmissionId, - submissionId, - AuditLogElement.responseStatusCode, - HttpStatus.OK.value(), - AuditLogElement.remoteAddress, - expectedRemoteAddress, - AuditLogElement.cyberOnly, - true)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceTest.java deleted file mode 100644 index a03b266..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceTest.java +++ /dev/null @@ -1,859 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.*; - -import jakarta.persistence.EntityNotFoundException; -import org.apache.commons.lang3.RandomStringUtils; -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.*; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.mock.mockito.MockBean; - -import gov.irs.a2a.mef.mefheader.TestCdType; -import gov.irs.mef.exception.ServiceException; -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.services.ServiceContext; -import gov.irs.mef.services.transmitter.mtom.GetAcksResult; - -import gov.irs.directfile.models.RejectedStatus; -import gov.irs.directfile.status.acknowledgement.domain.Status; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.*; -import gov.irs.directfile.status.domain.Error; -import gov.irs.directfile.status.error.ErrorRepository; -import gov.irs.directfile.status.error.ToolkitErrorRepository; -import gov.irs.directfile.status.mef.client.MeFAcksMTOMClientService; -import gov.irs.directfile.status.mef.client.MeFLoginClientService; -import gov.irs.directfile.status.mef.client.MeFLogoutClientService; -import gov.irs.directfile.status.mef.client.ServiceContextWrapper; -import gov.irs.directfile.status.repository.PodIdentifierRepository; -import gov.irs.directfile.status.services.StatusChangeMessageService; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.anySet; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.*; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@EnableConfigurationProperties(StatusProperties.class) -@ImportAutoConfiguration(classes = SecurityAutoConfiguration.class) -@DataJpaTest -@ExtendWith(MockitoExtension.class) -class AcknowledgementServiceTest { - @BeforeEach - void setUp() throws ServiceException, ToolkitException { - when(mockLoginClientService.loginWithDefaultAsid()).thenReturn(new ServiceContextWrapper(null)); - - acknowledgementService = new AcknowledgementService( - completedRepo, - pendingRepo, - taxReturnSubmissionRepository, - errorRepository, - toolkitErrorRepo, - statusProperties, - statusChangeMessageService, - mockGetAcksClientService, - mockLoginClientService, - mockLogoutClientService, - podIdentifierRepository); - } - - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - String ASID = "asid1235"; - - @Autowired - CompletedAcknowledgementRepository completedRepo; - - @Autowired - ErrorRepository errorRepository; - - @Autowired - PendingAcknowledgementRepository pendingRepo; - - @Autowired - TaxReturnSubmissionRepository taxReturnSubmissionRepository; - - @Autowired - ToolkitErrorRepository toolkitErrorRepo; - - @Autowired - PodIdentifierRepository podIdentifierRepository; - - @Autowired - StatusProperties statusProperties; - - @MockBean - private StatusChangeMessageService statusChangeMessageService; - - @MockBean - MeFAcksMTOMClientService mockGetAcksClientService; - - @MockBean - MeFLoginClientService mockLoginClientService; - - @MockBean - MeFLogoutClientService mockLogoutClientService; - - AcknowledgementService acknowledgementService; - - public PodIdentifier createPodIdentifer(String region, String asid, int index) { - PodIdentifier p = new PodIdentifier(); - p.setAsid(asid); - p.setRegion(region); - p.setPodId("dfsys-mef-status-deployment-" + index + "-" + region); - return p; - } - - @Test - void GetAcknowledgementWithACompleted() { - String submissionId = "1234562023021500001"; - UUID taxReturnId = UUID.randomUUID(); - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - Completed c = new Completed(); - c.setSubmissionId(submissionId); - c.setStatus("Accepted"); - completedRepo.save(c); - - var accepted = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Accepted, accepted.getStatus()); - } - - @Test - void GetAcknowledgementWithARejection() { - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation.reject.XML-123-4567-006"); - e.setMefErrorCategory("Reject and Stop"); - c.setErrors(List.of(e)); - errorRepository.save(e); - completedRepo.save(c); - - String submissionId = "12345620230215000001"; - UUID taxReturnId = UUID.randomUUID(); - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - var rejected = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Rejected, rejected.getStatus()); - assertEquals(1, rejected.getRejectionCodes().size()); - assertEquals("XML-123-4567-006", rejected.getRejectionCodes().getFirst().MeFErrorCode); - assertEquals("You messed up!", rejected.getRejectionCodes().getFirst().MeFDescription); - } - - @Test - void GetAcknowledgementWithMultipleRejections() { - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject"); - Error e2 = new Error(); - e2.setMefErrorCode("REJC-00001"); - e2.setErrorMessage("This was a huge problem"); - e2.setErrorCodeTranslationKey("translation/reject/REJC-00001"); - e2.setMefErrorCategory("Reject"); - c.setErrors(List.of(e, e2)); - errorRepository.saveAll(List.of(e, e2)); - completedRepo.save(c); - - String submissionId = "12345620230215000001"; - UUID taxReturnId = UUID.randomUUID(); - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - var rejected = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Rejected, rejected.getStatus()); - assertEquals(2, rejected.getRejectionCodes().size()); - assertEquals("XML-123-4567-006", rejected.getRejectionCodes().get(0).MeFErrorCode); - assertEquals("You messed up!", rejected.getRejectionCodes().get(0).MeFDescription); - assertEquals("REJC-00001", rejected.getRejectionCodes().get(1).MeFErrorCode); - assertEquals("This was a huge problem", rejected.getRejectionCodes().get(1).MeFDescription); - } - - @Test - @Disabled("This test has been flaking") - void GetAcknowledgementWithRejectionAndAcceptedReturnsLatestCompleted() { - UUID taxReturnId = UUID.randomUUID(); - String submissionId = "1234562023021500001"; - - Completed c = new Completed(); - c.setSubmissionId(submissionId); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation.reject.XML-123-4567-006"); - e.setMefErrorCategory("Reject and Stop"); - c.setErrors(List.of(e)); - errorRepository.save(e); - completedRepo.save(c); - - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - submissionId = "1234562023021500002"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - Completed c1 = new Completed(); - c1.setSubmissionId(submissionId); - c1.setStatus("Accepted"); - completedRepo.save(c1); - - var accepted = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Accepted, accepted.getStatus()); - } - - @Test - void - GetAcknowledgementWithNoTaxReturnSubmissionReturnsPendingIfStatusEndpointReturnsPendingByDefaultEnabledIsTrue() { - UUID taxReturnId = UUID.randomUUID(); - String submissionId = "1234562023021500001"; - - Completed c = new Completed(); - c.setSubmissionId(submissionId); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation.reject.XML-123-4567-006"); - e.setMefErrorCategory("Reject and Stop"); - c.setErrors(List.of(e)); - errorRepository.save(e); - completedRepo.save(c); - - var result = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Pending, result.getStatus()); - } - - @Test - void GetAcknowledgementWithPending() { - UUID taxReturnId = UUID.randomUUID(); - - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - pendingRepo.save(p); - - var pending = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Pending, pending.getStatus()); - } - - @Test - void - GetAcknowledgementWithNoPreviousLookup_ifCreatePendingUponLookupIsTrue_ReturnsPendingStatusButDoesNotSaveObjectInDB() { - UUID taxReturnId = UUID.fromString("e111c2c4-5de7-465d-8a00-b0e80caeedbc"); - var nothing = acknowledgementService.GetAcknowledgement(taxReturnId); - assertEquals(Status.Pending, nothing.getStatus()); - } - - List> createBatchSubmissionIds(List argument) - throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Method method = AcknowledgementService.class.getDeclaredMethod("batchPendings", Iterable.class); - method.setAccessible(true); - return (List>) method.invoke(acknowledgementService, argument); - } - - @Test - void batchSubmissionIdsReturnsASingleBatchForOneSubmissionId() { - try { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - var test = createBatchSubmissionIds(List.of(p)); - assertEquals(1, test.size()); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - @Test - void batchSubmissionIdsReturns10BatchesFor1000Ids() { - try { - List pendings = new ArrayList<>(); - for (int i = 0; i < 1000; i++) { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000" + i); - pendings.add(p); - } - var test = createBatchSubmissionIds(pendings); - assertEquals(10, test.size()); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - @Test - void batchSubmissionIdsReturns2BatchesFor101Ids() { - try { - List pendings = new ArrayList<>(); - for (int i = 0; i < 101; i++) { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000" + i); - pendings.add(p); - } - var test = createBatchSubmissionIds(pendings); - assertEquals(2, test.size()); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - @Test - void batchSubmissionIdsReturns1BatchFor0() { - try { - List pendings = new ArrayList<>(); - var test = createBatchSubmissionIds(pendings); - assertEquals(1, test.size()); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - @Test - void CreateToolkitErrorDeletesPendingRecordForSubmissionId() { - String submissionId = "12345678900987654321"; - Pending p = new Pending(); - p.setSubmissionId(submissionId); - pendingRepo.save(p); - ToolkitException tke = new ToolkitException("invalid request parameters"); - acknowledgementService.createToolkitError(p, tke); - Optional deletedPendingRecord = pendingRepo.findById(submissionId); - assertEquals(Optional.empty(), deletedPendingRecord); - } - - @Test - void CreateToolkitErrorCreatesTheRecordWithTheSubmissionIdAndError() { - String submissionId = "21423423423424423234"; - Pending p = new Pending(); - p.setSubmissionId(submissionId); - p.setPodId(getDefaultPodIdentifierFromProperties(0, "us-gov-east-1")); - pendingRepo.save(p); - - ToolkitException tke = new ToolkitException("invalid request parameters"); - acknowledgementService.createToolkitError(p, tke); - - Optional toolkitErrorRecord = toolkitErrorRepo.findById(submissionId); - - assertEquals(submissionId, toolkitErrorRecord.get().getSubmissionId()); - assertEquals( - "gov.irs.mef.exception.ToolkitException", - toolkitErrorRecord.get().getErrorName()); - assertEquals( - "gov.irs.mef.exception.ToolkitException: invalid request parameters", - toolkitErrorRecord.get().getErrorMessage()); - } - - @Test - @Disabled - void lookupSubmissionsAddsToolkitErrorRecordsOnToolkitExceptions() throws ServiceException, ToolkitException { - MockitoAnnotations.openMocks(this); - String meFClientErrorString = "MeFClientSDK000039: Invalid request parameters"; - pendingRepo.save(new Pending("12345")); - ToolkitException tke = new ToolkitException(meFClientErrorString); - when(mockGetAcksClientService.getAcks(isNull(), anySet())).thenThrow(tke); - acknowledgementService.LookupSubmissions(); - - Optional pendingRecord = pendingRepo.findById("12345"); - Optional toolkitError = toolkitErrorRepo.findById("12345"); - assertEquals(Optional.empty(), pendingRecord); - assertEquals( - "gov.irs.mef.exception.ToolkitException", toolkitError.get().getErrorName()); - assertEquals( - "gov.irs.mef.exception.ToolkitException: " + meFClientErrorString, - toolkitError.get().getErrorMessage()); - } - - @Test - @Disabled - void lookupSubmissionsHandlesToolkitExceptions() throws ServiceException, ToolkitException { - MockitoAnnotations.openMocks(this); - for (int i = 0; i < 100; i++) { - String genString = RandomStringUtils.random(20, true, true); - Pending p = new Pending(genString); - pendingRepo.save(p); - } - assertEquals(100, pendingRepo.count()); - - ToolkitException tke = new ToolkitException("Invalid request parameters"); - - GetAcksResult acksResult = mock(GetAcksResult.class); - - // We do this to mimic the expected behavior of the MeF client SDK on batch calls that have an issue with one - // piece of data in the batch. - // throw ToolkitException 7 times on a batch of size 100 - when(mockGetAcksClientService.getAcks(isNull(), anySet())) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenThrow(tke) - .thenReturn(new GetAcksResultWrapper(new AcknowledgementsListWrapper(new ArrayList<>()))); - - acknowledgementService.LookupSubmissions(); - - // This is to test the expected binary search pattern - verify(mockGetAcksClientService, times(15)).getAcks(isNull(), anySet()); - - // since we threw ToolkitException 7 times in a batch of size 100, we only expect one pending record to be - // deleted and then created as a toolkit error record in the database, - // because we use binary search pattern to divide the set until we find the single cause of the exception (100/2 - // 50/2 25/2 13/2 7/2 3/2 2/2 1/1) - assertEquals(1, toolkitErrorRepo.count()); - assertEquals(99, pendingRepo.count()); - } - - private String getDefaultPodIdentifierFromProperties(int index, String region) { - return "dfsys-mef-status-deployment-" + index + "-" + region; - } - - Map> getStatusSubmissionIdMap() { - PodIdentifier pi = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(pi); - - Map> statusSubmissionIdMap = acknowledgementService.createStatusSubmissionIdMap(); - List statuses = new ArrayList<>(); - statuses.add("accepted"); - statuses.add("rejected"); - statuses.add("pending"); - statuses.forEach(status -> { - String submissionId = UUID.randomUUID().toString().substring(0, 20); - if (Objects.equals(status, "pending")) { - Pending p = new Pending(); - p.setSubmissionId(submissionId); - p.setPodId(pi.getPodId()); - pendingRepo.save(p); - } - acknowledgementService.addToSubmissionIdMap(status, submissionId, statusSubmissionIdMap); - }); - return statusSubmissionIdMap; - } - - private ValidationMapCompleted getValidationErrorMap() { - Map> statusSubmissionIdMap = getStatusSubmissionIdMap(); - Map>> validationErrorMap = new HashMap<>(); - statusSubmissionIdMap.forEach((status, submissionIdList) -> { - if (status.equals("rejected")) { - String submissionId = submissionIdList.get(0); - validationErrorMap.put(submissionId, new ArrayList<>()); - List errorList1 = new ArrayList<>(); - List errorList2 = new ArrayList<>(); - String ruleNum = "R0000-904-03"; - String severityCd = "Reject and Stop"; - String errorMessageTxt = - "Software ID in the Return Header must have passed testing for the form family and ‘TaxYr’."; - errorList1.add(ruleNum); - errorList1.add(severityCd); - errorList1.add(errorMessageTxt); - validationErrorMap.get(submissionId).add(errorList1); - ruleNum = "F1040-525-03"; - severityCd = "Reject and Stop"; - errorMessageTxt = - "If 'PINTypeCd' in the Return Header has the value \"Self-Select On-Line\" and the filing status of the return is married filing jointly and Form 1040, [ 'SpecialProcessingLiteralCd' and 'CombatZoneCd' and 'SpecialProcessingCodeTxt' and 'PrimaryDeathDt' ] do not have values, then 'PrimaryBirthDt' in the Return Header must match the e-File database."; - errorList2.add(ruleNum); - errorList2.add(severityCd); - errorList2.add(errorMessageTxt); - validationErrorMap.get(submissionId).add(errorList2); - } - }); - Iterable completeds = acknowledgementService.createNewCompleteds(statusSubmissionIdMap); - return new ValidationMapCompleted(validationErrorMap, completeds); - } - - @Test - void stripPendingAcknowledgementsFromStatusSubmissionIdMap() { - Map> statusSubmissionIdMap = getStatusSubmissionIdMap(); - Map> newMap = - acknowledgementService.stripPendingAcknowledgementsFromStatusSubmissionIdMap(statusSubmissionIdMap); - assertNull(newMap.get("pending")); - assertEquals(newMap.get("rejected").size(), 1); - assertEquals(newMap.get("accepted").size(), 1); - } - - @Test - void addToSubmissionIdMapErrorDoesNotMutateSubmissionIdMap() { - Map> statusSubmissionIdMap = getStatusSubmissionIdMap(); - String status = "error"; - String submissionId = UUID.randomUUID().toString().substring(0, 20); - - acknowledgementService.addToSubmissionIdMap(status, submissionId, statusSubmissionIdMap); - assertNull(statusSubmissionIdMap.get("error")); - assertEquals(statusSubmissionIdMap.get("rejected").size(), 1); - assertEquals(statusSubmissionIdMap.get("accepted").size(), 1); - assertEquals(statusSubmissionIdMap.get("pending").size(), 1); - } - - @Test - void createNewCompletedsCreatesExpectedEntities() { - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 0); - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 0); - Map> statusSubmssionIdMap = getStatusSubmissionIdMap(); - Iterable completeds = acknowledgementService.createNewCompleteds(statusSubmssionIdMap); - completedRepo.saveAll(completeds); - // one pending is created, two completed (rejected and accepted) - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 1); - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 2); - } - - @Test - void bulkUpdateEntitiesWithNewErrors() { - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 0); - assertEquals(acknowledgementService.getAllError().spliterator().getExactSizeIfKnown(), 0); - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 0); - - ValidationMapCompleted validationMapCompleted = getValidationErrorMap(); - Map>> validationErrorMap = validationMapCompleted.validationErrorMap; - Iterable c = validationMapCompleted.completeds; - Map cmap = new HashMap<>(); - Map pmap = new HashMap<>(); - c.forEach(completed -> cmap.put(completed.getSubmissionId(), completed)); - - String podId = getDefaultPodIdentifierFromProperties(0, "us-gov-east-1"); - Iterable p = pendingRepo.findAllByPodId(podId); - p.forEach(pending -> pmap.put(pending.getSubmissionId(), pending)); - - acknowledgementService.bulkUpdateEntities(validationErrorMap, cmap, pmap); - - String rejectedSubmissionId = - validationErrorMap.entrySet().iterator().next().getKey(); - Completed rejectedAck = acknowledgementService - .getCompletedBySubmissionId(rejectedSubmissionId) - .get(); - - Pending pending = acknowledgementService.getAllPending().iterator().next(); - Iterator completeds = - acknowledgementService.getAllCompleted().iterator(); - - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 2); - assertEquals(acknowledgementService.getAllError().spliterator().getExactSizeIfKnown(), 2); - assertEquals(rejectedAck.getSubmissionId(), rejectedSubmissionId); - assertNotNull(rejectedAck.getErrors()); - - // the pending object that corresponded to the rejected completed is deleted, the one that remains - // is still pending from the standpoint of MeF so it was not deleted - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 1); - completeds.forEachRemaining(completed -> { - assertNotEquals(pending.getSubmissionId(), completed.getSubmissionId()); - }); - } - - @Test - void bulkUpdateEntitiesWithPreexistingErrors() { - ValidationMapCompleted validationMapCompleted = getValidationErrorMap(); - Map>> validationErrorMap1 = validationMapCompleted.validationErrorMap; - Iterable c = validationMapCompleted.completeds; - Map cmap = new HashMap<>(); - Map pmap = new HashMap<>(); - c.forEach(completed -> cmap.put(completed.getSubmissionId(), completed)); - - String podId = getDefaultPodIdentifierFromProperties(0, "us-gov-east-1"); - Iterable p = pendingRepo.findAllByPodId(podId); - p.forEach(pending -> pmap.put(pending.getSubmissionId(), pending)); - - acknowledgementService.bulkUpdateEntities(validationErrorMap1, cmap, pmap); - - String rejectedSubmissionId = - validationErrorMap1.entrySet().iterator().next().getKey(); - Completed rejectedAck = acknowledgementService - .getCompletedBySubmissionId(rejectedSubmissionId) - .get(); - Pending pending = acknowledgementService.getAllPending().iterator().next(); - Iterator completeds = - acknowledgementService.getAllCompleted().iterator(); - - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 2); - assertEquals(acknowledgementService.getAllError().spliterator().getExactSizeIfKnown(), 2); - assertEquals(rejectedAck.getSubmissionId(), rejectedSubmissionId); - assertNotNull(rejectedAck.getErrors()); - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 1); - completeds.forEachRemaining(completed -> { - assertNotEquals(pending.getSubmissionId(), completed.getSubmissionId()); - }); - - // mimic polling MeF again for the same errors but different submissions - // we would expect the rejected ack in the second batch to still have associated errors - ValidationMapCompleted validationMapCompleted2 = getValidationErrorMap(); - Map>> validationErrorMap2 = validationMapCompleted2.validationErrorMap; - Iterable c2 = validationMapCompleted2.completeds; - Map cmap2 = new HashMap<>(); - c2.forEach(completed -> cmap2.put(completed.getSubmissionId(), completed)); - - acknowledgementService.bulkUpdateEntities(validationErrorMap2, cmap2, pmap); - String rejectedSubmissionId2 = - validationErrorMap2.entrySet().iterator().next().getKey(); - Completed rejectedAck2 = acknowledgementService - .getCompletedBySubmissionId(rejectedSubmissionId2) - .get(); - Pending updatedPendings = - acknowledgementService.getAllPending().iterator().next(); - Iterator updatedCompleteds = - acknowledgementService.getAllCompleted().iterator(); - - // added another rejected and accepted submission object on top of the 2 in the first batch - assertEquals(acknowledgementService.getAllCompleted().spliterator().getExactSizeIfKnown(), 4); - // error count is the same because each error in the db is unique - assertEquals(acknowledgementService.getAllError().spliterator().getExactSizeIfKnown(), 2); - - assertEquals(rejectedAck2.getSubmissionId(), rejectedSubmissionId2); - // errors are still persisted - assertNotNull(rejectedAck2.getErrors()); - assertEquals(acknowledgementService.getAllPending().spliterator().getExactSizeIfKnown(), 2); - updatedCompleteds.forEachRemaining(completed -> { - assertNotEquals(updatedPendings.getSubmissionId(), completed.getSubmissionId()); - }); - assertEquals( - rejectedAck2.getErrors().getFirst().getErrorMessage(), - rejectedAck.getErrors().getFirst().getErrorMessage()); - assertEquals( - rejectedAck2.getErrors().getLast().getErrorMessage(), - rejectedAck.getErrors().getLast().getErrorMessage()); - } - - @Test - void getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission_returnsAcceptedSubmissionEvenIfNotTheLatest() { - UUID taxReturnId = UUID.randomUUID(); - - String olderAcceptedSubmissionId = "accepted"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, olderAcceptedSubmissionId)); - - String latestSubmissionId = "latest"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, latestSubmissionId)); - - Completed acceptedCompleted = new Completed(); - acceptedCompleted.setSubmissionId(olderAcceptedSubmissionId); - acceptedCompleted.setStatus("accepted"); - completedRepo.save(acceptedCompleted); - - Completed latestCompleted = new Completed(); - latestCompleted.setSubmissionId(latestSubmissionId); - latestCompleted.setStatus("rejected"); - completedRepo.save(latestCompleted); - - var submissionId = - acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(taxReturnId); - assertEquals(olderAcceptedSubmissionId, submissionId); - } - - @Test - void - getLatestAcceptedSubmissionIdOfParentTaxReturn_getsTheLatestAcceptedSubmissionIdOfTheParentTaxReturnEvenIfNotTheLatest() { - UUID taxReturnId = UUID.randomUUID(); - - String olderAcceptedSubmissionId = "accepted"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, olderAcceptedSubmissionId)); - - String latestSubmissionId = "latest"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, latestSubmissionId)); - - Completed acceptedCompleted = new Completed(); - acceptedCompleted.setSubmissionId(olderAcceptedSubmissionId); - acceptedCompleted.setStatus("accepted"); - completedRepo.save(acceptedCompleted); - - Completed latestCompleted = new Completed(); - latestCompleted.setSubmissionId(latestSubmissionId); - latestCompleted.setStatus("rejected"); - completedRepo.save(latestCompleted); - - var submissionId = - acknowledgementService.getLatestAcceptedSubmissionIdOfParentTaxReturn(olderAcceptedSubmissionId); - assertTrue(submissionId.isPresent()); - assertEquals(olderAcceptedSubmissionId, submissionId.get()); - } - - @Test - void getRejectionCodesForSubmissionId_returnsRejectionCodes() { - Error error1 = new Error(); - error1.setMefErrorCode("code1"); - error1.setErrorCodeTranslationKey("key1"); - error1.setMefErrorCategory("category1"); - error1.setErrorMessage("message1"); - error1 = errorRepository.save(error1); - - Completed completedRejection = new Completed(); - String submissionId = "rejected"; - completedRejection.setSubmissionId(submissionId); - completedRejection.setStatus("rejected"); - completedRejection.setErrors(List.of(error1)); - completedRepo.save(completedRejection); - - List rejectionCodes = acknowledgementService.getRejectionCodesForSubmissionId(submissionId); - - assertEquals(1, rejectionCodes.size()); - RejectedStatus rejectedStatus = rejectionCodes.getFirst(); - assertEquals(error1.getMefErrorCode(), rejectedStatus.MeFErrorCode); - assertEquals(error1.getErrorCodeTranslationKey(), rejectedStatus.TranslationKey); - assertEquals(error1.getErrorMessage(), rejectedStatus.MeFDescription); - } - - @Test - void getRejectionCodesForSubmissionId_returnsEmptyListWhenCompletedIsNotRejected() { - Completed completedAccepted = new Completed(); - String submissionId = "accepted"; - completedAccepted.setSubmissionId(submissionId); - completedAccepted.setStatus("accepted"); - completedRepo.save(completedAccepted); - - List rejectionCodes = acknowledgementService.getRejectionCodesForSubmissionId(submissionId); - - assertEquals(0, rejectionCodes.size()); - } - - @Test - void getRejectionCodesForSubmissionId_throwsExceptionWhenNoCompletedRecord() { - String submissionId = "missing"; - EntityNotFoundException thrown = assertThrows( - EntityNotFoundException.class, - () -> acknowledgementService.getRejectionCodesForSubmissionId(submissionId)); - - assertEquals("Could not find completed record for submission ID: " + submissionId, thrown.getMessage()); - } - - @Test - void whenCreateServiceContextWrapper_WithPodIdentifiers_ThenReturnsAsidFromDatabase() { - PodIdentifier p = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(p); - - String asid = podIdentifierRepository.findAsidByPodId(p.getPodId()).get(); - - ServiceContextWrapper serviceContextWrapper = acknowledgementService.createServiceContextWrapper(); - ServiceContext serviceContext = serviceContextWrapper.getServiceContext(); - assertNotNull(serviceContextWrapper); - assertNotNull(serviceContextWrapper.getServiceContext()); - assertEquals(serviceContext.getAppSysID(), statusProperties.getAsid()); - assertEquals(serviceContext.getAppSysID(), asid); - assertEquals(serviceContext.getEtin().toString(), statusProperties.getEtin()); - assertEquals(serviceContext.getTestCdType(), TestCdType.T); - } - - @Test - void whenCreateServiceContextWrapper_WithMultiplePodIdentifiers_ThenReturnsCorrectAsid() { - PodIdentifier p1 = createPodIdentifer("us-gov-east-1", ASID, 2); - PodIdentifier p2 = createPodIdentifer("us-gov-east-1", ASID + "2", 1); - PodIdentifier p3 = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(p1); - podIdentifierRepository.save(p2); - podIdentifierRepository.save(p3); - - String correctAsid = - podIdentifierRepository.findAsidByPodId(p3.getPodId()).get(); - - ServiceContextWrapper serviceContextWrapper = acknowledgementService.createServiceContextWrapper(); - ServiceContext serviceContext = serviceContextWrapper.getServiceContext(); - assertNotNull(serviceContextWrapper); - assertNotNull(serviceContextWrapper.getServiceContext()); - assertEquals(serviceContext.getAppSysID(), statusProperties.getAsid()); - assertEquals(serviceContext.getAppSysID(), correctAsid); - assertEquals(serviceContext.getEtin().toString(), statusProperties.getEtin()); - assertEquals(serviceContext.getTestCdType(), TestCdType.T); - } - - private record ValidationMapCompleted( - Map>> validationErrorMap, Iterable completeds) {} - - @Test - void whenRejectedStatusChangeMessages_DoPublish() { - List acksList = new ArrayList<>(); - PodIdentifier pi = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(pi); - Pending pending = new Pending("submissionId", pi.getPodId()); - pendingRepo.save(pending); - acksList.add(new AcknowledgementWrapper("submissionId", "reeee", "rejected")); - GetAcksResultWrapper acksResult = new GetAcksResultWrapper(new AcknowledgementsListWrapper(acksList)); - acknowledgementService.bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages( - acksResult, List.of(pending)); - Map> statusSubmissionIdMap = new HashMap<>(); - statusSubmissionIdMap.put("accepted", List.of()); - statusSubmissionIdMap.put("rejected", List.of("submissionId")); - verify(statusChangeMessageService, times(1)).publishStatusChangePayloadV1(statusSubmissionIdMap); - } - - @Test - void whenAcceptedStatusChangeMessages_DoPublish() { - List acksList = new ArrayList<>(); - PodIdentifier pi = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(pi); - Pending pending = new Pending("submissionId3", pi.getPodId()); - pendingRepo.save(pending); - acksList.add(new AcknowledgementWrapper("submissionId3", "beeee", "accepted")); - GetAcksResultWrapper acksResult = new GetAcksResultWrapper(new AcknowledgementsListWrapper(acksList)); - acknowledgementService.bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages( - acksResult, List.of(pending)); - Map> statusSubmissionIdMap = new HashMap<>(); - statusSubmissionIdMap.put("accepted", List.of("submissionId3")); - statusSubmissionIdMap.put("rejected", List.of()); - verify(statusChangeMessageService, times(1)).publishStatusChangePayloadV1(statusSubmissionIdMap); - } - - @Test - void whenAcceptedandRejectedStatusChangeMessages_DoPublish() { - List acksList = new ArrayList<>(); - PodIdentifier pi = createPodIdentifer("us-gov-east-1", statusProperties.getAsid(), 0); - podIdentifierRepository.save(pi); - Pending pending = new Pending("subId3", pi.getPodId()); - Pending pending2 = new Pending("subId", pi.getPodId()); - pendingRepo.save(pending); - pendingRepo.save(pending2); - acksList.add(new AcknowledgementWrapper("subId3", "yerp", "accepted")); - acksList.add(new AcknowledgementWrapper("subId", "nerp", "rejected")); - GetAcksResultWrapper acksResult = new GetAcksResultWrapper(new AcknowledgementsListWrapper(acksList)); - acknowledgementService.bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages( - acksResult, List.of(pending, pending2)); - Map> statusSubmissionIdMap = new HashMap<>(); - statusSubmissionIdMap.put("accepted", List.of("subId3")); - statusSubmissionIdMap.put("rejected", List.of("subId")); - verify(statusChangeMessageService, times(1)).publishStatusChangePayloadV1(statusSubmissionIdMap); - } - - @Test - void whenNoStatusChangeMessages_NoPublish() { - List acksList = new ArrayList<>(); - GetAcksResultWrapper acksResult = new GetAcksResultWrapper(new AcknowledgementsListWrapper(acksList)); - acknowledgementService.bulkUpdateRecordsFromAckResultAndEnqueueStatusChangeMessages( - acksResult, new ArrayList<>()); - Map> statusSubmissionIdMap = new HashMap<>(); - statusSubmissionIdMap.put("accepted", List.of()); - statusSubmissionIdMap.put("rejected", List.of()); - verify(statusChangeMessageService, times(0)).publishStatusChangePayloadV1(statusSubmissionIdMap); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceWithMocksTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceWithMocksTest.java deleted file mode 100644 index 1cf6fb8..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/AcknowledgementServiceWithMocksTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.*; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; -import static org.mockito.Mockito.times; - -// AcknowledgementServiceTest is a @SpringBootTest -// This test uses mocks for lighter weight tests that don't need to test integration details as heavily. -@ExtendWith(MockitoExtension.class) -public class AcknowledgementServiceWithMocksTest { - - @Mock - private TaxReturnSubmissionRepository taxReturnSubmissionRepository; - - @Mock - private CompletedAcknowledgementRepository completedRepo; - - @InjectMocks - AcknowledgementService acknowledgementService; - - @Test - void getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission_returnsNullIfNoSubmissionIdsExist() { - // Given - var taxReturnId = UUID.randomUUID(); - - when(taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId)) - .thenReturn(Optional.empty()); - when(taxReturnSubmissionRepository.getLatestSubmissionIdByTaxReturnId(taxReturnId)) - .thenReturn(Optional.empty()); - - // When - String submissionId = - acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(taxReturnId); - - // Then - verify(taxReturnSubmissionRepository, times(1)).getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId); - verify(taxReturnSubmissionRepository, times(1)).getLatestSubmissionIdByTaxReturnId(taxReturnId); - assertNull(submissionId); - } - - @Test - void - getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission_justGetsTheLatestSubmissionIdIfNoAcceptedSubmissionIsFound() { - // Given - var taxReturnId = UUID.randomUUID(); - var latestSubmissionId = "theLatestSubmissionId"; - - when(taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId)) - .thenReturn(Optional.empty()); - when(taxReturnSubmissionRepository.getLatestSubmissionIdByTaxReturnId(taxReturnId)) - .thenReturn(Optional.of(latestSubmissionId)); - - // When - String submissionId = - acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(taxReturnId); - - // Then - verify(taxReturnSubmissionRepository, times(1)).getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId); - verify(taxReturnSubmissionRepository, times(1)).getLatestSubmissionIdByTaxReturnId(taxReturnId); - assertEquals(latestSubmissionId, submissionId); - } - - @Test - void - getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission_getsTheLatestAcceptedSubmissionIdEvenIfItIsNotTheLatest() { - // Given - var taxReturnId = UUID.randomUUID(); - var latestAcceptedSubmissionId = "theLatestAcceptedSubmissionId"; - - when(taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId)) - .thenReturn(Optional.of(latestAcceptedSubmissionId)); - - // When - String submissionId = - acknowledgementService.getLatestSubmissionIdByTaxReturnIdPreferringAcceptedSubmission(taxReturnId); - - // Then - verify(taxReturnSubmissionRepository, times(1)).getLatestAcceptedSubmissionIdForTaxReturnId(taxReturnId); - verify(taxReturnSubmissionRepository, times(0)).getLatestSubmissionIdByTaxReturnId(taxReturnId); - assertEquals(latestAcceptedSubmissionId, submissionId); - } - - @Test - void getLatestAcceptedSubmissionIdOfParentTaxReturn_returnsEmptyIfNoAcceptedSubmissionFound() { - // Given - var requestedSubmissionId = "requestedSubmissionId"; - - when(taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId)) - .thenReturn(Optional.empty()); - - // When - Optional latestAcceptedSubmissionId = - acknowledgementService.getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId); - - // Then - verify(taxReturnSubmissionRepository, times(1)) - .getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId); - assertTrue(latestAcceptedSubmissionId.isEmpty()); - } - - @Test - void getLatestAcceptedSubmissionIdOfParentTaxReturn_returnsTheAcceptedSubmissionId() { - // Given - var requestedSubmissionId = "requestedSubmissionId"; - var acceptedSubmissionId = "acceptedSubmissionId"; - - when(taxReturnSubmissionRepository.getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId)) - .thenReturn(Optional.of(acceptedSubmissionId)); - - // When - Optional latestAcceptedSubmissionId = - acknowledgementService.getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId); - - // Then - verify(taxReturnSubmissionRepository, times(1)) - .getLatestAcceptedSubmissionIdOfParentTaxReturn(requestedSubmissionId); - assertTrue(latestAcceptedSubmissionId.isPresent()); - assertEquals(acceptedSubmissionId, latestAcceptedSubmissionId.get()); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepositoryTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepositoryTest.java deleted file mode 100644 index c36c8e9..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/CompletedAcknowledgementRepositoryTest.java +++ /dev/null @@ -1,156 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.List; - -import ch.qos.logback.classic.Level; -import org.hibernate.engine.jdbc.batch.JdbcBatchLogging; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.directfile.status.domain.Completed; -import gov.irs.directfile.status.domain.Error; -import gov.irs.directfile.status.error.ErrorRepository; -import gov.irs.directfile.status.extension.BatchUtil; -import gov.irs.directfile.status.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.*; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ImportAutoConfiguration(classes = SecurityAutoConfiguration.class) -@DataJpaTest(properties = "spring.main.web-application-type=servlet") -class CompletedAcknowledgementRepositoryTest { - - @Autowired - CompletedAcknowledgementRepository completedRepo; - - @Autowired - ErrorRepository errorRepository; - - @RegisterExtension - private static final LoggerExtension batchLogVerifier = new LoggerExtension(Level.TRACE, JdbcBatchLogging.NAME); - - @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}") - private int batchSize; - - @Test - public void CanAddAnAccepted() { - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Accepted"); - completedRepo.save(c); - var completed = - completedRepo.GetCompletedSubmission("12345620230215000001").get(); - assertEquals("Accepted", completed.getStatus()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Completed.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanAddARejected() { - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject and Stop"); - c.setErrors(List.of(e)); - // must add error to database first! - errorRepository.save(e); - completedRepo.save(c); - var completed = - completedRepo.GetCompletedSubmission("12345620230215000001").get(); - assertEquals("Rejected", completed.getStatus()); - assertEquals("XML-123-4567-006", completed.getErrors().get(0).getMefErrorCode()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Completed.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage(BatchUtil.buildBatchMessage( - 1, batchSize, Completed.class.getName() + ".errors", BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanAddARejectedWithMultipleErrors() { - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject"); - Error e2 = new Error(); - e2.setMefErrorCode("REJC-00001"); - e2.setErrorMessage("This was a huge problem"); - e2.setErrorCodeTranslationKey("translation/reject/REJC-00001"); - e2.setMefErrorCategory("Reject"); - c.setErrors(List.of(e, e2)); - errorRepository.saveAll(List.of(e, e2)); - completedRepo.save(c); - - var completed = - completedRepo.GetCompletedSubmission("12345620230215000001").get(); - assertEquals("Rejected", completed.getStatus()); - assertEquals("XML-123-4567-006", completed.getErrors().get(0).getMefErrorCode()); - assertEquals("REJC-00001", completed.getErrors().get(1).getMefErrorCode()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(2, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Completed.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage(BatchUtil.buildBatchMessage( - 2, batchSize, Completed.class.getName() + ".errors", BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanQueryForANonExistentSubmissionId() { - var completed = completedRepo.GetCompletedSubmission("12345620230215000001"); - assertTrue(completed.isEmpty()); - } - - @Test - public void CanAddTheSameErrorToTwoDifferentCompletedRecords() { - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject and Stop"); - errorRepository.save(e); - - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - c.setErrors(List.of(e)); - completedRepo.save(c); - - Completed c2 = new Completed(); - c2.setSubmissionId("12345620230215000002"); - c2.setStatus("Rejected"); - c2.setErrors(List.of(e)); - completedRepo.save(c2); - - assertEquals(1, errorRepository.findAll().spliterator().getExactSizeIfKnown()); - assertEquals(2, completedRepo.findAll().spliterator().getExactSizeIfKnown()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(2, batchSize, Completed.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage(BatchUtil.buildBatchMessage( - 2, batchSize, Completed.class.getName() + ".errors", BatchUtil.BatchType.INSERT)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepositoryTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepositoryTest.java deleted file mode 100644 index 27cf2d9..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/PendingAcknowledgementRepositoryTest.java +++ /dev/null @@ -1,143 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.List; - -import ch.qos.logback.classic.Level; -import org.hibernate.engine.jdbc.batch.JdbcBatchLogging; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; - -import gov.irs.directfile.status.domain.Pending; -import gov.irs.directfile.status.extension.BatchUtil; -import gov.irs.directfile.status.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.*; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ImportAutoConfiguration(classes = SecurityAutoConfiguration.class) -@DataJpaTest(properties = "spring.main.web-application-type=servlet") -public class PendingAcknowledgementRepositoryTest { - @Autowired - PendingAcknowledgementRepository pendingRepo; - - @Autowired - private TestEntityManager testEntityManager; - - @RegisterExtension - private static final LoggerExtension batchLogVerifier = new LoggerExtension(Level.TRACE, JdbcBatchLogging.NAME); - - @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}") - private int batchSize; - - @Test - public void CanAddASubmissionIdToTheTable() { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000010"); - pendingRepo.save(p); - - // Verify JDBC batching - testEntityManager.flush(); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanAddMultipleSubmissionsToTheTable() { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - pendingRepo.save(p); - Pending p2 = new Pending(); - p2.setSubmissionId("12345620230215000002"); - pendingRepo.save(p2); - Pending p3 = new Pending(); - Pending p4 = new Pending(); - p3.setSubmissionId("12345620230215000003"); - p4.setSubmissionId("12345620230215000004"); - var multiple = List.of(p3, p4); - pendingRepo.saveAll(multiple); - - // Verify JDBC batching - testEntityManager.flush(); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(4, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanRetrieveFromPendingTable() { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - pendingRepo.save(p); - var pending = pendingRepo.GetPendingSubmission("12345620230215000001"); - assertEquals(p.getSubmissionId(), pending.get().getSubmissionId()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanDeleteFromPendingTable() { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - pendingRepo.save(p); - Pending p2 = new Pending(); - p2.setSubmissionId("12345620230215000001"); - pendingRepo.delete(p2); - var option = pendingRepo.GetPendingSubmission("12345620230215000001"); - assertTrue(option.isEmpty()); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.DELETE)); - } - - @Test - public void CannotEnterTwoOfTheSameSubmissionIdsIntoThePendingTable() { - Pending p = new Pending(); - p.setSubmissionId("12345620230215000001"); - pendingRepo.save(p); - Pending p2 = new Pending(); - p2.setSubmissionId("12345620230215000001"); - pendingRepo.save(p2); - var all = pendingRepo.findAll(); - var size = all.spliterator().getExactSizeIfKnown(); - assertEquals(1, size); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanQueryForANonExistentPendingWithNoResults() { - var empty = pendingRepo.GetPendingSubmission("12345620230215000001"); - assertTrue(empty.isEmpty()); - } - - @Test - public void CannotEnterASubmissionIdThatIsTooLong() { - Pending p = new Pending(); - p.setSubmissionId("123456202302150000001"); - assertEquals(0, pendingRepo.findAll().spliterator().getExactSizeIfKnown()); - // I wish I knew why this saves - // TODO: make this throw... - pendingRepo.save(p); - - assertThrows(org.springframework.dao.DataIntegrityViolationException.class, () -> { - assertEquals(0, pendingRepo.findAll().spliterator().getExactSizeIfKnown()); - }); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Pending.class.getName(), BatchUtil.BatchType.INSERT)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepositoryTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepositoryTest.java deleted file mode 100644 index d8969d0..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/acknowledgement/TaxReturnSubmissionRepositoryTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package gov.irs.directfile.status.acknowledgement; - -import java.util.Optional; -import java.util.UUID; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.directfile.status.domain.TaxReturnSubmission; - -import static org.junit.jupiter.api.Assertions.*; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@DataJpaTest -class TaxReturnSubmissionRepositoryTest { - @Autowired - TaxReturnSubmissionRepository taxReturnSubmissionRepository; - - @Test - public void canSaveAndRetrieveTaxReturnSubmissions() { - UUID taxReturnId = UUID.randomUUID(); - String submissionId = "12345678901234567890"; - taxReturnSubmissionRepository.save(new TaxReturnSubmission(taxReturnId, submissionId)); - - Optional result = taxReturnSubmissionRepository.getLatestSubmissionIdByTaxReturnId(taxReturnId); - - assertTrue(result.isPresent()); - assertEquals(result.get(), submissionId); - - // Note: Hibernate disables batching for entities having an identity PK, so no batching to test for here - } - - @Test - public void returnsEmptyOptionalWhenTryingToFindSubmissionIdOfTaxReturnThatDoesNotExist() { - UUID taxReturnId = UUID.randomUUID(); - Optional result = taxReturnSubmissionRepository.getLatestSubmissionIdByTaxReturnId(taxReturnId); - - assertTrue(result.isEmpty()); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/config/AWSCredentialsConfigurationTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/config/AWSCredentialsConfigurationTest.java deleted file mode 100644 index 91fa766..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/config/AWSCredentialsConfigurationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package gov.irs.directfile.status.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -import static org.assertj.core.api.Assertions.assertThat; - -class AWSCredentialsConfigurationTest { - - @Test - void staticCredentialProviderCreatedWhenApplicablePropertySetToFalse() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - }); - } - - @Test - void staticCredentialProviderCreatedWhenApplicablePropertyIsNotSet() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues("aws.accessKey=test", "aws.secretKey=test") - .withUserConfiguration(AWSCredentialsConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - }); - } - - @Test - void defaultCredentialProviderCreatedWhenApplicablePropertySetToTrue() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - }); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/config/EncryptionClientConfigurationTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/config/EncryptionClientConfigurationTest.java deleted file mode 100644 index 1b2cc9b..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/config/EncryptionClientConfigurationTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.irs.directfile.status.config; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import software.amazon.awssdk.services.kms.KmsClient; -import software.amazon.encryption.s3.materials.CryptographicMaterialsManager; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest( - classes = {EncryptionClientConfiguration.class, AWSCredentialsConfiguration.class}, - webEnvironment = SpringBootTest.WebEnvironment.NONE) -class EncryptionClientConfigurationTest { - - @Autowired - EncryptionClientConfiguration encryptionClientConfiguration; - - @Test - void regionalKmsClientIsNotNull() { - KmsClient kmsClient = encryptionClientConfiguration.regionalKmsClient(); - assertNotNull(kmsClient); - } - - @Test - void kmsCryptoIsNotNull() { - String testKmsKeyArn = "test-kms-arn"; - CryptographicMaterialsManager cryptographicMaterialsManager = - encryptionClientConfiguration.kmsCrypto(testKmsKeyArn); - assertNotNull(cryptographicMaterialsManager); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientConfigurationTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientConfigurationTest.java deleted file mode 100644 index bb51a42..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientConfigurationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package gov.irs.directfile.status.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class SnsClientConfigurationTest { - - @Test - void snsClientBeanCreatedWhenStaticCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "status.sns.endpoint=http://directfile.test", - "status.sns.status-change-topic-arn=test-topic-arn", - "status.sns.region=us-west-2", - "status.sns.accessKey=test", - "status.sns.secretKey=test", - "status.sns.status-change-publish-enabled=true", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfiguration.class, SnsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - assertThat(context.getBean(SnsClientConfiguration.class)).isNotNull(); - }); - } - - @Test - void snsClientBeanCreatedWhenDefaultCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "status.sns.endpoint=http://directfile.test", - "status.sns.status-change-topic-arn=test-topic-arn", - "status.sns.region=us-west-2", - "status.sns.accessKey=test", - "status.sns.secretKey=test", - "status.sns.status-change-publish-enabled=true", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfiguration.class, SnsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - assertThat(context.getBean(SnsClientConfiguration.class)).isNotNull(); - }); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientTestConfiguration.java b/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientTestConfiguration.java deleted file mode 100644 index 9425186..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SnsClientTestConfiguration.java +++ /dev/null @@ -1,34 +0,0 @@ -package gov.irs.directfile.status.config; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import software.amazon.awssdk.services.sns.SnsClient; -import software.amazon.awssdk.services.sns.model.ListSubscriptionsByTopicRequest; -import software.amazon.awssdk.services.sns.model.ListSubscriptionsByTopicResponse; -import software.amazon.awssdk.services.sns.model.Subscription; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@TestConfiguration -public class SnsClientTestConfiguration { - @Bean - @Primary - public SnsClient testSnsClient() { - ListSubscriptionsByTopicResponse listSubscriptionsByTopicResponse = - mock(ListSubscriptionsByTopicResponse.class); - List subscriptions = new ArrayList<>(); - subscriptions.add(mock(Subscription.class)); - when(listSubscriptionsByTopicResponse.subscriptions()).thenReturn(subscriptions); - - SnsClient snsClient = mock(SnsClient.class); - when(snsClient.listSubscriptionsByTopic(any(ListSubscriptionsByTopicRequest.class))) - .thenReturn(listSubscriptionsByTopicResponse); - return snsClient; - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SqsClientConfigurationTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/config/SqsClientConfigurationTest.java deleted file mode 100644 index 1fb540c..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/config/SqsClientConfigurationTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package gov.irs.directfile.status.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; -import software.amazon.awssdk.services.sqs.SqsClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class SqsClientConfigurationTest { - - @Test - void sqsClientBeanCreatedWhenStaticCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "status.message-queue.endpoint=http://directfile.test", - "status.message-queue.status-change-queue=test-queue-01", - "status.message-queue.pending-submission-queue=test-queue-02", - "status.message-queue.dlq-pending-submission-queue=test-queue-03", - "status.message-queue.region=us-west-2", - "status.message-queue.accessKey=test", - "status.message-queue.secretKey=test", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfiguration.class, SqsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - assertThat(context.getBean(SqsClient.class)).isNotNull(); - }); - } - - @Test - void sqsClientBeanCreatedWhenDefaultCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "status.message-queue.endpoint=http://directfile.test", - "status.message-queue.status-change-queue=test-queue-01", - "status.message-queue.pending-submission-queue=test-queue-02", - "status.message-queue.dlq-pending-submission-queue=test-queue-03", - "status.message-queue.region=us-west-2", - "status.message-queue.accessKey=test", - "status.message-queue.secretKey=test", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfiguration.class, SqsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - assertThat(context.getBean(SqsClient.class)).isNotNull(); - }); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/error/ErrorRepositoryTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/error/ErrorRepositoryTest.java deleted file mode 100644 index ef67c33..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/error/ErrorRepositoryTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package gov.irs.directfile.status.error; - -import java.util.List; - -import ch.qos.logback.classic.Level; -import org.hibernate.engine.jdbc.batch.JdbcBatchLogging; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; - -import gov.irs.directfile.status.acknowledgement.CompletedAcknowledgementRepository; -import gov.irs.directfile.status.domain.Completed; -import gov.irs.directfile.status.domain.Error; -import gov.irs.directfile.status.extension.BatchUtil; -import gov.irs.directfile.status.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.*; - -// For right now, Errors only exist as information on -// the Reject. It doesn't need a direct access right now. -// It may/will in the future. -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ImportAutoConfiguration(classes = SecurityAutoConfiguration.class) -@DataJpaTest(properties = "spring.main.web-application-type=servlet") -class ErrorRepositoryTest { - - @Autowired - CompletedAcknowledgementRepository completedRepo; - - @Autowired - ErrorRepository errorRepository; - - @Autowired - private TestEntityManager testEntityManager; - - @RegisterExtension - private static final LoggerExtension batchLogVerifier = new LoggerExtension(Level.TRACE, JdbcBatchLogging.NAME); - - @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}") - private int batchSize; - - @Test - public void CanAddABasicError() { - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject"); - errorRepository.save(e); - Error retrieved = errorRepository.findById("XML-123-4567-006").get(); - assertEquals(e.getErrorCodeTranslationKey(), retrieved.getErrorCodeTranslationKey()); - assertEquals(e.getMefErrorCode(), retrieved.getMefErrorCode()); - assertEquals(e.getErrorMessage(), retrieved.getErrorMessage()); - assertEquals(e.getMefErrorCategory(), retrieved.getMefErrorCategory()); - - // Verify JDBC batching - testEntityManager.flush(); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CanAddAnErrorToACompletedRecord() { - // you should never do it this way! - // Errors should be created first - Completed c = new Completed(); - c.setSubmissionId("12345620230215000001"); - c.setStatus("Rejected"); - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject"); - e.setCompleted(List.of(c)); - completedRepo.save(c); - errorRepository.save(e); - Error retrieved = errorRepository.findById("XML-123-4567-006").get(); - assertEquals("12345620230215000001", retrieved.getCompleted().get(0).getSubmissionId()); - - // Verify JDBC batching - testEntityManager.flush(); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Completed.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - } - - @Test - public void CallingSaveOnAKnownIDWithNewInformationUpdatesTheRecord() { - Error e = new Error(); - e.setMefErrorCode("XML-123-4567-006"); - e.setErrorMessage("You messed up!"); - e.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e.setMefErrorCategory("Reject"); - errorRepository.save(e); - Error e2 = new Error(); - e2.setMefErrorCode("XML-123-4567-006"); - e2.setErrorMessage("This is bad"); - e2.setErrorCodeTranslationKey("translation/reject/XML-123-4567-006"); - e2.setMefErrorCategory("Reject"); - errorRepository.save(e2); - - Error retrieved = errorRepository.findById("XML-123-4567-006").get(); - assertEquals(e.getErrorCodeTranslationKey(), retrieved.getErrorCodeTranslationKey()); - assertEquals(e.getMefErrorCode(), retrieved.getMefErrorCode()); - assertEquals(e2.getErrorMessage(), retrieved.getErrorMessage()); - assertEquals(e.getMefErrorCategory(), retrieved.getMefErrorCategory()); - - // Verify JDBC batching - testEntityManager.flush(); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.INSERT)); - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, Error.class.getName(), BatchUtil.BatchType.UPDATE)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/error/ToolkitErrorRepositoryTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/error/ToolkitErrorRepositoryTest.java deleted file mode 100644 index 00499da..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/error/ToolkitErrorRepositoryTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package gov.irs.directfile.status.error; - -import ch.qos.logback.classic.Level; -import jakarta.validation.ConstraintViolationException; -import org.hibernate.engine.jdbc.batch.JdbcBatchLogging; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.transaction.TransactionSystemException; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import gov.irs.directfile.status.domain.ToolkitError; -import gov.irs.directfile.status.extension.BatchUtil; -import gov.irs.directfile.status.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.*; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@ImportAutoConfiguration(classes = SecurityAutoConfiguration.class) -@Transactional(propagation = Propagation.NOT_SUPPORTED) // Allows CrudRepository Transactional scope to work as intended -@DataJpaTest -public class ToolkitErrorRepositoryTest { - @Autowired - ToolkitErrorRepository toolkitErrorRepo; - - @RegisterExtension - private static final LoggerExtension batchLogVerifier = new LoggerExtension(Level.TRACE, JdbcBatchLogging.NAME); - - @Value("${spring.jpa.properties.hibernate.jdbc.batch_size}") - private int batchSize; - - @Test - public void DoesNotAllowNullErrorName() { - ToolkitError tke = new ToolkitError(); - tke.setSubmissionId("12345620230215000010"); - tke.setErrorMessage("something"); - TransactionSystemException tse = assertThrows(TransactionSystemException.class, () -> { - toolkitErrorRepo.save(tke); - }); - - assertEquals( - ConstraintViolationException.class, tse.getMostSpecificCause().getClass()); - } - - @Test - public void DoesNotAllowNullErrorMessage() { - ToolkitError tke = new ToolkitError(); - tke.setSubmissionId("12345678900987654321"); - tke.setErrorName("ToolkitException"); - TransactionSystemException tse = assertThrows(TransactionSystemException.class, () -> { - toolkitErrorRepo.save(tke); - }); - assertEquals( - ConstraintViolationException.class, tse.getMostSpecificCause().getClass()); - } - - @Test - public void SavesWithValidFields() { - ToolkitError tke = new ToolkitError(); - tke.setSubmissionId("12345678900987654321"); - tke.setErrorName("ToolkitException"); - tke.setErrorMessage("Something went wrong!"); - - toolkitErrorRepo.save(tke); - - assert (toolkitErrorRepo.findById(tke.getSubmissionId())).isPresent(); - - // Verify JDBC batching - batchLogVerifier.verifyLogContainsMessage( - BatchUtil.buildBatchMessage(1, batchSize, ToolkitError.class.getName(), BatchUtil.BatchType.INSERT)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/extension/BatchUtil.java b/direct-file/status/src/test/java/gov/irs/directfile/status/extension/BatchUtil.java deleted file mode 100644 index 949274a..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/extension/BatchUtil.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.status.extension; - -public final class BatchUtil { - private BatchUtil() { - // no instantiation allowed - } - - public enum BatchType { - INSERT, - UPDATE, - DELETE - } - - public static String buildBatchMessage(int count, int batchSize, String entityName, BatchType type) { - return String.format("Executing JDBC batch (%d / %d) - `%s#%s`", count, batchSize, entityName, type); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/extension/LoggerExtension.java b/direct-file/status/src/test/java/gov/irs/directfile/status/extension/LoggerExtension.java deleted file mode 100644 index 8813722..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/extension/LoggerExtension.java +++ /dev/null @@ -1,105 +0,0 @@ -package gov.irs.directfile.status.extension; - -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.slf4j.LoggerFactory; -import org.slf4j.event.KeyValuePair; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.events.Event; - -import static org.junit.jupiter.api.Assertions.*; - -public class LoggerExtension implements BeforeEachCallback, AfterEachCallback { - private Logger logger; - private ListAppender appender; - private final String loggerName; - private final Level level; - - public LoggerExtension(Level level, String loggerName) { - this.loggerName = loggerName; - this.level = level; - } - - @Override - public void beforeEach(ExtensionContext context) { - logger = (Logger) LoggerFactory.getLogger(loggerName); - appender = new ListAppender<>(); - appender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); - logger.setLevel(level); - logger.addAppender(appender); - appender.start(); - } - - @Override - public void afterEach(ExtensionContext context) { - logger.detachAppender(appender); - } - - public void verifyLogEvent(Event event) { - verifyLogEvent(event, 0, null); - } - - public void verifyLogEvent(Event event, Map logPropertiesToAssert) { - verifyLogEvent(event, 0, logPropertiesToAssert); - } - - public void verifyLogEvent(Event event, int index) { - verifyLogEvent(event, index, null); - } - - public void verifyLogEvent(Event event, int index, Map logPropertiesToAssert) { - ILoggingEvent loggingEvent = appender.list.get(index); - - List keyValuePairs = loggingEvent.getKeyValuePairs(); - Map mdcPropertyMap = loggingEvent.getMDCPropertyMap(); - - HashMap combinedMap = new HashMap<>(mdcPropertyMap); - ListIterator keyValuePairListIterator = keyValuePairs.listIterator(); - while (keyValuePairListIterator.hasNext()) { - KeyValuePair next = keyValuePairListIterator.next(); - // a collision here causes logback to silently exclude all keyValuePairs from json output - assertFalse(combinedMap.containsKey(next.key)); - combinedMap.put(next.key, next.value == null ? null : next.value.toString()); - } - - assertEquals(combinedMap.get(AuditLogElement.cyberOnly.toString()), "true", "cyberOnly not set (XXXX flag)"); - assertEquals(event.getEventStatus().toString(), combinedMap.get(AuditLogElement.eventStatus.toString())); - assertEquals(event.getEventId().toString(), combinedMap.get(AuditLogElement.eventId.toString())); - assertEquals( - event.getEventPrincipal().getUserType().toString(), - combinedMap.get(AuditLogElement.userType.toString())); - assertEquals(event.getEventErrorMessage(), combinedMap.get(AuditLogElement.eventErrorMessage.toString())); - assertEquals(event.getDetail(), combinedMap.get(AuditLogElement.detail.toString())); - - if (logPropertiesToAssert != null) { - for (Map.Entry entry : logPropertiesToAssert.entrySet()) { - assertEquals( - entry.getValue().toString(), - combinedMap.get(entry.getKey().toString())); - } - } - } - - public void verifyLogContainsMessage(String message) { - boolean foundMessage = false; - for (ILoggingEvent loggingEvent : appender.list) { - if (loggingEvent.getMessage().equals(message)) { - foundMessage = true; - break; - } - } - assertTrue(foundMessage, String.format("log message not found: %s", message)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/MessageQueueListenerServiceTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/MessageQueueListenerServiceTest.java deleted file mode 100644 index 18799b2..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/MessageQueueListenerServiceTest.java +++ /dev/null @@ -1,133 +0,0 @@ -package gov.irs.directfile.status.services; - -import com.amazon.sqs.javamessaging.message.SQSTextMessage; -import jakarta.jms.JMSException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.status.config.MessageQueueConfiguration; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class MessageQueueListenerServiceTest { - @Mock - private MessageQueueConfiguration messageQueueConfiguration; - - @Mock - private PendingSubmissionMessageRouter pendingSubmissionMessageRouter; - - @Mock - private SubmissionConfirmationMessageRouter submissionConfirmationMessageRouter; - - private MessageQueueListenerService messageQueueListenerService; - - String pendingSubmissionMessageJson = - """ - { - "payload": { - "@type": "PendingSubmissionPayloadV1", - "pendings": [ - { - "taxReturnId": "00000000-0000-1111-1111-000000000000", - "submissionId": "11111111" - }, - { - "taxReturnId": "00000000-0000-2222-2222-000000000000", - "submissionId": "22222222" - } - ] - }, - "headers": { - "headers": { - "VERSION": "1.0" - } - } - } - """; - - String submissionConfirmationMessageJson = - """ - { - "payload": { - "@type": "SubmissionConfirmationPayloadV1", - "receipts": [ - { - "taxReturnId": "f6cdd8d9-2606-4acc-a331-28554f9bc72b", - "submissionId": "submissionId1", - "receiptId": "receiptId1", - "submissionReceivedAt": 1721754334033 - }, - { - "taxReturnId": "248fcc48-b362-497e-8927-e3c88b653009", - "submissionId": "submissionId2", - "receiptId": "receiptId2", - "submissionReceivedAt": 1721754334033 - } - ] - }, - "headers": { - "headers": { - "VERSION": "1.0" - } - } - } - """; - - @BeforeEach - public void setup() { - messageQueueListenerService = new MessageQueueListenerService( - messageQueueConfiguration, pendingSubmissionMessageRouter, submissionConfirmationMessageRouter); - } - - @Test - public void onMessage_success_pendingSubmissionMessage() throws JMSException { - SQSTextMessage mockMessage = mock(SQSTextMessage.class); - when(mockMessage.getText()).thenReturn(pendingSubmissionMessageJson); - - assertDoesNotThrow(() -> { - messageQueueListenerService.onMessage(mockMessage); - - // Verify that only the pending submission handler is called and message acknowledged - verify(pendingSubmissionMessageRouter, times(1)).handlePendingSubmissionMessage(any()); - verify(submissionConfirmationMessageRouter, never()).handleSubmissionConfirmationMessage(any()); - verify(mockMessage, times(1)).acknowledge(); - }); - } - - @Test - public void onMessage_success_submissionConfirmationMessage() throws JMSException { - SQSTextMessage mockMessage = mock(SQSTextMessage.class); - when(mockMessage.getText()).thenReturn(submissionConfirmationMessageJson); - - assertDoesNotThrow(() -> { - messageQueueListenerService.onMessage(mockMessage); - - // Verify that only the submission confirmation handler is called and message acknowledged - verify(pendingSubmissionMessageRouter, never()).handlePendingSubmissionMessage(any()); - verify(submissionConfirmationMessageRouter, times(1)).handleSubmissionConfirmationMessage(any()); - verify(mockMessage, times(1)).acknowledge(); - }); - } - - @Test - public void onMessage_exceptionThrown() throws JMSException { - SQSTextMessage mockMessage = mock(SQSTextMessage.class); - when(mockMessage.getText()) - .thenReturn( - """ - {"some_key":"some_val_without_a_closing_string}\s - """); - - messageQueueListenerService.onMessage(mockMessage); - - // Verify that handlers and message.acknowledge() are not called - verify(pendingSubmissionMessageRouter, never()).handlePendingSubmissionMessage(any()); - verify(submissionConfirmationMessageRouter, never()).handleSubmissionConfirmationMessage(any()); - verify(mockMessage, never()).acknowledge(); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouterTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouterTest.java deleted file mode 100644 index 3b90ddd..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/PendingSubmissionMessageRouterTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.ArrayList; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.models.message.pending.PendingSubmissionMessageVersion; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.models.message.pending.payload.PendingSubmissionPayloadV1; -import gov.irs.directfile.status.services.handlers.pending.PendingSubmissionV1Handler; -import gov.irs.directfile.status.services.handlers.pending.UnsupportedMessageVersionHandler; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -public class PendingSubmissionMessageRouterTest { - - @Mock - public PendingSubmissionV1Handler pendingSubmissionV1Handler; - - @Mock - public UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - private PendingSubmissionMessageRouter pendingSubmissionMessageRouter; - - @BeforeEach - public void setup() { - pendingSubmissionMessageRouter = - new PendingSubmissionMessageRouter(unsupportedMessageVersionHandler, pendingSubmissionV1Handler); - } - - @Test - public void itGetsHandlerWhenProvidedAValidPendingSubmissionMessageVersion() { - // Arrange: Create a VersionedPendingSubmissionMessage, with a header specifying V1 - AbstractPendingSubmissionPayload payload = new PendingSubmissionPayloadV1(new ArrayList<>()); - VersionedPendingSubmissionMessage queueMessage = - new VersionedPendingSubmissionMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - PendingSubmissionMessageVersion.V1.getVersion())); - - // Act: Call handlePendingSubmissionMessage() - assertDoesNotThrow(() -> { - pendingSubmissionMessageRouter.handlePendingSubmissionMessage(queueMessage); - - // Assert: Expect that an exception was not thrown, and that the - // PendingSubmissionV1Handler.handlePendingSubmissionMessage() was called - verify(pendingSubmissionV1Handler, times(1)).handlePendingSubmissionMessage(any()); - }); - } - - @Test - public void itHandlesUnsupportedVersions() { - // Arrange: Create a VersionedPendingSubmissionMessage, with a header specifying an unsupported version - AbstractPendingSubmissionPayload payload = new PendingSubmissionPayloadV1(new ArrayList<>()); - String unsupportedVersion = "9.0.EGG"; - - VersionedPendingSubmissionMessage messageWithUnsupportedVersion = - new VersionedPendingSubmissionMessage<>( - payload, - new QueueMessageHeaders().addHeader(MessageHeaderAttribute.VERSION, unsupportedVersion)); - - // Act: call handlePendingSubmissionMessage() - assertThrows(UnsupportedVersionException.class, () -> { - pendingSubmissionMessageRouter.handlePendingSubmissionMessage(messageWithUnsupportedVersion); - - // Assert: Check that we called the UnsupportedVersionHandler - verify(unsupportedMessageVersionHandler, times(1)).handlePendingSubmissionMessage(any()); - }); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/StatusChangeMessageServiceTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/StatusChangeMessageServiceTest.java deleted file mode 100644 index 0e8c83f..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/StatusChangeMessageServiceTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.List; -import java.util.Map; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.PublisherException; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.status.StatusChangeMessageVersion; -import gov.irs.directfile.models.message.status.VersionedStatusChangeMessage; -import gov.irs.directfile.models.message.status.payload.AbstractStatusChangePayload; -import gov.irs.directfile.models.message.status.payload.StatusChangePayloadV1; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; -import static org.mockito.Mockito.doThrow; - -@ExtendWith(MockitoExtension.class) -class StatusChangeMessageServiceTest { - private StatusChangeMessageService statusChangeMessageService; - - @Mock - private StatusChangeSqsPublisher sqsPublisher; - - @Mock - private StatusChangeSnsPublisher snsPublisher; - - private static final Map> v1Object; - private static final String v1Json; - - static { - ObjectMapper objectMapper = new ObjectMapper(); - - v1Object = Map.of( - "accepted", List.of("11111111", "33333333"), - "rejected", List.of("22222222", "44444444")); - - VersionedStatusChangeMessage v1VersionedObject = - new VersionedStatusChangeMessage<>( - new StatusChangePayloadV1(v1Object), - new QueueMessageHeaders() - .addHeader(MessageHeaderAttribute.VERSION, StatusChangeMessageVersion.V1.getVersion())); - - try { - v1Json = objectMapper.writeValueAsString(v1VersionedObject); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - @BeforeEach - public void setup() { - statusChangeMessageService = - new StatusChangeMessageService(List.of(sqsPublisher, snsPublisher), new ObjectMapper()); - } - - @Test - public void publishStatusChangePayloadV1_success() { - statusChangeMessageService.publishStatusChangePayloadV1(v1Object); - - ArgumentCaptor sqsPublishArgumentCaptor = ArgumentCaptor.forClass(String.class); - verify(sqsPublisher, times(1)).publish(sqsPublishArgumentCaptor.capture()); - assertEquals(v1Json, sqsPublishArgumentCaptor.getValue()); - - ArgumentCaptor snsPublishArgumentCaptor = ArgumentCaptor.forClass(String.class); - verify(snsPublisher, times(1)).publish(snsPublishArgumentCaptor.capture()); - assertEquals(v1Json, snsPublishArgumentCaptor.getValue()); - } - - @ParameterizedTest - @NullAndEmptySource - public void publishStatusChangePayloadV1_nullOrEmptyPublishers(List publishers) { - StatusChangeMessageService noPublishersService = new StatusChangeMessageService(publishers, new ObjectMapper()); - noPublishersService.publishStatusChangePayloadV1(v1Object); - verify(sqsPublisher, never()).publish(any()); - verify(snsPublisher, never()).publish(any()); - } - - @Test - public void publishSubmissionConfirmationPayloadV1_writeValueAsStringFails() throws JsonProcessingException { - ObjectMapper mockMapper = Mockito.mock(ObjectMapper.class); - StatusChangeMessageService testService = - new StatusChangeMessageService(List.of(sqsPublisher, snsPublisher), mockMapper); - doThrow(new JsonProcessingException("bad json") {}).when(mockMapper).writeValueAsString(any()); - - assertThrows(PublisherException.class, () -> testService.publishStatusChangePayloadV1(v1Object)); - } - - @Test - public void publishStatusChangePayloadV1_publishFails() { - doThrow(new PublisherException("could not publish")).when(snsPublisher).publish(any()); - - assertThrows(PublisherException.class, () -> statusChangeMessageService.publishStatusChangePayloadV1(v1Object)); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouterTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouterTest.java deleted file mode 100644 index 0f1c0f7..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/SubmissionConfirmationMessageRouterTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package gov.irs.directfile.status.services; - -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV1; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.status.services.handlers.confirmation.SubmissionConfirmationV1Handler; -import gov.irs.directfile.status.services.handlers.confirmation.SubmissionConfirmationV2Handler; -import gov.irs.directfile.status.services.handlers.confirmation.UnsupportedMessageVersionHandler; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -public class SubmissionConfirmationMessageRouterTest { - - @Mock - public SubmissionConfirmationV1Handler submissionConfirmationV1Handler; - - @Mock - public SubmissionConfirmationV2Handler submissionConfirmationV2Handler; - - @Mock - public UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - private SubmissionConfirmationMessageRouter submissionConfirmationMessageRouter; - - @BeforeEach - public void setup() { - submissionConfirmationMessageRouter = new SubmissionConfirmationMessageRouter( - unsupportedMessageVersionHandler, submissionConfirmationV1Handler, submissionConfirmationV2Handler); - } - - @Test - public void itGetsHandlerWhenProvidedAValidConfirmationMessageVersion() { - // Arrange: Create a VersionedSubmissionConfirmationMessage, with a header specifying V1 - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV1(List.of()); - VersionedSubmissionConfirmationMessage queueMessage = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V1.getVersion())); - - // Act: Call handleSubmissionConfirmationMessage() - assertDoesNotThrow(() -> { - submissionConfirmationMessageRouter.handleSubmissionConfirmationMessage(queueMessage); - - // Assert: Expect that an exception was not thrown, and that the - // SubmissionConfirmationV1Handler.handleSubmissionConfirmationMessage() was called - verify(submissionConfirmationV1Handler, times(1)).handleSubmissionConfirmationMessage(any()); - }); - } - - @Test - public void givenConfirmationMessageV2_whenHandleSubmissionConfirmationMessage_thenCorrectHandlerChosen() { - // Arrange: Create a VersionedSubmissionConfirmationMessage, with a header specifying V2 - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV2(List.of()); - VersionedSubmissionConfirmationMessage queueMessage = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V2.getVersion())); - - // Act: Call handleSubmissionConfirmationMessage() - assertDoesNotThrow(() -> { - submissionConfirmationMessageRouter.handleSubmissionConfirmationMessage(queueMessage); - - // Assert: Expect that an exception was not thrown, and that the - // SubmissionConfirmationV2Handler.handleSubmissionConfirmationMessage() was called - verify(submissionConfirmationV2Handler, times(1)).handleSubmissionConfirmationMessage(any()); - }); - } - - @Test - public void itHandlesUnsupportedVersions() { - // Arrange: Create a VersionedSubmissionMessage, with a header specifying an unsupported version - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV2(List.of()); - String unsupportedVersion = "9.0.EGG"; - - VersionedSubmissionConfirmationMessage messageWithUnsupportedVersion = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders().addHeader(MessageHeaderAttribute.VERSION, unsupportedVersion)); - - // Act: call handleSubmissionConfirmationMessage() - assertThrows(UnsupportedVersionException.class, () -> { - submissionConfirmationMessageRouter.handleSubmissionConfirmationMessage(messageWithUnsupportedVersion); - - // Assert: Check that we called the UnsupportedVersionHandler - verify(unsupportedMessageVersionHandler, times(1)).handleSubmissionConfirmationMessage(any()); - }); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1HandlerTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1HandlerTest.java deleted file mode 100644 index d8245dc..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV1HandlerTest.java +++ /dev/null @@ -1,84 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import java.util.Date; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV1; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@EnableConfigurationProperties(StatusProperties.class) -@DataJpaTest -class SubmissionConfirmationV1HandlerTest { - @Autowired - PendingAcknowledgementRepository pendingRepo; - - @Autowired - TaxReturnSubmissionRepository taxReturnSubmissionRepo; - - @Autowired - private StatusProperties statusProperties; - - @Test - public void handleSubmissionConfirmationMessage() { - SubmissionConfirmationV1Handler handler = - new SubmissionConfirmationV1Handler(pendingRepo, taxReturnSubmissionRepo, statusProperties); - - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt1 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId1", "receiptId1", new Date()); - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt2 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId2", "receiptId2", new Date()); - List taxReturnSubmissionReceipts = - List.of(taxReturnSubmissionReceipt1, taxReturnSubmissionReceipt2); - - AbstractSubmissionConfirmationPayload payload = - new SubmissionConfirmationPayloadV1(taxReturnSubmissionReceipts); - VersionedSubmissionConfirmationMessage queueMessage = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V1.getVersion())); - - handler.handleSubmissionConfirmationMessage(queueMessage); - - assertEquals(2, pendingRepo.count()); - Optional pending1 = pendingRepo.GetPendingSubmission(taxReturnSubmissionReceipt1.getSubmissionId()); - assertTrue(pending1.isPresent() - && pending1.get().getSubmissionId().equals(taxReturnSubmissionReceipt1.getSubmissionId())); - Optional pending2 = pendingRepo.GetPendingSubmission(taxReturnSubmissionReceipt2.getSubmissionId()); - assertTrue(pending2.isPresent() - && pending2.get().getSubmissionId().equals(taxReturnSubmissionReceipt2.getSubmissionId())); - - assertEquals(2, taxReturnSubmissionRepo.count()); - Optional submissionId1 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnSubmissionReceipt1.getTaxReturnId()); - assertTrue( - submissionId1.isPresent() && submissionId1.get().equals(taxReturnSubmissionReceipt1.getSubmissionId())); - Optional submissionId2 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnSubmissionReceipt2.getTaxReturnId()); - assertTrue( - submissionId2.isPresent() && submissionId2.get().equals(taxReturnSubmissionReceipt2.getSubmissionId())); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2HandlerTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2HandlerTest.java deleted file mode 100644 index 4ce6db7..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/confirmation/SubmissionConfirmationV2HandlerTest.java +++ /dev/null @@ -1,117 +0,0 @@ -package gov.irs.directfile.status.services.handlers.confirmation; - -import java.util.*; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@EnableConfigurationProperties(StatusProperties.class) -@DataJpaTest -class SubmissionConfirmationV2HandlerTest { - @Autowired - PendingAcknowledgementRepository pendingRepo; - - @Autowired - TaxReturnSubmissionRepository taxReturnSubmissionRepo; - - @Autowired - StatusProperties statusProperties; - - @Test - public void handleSubmissionConfirmationMessage() { - SubmissionConfirmationV2Handler handler = - new SubmissionConfirmationV2Handler(pendingRepo, taxReturnSubmissionRepo, statusProperties); - - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt1 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId1", "receiptId1", new Date()); - SubmissionConfirmationPayloadV2Entry entry1 = new SubmissionConfirmationPayloadV2Entry( - taxReturnSubmissionReceipt1, SubmissionEventTypeEnum.SUBMITTED, Map.of()); - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt2 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId2", "receiptId2", new Date()); - SubmissionConfirmationPayloadV2Entry entry2 = new SubmissionConfirmationPayloadV2Entry( - taxReturnSubmissionReceipt2, SubmissionEventTypeEnum.FAILED, Map.of()); - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt3 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId3", "receiptId3", new Date()); - SubmissionConfirmationPayloadV2Entry entry3 = new SubmissionConfirmationPayloadV2Entry( - taxReturnSubmissionReceipt3, SubmissionEventTypeEnum.SUBMITTED, Map.of()); - - List entries = List.of(entry1, entry2, entry3); - - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV2(entries); - VersionedSubmissionConfirmationMessage queueMessage = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V2.getVersion())); - - handler.handleSubmissionConfirmationMessage(queueMessage); - - assertEquals(2, pendingRepo.count()); - Optional pending1 = pendingRepo.GetPendingSubmission(taxReturnSubmissionReceipt1.getSubmissionId()); - assertTrue(pending1.isPresent() - && pending1.get().getSubmissionId().equals(taxReturnSubmissionReceipt1.getSubmissionId())); - Optional pending2 = pendingRepo.GetPendingSubmission(taxReturnSubmissionReceipt3.getSubmissionId()); - assertTrue(pending2.isPresent() - && pending2.get().getSubmissionId().equals(taxReturnSubmissionReceipt3.getSubmissionId())); - - assertEquals(2, taxReturnSubmissionRepo.count()); - Optional submissionId1 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnSubmissionReceipt1.getTaxReturnId()); - assertTrue( - submissionId1.isPresent() && submissionId1.get().equals(taxReturnSubmissionReceipt1.getSubmissionId())); - Optional submissionId2 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnSubmissionReceipt3.getTaxReturnId()); - assertTrue( - submissionId2.isPresent() && submissionId2.get().equals(taxReturnSubmissionReceipt3.getSubmissionId())); - } - - @Test - public void handleSubmissionConfirmationMessage_noSubmittedReturns() { - SubmissionConfirmationV2Handler handler = - new SubmissionConfirmationV2Handler(pendingRepo, taxReturnSubmissionRepo, statusProperties); - - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt1 = - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "submissionId1", "receiptId1", new Date()); - SubmissionConfirmationPayloadV2Entry entry1 = new SubmissionConfirmationPayloadV2Entry( - taxReturnSubmissionReceipt1, SubmissionEventTypeEnum.FAILED, Map.of()); - - List entries = List.of(entry1); - - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV2(entries); - VersionedSubmissionConfirmationMessage queueMessage = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V2.getVersion())); - - handler.handleSubmissionConfirmationMessage(queueMessage); - - assertEquals(0, pendingRepo.count()); - assertEquals(0, taxReturnSubmissionRepo.count()); - } -} diff --git a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1HandlerTest.java b/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1HandlerTest.java deleted file mode 100644 index c822a21..0000000 --- a/direct-file/status/src/test/java/gov/irs/directfile/status/services/handlers/pending/PendingSubmissionV1HandlerTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package gov.irs.directfile.status.services.handlers.pending; - -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.pending.PendingSubmissionMessageVersion; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.models.message.pending.payload.PendingSubmissionPayloadV1; -import gov.irs.directfile.status.acknowledgement.PendingAcknowledgementRepository; -import gov.irs.directfile.status.acknowledgement.TaxReturnSubmissionRepository; -import gov.irs.directfile.status.config.StatusProperties; -import gov.irs.directfile.status.domain.Pending; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) -@EnableConfigurationProperties(StatusProperties.class) -@DataJpaTest -class PendingSubmissionV1HandlerTest { - @Autowired - PendingAcknowledgementRepository pendingRepo; - - @Autowired - TaxReturnSubmissionRepository taxReturnSubmissionRepo; - - @Autowired - StatusProperties statusProperties; - - @Test - public void handlePendingSubmissionMessage() { - PendingSubmissionV1Handler handler = - new PendingSubmissionV1Handler(pendingRepo, taxReturnSubmissionRepo, statusProperties); - - TaxReturnIdAndSubmissionId taxReturnIdAndSubmissionId1 = - new TaxReturnIdAndSubmissionId(UUID.randomUUID(), "submissionId1"); - TaxReturnIdAndSubmissionId taxReturnIdAndSubmissionId2 = - new TaxReturnIdAndSubmissionId(UUID.randomUUID(), "submissionId2"); - List taxReturnIdAndSubmissionIds = - List.of(taxReturnIdAndSubmissionId1, taxReturnIdAndSubmissionId2); - - AbstractPendingSubmissionPayload payload = new PendingSubmissionPayloadV1(taxReturnIdAndSubmissionIds); - VersionedPendingSubmissionMessage queueMessage = - new VersionedPendingSubmissionMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - PendingSubmissionMessageVersion.V1.getVersion())); - - handler.handlePendingSubmissionMessage(queueMessage); - - assertEquals(2, pendingRepo.count()); - Optional pending1 = pendingRepo.GetPendingSubmission(taxReturnIdAndSubmissionId1.getSubmissionId()); - assertTrue(pending1.isPresent() - && pending1.get().getSubmissionId().equals(taxReturnIdAndSubmissionId1.getSubmissionId())); - Optional pending2 = pendingRepo.GetPendingSubmission(taxReturnIdAndSubmissionId2.getSubmissionId()); - assertTrue(pending2.isPresent() - && pending2.get().getSubmissionId().equals(taxReturnIdAndSubmissionId2.getSubmissionId())); - - assertEquals(2, taxReturnSubmissionRepo.count()); - Optional submissionId1 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnIdAndSubmissionId1.getTaxReturnId()); - assertTrue( - submissionId1.isPresent() && submissionId1.get().equals(taxReturnIdAndSubmissionId1.getSubmissionId())); - Optional submissionId2 = taxReturnSubmissionRepo.getLatestSubmissionIdByTaxReturnId( - taxReturnIdAndSubmissionId2.getTaxReturnId()); - assertTrue( - submissionId2.isPresent() && submissionId2.get().equals(taxReturnIdAndSubmissionId2.getSubmissionId())); - } -} diff --git a/direct-file/status/src/test/resources/application-default.yaml b/direct-file/status/src/test/resources/application-default.yaml deleted file mode 100644 index a3c46b5..0000000 --- a/direct-file/status/src/test/resources/application-default.yaml +++ /dev/null @@ -1,38 +0,0 @@ -spring: - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;CASE_INSENSITIVE_IDENTIFIERS=true - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.H2Dialect #Override PostgreSQLDialect defined in src/main/resources/application.yaml, SpringBoot v3.3.0 enforced using dialect -status: - private-key: src/test/resources/private.p12 - private-key-password: 000 - unit-testing: true - etin: ${STATUS_ETIN:99999} - asid: 000 - efin: 00 - prod: false - toolkit: 000 - root-translation-key: status - translation-key-splitter: . - ack-poll-in-milliseconds: 1200000 - messageQueue: - url: http://localhost:4577/000000000000/pending-submission-queue - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - sqs-message-handling-enabled: false - -direct-file: - local-encryption: - local-wrapping-key: lYIIKutUatfMwdEGB8qtUpQc3wMNtT5pfM+zW57qrv4= - -aws: - enabled: false - default-credentials-provider-chain-enabled: false - access-key: test - secret-key: test - region: us-west-2 - kmsEndpoint: http://directfile.test diff --git a/direct-file/status/src/test/resources/config/logging.properties b/direct-file/status/src/test/resources/config/logging.properties deleted file mode 100644 index 62cb168..0000000 --- a/direct-file/status/src/test/resources/config/logging.properties +++ /dev/null @@ -1,2 +0,0 @@ -# This is an empty logging properties file because the MeF SDK requires one -# Because we use some MeF Java classes in our code, it requires us to have this. \ No newline at end of file diff --git a/direct-file/submit/.dockerignore b/direct-file/submit/.dockerignore deleted file mode 100644 index c66b71d..0000000 --- a/direct-file/submit/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -**/application-local.* -/src/main/java/gov/irs/directfile/submit/xml -.env* -.git/ -Dockerfile* diff --git a/direct-file/submit/.gitignore b/direct-file/submit/.gitignore deleted file mode 100644 index e4fb2d1..0000000 --- a/direct-file/submit/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -HELP.md -target/ -!**/src/main/**/target/ -!**/src/test/**/target/ - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -build/ -!**/src/main/**/build/ -!**/src/test/**/build/ - -### VS Code ### -.vscode/ - -sample_runner.sh -/test/ -/src/main/java/resources/test -*.jar -/target -/.secret/ -/src/main/resources/application-local.* -/src/main/resources/test/run -audit_log.txt - -### Spot Bugs ### -/src/main/resources/spotbugs/output/spotbugs.xml \ No newline at end of file diff --git a/direct-file/submit/.liquibase.properties b/direct-file/submit/.liquibase.properties deleted file mode 100644 index 2e98b4c..0000000 --- a/direct-file/submit/.liquibase.properties +++ /dev/null @@ -1,5 +0,0 @@ -changeLogFile=db/changelog.yaml -url=jdbc:postgresql://localhost:32768/directfile-submit -username=postgres -password=postgres -changesetAuthor=directfile \ No newline at end of file diff --git a/direct-file/submit/.mvn/wrapper/maven-wrapper.properties b/direct-file/submit/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 23c7e59..0000000 --- a/direct-file/submit/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -wrapperVersion=3.3.2 -distributionType=only-script -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip diff --git a/direct-file/submit/Dockerfile-local b/direct-file/submit/Dockerfile-local deleted file mode 100644 index b50ea28..0000000 --- a/direct-file/submit/Dockerfile-local +++ /dev/null @@ -1,54 +0,0 @@ -#syntax=docker/dockerfile:1.7-labs -# build factgraph since it will be a dependency in share-libs-builder -FROM sbtscala/scala-sbt:eclipse-temurin-alpine-21.0.2_13_1.9.9_3.3.3 AS factgraph-builder -WORKDIR /build/ -COPY --from=factgraph-repo js/src/ js/src/ -COPY --from=factgraph-repo jvm/src/ jvm/src/ -COPY --from=factgraph-repo project/build.properties project/plugins.sbt project/ -COPY --from=factgraph-repo shared/ shared/ -COPY --from=factgraph-repo build.sbt . -RUN sbt compile package publishM2 - -# build shared dependencies -FROM eclipse-temurin:21-jdk-alpine AS shared-dependencies-builder -COPY --from=factgraph-builder /root/.m2/repository/gov/irs/factgraph/fact-graph_3/ /root/.m2/repository/gov/irs/factgraph/fact-graph_3/ -ARG MAVEN_OPTS="" -WORKDIR /build/ -COPY --from=config . ./config/ -COPY --from=boms . ./boms/ -WORKDIR /build/libs/ -COPY --from=shared-libs .mvn/wrapper/maven-wrapper.properties .mvn/wrapper/ -COPY --from=shared-libs mvnw ./ -COPY --from=shared-libs --parents **/pom.xml ./ -RUN ./mvnw dependency:resolve -P resolve -COPY --from=shared-libs starters/ ./starters/ -COPY --from=shared-libs data-models/ ./data-models/ -RUN ./mvnw install - -FROM shared-dependencies-builder AS mef-submit-builder -ARG MAVEN_OPTS="" -ENV MEF_REPO /mef-client-sdk -ENV A2A_TOOLKIT_HOME /${MEF_REPO}/MeF_Client_SDK/Java/source/ -COPY --from=mef-sdk-repo MeF_Client_SDK/ /${MEF_REPO}/MeF_Client_SDK/ -COPY --from=config . /config/ -WORKDIR /build/ -COPY --from=scripts install-mef-sdk.sh . -COPY mvnw pom.xml ./ -COPY .mvn/wrapper/maven-wrapper.properties .mvn/wrapper/ -RUN ./install-mef-sdk.sh -RUN ./mvnw dependency:resolve -COPY src/ /build/src/ -RUN ./mvnw package - -FROM eclipse-temurin:21-jre-alpine -COPY --from=mef-submit-builder /build/target/mef-submit-0.0.1-SNAPSHOT.jar /app.jar -COPY --from=mef-sdk-repo MeF_Client_SDK/Java/source/ /mef-client-sdk-src/ -# Run from dir that allows mef-sdk to write it's files to the working directory (next iteration: configure mef-sdk) -# Pre-create `/mef-data`, the prefix used in the Spring profile `application-docker.yaml` (`submit.directories.*`)# Pre-create `/mef-data`, the prefix used in the Spring profile `application-docker.yaml` (`submit.directories.*`) -RUN adduser --system --no-create-home jar-runner && \ - mkdir -p /mef-data && \ - mkdir -p /jar-run && \ - chown jar-runner /mef-data /jar-run -WORKDIR /jar-run -USER jar-runner -CMD ["java", "-jar", "/app.jar"] diff --git a/direct-file/submit/README.md b/direct-file/submit/README.md deleted file mode 100644 index 74baac1..0000000 --- a/direct-file/submit/README.md +++ /dev/null @@ -1,186 +0,0 @@ -# MEF Submit - -If you use a proxy, first see `MAVEN_OPTS` in [the project readme](../README.md#important-configuration-variables) and [the OMB Connect readme](../README-omb-connect.md) for information about ensuring your proxy settings are passed to all build steps. - -## Prerequisites - -#### Setup dependencies and build - -> [!NOTE] -> For setup please see the most up-to-date instructions which are found in the [Onboarding docs](../../ONBOARDING.md). - -- Set an environment variable, `MEF_REPO`, whose value is the path where you want the MeF SDK repo cloned to. You can -set this up in your shell dotfile to have it loaded each time automatically. E.g. - - ```shell - echo EXPORT MEF_REPO="~/irs/mef-sdk" >> ~/.zprofile - ``` - -- Build and install the dependencies and build the submit app. - - ```sh - INSTALL_MEF=1 ../scripts/build-project.sh - ``` - -- Verify that java files exist in [the efile directory](./src/main/java/gov/irs/directfile/submit/xml/gov/irs/efile) - -#### Running the application locally -- Follow the pre-requisite steps -- Set the 'MISSING' `application.yaml` properties. Setting test values for `etin`, `asid`, and `efin` listed below should work for local development where a connection to a MeF client is not required for your development work. - NOTE: If you need to connect to the Mef client for your development work, you will need to use a separate set of variables, set the missing keystore values, and there may be additional setup specific to the MeF Client. - ```yaml - submit: - etin: 11111 - asid: 22222222 - efin: 333333 - ``` -- Run the application (you can do this from your IDE or the command line) - ```sh - # To use the command line run the following from the project root - ./mvnw compile - ./mvnw spring-boot:run -Dspring-boot.run.profiles=development - ``` -## Docker - -Ensure that the appropriate environment variables are set up depending on how you are running the application. -See [environment](#environment) below. - -Build the application: - -```bash -docker compose build mef-submit -``` - -Then run it: - -```bash -docker compose up -d mef-submit -``` - -The app probably failed for you due to lack of configuration. You can look at the reason why it failed to start with: - -```bash -docker compose logs mef-submit -``` - -## Running locally - -### Environment - -Set the following environment variables in your local environment which will facilitate running both the applications as well as the docker containers. On macbooks, placing the export statements below in the `.zshrc` (gets run and evaluated everytime a shell instance is started) or `.zprofile` (gets run and evaluated when a user logs in) file will accomplish this. If using the bash shell, placing them in `.bashrc` should do (and effectively behave similar to `.zshrc`). - -```sh -# Get the base64 encoded keystore from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_KEYSTORE_KEYSTOREBASE64="[base64-encoded-keystore]" - -# Get the keystore password from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_KEYSTORE_KEYSTOREPASSWORD="[keystore-password]" - -# Get the keystore alias from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_KEYSTORE_KEYSTOREALIAS="[keystore-alias]" - -# Get the ASID value for the submit application from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_ASID="[submit-asid]" - -# Get the EFIN value for the submit application from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_EFIN="[submit-efin]" - -# Get the ETIN value for the submit application from a fellow developer and replace the value in between quotes with the actual value -export SUBMIT_ETIN="[submit-etin]" - -# Replace wa with your own initials *** NOTE: characters must be lowercase *** -export SUBMIT_ID_VAR_CHARS="wa" -``` - -You'll also need to set up the `LOCAL_WRAPPING_KEY` following the instructions in the [backend README](../backend/README.md#initial-setup) -``` -export LOCAL_WRAPPING_KEY="[local-wrapping-key]" -``` - -Maven command for running the application locally: - -```sh -./mvnw spring-boot:run -Dspring-boot.run.profiles=development -``` - -### Developer Notes: -Files in the `direct-file/submit/src/main/java/gov/irs/directfile/submit/gen` directory are generated by the `direct-file/utils/mef-code-generator` application. - - -### Static Analysis -We use [SpotBugs](https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html) and [PMD](https://pmd.github.io/pmd/index.html) for static code analysis in this app. The app is configured to have pre-commit hooks -run SpotBugs and PMD. - -Spotbugs and PMD both generate static analysis reports that can be used to resolve issues in the project. - -PMD is configured view an [xml file](src/main/resources/pmd/static-analysis-ruleset.xml) that specifies the linting rules we adhere to - -**How do I see the reports?** - -To see a formatted html page for the static analysis reports you can run: - -```bash -./mvnw compile site:run -``` -This will start a site at `localhost:9898`. Navigate to `Project Reports` and then click on PMD or Spotbugs to view errors in the app. - - -If you want to ignore the pre-commit hook that runs spotbugs do: - -`git commit --no-verify` - - - -To generate each report, you can run: -```bash -./mvnw compile spotbugs:spotbugs -``` - -```bash -./mvnw pmd:pmd -``` -The xml file this generates isn't very readable, so use `./mvnw spotbugs:gui` for an interactive guild or run `./mvnw site` to see an html report of the xml report. - -To check if the project currently passes static analysis: -```bash -./mvnw compile spotbugs:check -``` - -```bash -./mvnw pmd:check -``` -SpotBugs also offers a local gui that displays information based on the output of spotbugs. Calling compile before spotless:gui, ensures -we have all the latest changes reflected in the spotbugs report. - -```bash -./mvnw compile spotbugs:gui -``` - -I've also configured the build to generate the spotbugs report when you run `./mvnw clean compile`. SpotBugs looks at the generated target folder -of the project, so doing a `./mvnw clean compile` will ensure you're seeing the latest spotbugs report. - -For more information on Spotbugs: - -Docs Site: https://spotbugs.readthedocs.io/en/latest/introduction.html - -Github Repo: https://github.com/spotbugs/spotbugs - -Maven Spotbugs Plugin Docs: https://spotbugs.github.io/spotbugs-maven-plugin/plugin-info.html - -PMD Docs Site: https://docs.pmd-code.org/latest/index.html - -PMD Java Rules: https://docs.pmd-code.org/latest/pmd_rules_java.html - -PMD Maven Plugin Docs: https://maven.apache.org/plugins/maven-pmd-plugin/index.html -## Health Check -The Submit App uses [Spring Boot Actuator](https://docs.spring.io/spring-boot/docs/2.5.6/reference/html/actuator.html#actuator.endpoints.enabling) to expose a health check endpoint. -When running the app locally, the health check endpoint should be available at: - -```text -http://localhost:{PORT}/actuator/health -``` - - -## Tests - -Run tests locally with `./mvnw test` diff --git a/direct-file/submit/mvnw b/direct-file/submit/mvnw deleted file mode 100755 index 19529dd..0000000 --- a/direct-file/submit/mvnw +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.2 -# -# Optional ENV vars -# ----------------- -# JAVA_HOME - location of a JDK home dir, required when download maven via java source -# MVNW_REPOURL - repo url base for downloading maven distribution -# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output -# ---------------------------------------------------------------------------- - -set -euf -[ "${MVNW_VERBOSE-}" != debug ] || set -x - -# OS specific support. -native_path() { printf %s\\n "$1"; } -case "$(uname)" in -CYGWIN* | MINGW*) - [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" - native_path() { cygpath --path --windows "$1"; } - ;; -esac - -# set JAVACMD and JAVACCMD -set_java_home() { - # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched - if [ -n "${JAVA_HOME-}" ]; then - if [ -x "$JAVA_HOME/jre/sh/java" ]; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - JAVACCMD="$JAVA_HOME/jre/sh/javac" - else - JAVACMD="$JAVA_HOME/bin/java" - JAVACCMD="$JAVA_HOME/bin/javac" - - if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then - echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 - echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 - return 1 - fi - fi - else - JAVACMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v java - )" || : - JAVACCMD="$( - 'set' +e - 'unset' -f command 2>/dev/null - 'command' -v javac - )" || : - - if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then - echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 - return 1 - fi - fi -} - -# hash string like Java String::hashCode -hash_string() { - str="${1:-}" h=0 - while [ -n "$str" ]; do - char="${str%"${str#?}"}" - h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) - str="${str#?}" - done - printf %x\\n $h -} - -verbose() { :; } -[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - -die() { - printf %s\\n "$1" >&2 - exit 1 -} - -trim() { - # MWRAPPER-139: - # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. - # Needed for removing poorly interpreted newline sequences when running in more - # exotic environments such as mingw bash on Windows. - printf "%s" "${1}" | tr -d '[:space:]' -} - -# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties -while IFS="=" read -r key value; do - case "${key-}" in - distributionUrl) distributionUrl=$(trim "${value-}") ;; - distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; - esac -done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" - -case "${distributionUrl##*/}" in -maven-mvnd-*bin.*) - MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ - case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in - *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; - :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; - :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; - :Linux*x86_64*) distributionPlatform=linux-amd64 ;; - *) - echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 - distributionPlatform=linux-amd64 - ;; - esac - distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" - ;; -maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; -esac - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" -distributionUrlName="${distributionUrl##*/}" -distributionUrlNameMain="${distributionUrlName%.*}" -distributionUrlNameMain="${distributionUrlNameMain%-bin}" -MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" -MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" - -exec_maven() { - unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : - exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" -} - -if [ -d "$MAVEN_HOME" ]; then - verbose "found existing MAVEN_HOME at $MAVEN_HOME" - exec_maven "$@" -fi - -case "${distributionUrl-}" in -*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; -*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; -esac - -# prepare tmp dir -if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then - clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } - trap clean HUP INT TERM EXIT -else - die "cannot create temp dir" -fi - -mkdir -p -- "${MAVEN_HOME%/*}" - -# Download and Install Apache Maven -verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -verbose "Downloading from: $distributionUrl" -verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -# select .zip or .tar.gz -if ! command -v unzip >/dev/null; then - distributionUrl="${distributionUrl%.zip}.tar.gz" - distributionUrlName="${distributionUrl##*/}" -fi - -# verbose opt -__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' -[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v - -# normalize http auth -case "${MVNW_PASSWORD:+has-password}" in -'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; -has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; -esac - -if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then - verbose "Found wget ... using wget" - wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" -elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then - verbose "Found curl ... using curl" - curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" -elif set_java_home; then - verbose "Falling back to use Java to download" - javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" - targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" - cat >"$javaSource" <<-END - public class Downloader extends java.net.Authenticator - { - protected java.net.PasswordAuthentication getPasswordAuthentication() - { - return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); - } - public static void main( String[] args ) throws Exception - { - setDefault( new Downloader() ); - java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); - } - } - END - # For Cygwin/MinGW, switch paths to Windows format before running javac and java - verbose " - Compiling Downloader.java ..." - "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" - verbose " - Running Downloader.java ..." - "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" -fi - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -if [ -n "${distributionSha256Sum-}" ]; then - distributionSha256Result=false - if [ "$MVN_CMD" = mvnd.sh ]; then - echo "Checksum validation is not supported for maven-mvnd." >&2 - echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - elif command -v shasum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then - distributionSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 - echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 - exit 1 - fi - if [ $distributionSha256Result = false ]; then - echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 - echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 - exit 1 - fi -fi - -# unzip and move -if command -v unzip >/dev/null; then - unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" -else - tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" -fi -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" - -clean || : -exec_maven "$@" diff --git a/direct-file/submit/mvnw.cmd b/direct-file/submit/mvnw.cmd deleted file mode 100644 index b150b91..0000000 --- a/direct-file/submit/mvnw.cmd +++ /dev/null @@ -1,149 +0,0 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/direct-file/submit/pom.xml b/direct-file/submit/pom.xml deleted file mode 100644 index fcc690b..0000000 --- a/direct-file/submit/pom.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - 4.0.0 - - gov.irs.directfile.boot - irs-spring-boot-starter-parent - 0.0.1-SNAPSHOT - ../boms/irs-spring-boot-starter-parent - - gov.irs.directfile - mef-submit - 0.0.1-SNAPSHOT - MeF submit - MeF submission application - - - ${project.basedir}/../config - - - - gov.irs.directfile - data-models - - - org.liquibase - liquibase-core - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-actuator - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - org.postgresql - postgresql - runtime - - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-test - test - - - jakarta.xml.ws - jakarta.xml.ws-api - - - com.sun.xml.bind - jaxb-impl - - - com.sun.xml.ws - jaxws-rt - - - com.h2database - h2 - test - - - org.apache.commons - commons-compress - - - software.amazon.awssdk - s3 - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - sts - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - sns - - - commons-logging - commons-logging - - - - - software.amazon.awssdk - sqs - - - commons-logging - commons-logging - - - - - com.amazonaws - amazon-sqs-java-messaging-lib - - - org.slf4j - slf4j-api - - - - - software.amazon.encryption.s3 - amazon-s3-encryption-client-java - - - org.apache.commons - commons-lang3 - - - net.logstash.logback - logstash-logback-encoder - runtime - - - com.github.spotbugs - spotbugs-annotations - - - - - - org.apache.maven.plugins - maven-site-plugin - - - 9898 - ${basedir}/target/site/tempdir - - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - -XX:+EnableDynamicAgentLoading ${argLine} - - - SPRING_PROFILES_ACTIVE - - - - - - - diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/BatchingProperties.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/BatchingProperties.java deleted file mode 100644 index 709c921..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/BatchingProperties.java +++ /dev/null @@ -1,23 +0,0 @@ -package gov.irs.directfile.submit; - -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public final class BatchingProperties { - private int maxBatchSize; - private long batchTimeoutMilliseconds; - - public BatchingProperties(int maxBatchSize, long batchTimeoutMilliseconds) { - this.maxBatchSize = maxBatchSize; - this.batchTimeoutMilliseconds = batchTimeoutMilliseconds; - } - - @Override - public String toString() { - return "BatchingProperties{" + "maxBatchSize=" - + maxBatchSize + ", batchTimeoutMilliseconds=" - + batchTimeoutMilliseconds + '}'; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/Runner.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/Runner.java deleted file mode 100644 index 4ff1198..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/Runner.java +++ /dev/null @@ -1,63 +0,0 @@ -package gov.irs.directfile.submit; - -import jakarta.annotation.PostConstruct; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.service.ActionHandler; -import gov.irs.directfile.submit.service.OfflineModeService; - -@Slf4j -@Service -public class Runner { - - // This is the message queue of actions - // It could be added to by background threads (from timers) - // but should only be read in one place. - ActionQueue actions; - - private final ActionHandler actionHandler; - private final OfflineModeService offlineModeService; - - public Runner(ActionQueue actions, ActionHandler actionHandler, OfflineModeService offlineModeService) { - this.actions = actions; - this.actionHandler = actionHandler; - this.offlineModeService = offlineModeService; - } - - @PostConstruct - public void setup() { - this.Start(); - } - - void Start() { - Runnable runnable = this::handleActions; - log.info("starting message loop"); - new Thread(runnable).start(); - } - - private void handleActions() { - try { - while (true) { - step(); - } - } catch (InterruptedException e) { - log.error("Exiting", e); - } - } - - public void step() throws InterruptedException { - if (!offlineModeService.isOfflineModeEnabled()) { - if (actions.getInProgressActions().isEmpty()) { - log.info("Handling new action"); - var action = actions.getNewActions().take(); - actionHandler.handleAction(action); - } else { - log.info("Handling in-progress action"); - var action = actions.getInProgressActions().take(); - actionHandler.handleAction(action); - } - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitApplication.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitApplication.java deleted file mode 100644 index c60748a..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitApplication.java +++ /dev/null @@ -1,19 +0,0 @@ -package gov.irs.directfile.submit; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.properties.EnableConfigurationProperties; - -import gov.irs.directfile.submit.config.*; - -@SpringBootApplication -@EnableConfigurationProperties({ - Config.class, -}) -public class SubmitApplication { - - public static void main(String[] args) { - System.setProperty("spring.devtools.restart.enabled", "false"); - SpringApplication.run(SubmitApplication.class, args); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitService.java deleted file mode 100644 index 20f0f0b..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/SubmitService.java +++ /dev/null @@ -1,60 +0,0 @@ -package gov.irs.directfile.submit; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import jakarta.annotation.PostConstruct; -import jakarta.transaction.Transactional; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.service.*; - -@Service -@EnableScheduling -@Transactional -@Slf4j -@SuppressWarnings({"PMD.ExcessiveParameterList", "PMD.SignatureDeclareThrowsException", "PMD.AvoidCatchingThrowable"}) -public class SubmitService { - private final Config config; - private final SqsConnectionSetupService sqsConnectionSetupService; - - private final UserSubmissionConsumer userSubmissionConsumer; - - @SneakyThrows - public SubmitService( - Config configuration, - SqsConnectionSetupService sqsConnectionSetupService, - UserSubmissionConsumer userSubmissionConsumer) { - this.config = configuration; - this.sqsConnectionSetupService = sqsConnectionSetupService; - this.userSubmissionConsumer = userSubmissionConsumer; - log.info("Setting up the MeF connection"); - } - - @PostConstruct - public void setup() throws Exception { - createDirectories(); - - if (config.isRunnerDisabledForTesting()) { - log.info("exiting setup before creating services because this is a test tun"); - return; - } - - if (config.getMessageQueue().isSqsMessageHandlingEnabled()) { - sqsConnectionSetupService.setup(userSubmissionConsumer); - } - } - - private void createDirectories() { - try { - log.info("Attempting to create directories for data writes"); - new DirectoryCreator(config).CreateDirectories(); - } catch (IOException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionContext.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionContext.java deleted file mode 100644 index 2140ddc..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionContext.java +++ /dev/null @@ -1,36 +0,0 @@ -package gov.irs.directfile.submit.actions; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import gov.irs.a2a.mef.mefheader.TestCdType; -import gov.irs.mef.services.ServiceContext; -import gov.irs.mef.services.data.ETIN; - -import gov.irs.directfile.submit.config.Config; - -@Slf4j -@SuppressWarnings("PMD.LiteralsFirstInComparisons") -@Getter -public class ActionContext { - private Config config; - private ServiceContext serviceContext; - - public ActionContext(Config config) { - this.config = config; - TestCdType testCd = TestCdType.T; - if (config.isProd()) { - log.info("This is a production release pointing at real MeF! Pointing toolkit to prod"); - testCd = TestCdType.P; - } else { - log.info("Non-prod release, pointing at PRE PROD!"); - } - - CreateServiceContext(config.getEtin(), config.getAsid(), testCd); - } - - private void CreateServiceContext(String etinString, String asidString, TestCdType testCd) { - ETIN etin = new ETIN(etinString); - serviceContext = new ServiceContext(etin, asidString, testCd); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionException.java deleted file mode 100644 index 791aacd..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/ActionException.java +++ /dev/null @@ -1,16 +0,0 @@ -package gov.irs.directfile.submit.actions; - -public class ActionException extends Exception { - - public ActionException(String message) { - super(message); - } - - public ActionException(String message, Throwable cause) { - super(message, cause); - } - - public ActionException(Throwable e) { - super(e); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandler.java deleted file mode 100644 index bbe1b04..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandler.java +++ /dev/null @@ -1,67 +0,0 @@ -package gov.irs.directfile.submit.actions; - -import java.util.List; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.mef.inputcomposition.PostmarkedSubmissionArchive; -import gov.irs.mef.inputcomposition.SubmissionBuilder; -import gov.irs.mef.inputcomposition.SubmissionContainer; - -import gov.irs.directfile.audit.AuditService; -import gov.irs.directfile.submit.actions.exception.BundleArchiveActionException; -import gov.irs.directfile.submit.actions.results.BundleArchivesActionResult; -import gov.irs.directfile.submit.command.BundleArchiveAction; -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionArchiveContainer; -import gov.irs.directfile.submit.domain.UserContextData; - -@Slf4j -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@Service -public class BundleArchivesActionHandler { - - private final ActionContext actionContext; - - public BundleArchivesActionHandler(ActionContext actionContext) { - this.actionContext = actionContext; - } - - private static final AuditService auditService = new AuditService(); - - public BundleArchivesActionResult handleBundleCommand(BundleArchiveAction bundleArchiveActionCommand) - throws BundleArchiveActionException { - SubmissionContainer container = null; - List archives = - bundleArchiveActionCommand.getCreateArchiveActionResult().getSubmissionArchiveContainers(); - - try { - - // TODO: what is the maximum bundle size? - PostmarkedSubmissionArchive[] archs = new PostmarkedSubmissionArchive[archives.size()]; - for (int i = 0; i < archives.size(); i++) { - archs[i] = archives.get(i).Archive; - } - container = SubmissionBuilder.createSubmissionContainer( - archs, actionContext.getConfig().getDirectories().getBatched()); - - } catch (Exception e) { - throw new BundleArchiveActionException( - getUserContextDataList(archives), - bundleArchiveActionCommand.getCreateArchiveActionResult().getBatch(), - e); - } - - return new BundleArchivesActionResult( - bundleArchiveActionCommand.getCreateArchiveActionResult().getBatch(), - new BundledArchives(getUserContextDataList(archives), container)); - } - - private List getUserContextDataList(List archives) { - return archives.stream().map(x -> x.UserContext).toList(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CleanupActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CleanupActionHandler.java deleted file mode 100644 index 3bb362a..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CleanupActionHandler.java +++ /dev/null @@ -1,95 +0,0 @@ -package gov.irs.directfile.submit.actions; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.stream.Stream; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.actions.results.CleanupActionResult; -import gov.irs.directfile.submit.command.CleanupAction; -import gov.irs.directfile.submit.domain.DocumentStoreResource; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Slf4j -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial Spotbugs Setup") -@Service -public class CleanupActionHandler { - - private final ActionContext actionContext; - private final ISynchronousDocumentStoreService documentStoreService; - - public CleanupActionHandler(ActionContext actionContext, ISynchronousDocumentStoreService documentStoreService) { - this.actionContext = actionContext; - this.documentStoreService = documentStoreService; - } - - public void cleanupBatch(SubmissionBatch submissionBatch) throws ActionException { - cleanDirectory(Path.of(actionContext.getConfig().getDirectories().getToProcess())); - cleanDirectory(Path.of(actionContext.getConfig().getDirectories().getProcessed())); - cleanDirectory(Path.of(actionContext.getConfig().getDirectories().getToBatch())); - cleanDirectory(Path.of(actionContext.getConfig().getDirectories().getBatched())); - cleanDocumentStore(submissionBatch); - } - - public CleanupActionResult handleAction(CleanupAction cleanupAction) throws ActionException { - this.cleanupBatch(cleanupAction.getSubmissionBatch()); - return new CleanupActionResult(); - } - - void cleanDirectory(Path path) { - // check if the path exists - if (!Files.exists(path)) { - log.info("Path does not exist: {}", path); - return; - } - - // clear the files so the directories can be deleted. - try (Stream walk = Files.walk(path)) { - walk.filter(Files::isRegularFile).forEach(x -> { - try { - Files.deleteIfExists(x); - } catch (IOException e) { - log.error("Error deleting file: {}", x, e); - } - }); - } catch (IOException e) { - throw new RuntimeException(e); - } - - // same thing, but with the directories - try (Stream walk = Files.walk(path)) { - walk.filter(Files::isDirectory).forEach(x -> { - if (x.compareTo(path) != 0) { - try { - Files.delete(x); - } catch (IOException e) { - log.error("Error deleting directory: {}", x, e); - } - } - }); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - void cleanDocumentStore(SubmissionBatch batch) { - List allKeys = documentStoreService.getObjectKeys(batch.path()).stream() - .map(DocumentStoreResource::getFullLocation) - .toList(); - - // 2. Do a nested for loop in batches of 1000 to delete the objects from s3 - int maxObjectsPerRequest = 1000; - for (int i = 0; i < allKeys.size(); i += maxObjectsPerRequest) { - List partition = allKeys.subList(i, Math.min(i + maxObjectsPerRequest, allKeys.size())); - documentStoreService.deleteObjects(partition); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CreateArchiveActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CreateArchiveActionHandler.java deleted file mode 100644 index 2d9a163..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/CreateArchiveActionHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -package gov.irs.directfile.submit.actions; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import javax.xml.datatype.XMLGregorianCalendar; - -import com.fasterxml.jackson.databind.ObjectMapper; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.inputcomposition.*; - -import gov.irs.directfile.submit.actions.exception.CreateArchiveActionException; -import gov.irs.directfile.submit.actions.results.CreateArchiveActionResult; -import gov.irs.directfile.submit.command.CreateArchiveAction; -import gov.irs.directfile.submit.domain.SubmissionArchiveContainer; -import gov.irs.directfile.submit.domain.UserContextData; -import gov.irs.directfile.submit.service.LocalWriteUtilityService; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Slf4j -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@Service -public class CreateArchiveActionHandler { - private final ISynchronousDocumentStoreService storageService; - - private final ObjectMapper objectMapper = new ObjectMapper(); - private final ActionContext actionContext; - - public CreateArchiveActionHandler(ActionContext actionContext, ISynchronousDocumentStoreService storageService) { - this.actionContext = actionContext; - this.storageService = storageService; - } - - public CreateArchiveActionResult handleCommand(CreateArchiveAction createArchiveActionCommand) - throws ActionException { - ArrayList archives = new ArrayList<>(); - List userSubmissions = storageService.getSubFolders( - createArchiveActionCommand.getSubmissionBatch().path()); - - if (!userSubmissions.isEmpty()) { - log.info( - "Creating archives for xmls with manifests for batch {}", - createArchiveActionCommand.getSubmissionBatch()); - } - for (String submissionObjectKey : userSubmissions) { - SubmissionArchive archive = null; - - try { - // 1a. Pull down the UserContext b/c we need it for everything else - String userContextDataObjectKey = submissionObjectKey + "userContext.json"; - String userContextJsonString = storageService.getObjectAsString(userContextDataObjectKey); - UserContextData UserContext = objectMapper.readValue(userContextJsonString, UserContextData.class); - - // 1b. Pull down submission.xml and write to disk so later actions can access it - String submissionXMLKey = submissionObjectKey + "submission.xml"; - String submissionXMLString = storageService.getObjectAsString(submissionXMLKey); - Path submissionXml = LocalWriteUtilityService.writeXmlToDisk( - submissionXMLString, - UserContext.getSubmissionId(), - actionContext.getConfig().getDirectories().getProcessed(), - "submission"); - - // 1c. Pull down manifest.xml and write to disk so later actions can access it - String manifestXMLKey = submissionObjectKey + "manifest.xml"; - String manifestXMString = storageService.getObjectAsString(manifestXMLKey); - Path manifestXml = LocalWriteUtilityService.writeXmlToDisk( - manifestXMString, - UserContext.getSubmissionId(), - actionContext.getConfig().getDirectories().getProcessed(), - UserContext.getSubmissionId() + ".manifest"); - - // 2. Create an archive for the submission - archive = SubmissionBuilder.createIRSSubmissionArchive( - UserContext.getSubmissionId(), - new SubmissionManifest(manifestXml.toFile()), - new SubmissionXML(submissionXml.toFile()), - new BinaryAttachment - [] {}, // Passing empty array for Binary Attachments because we don't use them - actionContext.getConfig().getDirectories().getToBatch()); - - // 3. Create a timestamped archive so that users in PT can file in their time - XMLGregorianCalendar calendar; - try { - calendar = LocalWriteUtilityService.CreateGregorianDateFromString(UserContext.getSignDate()); - } catch (Exception ex) { - log.error("Attempted to create a timestamped archive without a valid timestamp. Using today."); - calendar = LocalWriteUtilityService.Today(); - } - var timestampedArchive = - SubmissionBuilder.createPostmarkedSubmissionArchive(archive, calendar.toGregorianCalendar()); - - archives.add(new SubmissionArchiveContainer(UserContext, timestampedArchive)); - } catch (ToolkitException | IOException e) { - throw new CreateArchiveActionException(e); - } - } - - return new CreateArchiveActionResult(createArchiveActionCommand.getSubmissionBatch(), archives); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/IAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/IAction.java deleted file mode 100644 index b33219a..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/IAction.java +++ /dev/null @@ -1,5 +0,0 @@ -package gov.irs.directfile.submit.actions; - -public interface IAction { - T Act(ActionContext context) throws ActionException; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionException.java deleted file mode 100644 index b9ec154..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionException.java +++ /dev/null @@ -1,28 +0,0 @@ -package gov.irs.directfile.submit.actions.exception; - -import java.util.List; - -import lombok.Getter; - -import gov.irs.directfile.submit.actions.ActionException; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserContextData; - -@Getter -public class BundleArchiveActionException extends ActionException { - private final List userContextDataList; - private SubmissionBatch batch; - - public BundleArchiveActionException(List userContextDataList, SubmissionBatch batch, Throwable e) { - super(e); - this.userContextDataList = userContextDataList; - this.batch = batch; - } - - public String userContextDataTaxReturnIdsToString() { - return "UserContextData{" + "TaxReturnIds=" - + getUserContextDataList().stream() - .map(UserContextData::getTaxReturnId) - .toList() + "}"; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/CreateArchiveActionException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/CreateArchiveActionException.java deleted file mode 100644 index 9221752..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/CreateArchiveActionException.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.irs.directfile.submit.actions.exception; - -import lombok.Getter; - -import gov.irs.directfile.submit.actions.ActionException; - -@Getter -public class CreateArchiveActionException extends ActionException { - - public CreateArchiveActionException(Throwable e) { - super(e); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/SubmissionFailureException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/SubmissionFailureException.java deleted file mode 100644 index 3391b4d..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/exception/SubmissionFailureException.java +++ /dev/null @@ -1,19 +0,0 @@ -package gov.irs.directfile.submit.actions.exception; - -import lombok.Getter; - -import gov.irs.directfile.submit.actions.ActionException; -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Getter -public class SubmissionFailureException extends ActionException { - private SubmissionBatch batch; - private BundledArchives bundledArchives; - - public SubmissionFailureException(SubmissionBatch batch, BundledArchives archives, Throwable e) { - super(e); - this.batch = batch; - this.bundledArchives = archives; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/BundleArchivesActionResult.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/BundleArchivesActionResult.java deleted file mode 100644 index e6c07a3..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/BundleArchivesActionResult.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.submit.actions.results; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Getter -@AllArgsConstructor -public class BundleArchivesActionResult { - private SubmissionBatch batch; - private BundledArchives bundledArchives; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CleanupActionResult.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CleanupActionResult.java deleted file mode 100644 index 0e4bf7b..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CleanupActionResult.java +++ /dev/null @@ -1,3 +0,0 @@ -package gov.irs.directfile.submit.actions.results; - -public class CleanupActionResult {} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CreateArchiveActionResult.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CreateArchiveActionResult.java deleted file mode 100644 index 2d7b98f..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/CreateArchiveActionResult.java +++ /dev/null @@ -1,20 +0,0 @@ -package gov.irs.directfile.submit.actions.results; - -import java.util.List; - -import lombok.Getter; - -import gov.irs.directfile.submit.domain.SubmissionArchiveContainer; -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Getter -public class CreateArchiveActionResult { - private SubmissionBatch batch; - private List submissionArchiveContainers; - - public CreateArchiveActionResult( - SubmissionBatch batch, List submissionArchiveContainers) { - this.batch = batch; - this.submissionArchiveContainers = submissionArchiveContainers; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/SubmissionFailureActionResult.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/SubmissionFailureActionResult.java deleted file mode 100644 index f259381..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/actions/results/SubmissionFailureActionResult.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.submit.actions.results; - -import lombok.Getter; - -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Getter -public class SubmissionFailureActionResult { - private SubmissionBatch batch; - - public SubmissionFailureActionResult(SubmissionBatch batch) { - this.batch = batch; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/Action.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/Action.java deleted file mode 100644 index d1b9f2c..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/Action.java +++ /dev/null @@ -1,6 +0,0 @@ -package gov.irs.directfile.submit.command; - -public abstract class Action { - - public abstract ActionType getType(); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/ActionType.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/ActionType.java deleted file mode 100644 index 87cb403..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/ActionType.java +++ /dev/null @@ -1,9 +0,0 @@ -package gov.irs.directfile.submit.command; - -public enum ActionType { - CREATE_ARCHIVE, - BUNDLE_ARCHIVE, - SUBMIT_BUNDLE, - SUBMISSION_FAILURE, - CLEANUP -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/BundleArchiveAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/BundleArchiveAction.java deleted file mode 100644 index 5892baa..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/BundleArchiveAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.command; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.actions.results.CreateArchiveActionResult; - -@Getter -@AllArgsConstructor -public class BundleArchiveAction extends Action { - - private final CreateArchiveActionResult createArchiveActionResult; - - @Override - public ActionType getType() { - return ActionType.BUNDLE_ARCHIVE; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CleanupAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CleanupAction.java deleted file mode 100644 index 6b260ab..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CleanupAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.submit.command; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@AllArgsConstructor -@Getter -public class CleanupAction extends Action { - private final SubmissionBatch submissionBatch; - - @Override - public ActionType getType() { - return ActionType.CLEANUP; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CreateArchiveAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CreateArchiveAction.java deleted file mode 100644 index 41f7557..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/CreateArchiveAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.submit.command; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Getter -@AllArgsConstructor -public class CreateArchiveAction extends Action { - private final SubmissionBatch submissionBatch; - - @Override - public ActionType getType() { - return ActionType.CREATE_ARCHIVE; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmissionFailureAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmissionFailureAction.java deleted file mode 100644 index 7f09b79..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmissionFailureAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.irs.directfile.submit.command; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; - -@Getter -@AllArgsConstructor -public class SubmissionFailureAction extends Action { - private final SubmissionFailureException submissionFailureException; - - @Override - public ActionType getType() { - return ActionType.SUBMISSION_FAILURE; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmitBundleAction.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmitBundleAction.java deleted file mode 100644 index d076605..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/command/SubmitBundleAction.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.command; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -import gov.irs.directfile.submit.actions.results.BundleArchivesActionResult; - -@Getter -@AllArgsConstructor -public class SubmitBundleAction extends Action { - - private final BundleArchivesActionResult bundleArchivesActionResult; - - @Override - public ActionType getType() { - return ActionType.SUBMIT_BUNDLE; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSClientConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSClientConfig.java deleted file mode 100644 index 5437bb4..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSClientConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties(prefix = "aws") -@AllArgsConstructor -@Getter -public class AWSClientConfig { - private String accessKey; - private String secretKey; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSCredentialsConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSCredentialsConfig.java deleted file mode 100644 index fa2bee7..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/AWSCredentialsConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -@Configuration -@AllArgsConstructor -@EnableConfigurationProperties(AWSClientConfig.class) -public class AWSCredentialsConfig { - - private final AWSClientConfig awsClientConfig; - - @Bean - @ConditionalOnProperty( - name = "aws.default-credentials-provider-chain-enabled", - havingValue = "false", - matchIfMissing = true) - public AwsCredentialsProvider staticAWSCredentialsProvider() { - return StaticCredentialsProvider.create( - AwsBasicCredentials.create(awsClientConfig.getAccessKey(), awsClientConfig.getSecretKey())); - } - - @Bean - @ConditionalOnProperty(name = "aws.default-credentials-provider-chain-enabled", havingValue = "true") - public AwsCredentialsProvider defaultAWSCredentialsProvider() { - return DefaultCredentialsProvider.create(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionContextConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionContextConfig.java deleted file mode 100644 index dedd863..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionContextConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import gov.irs.mef.ApplicationContext; - -import gov.irs.directfile.submit.actions.ActionContext; - -@Configuration -@Slf4j -public class ActionContextConfig { - @Bean - public ActionContext actionContext(Config config) { - log.info("Setting the MeF toolkit"); - ApplicationContext.setToolkitHome(config.getToolkit()); - log.info("Toolkit set"); - return new ActionContext(config); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionQueueConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionQueueConfig.java deleted file mode 100644 index c963208..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/ActionQueueConfig.java +++ /dev/null @@ -1,24 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; - -@Configuration -public class ActionQueueConfig { - - @Bean - public ActionQueue actions() { - return new ActionQueue(); - } - - @Bean - public Set inProgressBatches() { - return ConcurrentHashMap.newKeySet(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/BatchingConfiguration.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/BatchingConfiguration.java deleted file mode 100644 index d7981d8..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/BatchingConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.time.Clock; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import gov.irs.directfile.submit.BatchingProperties; - -@Configuration -@Slf4j -public class BatchingConfiguration { - @Value("${submit.batching.batchSize}") - private int batchSize; - - @Value("${submit.batching.batchTimeoutMilliseconds}") - private long batchTimeoutMilliseconds; - - @Bean - public BatchingProperties batchingProperties() { - - BatchingProperties properties = BatchingProperties.builder() - .batchTimeoutMilliseconds(batchTimeoutMilliseconds) - .maxBatchSize(batchSize) - .build(); - log.info("Starting app with Batching Properties " + properties); - return properties; - } - - @Bean - public Clock batchingClock() { - return Clock.systemUTC(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/Config.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/Config.java deleted file mode 100644 index 66707ee..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/Config.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@AllArgsConstructor -@Getter -@ConfigurationProperties(prefix = "submit") -public class Config { - private String Environment; - private KeystoreConfig Keystore; - private IntervalsConfig Intervals; - private DirectoriesConfig Directories; - private DocumentStoreConfig DocumentStore; - private MessageQueueConfig MessageQueue; - private String Etin; - - @Setter - private String Asid; - - private String Efin; - private String Toolkit; - private boolean Prod; - private boolean RunnerDisabledForTesting; - private boolean SubmitActionEnabled; - private String VendorControlNumber; - private String softwareId; - private String softwareVersionNum; - private String applicationId; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DirectoriesConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DirectoriesConfig.java deleted file mode 100644 index 72b1755..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DirectoriesConfig.java +++ /dev/null @@ -1,15 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class DirectoriesConfig { - private String Input; - private String ToProcess; - private String Processed; - private String ToBatch; - private String Batched; - private String Submitted; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DocumentStoreConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DocumentStoreConfig.java deleted file mode 100644 index 7ef7e46..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/DocumentStoreConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@AllArgsConstructor -@Getter -@ConfigurationProperties(prefix = "submit.documentstore") -public class DocumentStoreConfig { - private String region; - private String accessKey; - private String secretKey; - private String assumeRoleArn; - private String assumeRoleDurationSeconds; - private String assumeRoleSessionName; - private String kmsWrappingKeyArn; - private String endpoint; - private String bucket; - private String environmentPrefix; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionClientConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionClientConfig.java deleted file mode 100644 index d500e53..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionClientConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.net.URI; -import java.util.Base64; -import javax.crypto.SecretKey; -import javax.crypto.spec.SecretKeySpec; - -import lombok.AllArgsConstructor; -import lombok.NonNull; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.kms.KmsClient; -import software.amazon.encryption.s3.materials.CryptographicMaterialsManager; -import software.amazon.encryption.s3.materials.DefaultCryptoMaterialsManager; -import software.amazon.encryption.s3.materials.KmsKeyring; - -@AllArgsConstructor -@Configuration -@EnableConfigurationProperties(EncryptionConfig.class) -public class EncryptionClientConfig { - private final EncryptionConfig encryptionConfig; - private final AwsCredentialsProvider awsCredentialsProvider; - - protected KmsClient regionalKmsClient() { - return KmsClient.builder() - .region(Region.of(encryptionConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(encryptionConfig.getKmsEndpoint())) - .build(); - } - - protected CryptographicMaterialsManager kmsCrypto(@NonNull String kmsWrappingKeyArn) { - return DefaultCryptoMaterialsManager.builder() - .keyring(KmsKeyring.builder() - .kmsClient(regionalKmsClient()) - .wrappingKeyId(kmsWrappingKeyArn) - .build()) - .build(); - } - - protected SecretKey getLocalAesWrappingKey() { - return new SecretKeySpec(Base64.getDecoder().decode(encryptionConfig.getLocalWrappingKey()), "AES"); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionConfig.java deleted file mode 100644 index d8f33e8..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/EncryptionConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@AllArgsConstructor -@Getter -@ConfigurationProperties -public class EncryptionConfig { - @Value("${aws.kmsEndpoint:#{null}}") - private String kmsEndpoint; - - @Value("${aws.region:#{null}}") - private String region; - - @Value("${direct-file.local-encryption.local-wrapping-key:#{null}}") - private String localWrappingKey; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/IntervalsConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/IntervalsConfig.java deleted file mode 100644 index 3d53588..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/IntervalsConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class IntervalsConfig { - private Integer ReturnsToProcess; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/KeystoreConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/KeystoreConfig.java deleted file mode 100644 index 596b33d..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/KeystoreConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@AllArgsConstructor -@Getter -public class KeystoreConfig { - private String keystoreBase64; - private String keystorePassword; - private String keystoreAlias; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/MessageQueueConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/MessageQueueConfig.java deleted file mode 100644 index 4aec1fe..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/MessageQueueConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties("submit.messagequeue") -@AllArgsConstructor -@Getter -public class MessageQueueConfig { - private final String endpoint; - private final String dispatchQueue; - private final String dlqDispatchQueue; - private final String pendingSubmissionQueue; - private final boolean pendingSubmissionPublishEnabled; - private final String submissionConfirmationQueue; - private final boolean submissionConfirmationPublishEnabled; - private final boolean sqsMessageHandlingEnabled; - private String region; - private final Credentials credentials; - - @AllArgsConstructor - @Getter - public static class Credentials { - private final String accessKey; - private final String secretKey; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/S3StorageClientConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/S3StorageClientConfig.java deleted file mode 100644 index 2c21c64..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/S3StorageClientConfig.java +++ /dev/null @@ -1,170 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.net.URI; -import java.time.Duration; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.S3AsyncClient; -import software.amazon.awssdk.services.s3.S3Client; -import software.amazon.awssdk.services.sts.StsClient; -import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; -import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; -import software.amazon.encryption.s3.S3AsyncEncryptionClient; -import software.amazon.encryption.s3.S3EncryptionClient; - -@Slf4j -@Configuration -@AllArgsConstructor -@EnableConfigurationProperties(DocumentStoreConfig.class) -@SuppressWarnings("PMD.AvoidDuplicateLiterals") -public class S3StorageClientConfig { - /** - * From the AWS Docs: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallTimeout() - * The amount of time to allow the client to complete the execution of an API call. - * - * The value for this property configures the amount of time for the entire execution, including all retry attempts. - * */ - private static final int S3_API_CALL_TIMEOUT_SECONDS = 15; - - /** - * From the AWS Docs: https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallAttemptTimeout() - * The amount of time to wait for the http request to complete before giving up and timing out. - * - * */ - private static final int S3_API_CALL_ATTEMPT_TIMEOUT_SECONDS = 5; - - private final AwsCredentialsProvider awsCredentialsProvider; - private final DocumentStoreConfig documentStoreConfig; - private final EncryptionClientConfig encryptionClientConfig; - - @Profile("!aws") - @Bean - public S3EncryptionClient localS3EncryptionClient() { - log.warn("S3: Using local encryption without AWS KMS. Not appropriate for deployed environments!"); - // set a temporary aws region system property to satisfy the default credentials provider - // that is triggered during initialization (before we override it with our own client definition in - // .wrappedClient()) - System.setProperty("aws.region", documentStoreConfig.getRegion()); - S3EncryptionClient client = S3EncryptionClient.builder() - .wrappedClient(synchronousStaticCredentialClient()) - .wrappedAsyncClient(asyncStaticCredentialClient()) - .aesKey(encryptionClientConfig.getLocalAesWrappingKey()) - .build(); - // remove temporary aws region system property - System.clearProperty("aws.region"); - return client; - } - - @Profile("!aws") - @Bean - public S3AsyncEncryptionClient localS3AsyncEncryptionClient() { - log.warn("S3: Using local encryption without AWS KMS. Not appropriate for deployed environments!"); - // set a temporary aws region system property to satisfy the default credentials provider - // that is triggered during initialization (before we override it with our own client definition in - // .wrappedClient()) - System.setProperty("aws.region", documentStoreConfig.getRegion()); - S3AsyncEncryptionClient client = S3AsyncEncryptionClient.builder() - .wrappedClient(asyncStaticCredentialClient()) - .aesKey(encryptionClientConfig.getLocalAesWrappingKey()) - .build(); - // remove temporary aws region system property - System.clearProperty("aws.region"); - return client; - } - - @Profile("!aws") - @Bean - public S3AsyncClient asyncStaticCredentialClient() { - return S3AsyncClient.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(documentStoreConfig.getEndpoint())) - .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofSeconds(S3_API_CALL_TIMEOUT_SECONDS)) - .apiCallAttemptTimeout(Duration.ofSeconds(S3_API_CALL_ATTEMPT_TIMEOUT_SECONDS))) - .build(); - } - - @Profile("!aws") - @Bean - public S3Client synchronousStaticCredentialClient() { - return S3Client.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(documentStoreConfig.getEndpoint())) - .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofSeconds(S3_API_CALL_TIMEOUT_SECONDS)) - .apiCallAttemptTimeout(Duration.ofSeconds(S3_API_CALL_ATTEMPT_TIMEOUT_SECONDS))) - .build(); - } - - @Profile("aws") - @Bean - public S3AsyncEncryptionClient s3AsyncEncryptionClient() { - log.info("S3: Setting up KMS for encryption..."); - return S3AsyncEncryptionClient.builder() - .wrappedClient(s3AssumeRoleClient()) - .cryptoMaterialsManager(encryptionClientConfig.kmsCrypto(documentStoreConfig.getKmsWrappingKeyArn())) - .build(); - } - - @Profile("aws") - @Bean - public S3EncryptionClient s3SynchronousEncryptionClient() { - log.info("S3: Setting up KMS for encryption..."); - return S3EncryptionClient.builder() - .wrappedClient(s3SynchronousAssumeRoleClient()) - .wrappedAsyncClient(s3AssumeRoleClient()) - .cryptoMaterialsManager(encryptionClientConfig.kmsCrypto(documentStoreConfig.getKmsWrappingKeyArn())) - .build(); - } - - @Profile("aws") - @Bean - public S3AsyncClient s3AssumeRoleClient() { - return S3AsyncClient.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(StsAssumeRoleCredentialsProvider.builder() - .stsClient(StsClient.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .build()) - .refreshRequest(AssumeRoleRequest.builder() - .roleArn(documentStoreConfig.getAssumeRoleArn()) - .roleSessionName(documentStoreConfig.getAssumeRoleSessionName()) - .durationSeconds(Integer.parseInt(documentStoreConfig.getAssumeRoleDurationSeconds())) - .build()) - .build()) - .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofSeconds(S3_API_CALL_TIMEOUT_SECONDS)) - .apiCallAttemptTimeout(Duration.ofSeconds(S3_API_CALL_ATTEMPT_TIMEOUT_SECONDS))) - .endpointOverride(URI.create(documentStoreConfig.getEndpoint())) - .build(); - } - - @Profile("aws") - @Bean - public S3Client s3SynchronousAssumeRoleClient() { - return S3Client.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(StsAssumeRoleCredentialsProvider.builder() - .stsClient(StsClient.builder() - .region(Region.of(documentStoreConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .build()) - .refreshRequest(AssumeRoleRequest.builder() - .roleArn(documentStoreConfig.getAssumeRoleArn()) - .roleSessionName(documentStoreConfig.getAssumeRoleSessionName()) - .durationSeconds(Integer.parseInt(documentStoreConfig.getAssumeRoleDurationSeconds())) - .build()) - .build()) - .overrideConfiguration(b -> b.apiCallTimeout(Duration.ofSeconds(S3_API_CALL_TIMEOUT_SECONDS)) - .apiCallAttemptTimeout(Duration.ofSeconds(S3_API_CALL_ATTEMPT_TIMEOUT_SECONDS))) - .endpointOverride(URI.create(documentStoreConfig.getEndpoint())) - .build(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsClientConfiguration.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsClientConfiguration.java deleted file mode 100644 index 8d7c743..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsClientConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.net.URI; - -import lombok.AllArgsConstructor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.sns.SnsClient; - -@Configuration -@ConditionalOnProperty(value = "submit.sns.submission-confirmation-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(SnsConfig.class) -@AllArgsConstructor -public class SnsClientConfiguration { - - private final AwsCredentialsProvider awsCredentialsProvider; - - @Bean - public SnsClient snsClient(SnsConfig snsConfig) { - return SnsClient.builder() - .region(Region.of(snsConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(snsConfig.getEndpoint())) - .build(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsConfig.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsConfig.java deleted file mode 100644 index e1e014a..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SnsConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package gov.irs.directfile.submit.config; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties("submit.sns") -@AllArgsConstructor -@Getter -public class SnsConfig { - private final String endpoint; - private final String submissionConfirmationTopicArn; - private final boolean submissionConfirmationPublishEnabled; - private final String region; - private final Credentials credentials; - - @AllArgsConstructor - @Getter - public static class Credentials { - private final String accessKey; - private final String secretKey; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SqsClientConfiguration.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SqsClientConfiguration.java deleted file mode 100644 index 32f8118..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/config/SqsClientConfiguration.java +++ /dev/null @@ -1,28 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.net.URI; - -import lombok.AllArgsConstructor; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.sqs.SqsClient; - -@Configuration -@EnableConfigurationProperties(MessageQueueConfig.class) -@AllArgsConstructor -public class SqsClientConfiguration { - - private final AwsCredentialsProvider awsCredentialsProvider; - - @Bean - public SqsClient sqsClient(MessageQueueConfig messageQueueConfig) { - return SqsClient.builder() - .region(Region.of(messageQueueConfig.getRegion())) - .credentialsProvider(awsCredentialsProvider) - .endpointOverride(URI.create(messageQueueConfig.getEndpoint())) - .build(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/ActionQueue.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/ActionQueue.java deleted file mode 100644 index 0407c92..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/ActionQueue.java +++ /dev/null @@ -1,20 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.Getter; -import lombok.Setter; - -import gov.irs.directfile.submit.command.Action; - -@Getter -@Setter -@SuppressFBWarnings( - value = {"EI_EXPOSE_REP"}, - justification = "Initial SpotBugs Setup") -public class ActionQueue { - private BlockingQueue inProgressActions = new LinkedBlockingQueue<>(); - private BlockingQueue newActions = new LinkedBlockingQueue<>(); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/BundledArchives.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/BundledArchives.java deleted file mode 100644 index d9cbd97..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/BundledArchives.java +++ /dev/null @@ -1,26 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.List; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import gov.irs.mef.inputcomposition.SubmissionContainer; - -@SuppressFBWarnings( - value = {"NM_FIELD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -public class BundledArchives { - public BundledArchives(List userContexts, SubmissionContainer submissionContainer) { - UserContexts = userContexts; - this.submissionContainer = submissionContainer; - } - - public List UserContexts; - public SubmissionContainer submissionContainer; - - @Override - public String toString() { - return "BundledArchives{" + "SubmissionIds=" - + UserContexts.stream().map(UserContextData::getSubmissionId).toList() + '}'; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/DocumentStoreResource.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/DocumentStoreResource.java deleted file mode 100644 index d979f61..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/DocumentStoreResource.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.time.Instant; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class DocumentStoreResource { - String fullLocation; - String resourceId; - Instant lastModified; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SendSubmissionsResultWrapper.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SendSubmissionsResultWrapper.java deleted file mode 100644 index b887a73..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SendSubmissionsResultWrapper.java +++ /dev/null @@ -1,43 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import lombok.Getter; -import lombok.Setter; - -import gov.irs.mef.services.transmitter.mtom.SendSubmissionsResult; - -@Getter -@Setter -public class SendSubmissionsResultWrapper { - private SendSubmissionsResult submissionsResult; - private List submissionReceiptGrpWrappers; - - public SendSubmissionsResultWrapper(SendSubmissionsResult submissionsResult) { - this.submissionsResult = submissionsResult; - - if (sendSubmissionsResultHasReceipts(submissionsResult)) { - this.submissionReceiptGrpWrappers = submissionsResult.getSubmissionReceiptList().getReceipts().stream() - .map(SubmissionReceiptGrpWrapper::new) - .collect(Collectors.toList()); - } else { - this.submissionReceiptGrpWrappers = Collections.emptyList(); - } - } - - public SendSubmissionsResultWrapper(List submissionReceiptGrpWrappers) { - this.submissionReceiptGrpWrappers = submissionReceiptGrpWrappers; - } - - private static boolean sendSubmissionsResultHasReceipts(SendSubmissionsResult submissionsResult) { - return submissionsResult != null - && submissionsResult.getSubmissionReceiptList() != null - && submissionsResult.getSubmissionReceiptList().getReceipts() != null; - } - - public List getReceipts() { - return submissionReceiptGrpWrappers; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionArchiveContainer.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionArchiveContainer.java deleted file mode 100644 index 14eaabe..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionArchiveContainer.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import gov.irs.mef.inputcomposition.PostmarkedSubmissionArchive; - -@SuppressFBWarnings( - value = {"NM_FIELD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -public class SubmissionArchiveContainer { - public SubmissionArchiveContainer(UserContextData userContext, PostmarkedSubmissionArchive archive) { - this.UserContext = userContext; - this.Archive = archive; - } - - public UserContextData UserContext; - public PostmarkedSubmissionArchive Archive; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionBatch.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionBatch.java deleted file mode 100644 index aa7c86e..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionBatch.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.Objects; - -public record SubmissionBatch(long batchId, String path) { - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - SubmissionBatch that = (SubmissionBatch) o; - return Objects.equals(path, that.path); - } - - @Override - public int hashCode() { - return Objects.hash(path); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionData.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionData.java deleted file mode 100644 index ce2f7e6..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionData.java +++ /dev/null @@ -1,29 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import gov.irs.mef.inputcomposition.BinaryAttachment; -import gov.irs.mef.inputcomposition.SubmissionManifest; -import gov.irs.mef.inputcomposition.SubmissionXML; - -@SuppressFBWarnings( - value = {"URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}, - justification = "Initial SpotBugs Setup") -@SuppressWarnings("PMD.ArrayIsStoredDirectly") -public class SubmissionData { - public SubmissionData( - UserContextData userContext, - SubmissionManifest manifest, - SubmissionXML xml, - BinaryAttachment[] binaryObjects) { - UserContext = userContext; - Manifest = manifest; - Xml = xml; - BinaryObjects = binaryObjects; - } - - public UserContextData UserContext; - public SubmissionManifest Manifest; - public SubmissionXML Xml; - public BinaryAttachment[] BinaryObjects; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionReceiptGrpWrapper.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionReceiptGrpWrapper.java deleted file mode 100644 index 506f47f..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmissionReceiptGrpWrapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import javax.xml.datatype.XMLGregorianCalendar; - -import lombok.Getter; -import lombok.Setter; - -import gov.irs.mef.SubmissionReceiptList; - -@Getter -@Setter -public class SubmissionReceiptGrpWrapper { - private SubmissionReceiptList.SubmissionReceiptGrp submissionReceiptGrp; - private final String submissionId; - private final String receiptId; - private final XMLGregorianCalendar submissionReceivedTs; - - SubmissionReceiptGrpWrapper(SubmissionReceiptList.SubmissionReceiptGrp submissionReceiptGrp) { - this.submissionId = submissionReceiptGrp.getSubmissionId(); - this.receiptId = submissionReceiptGrp.getReceiptId(); - this.submissionReceivedTs = submissionReceiptGrp.getSubmissionReceivedTs(); - } - - public SubmissionReceiptGrpWrapper( - String submissionId, String receiptId, XMLGregorianCalendar submissionReceivedTs) { - this.submissionId = submissionId; - this.receiptId = receiptId; - this.submissionReceivedTs = submissionReceivedTs; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmittedDataContainer.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmittedDataContainer.java deleted file mode 100644 index 4cee193..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/SubmittedDataContainer.java +++ /dev/null @@ -1,72 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import javax.xml.datatype.XMLGregorianCalendar; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; - -@Slf4j -public class SubmittedDataContainer { - public SubmittedDataContainer( - List userContexts, - SendSubmissionsResultWrapper sendSubmissionsResultWrapper, - SubmissionBatch submissionBatch) { - this.userContexts = userContexts; - this.sendSubmissionsResultWrapper = sendSubmissionsResultWrapper; - this.submissionBatch = submissionBatch; - } - - public List userContexts; - - public SubmissionBatch submissionBatch; - - @Getter - private SendSubmissionsResultWrapper sendSubmissionsResultWrapper; - - public List getTaxReturnIdAndSubmissionIds() { - return userContexts.stream() - .map(userContextData -> new TaxReturnIdAndSubmissionId( - UUID.fromString(userContextData.getTaxReturnId()), userContextData.getSubmissionId())) - .toList(); - } - - public List getSuccessSubmissionConfirmationPayloadV2Entries() { - HashMap submissionIdToTaxReturnIdMap = new HashMap<>(); - userContexts.forEach(userContextData -> - submissionIdToTaxReturnIdMap.put(userContextData.getSubmissionId(), userContextData.getTaxReturnId())); - - return sendSubmissionsResultWrapper.getReceipts().stream() - .map(submissionReceiptGrpWrapper -> { - String submissionId = submissionReceiptGrpWrapper.getSubmissionId(); - String taxReturnId = submissionIdToTaxReturnIdMap.get(submissionId); - - if (taxReturnId == null) { - log.error( - "Unable to find taxReturnId by submissionId: {}. The submissionId sent to MeF may not match the submissionId in the MeF response", - submissionId); - } - - String receiptId = submissionReceiptGrpWrapper.getReceiptId(); - XMLGregorianCalendar submissionReceivedTs = submissionReceiptGrpWrapper.getSubmissionReceivedTs(); - - TaxReturnSubmissionReceipt taxReturnSubmissionReceipt = new TaxReturnSubmissionReceipt( - UUID.fromString(taxReturnId), - submissionId, - receiptId, - submissionReceivedTs.toGregorianCalendar().getTime()); - - return new SubmissionConfirmationPayloadV2Entry( - taxReturnSubmissionReceipt, SubmissionEventTypeEnum.SUBMITTED, Map.of()); - }) - .toList(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserContextData.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserContextData.java deleted file mode 100644 index d4097bf..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserContextData.java +++ /dev/null @@ -1,48 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.Getter; - -import gov.irs.directfile.audit.events.TinType; - -@Getter -public class UserContextData { - private final String submissionId; - private final String userId; - private final String taxReturnId; - private final String userTin; - private final TinType userTinType; - private final String remoteAddress; - private final String signDate; - - /** - * To allow Jackson to deserialize JSON into this immutable object, - * we need to tell Jackson that we want to use the constructor - * for deserialization, since we don't expose any setters. - *

- * This is done with the @JsonCreator annotation. - * We also need to tell Jackson which fields in the json - * correspond to which fields in the constructor. - * This is done with the @JsonProperty annotation. - *

- * Used this link for reference. - */ - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - public UserContextData( - @JsonProperty("submissionId") String submissionId, - @JsonProperty("userId") String userId, - @JsonProperty("taxReturnId") String taxReturnId, - @JsonProperty("userTin") String userTin, - @JsonProperty("userTinType") TinType userTinType, - @JsonProperty("remoteAddress") String remoteAddress, - @JsonProperty("signDate") String localDateTime) { - this.submissionId = submissionId; - this.userId = userId; - this.taxReturnId = taxReturnId; - this.userTin = userTin; - this.userTinType = userTinType; - this.remoteAddress = remoteAddress; - this.signDate = localDateTime; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserSubmission.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserSubmission.java deleted file mode 100644 index 01abf7b..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/UserSubmission.java +++ /dev/null @@ -1,21 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import gov.irs.directfile.models.Dispatch; - -public record UserSubmission( - String userId, - String taxReturnId, - String submissionId, - String manifestXmlPath, - String submissionXmlPath, - String userContextPath) { - public static UserSubmission fromDispatch(Dispatch dispatch) { - return new UserSubmission( - dispatch.getUserId().toString(), - dispatch.getTaxReturnId().toString(), - dispatch.getMefSubmissionId(), - dispatch.getPathToManifest(), - dispatch.getPathToSubmission(), - dispatch.getPathToUserContext()); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/model/PodIdentifier.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/model/PodIdentifier.java deleted file mode 100644 index b3b4dc2..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/model/PodIdentifier.java +++ /dev/null @@ -1,30 +0,0 @@ -package gov.irs.directfile.submit.domain.model; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.Setter; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - -@Getter -@Setter -@Entity(name = "PodIdentifier") -@Table(name = "pod_identifier") -public class PodIdentifier { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "asid", length = 50) - private String asid; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "region", length = 50) - private String region; - - @JdbcTypeCode(SqlTypes.VARCHAR) - @Column(columnDefinition = "varchar", name = "podId", length = 255) - private String podId; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilder.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilder.java deleted file mode 100644 index bd72a38..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -package gov.irs.directfile.submit.domain.storagelocations; - -import java.util.UUID; - -public class StorageLocationBuilder { - private static final String S3_SUBMISSIONS_FOLDER = "pre-submission-batching"; - - public static String getTaxReturnLocation(int taxFilingYear, UUID taxReturnId) { - return taxFilingYear + "/taxreturns/" + taxReturnId; - } - - public static String getSubmissionLocation( - int taxFilingYear, UUID taxReturnId, String submissionId, String fileExtension) { - return getSubmissionLocation(taxFilingYear, taxReturnId) + submissionId + "." + fileExtension; - } - - public static String getSubmissionLocation(int taxFilingYear, UUID taxReturnId) { - return getTaxReturnLocation(taxFilingYear, taxReturnId) + "/submissions/"; - } - - public static String generateObjectKeyPrefixForSubmission( - long batchId, String submissionId, String applicationId, int batchControlYear) { - // {bucketName}/{configurable-application-id}/{batchControlYear}/{batch-number}/{submission-id}/DATA-GOES-HERE - return String.format( - "%s/%s/%s/%s/%s", S3_SUBMISSIONS_FOLDER, applicationId, batchControlYear, batchId, submissionId); - } - - public static String getErrorFolderLocation(String applicationId, int batchControlYear) { - return String.format("%s/errors/%s/%s/", S3_SUBMISSIONS_FOLDER, applicationId, batchControlYear); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LoginFailureException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LoginFailureException.java deleted file mode 100644 index 5ddbec2..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LoginFailureException.java +++ /dev/null @@ -1,15 +0,0 @@ -package gov.irs.directfile.submit.exception; - -public class LoginFailureException extends Exception { - public LoginFailureException(String message) { - super(message); - } - - public LoginFailureException(String message, Throwable cause) { - super(message, cause); - } - - public LoginFailureException(Throwable cause) { - super(cause); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LogoutFailureException.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LogoutFailureException.java deleted file mode 100644 index f809179..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/exception/LogoutFailureException.java +++ /dev/null @@ -1,15 +0,0 @@ -package gov.irs.directfile.submit.exception; - -public class LogoutFailureException extends Exception { - public LogoutFailureException(String message) { - super(message); - } - - public LogoutFailureException(String message, Throwable cause) { - super(message, cause); - } - - public LogoutFailureException(Throwable cause) { - super(cause); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/DocumentStorageBatchRepository.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/DocumentStorageBatchRepository.java deleted file mode 100644 index 2a38b74..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/DocumentStorageBatchRepository.java +++ /dev/null @@ -1,185 +0,0 @@ -package gov.irs.directfile.submit.repository; - -import java.io.ByteArrayInputStream; -import java.time.Clock; -import java.time.Instant; -import java.time.Year; -import java.util.List; -import java.util.Optional; - -import com.fasterxml.jackson.databind.ObjectMapper; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Repository; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.submit.BatchingProperties; -import gov.irs.directfile.submit.domain.DocumentStoreResource; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.domain.storagelocations.StorageLocationBuilder; -import gov.irs.directfile.submit.repository.interfaces.IBatchRepository; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Slf4j -@Repository -@SuppressFBWarnings( - value = {"DM_DEFAULT_ENCODING"}, - justification = "Initial SpotBugs Setup") -public class DocumentStorageBatchRepository implements IBatchRepository { - private final ObjectMapper objectMapper = new ObjectMapper(); - private static final String S3_SUBMISSIONS_FOLDER = "pre-submission-batching"; - private final String applicationId; - private final ISynchronousDocumentStoreService synchronousDocumentStoreService; - private final BatchingProperties batchingProperties; - private final Clock clock; - - @Autowired - public DocumentStorageBatchRepository( - ISynchronousDocumentStoreService synchronousDocumentStoreService, - @Value("${submit.application-id}") String applicationId, - BatchingProperties batchingProperties, - Clock clock) { - this.synchronousDocumentStoreService = synchronousDocumentStoreService; - this.applicationId = applicationId; - this.batchingProperties = batchingProperties; - this.clock = clock; - } - - @Override - public long getCurrentWritingBatch(String applicationId) { - // 1. S3 ls for /{configurable-application-id}/{batchControlYear}/, store in variable - int taxYear = getBatchControlYear(); - String taxYearS3Key = S3_SUBMISSIONS_FOLDER + "/" + applicationId + "/" + taxYear + "/"; - Optional mostRecentBatchPrefixOptional = - synchronousDocumentStoreService.getMostRecentFolderForPrefix(taxYearS3Key); - - // Case where no batches are found in s3 - if (mostRecentBatchPrefixOptional.isEmpty()) { - return 0L; - } else { - // Case where a batch is found in s3 - String mostRecentBatchPrefix = mostRecentBatchPrefixOptional.get(); - - long currentBatchNumber = extractBatchNumberFromPrefix(mostRecentBatchPrefix); - List userSubmissions = synchronousDocumentStoreService.getSubFolders(mostRecentBatchPrefix); - boolean batchHasRecords = !userSubmissions.isEmpty(); - if (batchHasRecords) { - // Get the timestamp of the least recently modified item in the batch. The age of a batch = now() - - // oldest upload time. - String oldestSubmissionForBatch = userSubmissions.get(0); - Instant lastModifiedTimestamp = synchronousDocumentStoreService - .getLeastRecentModifiedResourceForPrefix(oldestSubmissionForBatch) - .get() - .getLastModified(); - - long batchAgeInMilliseconds = getBatchAge(lastModifiedTimestamp); - boolean isBatchOlderThanTimeout = - batchAgeInMilliseconds >= batchingProperties.getBatchTimeoutMilliseconds(); - // If the system finds a batch number, and the batch contains records, and the batch is older than the - // timeout, or the # of records is > maxBatchSize - // start a new batch, otherwise ret - if (isBatchOlderThanTimeout || userSubmissions.size() >= batchingProperties.getMaxBatchSize()) { - // The system should create a new batch with a number one higher - return currentBatchNumber + 1; - } - } - return currentBatchNumber; - } - } - - @Override - public void addSubmission(SubmissionBatch submissionBatch, UserSubmission userSubmission) throws Exception { - // Use the CreateXML action to generate XML for the userSubmission. - - // Get the documents from S3 artifact storage - var manifest = synchronousDocumentStoreService.getObjectAsString(userSubmission.manifestXmlPath()); - var submission = synchronousDocumentStoreService.getObjectAsString(userSubmission.submissionXmlPath()); - var userContext = synchronousDocumentStoreService.getObjectAsString(userSubmission.userContextPath()); - - // Upload to s3 batching area - int taxYear = getBatchControlYear(); - String s3ObjectKey = StorageLocationBuilder.generateObjectKeyPrefixForSubmission( - submissionBatch.batchId(), userSubmission.submissionId(), applicationId, taxYear); - - log.info( - String.format("Uploading User Submission XML for user %s to %s", userSubmission.userId(), s3ObjectKey)); - // Upload XML, user context, and binary objects to s3. Write UserContext, and BinaryObjects as Bytes - synchronousDocumentStoreService.write( - s3ObjectKey + "/" + "manifest.xml", new ByteArrayInputStream(manifest.getBytes())); - synchronousDocumentStoreService.write( - s3ObjectKey + "/" + "submission.xml", new ByteArrayInputStream(submission.getBytes())); - - synchronousDocumentStoreService.write( - s3ObjectKey + "/" + "userContext.json", new ByteArrayInputStream(userContext.getBytes())); - MDC.put(AuditLogElement.taxReturnId.toString(), userSubmission.taxReturnId()); - MDC.put(AuditLogElement.mefSubmissionId.toString(), userSubmission.submissionId()); - log.info(String.format("Successfully wrote XML for user %s to %s", userSubmission.userId(), s3ObjectKey)); - MDC.clear(); - } - - @Override - public Optional getSubmissionBatch(String applicationId, long batchId) { - String path = generateLocationForBatch(applicationId, batchId, getBatchControlYear()); - List keys = synchronousDocumentStoreService.getObjectKeys(path); - if (keys.isEmpty()) { - return Optional.empty(); - } else { - return Optional.of(new SubmissionBatch(batchId, path)); - } - } - - @Override - public List getUnprocessedBatches(String applicationId) { - long currentBatchNumber = this.getCurrentWritingBatch(applicationId); - String path = generateLocationForApplicationId(applicationId, getBatchControlYear()); - - List subFolders = synchronousDocumentStoreService.getSubFolders(path); - List submissionBatches = subFolders.stream() - .map(subFolder -> extractBatchNumberFromPrefix(subFolder)) - .filter(batchNumber -> batchNumber != currentBatchNumber) - .map(batchNumber -> new SubmissionBatch( - batchNumber, generateLocationForBatch(applicationId, batchNumber, getBatchControlYear()))) - .toList(); - return submissionBatches; - } - - private static long extractBatchNumberFromPrefix(String mostRecentBatchPrefix) { - String[] split = mostRecentBatchPrefix.split("/"); - return Long.parseLong(split[split.length - 1]); - } - - private long getBatchAge(Instant lastModifiedTimestamp) { - Instant currentTime = clock.instant(); - return currentTime.toEpochMilli() - lastModifiedTimestamp.toEpochMilli(); - } - - public static String generateLocationForBatch(String applicationId, long batchId, int batchControlYear) { - return S3_SUBMISSIONS_FOLDER + "/" + applicationId + "/" + batchControlYear + "/" + batchId + "/"; - } - - public static String generateLocationForApplicationId(String applicationId, int batchControlYear) { - return S3_SUBMISSIONS_FOLDER + "/" + applicationId + "/" + batchControlYear + "/"; - } - - /** - * For purposes of uploading to s3, we use a specific path for the objects going to s3: - * {S3_SUBMISSIONS_FOLDER}/{configurable-application-id}/{batchControlYear}/{batchId} - * - * Today this is hardcoded to currentYear - 1, but in the future we will want - * to support multiple different years for batches - a Year over Year Solution. - * - * Such a solution would likely require a few changes: - * 1. Knowing when a UserSubmission was created. Possibly derive the year - * from the dispatch object in the UserSubmissionMapper - * - * 2. Use the derived year to find the currentWriting batch for a given year. - * - * */ - private int getBatchControlYear() { - return Year.now(clock).getValue() - 1; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/PodIdentifierRepository.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/PodIdentifierRepository.java deleted file mode 100644 index 43fe5e4..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/PodIdentifierRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package gov.irs.directfile.submit.repository; - -import java.util.Optional; - -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.CrudRepository; - -import gov.irs.directfile.submit.domain.model.PodIdentifier; - -public interface PodIdentifierRepository extends CrudRepository { - - @Query(value = "SELECT asid from pod_identifier WHERE pod_id = :pod_id", nativeQuery = true) - Optional findAsidByPodId(String pod_id); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/interfaces/IBatchRepository.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/interfaces/IBatchRepository.java deleted file mode 100644 index cc670de..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/repository/interfaces/IBatchRepository.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.repository.interfaces; - -import java.util.List; -import java.util.Optional; - -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserSubmission; - -@SuppressWarnings({"PMD.SignatureDeclareThrowsException", "PMD.UnnecessaryModifier"}) -public interface IBatchRepository { - public long getCurrentWritingBatch(String applicationId); - - public void addSubmission(SubmissionBatch submissionBatch, UserSubmission userSubmission) throws Exception; - - public Optional getSubmissionBatch(String applicationId, long batchId); - - public List getUnprocessedBatches(String applicationId); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ActionHandler.java deleted file mode 100644 index d0cb155..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ActionHandler.java +++ /dev/null @@ -1,322 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.text.SimpleDateFormat; -import java.util.*; - -import com.fasterxml.jackson.core.JsonProcessingException; -import jakarta.annotation.PostConstruct; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.SubmissionEventFailureCategoryEnum; -import gov.irs.directfile.models.message.SubmissionEventFailureDetailEnum; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; -import gov.irs.directfile.submit.actions.*; -import gov.irs.directfile.submit.actions.exception.BundleArchiveActionException; -import gov.irs.directfile.submit.actions.exception.CreateArchiveActionException; -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; -import gov.irs.directfile.submit.actions.results.BundleArchivesActionResult; -import gov.irs.directfile.submit.actions.results.CreateArchiveActionResult; -import gov.irs.directfile.submit.actions.results.SubmissionFailureActionResult; -import gov.irs.directfile.submit.command.*; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.SubmittedDataContainer; -import gov.irs.directfile.submit.domain.UserContextData; -import gov.irs.directfile.submit.exception.LoginFailureException; -import gov.irs.directfile.submit.exception.LogoutFailureException; -import gov.irs.directfile.submit.repository.PodIdentifierRepository; -import gov.irs.directfile.submit.service.interfaces.IBundleSubmissionActionHandler; -import gov.irs.directfile.submit.service.interfaces.ISubmissionFailureService; - -@Slf4j -@Service -@SuppressWarnings({ - "PMD.ExceptionAsFlowControl", - "PMD.ExcessiveParameterList", - "PMD.SimpleDateFormatNeedsLocale", - "PMD.UselessParentheses" -}) -public class ActionHandler { - private final SqsConnectionSetupService sqsConnectionSetupService; - private final SubmissionConfirmationMessageService submissionConfirmationMessageService; - protected final ActionContext context; - private final ActionQueue actions; - private final IBundleSubmissionActionHandler bundleSubmissionService; - - private final OfflineModeService offlineModeService; - - private final Set inProgressBatches; - - private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss"); - private final BundleArchivesActionHandler bundleArchivesActionHandler; - - private final CleanupActionHandler cleanupActionHandler; - private final CreateArchiveActionHandler createArchiveActionHandler; - private final ISubmissionFailureService submissionFailureService; - private final PodIdentifierRepository podIdentifierRepository; - - public ActionHandler( - SqsConnectionSetupService sqsConnectionSetupService, - SubmissionConfirmationMessageService submissionConfirmationMessageService, - ActionQueue actions, - ActionContext actionContext, - IBundleSubmissionActionHandler bundleSubmissionService, - OfflineModeService offlineModeService, - Set inProgressBatches, - BundleArchivesActionHandler bundleArchivesActionHandler, - CleanupActionHandler cleanupActionHandler, - CreateArchiveActionHandler createArchiveActionHandler, - ISubmissionFailureService submissionFailureService, - PodIdentifierRepository podIdentifierRepository) { - this.sqsConnectionSetupService = sqsConnectionSetupService; - this.submissionConfirmationMessageService = submissionConfirmationMessageService; - this.context = actionContext; - this.actions = actions; - this.bundleSubmissionService = bundleSubmissionService; - this.offlineModeService = offlineModeService; - this.inProgressBatches = inProgressBatches; - this.bundleArchivesActionHandler = bundleArchivesActionHandler; - this.cleanupActionHandler = cleanupActionHandler; - this.createArchiveActionHandler = createArchiveActionHandler; - this.submissionFailureService = submissionFailureService; - this.podIdentifierRepository = podIdentifierRepository; - } - - @PostConstruct - public void init() { - updateAsid(context.getConfig()); - } - - protected void updateAsid(Config config) { - String applicationId = config.getApplicationId(); - String asid = getAsid(config, applicationId); - if (!Objects.equals(asid, config.getAsid()) && !asid.isEmpty() && !asid.isBlank()) { - log.info( - "Setting new ASID ending in {} in Config and ServiceContext for {}", - asid.substring(asid.length() - 1), - applicationId); - this.context.getConfig().setAsid(asid); - this.context.getServiceContext().setAppSysID(asid); - } - } - - protected String getAsid(Config config, String applicationId) { - log.info("Getting ASID for ActionContext update for {}", applicationId); - String asid = config.getAsid(); - Optional optAsid = podIdentifierRepository.findAsidByPodId(applicationId); - if (optAsid.isPresent()) { - log.info("Setting pod-specific ASID in Config for ActionContext for {}", applicationId); - asid = optAsid.get(); - } - return asid; - } - - public void handleAction(Action action) { - try { - // These info logs don't need that info. - log.info(String.format("running action: %s", action.getClass().getSimpleName())); - switch (action.getType()) { - case CREATE_ARCHIVE: - CreateArchiveActionResult archives = - createArchiveActionHandler.handleCommand((CreateArchiveAction) action); - - if (!archives.getSubmissionArchiveContainers().isEmpty()) { - actions.getInProgressActions().add(new BundleArchiveAction(archives)); - } - break; - case BUNDLE_ARCHIVE: - log.info("Creating a bundle to send to the MeF"); - BundleArchivesActionResult c = - bundleArchivesActionHandler.handleBundleCommand((BundleArchiveAction) action); - actions.getInProgressActions().add(new SubmitBundleAction(c)); - break; - case SUBMIT_BUNDLE: - log.info("Submit bundle action received"); - - SubmittedDataContainer submittedDataContainer; - if (context.getConfig().isSubmitActionEnabled() && !offlineModeService.getShouldStayOffline()) { - long startTime = System.currentTimeMillis(); - Date date = new Date(startTime); - log.info("Logging in at {}", simpleDateFormat.format(date)); - bundleSubmissionService.login(); - log.info("Submitting bundle"); - - submittedDataContainer = bundleSubmissionService.handleCommand((SubmitBundleAction) action); - log.info( - "Successfully Submitted {} submissions for batch {} ", - submittedDataContainer.userContexts.size(), - submittedDataContainer.submissionBatch.path()); - // TODO: call the ack system and let them know. - long endTime = System.currentTimeMillis(); - date = new Date(endTime); - log.info( - "Logging out at {}, elapsed time in milliseconds: {}", - simpleDateFormat.format(date), - (endTime - startTime)); - bundleSubmissionService.logout(); - actions.getInProgressActions().add(new CleanupAction(submittedDataContainer.submissionBatch)); - - List taxReturnIdAndSubmissionIds = - submittedDataContainer.getTaxReturnIdAndSubmissionIds(); - sqsConnectionSetupService.sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue( - taxReturnIdAndSubmissionIds); - - List taxReturnSubmissionReceipts = - submittedDataContainer.getSuccessSubmissionConfirmationPayloadV2Entries(); - submissionConfirmationMessageService.publishSubmissionConfirmationPayloadV2( - taxReturnSubmissionReceipts); - } else { - SubmitBundleAction bundleAction = (SubmitBundleAction) action; - log.info( - "Submit action not enabled. There were {} tax returns in batch {} ", - bundleAction - .getBundleArchivesActionResult() - .getBundledArchives() - .UserContexts - .size(), - bundleAction.getBundleArchivesActionResult().getBatch()); - - actions.getInProgressActions() - .add(new CleanupAction(bundleAction - .getBundleArchivesActionResult() - .getBatch())); - } - break; - case SUBMISSION_FAILURE: - SubmissionFailureActionResult submissionFailureActionResult = - submissionFailureService.handleCommand((SubmissionFailureAction) action); - actions.getInProgressActions().add(new CleanupAction(submissionFailureActionResult.getBatch())); - break; - case CLEANUP: - log.info("Cleaning up the file system"); - cleanupActionHandler.handleAction((CleanupAction) action); - inProgressBatches.remove(((CleanupAction) action).getSubmissionBatch()); - break; - default: - throw new RuntimeException("missing type"); - } - } catch (SubmissionFailureException e) { - try { - /* - * If Submission fails. Check if MeF is online by trying to logout. - * If logout succeeds (no exception is thrown), we know MeF is online, meaning there was an issue - * with the Submitted Bundle. Handle the Submission Failure by kicking off the retry process. - * */ - log.error( - "Failed to Submit Bundle for batch at path {} to MeF", - e.getBatch().path()); - bundleSubmissionService.logout(); - handleSubmissionFailure(e); - } catch (LogoutFailureException logoutFailureException) { - if (!offlineModeService.isOfflineModeEnabled()) { - log.info("Enabling Offline Mode. Unable to login."); - offlineModeService.enableOfflineMode(); - } - // Re-Queue the failed action to be handled when we are back online - actions.getInProgressActions().add(action); - } - - } catch (LoginFailureException e) { - try { - log.error("Failed to log in to MeF"); - bundleSubmissionService.logout(); - } catch (LogoutFailureException logoutFailureException) { - if (!offlineModeService.isOfflineModeEnabled()) { - log.info("Enabling Offline Mode. Unable to logout."); - offlineModeService.enableOfflineMode(); - } - // Re-Queue the failed action to be handled when we are back online - actions.getInProgressActions().add(action); - } - } catch (LogoutFailureException e) { - if (!offlineModeService.isOfflineModeEnabled()) { - log.info("Enabling Offline Mode. Unable to logout."); - offlineModeService.enableOfflineMode(); - } - // Re-Queue the failed action to be handled when we are back online - actions.getInProgressActions().add(action); - } catch (BundleArchiveActionException e) { - handleBundleArchiveActionException(e); - } catch (CreateArchiveActionException e) { - log.error("CreateArchiveActionException", e); - } catch (ActionException e) { - log.error("action exception", e); - } catch (JsonProcessingException e) { - log.error("JsonProcessingException", e); - } catch (Exception e) { - log.error("Unknown error caught in Action Handler", e); - } - } - - private void handleBundleArchiveActionException(BundleArchiveActionException e) { - log.error( - "BundleArchiveActionException occurred. Unable to bundle the following tax returns: {}", - e.userContextDataTaxReturnIdsToString(), - e); - - // publish failure message containing taxreturn submission in the batch - List userContextDataList = e.getUserContextDataList(); - List entries = userContextDataList.stream() - .map(userContextData -> { - // Create failureEventMetadata - Map failureEventMetadata = new HashMap<>(); - failureEventMetadata.put( - "errorMessage", String.format("BundleArchiveAction failed, %s", e.getMessage())); - failureEventMetadata.put( - "failureCategory", SubmissionEventFailureCategoryEnum.PROCESSING.getFailureCategory()); - failureEventMetadata.put( - "failureDetail", SubmissionEventFailureDetailEnum.SUBMISSION_PROCESSING.getFailureDetail()); - - // Create message payload for Submission Confirmation queue - return getFailureEventSubmissionConfirmationPayloadV2Entry(userContextData, failureEventMetadata); - }) - .toList(); - submissionConfirmationMessageService.publishSubmissionConfirmationPayloadV2(entries); - actions.getInProgressActions().add(new CleanupAction(e.getBatch())); - } - - private void handleSubmissionFailure(SubmissionFailureException e) { - int numberOfSubmissions = e.getBundledArchives().UserContexts.size(); - if (numberOfSubmissions > 1) { - actions.getInProgressActions().add(new SubmissionFailureAction(e)); - } else if (numberOfSubmissions == 1) { - UserContextData failedSubmissionUserContext = - e.getBundledArchives().UserContexts.get(0); - log.error(String.format( - "Failed to submit return to MeF for user %s", failedSubmissionUserContext.getUserId())); - - Map failureEventMetadata = new HashMap<>(); - // TODO: These should probably be keys somewhere - failureEventMetadata.put("errorMessage", String.format("Submission to MeF failed, %s", e.getMessage())); - failureEventMetadata.put( - "failureCategory", SubmissionEventFailureCategoryEnum.PROCESSING.getFailureCategory()); - failureEventMetadata.put( - "failureDetail", SubmissionEventFailureDetailEnum.SUBMISSION_PROCESSING.getFailureDetail()); - - SubmissionConfirmationPayloadV2Entry entry = getFailureEventSubmissionConfirmationPayloadV2Entry( - failedSubmissionUserContext, failureEventMetadata); - submissionConfirmationMessageService.publishSubmissionConfirmationPayloadV2(List.of(entry)); - actions.getInProgressActions().add(new CleanupAction(e.getBatch())); - } else { - log.error("Unable to submit bundle to MeF because batch is empty."); - } - } - - private static SubmissionConfirmationPayloadV2Entry getFailureEventSubmissionConfirmationPayloadV2Entry( - UserContextData failedSubmissionUserContext, Map failureEventMetadata) { - SubmissionConfirmationPayloadV2Entry entry = new SubmissionConfirmationPayloadV2Entry( - new TaxReturnSubmissionReceipt( - UUID.fromString(failedSubmissionUserContext.getTaxReturnId()), - failedSubmissionUserContext.getSubmissionId(), - null, - null), - SubmissionEventTypeEnum.FAILED, - failureEventMetadata); - return entry; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DirectoryCreator.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DirectoryCreator.java deleted file mode 100644 index 86a83df..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DirectoryCreator.java +++ /dev/null @@ -1,38 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.beans.PropertyDescriptor; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.nio.file.Files; -import java.nio.file.Path; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.springframework.beans.BeanUtils; - -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DirectoriesConfig; - -// on startup this verifies the directories and creates them if necessary -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -public class DirectoryCreator { - private final Config config; - - public DirectoryCreator(Config config) { - this.config = config; - } - - public void CreateDirectories() throws IOException, IllegalAccessException, InvocationTargetException { - PropertyDescriptor[] directoriesConfigPropertyDescriptors = - BeanUtils.getPropertyDescriptors(DirectoriesConfig.class); - for (PropertyDescriptor pd : directoriesConfigPropertyDescriptors) { - if (!String.class.equals(pd.getPropertyType())) { - continue; - } - String dirString = (String) pd.getReadMethod().invoke(config.getDirectories()); - Path path = Path.of(dirString); - Files.createDirectories(path); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DispatchMessageRouter.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DispatchMessageRouter.java deleted file mode 100644 index 42a3258..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DispatchMessageRouter.java +++ /dev/null @@ -1,59 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.dispatch.DispatchMessageVersion; -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.submit.service.handlers.dispatch.DispatchHandler; -import gov.irs.directfile.submit.service.handlers.dispatch.DispatchV1Handler; -import gov.irs.directfile.submit.service.handlers.dispatch.UnsupportedMessageVersionHandler; - -@Service -@SuppressWarnings("PMD.SignatureDeclareThrowsException") -public class DispatchMessageRouter { - private final Map handlers = new HashMap<>(); - private final UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - public DispatchMessageRouter( - UnsupportedMessageVersionHandler unsupportedMessageVersionHandler, DispatchV1Handler dispatchV1Handler) { - this.unsupportedMessageVersionHandler = unsupportedMessageVersionHandler; - this.handlers.put(DispatchMessageVersion.V1, dispatchV1Handler); - } - - public void handleDispatchMessage(VersionedDispatchMessage message) throws Exception { - QueueMessageHeaders headers = message.getHeaders(); - Optional versionOptional = headers.getAttribute(MessageHeaderAttribute.VERSION); - - // We can assume a version number is present here since a VersionedDispatchMessage - // mandates that on construction. - - // Get enum for this version (may throw UnsupportedVersionException which we should handle and - // rethrow to get message back on queue/DLQ). - DispatchMessageVersion version; - try { - version = DispatchMessageVersion.getEnum(versionOptional.get()); - } catch (UnsupportedVersionException e) { - unsupportedMessageVersionHandler.handleDispatchMessage(message); - throw e; - } - - // Get handler. If not found, we have an unsupported version so handle and throw exception. - DispatchHandler handler = handlers.get(version); - if (handler == null) { - unsupportedMessageVersionHandler.handleDispatchMessage(message); - throw new UnsupportedVersionException( - String.format("No handler found for DispatchMessageVersion (%s)", version.getVersion())); - } - - // We should have a good handler, so handle the message. - handler.handleDispatchMessage(message); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureService.java deleted file mode 100644 index 170e9ac..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureService.java +++ /dev/null @@ -1,140 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Clock; -import java.time.Year; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.actions.results.SubmissionFailureActionResult; -import gov.irs.directfile.submit.command.SubmissionFailureAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.DocumentStoreResource; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.service.interfaces.ISubmissionFailureService; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Slf4j -@Service -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -public class DocumentStorageSubmissionFailureService implements ISubmissionFailureService { - private static final String S3_SUBMISSIONS_FOLDER = "pre-submission-batching"; - - private final ISynchronousDocumentStoreService synchronousDocumentStoreService; - private final String applicationId; - private final Clock clock; - - public DocumentStorageSubmissionFailureService( - ISynchronousDocumentStoreService synchronousDocumentStoreService, - @Value("${submit.application-id}") String applicationId, - Clock clock) { - this.synchronousDocumentStoreService = synchronousDocumentStoreService; - this.applicationId = applicationId; - this.clock = clock; - } - - @Override - public void Setup(Config config) throws Throwable {} - - /** - * This method is responsible for copying files of a failed batch (Unable to Submit to MeF) - * to an error path that will re-submit each indiviudal submission to MeF as it's own batch. - * - * If a batch contains 10 submissions. This method will copy the files over - * such that we will re-submit 10 batches, each of size 1, when our asynchronous ErrorBatchPoller picks them up. - * */ - @Override - public void processFailedBatch(SubmissionBatch batch) { - /** - * - * A batch stores submissions at this path. - * BATCH_PATH: pre-submission-batching/{configurable-application-id}/{batch-control-year}/{batch-number}/ - * - * The files for a given submission are at: - * - * BATCH_PATH/{submissionId}/manifest.xml - * => pre-submission-batching/{configurable-application-id}/{batch-control-year}/{batch-number}/{submissionId}/manifest.xml - * BATCH_PATH/{submissionId}/return.xml - * => pre-submission-batching/{configurable-application-id}/{batch-control-year}/{batch-number}/{submissionId}/return.xml - * BATCH_PATH/{submissionId}/userContext.json - * => pre-submission-batching/{configurable-application-id}/{batch-control-year}/{batch-number}/{submissionId}/userContext.json - * - * This method copies each of the files of a submission into its own folder that will - * be treated as a batch. - * - * An error batch stores the files for a submission that will be treated as its own batch: - * ERROR_PATH: pre-submission-batching/{configurable-application-id}/{tax-year}/errors/{batch-number}/ - * - * To treat a submission as its own batch, we will copy files to a unique path for each submission. - * We assign a submission number between 0 and the size of the batch. - * INDIVIDUAL_ERROR_BATCH = ERROR_PATH/{submissionNumber} - * - * Files for the submission in this batch will live at: - * - * INDIVIDUAL_ERROR_BATCH/manifest.xml - * => pre-submission-batching/{configurable-application-id}/{tax-year}/errors/{batch-number}/{submissionNumber}/{submissionId}/manifest.xml - * INDIVIDUAL_ERROR_BATCH/return.xml - * => pre-submission-batching/{configurable-application-id}/{tax-year}/errors/{batch-number}/{submissionNumber}/{submissionId}/return.xml - * INDIVIDUAL_ERROR_BATCH/userContext.json - * => pre-submission-batching/{configurable-application-id}/{tax-year}/errors/{batch-number}/{submissionNumber}/{submissionId}/manifest.xml - * - * */ - log.info("Processing Failed Batch for path: " + batch.path()); - String errorPath = String.format( - "%s/errors/%s/%s/%s", S3_SUBMISSIONS_FOLDER, applicationId, getBatchControlYear(), batch.batchId()); - // 1. Get the objects in the batch - List objects = synchronousDocumentStoreService.getObjectKeys(batch.path()); - - // 2. For each key, copy to the error path - List submissionIdObjectKeys = synchronousDocumentStoreService.getSubFolders(batch.path()); - Map submissionIdToSubmissionNumber = new HashMap<>(); - - /** - * We're going to treat each submission as its own batch. - * We are assigning a submissionNumber to each submission in the batch. - * - * */ - for (int i = 0; i < submissionIdObjectKeys.size(); i++) { - submissionIdToSubmissionNumber.put(submissionIdObjectKeys.get(i), i); - } - - for (DocumentStoreResource documentStoreResource : objects) { - String fullPath = documentStoreResource.getFullLocation(); - - // 2a. Find the path to files of a submission. This looks like - // "pre-submission-batching/{application-id}/{batch-control-year}/{batchId}/{submissionId}" - String submissionIdObjectKey = - fullPath.substring(0, fullPath.indexOf('/', batch.path().length()) + 1); - - // 2b. Find the filename associated with the submission. For example, this will look like - // {submissionId}/manifest.xml - String fileName = fullPath.substring(batch.path().length()); - int submissionNumber = submissionIdToSubmissionNumber.get(submissionIdObjectKey); - // 2c. Generate the path where the error batch will live - - // pre-submission-batching/errors/{applicationId}/{batchControlYear}/{batchId}/{submissionNumber}/{submissionId}/file.{xml,json} - String individualBatchErrorKey = String.format("%s/%s/%s", errorPath, submissionNumber, fileName); - synchronousDocumentStoreService.copyObject(documentStoreResource, individualBatchErrorKey); - } - log.info("Successfully moved failed batch to error bucket:" + batch.path()); - } - - @Override - public SubmissionFailureActionResult handleCommand(SubmissionFailureAction submissionFailureActionCommand) { - this.processFailedBatch( - submissionFailureActionCommand.getSubmissionFailureException().getBatch()); - return new SubmissionFailureActionResult( - submissionFailureActionCommand.getSubmissionFailureException().getBatch()); - } - - private int getBatchControlYear() { - return Year.now(clock).getValue() - 1; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ErrorBatchPoller.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ErrorBatchPoller.java deleted file mode 100644 index f9835ca..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/ErrorBatchPoller.java +++ /dev/null @@ -1,104 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Clock; -import java.time.Year; -import java.util.List; -import java.util.Set; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.command.CreateArchiveAction; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.storagelocations.StorageLocationBuilder; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Service -@Slf4j -public class ErrorBatchPoller { - - private final ActionQueue actions; - private final Set inProgressBatches; - - private final ISynchronousDocumentStoreService storageService; - private final String applicationId; - - private final ActionContext context; - private final Clock clock; - - public ErrorBatchPoller( - ActionQueue actions, - ISynchronousDocumentStoreService storageService, - @Value("${submit.application-id}") String applicationId, - Set inProgressBatches, - ActionContext context, - Clock clock) { - this.actions = actions; - this.storageService = storageService; - this.applicationId = applicationId; - this.inProgressBatches = inProgressBatches; - this.context = context; - this.clock = clock; - } - - @Scheduled(fixedRateString = "${submit.batching.errorPollingMilliseconds}", initialDelay = 1000L) - public void poll() { - if (!context.getConfig().isSubmitActionEnabled()) { - log.info("Submit action is disabled, not polling for error batches"); - return; - } - String errorPath = StorageLocationBuilder.getErrorFolderLocation(applicationId, getBatchControlYear()); - List errorSubfolders = storageService.getSubFolders(errorPath); - log.info("Polling for error batches..."); - if (!errorSubfolders.isEmpty()) { - log.info(String.format( - "Found %s error batches in poller. Re-processing as individual submissions", - errorSubfolders.size())); - /* - * errorSubfolders is a list of all the object paths for failed batches in the error subfolder. - * Each entry in this list is the path to a batch that failed, it has been copied to the error path. - * Each entry looks like this: - * pre-submission-batching/errors/{applicationId}/{batchControlYear}/{batch-id}/ - * - * */ - for (String errorSubFolder : errorSubfolders) { - /* - * errorSubFolderBatches is a list paths to each submission that will be retried as an individual batch. - * Each string in this list is formatted like this: - * pre-submission-batching/{configurable-application-id}/{tax-year}/errors/{batch-number}/{submissionNumber} - * - * This path allows us to treat each submission as its own batch. - * - */ - List errorSubFolderBatches = storageService.getSubFolders(errorSubFolder); - - for (String errorBatchPath : errorSubFolderBatches) { - - /* - errorBatchPath looks like this: - pre-submission-batching/{configurable-application-id}/{batchControlYear}/errors/{batch-number}/{submissionNumber} - - Get the submissionNumber and treat is as the batch id for this batch. - - */ - String[] split = errorBatchPath.split("/"); - long submissionNumber = Long.parseLong(split[split.length - 1]); - SubmissionBatch submissionBatch = new SubmissionBatch(submissionNumber, errorBatchPath); - - if (!inProgressBatches.contains(submissionBatch)) { - actions.getNewActions().add(new CreateArchiveAction(submissionBatch)); - inProgressBatches.add(submissionBatch); - } - } - } - } - } - - private int getBatchControlYear() { - return Year.now(clock).getValue() - 1; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/LocalWriteUtilityService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/LocalWriteUtilityService.java deleted file mode 100644 index 4506e70..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/LocalWriteUtilityService.java +++ /dev/null @@ -1,62 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -@SuppressFBWarnings( - value = {"DM_DEFAULT_ENCODING", "NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@SuppressWarnings("PMD.CloseResource") -public class LocalWriteUtilityService { - public static Path writeXmlToDisk(String xmlString, String submissionId, String outputDir, String fileName) { - try { - Path directory = Path.of(outputDir, submissionId); - if (!Files.exists(directory)) { - Files.createDirectory(directory); - } - Path returnPath = Path.of(outputDir, submissionId, fileName + ".xml"); - - BufferedWriter writer = new BufferedWriter(new FileWriter(returnPath.toFile())); - writer.write(xmlString); - writer.close(); - return returnPath; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static OffsetDateTime testNow; - - private static OffsetDateTime getNow() { - return testNow == null ? OffsetDateTime.now() : testNow; - } - - public static void setUpTestNow(OffsetDateTime testNowLocal) { - testNow = testNowLocal; - } - - public static void tearDownTestNow() { - testNow = null; - } - - public static XMLGregorianCalendar Today() { - OffsetDateTime date = getNow(); - // NOTE: ISO_OFFSET_DATE_TIME includes fractional seconds. - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX"); - var lex = date.format(formatter); - return DatatypeFactory.newDefaultInstance().newXMLGregorianCalendar(lex); - } - - public static XMLGregorianCalendar CreateGregorianDateFromString(String value) { - return DatatypeFactory.newDefaultInstance().newXMLGregorianCalendar(value); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/OfflineModeService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/OfflineModeService.java deleted file mode 100644 index a83c7ea..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/OfflineModeService.java +++ /dev/null @@ -1,35 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.concurrent.atomic.AtomicBoolean; - -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -@Service -@Slf4j -public class OfflineModeService { - - @Value("${submit.should-disable-mef-connectivity}") - @Getter - private Boolean shouldStayOffline = false; - - private final AtomicBoolean offlineModeEnabled = new AtomicBoolean(false); - - public OfflineModeService() {} - - public boolean isOfflineModeEnabled() { - return offlineModeEnabled.get(); - } - - public void disableOfflineMode() { - this.offlineModeEnabled.compareAndSet(true, false); - } - - public void enableOfflineMode() { - if (!isOfflineModeEnabled()) { - this.offlineModeEnabled.compareAndSet(false, true); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/PerformanceTestingBundleSubmissionActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/PerformanceTestingBundleSubmissionActionHandler.java deleted file mode 100644 index 9b5fa4d..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/PerformanceTestingBundleSubmissionActionHandler.java +++ /dev/null @@ -1,99 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Duration; -import java.util.*; -import javax.xml.datatype.XMLGregorianCalendar; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; -import gov.irs.directfile.submit.command.SubmitBundleAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.*; -import gov.irs.directfile.submit.exception.LoginFailureException; -import gov.irs.directfile.submit.exception.LogoutFailureException; -import gov.irs.directfile.submit.service.interfaces.IBundleSubmissionActionHandler; - -@Service -/** - * A Bundle Submission Service used for perf testing. - * - * This generates fake submission receipts so we can easily - * verify if the submit app is processing all the returns it receives - * by checking that the backend app receives an equivalent number of submission confirmations. - * */ -@SuppressFBWarnings( - value = {"NM_METHOD_NAMING_CONVENTION", "PREDICTABLE_RANDOM"}, - justification = - "Initial SpotBugs Setup. Random usage is not for security purposes and only used in performance testing.") -@Slf4j -public class PerformanceTestingBundleSubmissionActionHandler implements IBundleSubmissionActionHandler { - private final Config config; - private final ActionContext context; - private final Random random = new Random(); - private static final long TEN_SECONDS_IN_MILLIS = 10_000; - - public PerformanceTestingBundleSubmissionActionHandler(Config config, ActionContext context) { - log.info("Initializing Mock Bundle Submission Service for Performance Testing."); - this.config = config; - this.context = context; - } - - @Override - public boolean login() throws LoginFailureException { - return true; - } - - @Override - public boolean logout() throws LogoutFailureException { - return true; - } - - @Override - public SubmittedDataContainer submitBundles(BundledArchives bundledArchives, SubmissionBatch submissionBatch) - throws SubmissionFailureException { - SendSubmissionsResultWrapper fakeSubmissionResultWrapper = generateMockData(bundledArchives); - try { - - long jitter = random.nextLong(2000); - Thread.sleep(Duration.ofMillis(TEN_SECONDS_IN_MILLIS + jitter)); - log.info( - "Using Mock Bundle Submission Service for Performance Testing. Creating Mock MEF Response for batch {}", - submissionBatch); - return new SubmittedDataContainer( - bundledArchives.UserContexts, fakeSubmissionResultWrapper, submissionBatch); - } catch (Exception e) { - log.error("Exception in Mock Bundle Submission Action Handler"); - return new SubmittedDataContainer( - bundledArchives.UserContexts, fakeSubmissionResultWrapper, submissionBatch); - } - } - - private static SendSubmissionsResultWrapper generateMockData(BundledArchives bundledArchives) { - List fakeSubmissionReceiptWrappers = new ArrayList<>(); - bundledArchives.UserContexts.forEach(userContextData -> { - String fakeReceiptId = UUID.randomUUID().toString(); - XMLGregorianCalendar calendar = - LocalWriteUtilityService.CreateGregorianDateFromString(userContextData.getSignDate()); - fakeSubmissionReceiptWrappers.add( - new SubmissionReceiptGrpWrapper(userContextData.getSubmissionId(), fakeReceiptId, calendar)); - }); - - SendSubmissionsResultWrapper fakeSubmissionResultWrapper = - new SendSubmissionsResultWrapper(fakeSubmissionReceiptWrappers); - return fakeSubmissionResultWrapper; - } - - @Override - public SubmittedDataContainer handleCommand(SubmitBundleAction command) throws SubmissionFailureException { - return this.submitBundles( - command.getBundleArchivesActionResult().getBundledArchives(), - command.getBundleArchivesActionResult().getBatch()); - } - - @Override - public void Setup(Config config) throws Throwable {} -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SqsConnectionSetupService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SqsConnectionSetupService.java deleted file mode 100644 index 2d1bda3..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SqsConnectionSetupService.java +++ /dev/null @@ -1,122 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.List; - -import com.amazon.sqs.javamessaging.ProviderConfiguration; -import com.amazon.sqs.javamessaging.SQSConnection; -import com.amazon.sqs.javamessaging.SQSConnectionFactory; -import com.amazon.sqs.javamessaging.SQSSession; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.annotation.PreDestroy; -import jakarta.jms.*; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.*; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.pending.PendingSubmissionMessageVersion; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.models.message.pending.payload.PendingSubmissionPayloadV1; -import gov.irs.directfile.submit.config.MessageQueueConfig; - -@Slf4j -@Service -@SuppressWarnings({"PMD.AvoidReassigningParameters", "PMD.CloseResource", "PMD.UnusedPrivateMethod"}) -@EnableConfigurationProperties(MessageQueueConfig.class) -public class SqsConnectionSetupService { - private final SqsClient sqsClient; - private final String dispatchQueue; - private final String dispatchQueueDlq; - private final String pendingSubmissionQueue; - private final boolean isPendingSubmissionPublishEnabled; - private String pendingSubmissionQueueUrl = null; - private final ObjectMapper mapper = new ObjectMapper(); - private SQSConnection connection; - - SqsConnectionSetupService(SqsClient sqsClient, MessageQueueConfig messageQueueConfig) { - this.sqsClient = sqsClient; - dispatchQueue = messageQueueConfig.getDispatchQueue(); - dispatchQueueDlq = messageQueueConfig.getDlqDispatchQueue(); - pendingSubmissionQueue = messageQueueConfig.getPendingSubmissionQueue(); - isPendingSubmissionPublishEnabled = messageQueueConfig.isPendingSubmissionPublishEnabled(); - } - - public void setup(MessageListener messageListener) throws JMSException { - SQSConnectionFactory connectionFactory = new SQSConnectionFactory(new ProviderConfiguration(), sqsClient); - connection = connectionFactory.createConnection(); - - Session session = connection.createSession(false, SQSSession.UNORDERED_ACKNOWLEDGE); - Queue queue = session.createQueue(dispatchQueue); - MessageConsumer consumer = session.createConsumer(queue); - consumer.setMessageListener(messageListener); - connection.start(); - log.info("CONNECTED TO SQS"); - } - - public void sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue( - List taxReturnIdAndSubmissionIds) throws JsonProcessingException { - if (!isPendingSubmissionPublishEnabled) { - return; - } - - try { - AbstractPendingSubmissionPayload payload = new PendingSubmissionPayloadV1(taxReturnIdAndSubmissionIds); - VersionedPendingSubmissionMessage queueMessage = - new VersionedPendingSubmissionMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - PendingSubmissionMessageVersion.V1.getVersion())); - - String jsonString = mapper.writeValueAsString(queueMessage); - enqueueListOfSubmissionAndTaxReturnIds(jsonString); - } catch (SqsException | JsonProcessingException e) { - log.error("Error sending message to {}: {}", pendingSubmissionQueue, e.getMessage()); - } - } - - private void enqueueListOfSubmissionAndTaxReturnIds(String pendingSubmissionQueueMessage) { - if (StringUtils.isBlank(pendingSubmissionQueueUrl)) { - pendingSubmissionQueueUrl = getQueueUrl(pendingSubmissionQueue); - } - - SendMessageRequest sendMsgRequest = SendMessageRequest.builder() - .queueUrl(pendingSubmissionQueueUrl) - .messageBody(pendingSubmissionQueueMessage) - .build(); - - SendMessageResponse sendMessageResponse = sqsClient.sendMessage(sendMsgRequest); - if (sendMessageResponse.sdkHttpResponse().isSuccessful()) { - log.info("Sent list of tax return ids and submission ids to SQS {}", pendingSubmissionQueue); - } else { - log.error( - "SQS sendMessage request was unsuccessful. HTTP Status code: {}", - sendMessageResponse.sdkHttpResponse().statusCode()); - } - } - - private String getQueueUrl(String queueName) { - GetQueueUrlResponse getQueueUrlResponse = sqsClient.getQueueUrl( - GetQueueUrlRequest.builder().queueName(queueName).build()); - - return getQueueUrlResponse.queueUrl(); - } - - @PreDestroy - private void cleanup() throws JMSException { - if (connection != null) { - connection.stop(); - log.info("SQS connection stopped"); - connection.close(); - log.info("SQS connection closed"); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageService.java deleted file mode 100644 index 5b09fa7..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageService.java +++ /dev/null @@ -1,73 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.PublisherException; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; - -@Service -@Slf4j -public class SubmissionConfirmationMessageService { - private final List publishers; - private final ObjectMapper mapper; - - public SubmissionConfirmationMessageService(List publishers, ObjectMapper mapper) { - this.publishers = publishers; - this.mapper = mapper; - } - - public void publishSubmissionConfirmationPayloadV2(List entries) { - AbstractSubmissionConfirmationPayload payload = new SubmissionConfirmationPayloadV2(entries); - publishSubmissionConfirmationPayload(payload, SubmissionConfirmationMessageVersion.V2); - } - - private void publishSubmissionConfirmationPayload( - AbstractSubmissionConfirmationPayload payload, SubmissionConfirmationMessageVersion version) { - if (publishers == null || publishers.isEmpty()) { - return; - } - - VersionedSubmissionConfirmationMessage message = - new VersionedSubmissionConfirmationMessage<>( - payload, - new QueueMessageHeaders().addHeader(MessageHeaderAttribute.VERSION, version.getVersion())); - - String jsonString; - try { - jsonString = mapper.writeValueAsString(message); - } catch (JsonProcessingException e) { - String errorMessage = "Exception calling writeValueAsString"; - log.error(errorMessage, e); - throw new PublisherException(errorMessage, e); - } - - List errors = new ArrayList<>(); - for (SubmissionConfirmationPublisher publisher : publishers) { - try { - publisher.publish(jsonString); - } catch (Exception e) { - log.error("Exception calling publish", e); - errors.add(e.getMessage() + " (" + publisher.getClass().getSimpleName() + ")"); - } - } - - if (!errors.isEmpty()) { - String errorMessage = StringUtils.join(errors, "; "); - log.error(errorMessage); - throw new PublisherException(errorMessage); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationPublisher.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationPublisher.java deleted file mode 100644 index 005b7db..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationPublisher.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.irs.directfile.submit.service; - -import gov.irs.directfile.models.message.Publisher; - -public interface SubmissionConfirmationPublisher extends Publisher { - // Just a marker interface to allow Spring to inject all the publishers for this message type -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSnsPublisher.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSnsPublisher.java deleted file mode 100644 index 60a6b5b..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSnsPublisher.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.service; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sns.SnsClient; - -import gov.irs.directfile.models.message.SnsPublisher; -import gov.irs.directfile.submit.config.SnsConfig; - -@Service -@ConditionalOnProperty(value = "submit.sns.submission-confirmation-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(SnsConfig.class) -public class SubmissionConfirmationSnsPublisher extends SnsPublisher implements SubmissionConfirmationPublisher { - public SubmissionConfirmationSnsPublisher(SnsClient snsClient, SnsConfig snsConfig) { - super(snsClient, snsConfig.getSubmissionConfirmationTopicArn()); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSqsPublisher.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSqsPublisher.java deleted file mode 100644 index 0b36593..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SubmissionConfirmationSqsPublisher.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.irs.directfile.submit.service; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.services.sqs.SqsClient; - -import gov.irs.directfile.models.message.SqsPublisher; -import gov.irs.directfile.submit.config.MessageQueueConfig; - -@Service -@ConditionalOnProperty(value = "submit.messagequeue.submission-confirmation-publish-enabled", havingValue = "true") -@EnableConfigurationProperties(MessageQueueConfig.class) -public class SubmissionConfirmationSqsPublisher extends SqsPublisher implements SubmissionConfirmationPublisher { - public SubmissionConfirmationSqsPublisher(SqsClient sqsClient, MessageQueueConfig messageQueueConfig) { - super(sqsClient, messageQueueConfig.getSubmissionConfirmationQueue()); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SynchronousS3StorageService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SynchronousS3StorageService.java deleted file mode 100644 index 34d8d9d..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/SynchronousS3StorageService.java +++ /dev/null @@ -1,198 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.utils.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import software.amazon.awssdk.core.ResponseBytes; -import software.amazon.awssdk.core.sync.RequestBody; -import software.amazon.awssdk.services.s3.model.*; -import software.amazon.encryption.s3.S3EncryptionClient; - -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.DocumentStoreResource; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@Service -@Slf4j -@SuppressFBWarnings( - value = {"DM_DEFAULT_ENCODING", "NM_METHOD_NAMING_CONVENTION"}, - justification = "Initial SpotBugs Setup") -@SuppressWarnings({"PMD.AvoidReassigningParameters", "PMD.MissingOverride"}) -public class SynchronousS3StorageService implements ISynchronousDocumentStoreService { - private final S3EncryptionClient s3Client; - - private final String bucketName; - - private final String environmentPrefix; - - @Autowired - public SynchronousS3StorageService( - S3EncryptionClient s3Client, @Value("${submit.documentstore.bucket}") String bucketName, Config config) { - this.s3Client = s3Client; - this.bucketName = bucketName; - this.environmentPrefix = config.getDocumentStore().getEnvironmentPrefix(); - } - - @Override - public String write(String objectKey, InputStream payloadStream) throws IOException { - objectKey = ensureEnvironmentPrefixExists(objectKey); - - PutObjectRequest putObjectRequest = - PutObjectRequest.builder().bucket(bucketName).key(objectKey).build(); - RequestBody requestBody = RequestBody.fromBytes(IOUtils.toByteArray(payloadStream)); - PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, requestBody); - return putObjectResponse.eTag(); - } - - @Override - public String write(String objectKey, String content) { - objectKey = ensureEnvironmentPrefixExists(objectKey); - - PutObjectRequest putObjectRequest = - PutObjectRequest.builder().bucket(bucketName).key(objectKey).build(); - RequestBody requestBody = RequestBody.fromString(content, StandardCharsets.UTF_8); - PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, requestBody); - return putObjectResponse.eTag(); - } - - @Override - public List getObjectKeys(String prefix) { - prefix = ensureEnvironmentPrefixExists(prefix); - String emptyContinuationToken = null; - return getObjectKeysRecursive(prefix, new ArrayList<>(), emptyContinuationToken); - } - - @Override - public void deleteObjects(List keys) { - List identifiers = keys.stream() - .map(key -> ObjectIdentifier.builder().key(key).build()) - .toList(); - DeleteObjectsRequest deleteObjectsRequest = DeleteObjectsRequest.builder() - .bucket(bucketName) - .delete(Delete.builder().objects(identifiers).build()) - .build(); - s3Client.deleteObjects(deleteObjectsRequest); - } - - private List getObjectKeysRecursive( - String prefix, List results, String continuationToken) { - ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() - .bucket(bucketName) - .prefix(prefix) - .continuationToken(continuationToken) - .build(); - ListObjectsV2Response response = s3Client.listObjectsV2(listObjectsV2Request); - - List page = response.contents().stream() - .map(s3Object -> new DocumentStoreResource(s3Object.key(), s3Object.eTag(), s3Object.lastModified())) - .toList(); - results.addAll(page); - - if (response.isTruncated()) { - return getObjectKeysRecursive(prefix, results, response.nextContinuationToken()); - } else { - return results; - } - } - - public Optional getMostRecentFolderForPrefix(String prefix) { - prefix = ensureEnvironmentPrefixExists(prefix); - - ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() - .bucket(bucketName) - .prefix(prefix) - .delimiter("/") - .build(); - ListObjectsV2Response response = s3Client.listObjectsV2(listObjectsV2Request); - return response.commonPrefixes().stream() - .map(CommonPrefix::prefix) - .sorted() - .max(Comparator.comparing(Function.identity())); - } - - public List getSubFolders(String objectKey) { - objectKey = ensureEnvironmentPrefixExists(objectKey); - - return getSubFoldersRecursive(objectKey, new ArrayList<>(), null); - } - - private List getSubFoldersRecursive(String objectKey, List results, String continuationToken) { - objectKey = ensureEnvironmentPrefixExists(objectKey); - ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() - .bucket(bucketName) - .prefix(objectKey) - .continuationToken(continuationToken) - .delimiter("/") - .build(); - - ListObjectsV2Response response = s3Client.listObjectsV2(listObjectsV2Request); - - List pageResults = - response.commonPrefixes().stream().map(CommonPrefix::prefix).toList(); - results.addAll(pageResults); - - if (response.isTruncated()) { - return getSubFoldersRecursive(objectKey, results, response.nextContinuationToken()); - } else { - return results; - } - } - - public Optional getLeastRecentModifiedResourceForPrefix(String objectKey) { - objectKey = ensureEnvironmentPrefixExists(objectKey); - ListObjectsV2Request listObjectsV2Request = ListObjectsV2Request.builder() - .bucket(bucketName) - .prefix(objectKey) - .delimiter("/") - .build(); - - ListObjectsV2Response response = s3Client.listObjectsV2(listObjectsV2Request); - - return response.contents().stream() - .map(s3Object -> new DocumentStoreResource(s3Object.key(), s3Object.eTag(), s3Object.lastModified())) - .min(Comparator.comparing(DocumentStoreResource::getLastModified)); - } - - @Override - public String getObjectAsString(String objectKey) throws IOException { - objectKey = ensureEnvironmentPrefixExists(objectKey); - GetObjectRequest getObjectRequest = - GetObjectRequest.builder().bucket(bucketName).key(objectKey).build(); - - ResponseBytes getObjectResponse = s3Client.getObjectAsBytes(getObjectRequest); - return new String(getObjectResponse.asByteArray()); - } - - private String ensureEnvironmentPrefixExists(String objectKey) { - return StringUtils.prependIfMissing(objectKey, environmentPrefix); - } - - @Override - public void copyObject(DocumentStoreResource documentStoreResource, String destinationKey) { - destinationKey = ensureEnvironmentPrefixExists(destinationKey); - CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder() - .sourceBucket(bucketName) - .sourceKey(documentStoreResource.getFullLocation()) - .destinationKey(destinationKey) - .destinationBucket(bucketName) - .build(); - - s3Client.copyObject(copyObjectRequest); - } - - @Override - public void Setup(Config config) throws Throwable {} -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssembler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssembler.java deleted file mode 100644 index 6e12bc3..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssembler.java +++ /dev/null @@ -1,89 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Clock; -import java.time.Year; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -import jakarta.annotation.PostConstruct; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.BatchingProperties; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.repository.DocumentStorageBatchRepository; -import gov.irs.directfile.submit.repository.interfaces.IBatchRepository; - -@Service -@EnableScheduling -@SuppressWarnings("PMD.SignatureDeclareThrowsException") -public class UserSubmissionBatchAssembler { - private final IBatchRepository batchRepository; - - private final BatchingProperties batchingProperties; - private final String applicationId; - private final UserSubmissionBatchProcessor userSubmissionBatchProcessor; - - // Since the onTimeout() scheduled task runs in a separate thread from the rest - // of this service, we need to ensure atomic updates to the batch to avoid losing - // any submissions due to race conditions. - private final AtomicLong currentBatchId = new AtomicLong(0); - private final AtomicInteger currentBatchSize = new AtomicInteger(0); - private final Clock clock; - - public UserSubmissionBatchAssembler( - IBatchRepository batchRepository, - BatchingProperties batchingProperties, - @Value("${submit.application-id}") String applicationId, - UserSubmissionBatchProcessor userSubmissionBatchProcessor, - Clock clock) { - this.batchRepository = batchRepository; - this.batchingProperties = batchingProperties; - this.applicationId = applicationId; - this.userSubmissionBatchProcessor = userSubmissionBatchProcessor; - this.clock = clock; - } - - @PostConstruct - public void setup() throws Exception { - currentBatchId.set(batchRepository.getCurrentWritingBatch(applicationId)); - } - - @Scheduled(fixedRateString = "${submit.batching.batchTimeoutMilliseconds}") - public void onTimeout() { - synchronized (this) { - submitBatchForProcessing(currentBatchId.get()); - } - } - - private void submitBatchForProcessing(long batchId) { - if (currentBatchSize.get() > 0) { - userSubmissionBatchProcessor.processBatch(new SubmissionBatch( - batchId, - DocumentStorageBatchRepository.generateLocationForBatch( - applicationId, batchId, getBatchControlYear()))); - currentBatchId.incrementAndGet(); - } - currentBatchSize.set(0); - } - - public void addSubmission(UserSubmission userSubmission) throws Exception { - synchronized (this) { - long currentBatch = currentBatchId.get(); - String batchPath = DocumentStorageBatchRepository.generateLocationForBatch( - applicationId, currentBatch, getBatchControlYear()); - batchRepository.addSubmission(new SubmissionBatch(currentBatch, batchPath), userSubmission); - - if (currentBatchSize.incrementAndGet() >= batchingProperties.getMaxBatchSize()) { - submitBatchForProcessing(currentBatchId.get()); - } - } - } - - private int getBatchControlYear() { - return Year.now(clock).getValue() - 1; - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessor.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessor.java deleted file mode 100644 index a34afda..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessor.java +++ /dev/null @@ -1,78 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.List; -import java.util.Set; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.submit.command.CreateArchiveAction; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.repository.interfaces.IBatchRepository; - -@Service -@Slf4j -public class UserSubmissionBatchProcessor { - private final ActionQueue actions; - private final IBatchRepository batchRepository; - private final String applicationId; - - private final OfflineModeService offlineModeService; - - private final Set inProgressBatches; - - @Autowired - public UserSubmissionBatchProcessor( - ActionQueue actions, - IBatchRepository batchRepository, - @Value("${submit.application-id}") String applicationId, - OfflineModeService offlineModeService, - Set inProgressBatches) { - this.actions = actions; - this.batchRepository = batchRepository; - this.applicationId = applicationId; - this.offlineModeService = offlineModeService; - this.inProgressBatches = inProgressBatches; - } - - public void processOldBatches() { - if (!offlineModeService.isOfflineModeEnabled()) { - // 1. Get the current batch - // 2. From n - 1 to 0 AND exists(path) processBatch - - List submissionBatches = batchRepository.getUnprocessedBatches(applicationId); - - submissionBatches.forEach(batch -> { - if (!inProgressBatches.contains(batch)) { - log.info("Processing Old batch: " + batch.batchId() + " " + "for path " + batch.path()); - this.processBatch(batch); - inProgressBatches.add(batch); - } else { - log.info("Batch for path " + batch.path() + " is already in progress."); - } - }); - - } else { - log.info("Submit App is in offline mode. No batches will be processed at this time."); - } - } - - public void processBatch(SubmissionBatch submissionBatch) { - if (offlineModeService.isOfflineModeEnabled()) { - log.info( - "UserSubmissionBatchProcessor: Submit App is in offline mode. No batches will be processed until offline mode is disabled."); - } else { - if (!inProgressBatches.contains(submissionBatch)) { - CreateArchiveAction createArchiveActionCommand = new CreateArchiveAction(submissionBatch); - log.info("Adding batch" + submissionBatch + "to action queue"); - actions.getNewActions().add(createArchiveActionCommand); - inProgressBatches.add(submissionBatch); - } else { - log.info("Batch for path " + submissionBatch.path() + " is already in progress."); - } - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionConsumer.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionConsumer.java deleted file mode 100644 index c8a7c31..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/UserSubmissionConsumer.java +++ /dev/null @@ -1,54 +0,0 @@ -package gov.irs.directfile.submit.service; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.jms.Message; -import jakarta.jms.MessageListener; -import jakarta.jms.TextMessage; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; - -@Service -@Slf4j -public class UserSubmissionConsumer implements MessageListener { - private final DispatchMessageRouter dispatchMessageRouter; - private final ObjectMapper objectMapper; - - @Autowired - public UserSubmissionConsumer(DispatchMessageRouter dispatchMessageRouter, ObjectMapper objectMapper) { - this.dispatchMessageRouter = dispatchMessageRouter; - this.objectMapper = objectMapper; - } - - @Override - public void onMessage(Message message) { - String taxReturnId = ""; - try { - taxReturnId = message.getStringProperty("TAX-RETURN-ID"); - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId); - log.info("onMessage called, tax-return-id: {}", taxReturnId); - - String rawText = ((TextMessage) message).getText(); - VersionedDispatchMessage versionedDispatchMessage = - objectMapper.readValue(rawText, new TypeReference<>() {}); - dispatchMessageRouter.handleDispatchMessage(versionedDispatchMessage); - - message.acknowledge(); - } catch (Exception ex) { - MDC.put(AuditLogElement.taxReturnId.toString(), taxReturnId); - log.error( - "unable to process a message from the queue, tax-return-id: {}, {}", - taxReturnId, - ex.getClass().getName(), - ex); - } finally { - MDC.clear(); - } - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchHandler.java deleted file mode 100644 index 45c42b1..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package gov.irs.directfile.submit.service.handlers.dispatch; - -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; - -@SuppressWarnings("PMD.SignatureDeclareThrowsException") -public interface DispatchHandler { - void handleDispatchMessage(VersionedDispatchMessage message) throws Exception; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1Handler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1Handler.java deleted file mode 100644 index c71d14e..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1Handler.java +++ /dev/null @@ -1,28 +0,0 @@ -package gov.irs.directfile.submit.service.handlers.dispatch; - -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.Dispatch; -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; -import gov.irs.directfile.models.message.dispatch.payload.DispatchPayloadV1; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.service.UserSubmissionBatchAssembler; - -@Service -@Slf4j -@AllArgsConstructor -public class DispatchV1Handler implements DispatchHandler { - private final UserSubmissionBatchAssembler userSubmissionBatchAssembler; - - @Override - public void handleDispatchMessage(VersionedDispatchMessage message) throws Exception { - DispatchPayloadV1 payload = (DispatchPayloadV1) message.getPayload(); - Dispatch dispatch = payload.getDispatch(); - - UserSubmission userSubmission = UserSubmission.fromDispatch(dispatch); - userSubmissionBatchAssembler.addSubmission(userSubmission); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/UnsupportedMessageVersionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/UnsupportedMessageVersionHandler.java deleted file mode 100644 index 0c55c5f..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/handlers/dispatch/UnsupportedMessageVersionHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package gov.irs.directfile.submit.service.handlers.dispatch; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; - -@Service -@Slf4j -public class UnsupportedMessageVersionHandler implements DispatchHandler { - @Override - public void handleDispatchMessage(VersionedDispatchMessage payload) { - log.error("Unable to process Dispatch Message. Headers: {} ", payload.getHeaders()); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IBundleSubmissionActionHandler.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IBundleSubmissionActionHandler.java deleted file mode 100644 index 2de9a0a..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IBundleSubmissionActionHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package gov.irs.directfile.submit.service.interfaces; - -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; -import gov.irs.directfile.submit.command.SubmitBundleAction; -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.SubmittedDataContainer; -import gov.irs.directfile.submit.exception.LoginFailureException; -import gov.irs.directfile.submit.exception.LogoutFailureException; - -public interface IBundleSubmissionActionHandler extends IService { - - boolean login() throws LoginFailureException; - - boolean logout() throws LogoutFailureException; - - SubmittedDataContainer submitBundles(BundledArchives bundledArchives, SubmissionBatch submissionBatch) - throws SubmissionFailureException; - - SubmittedDataContainer handleCommand(SubmitBundleAction command) throws SubmissionFailureException; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IService.java deleted file mode 100644 index c2047fa..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/IService.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.irs.directfile.submit.service.interfaces; - -import gov.irs.directfile.submit.config.Config; - -public interface IService { - void Setup(Config config) throws Throwable; -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISubmissionFailureService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISubmissionFailureService.java deleted file mode 100644 index fbe62b2..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISubmissionFailureService.java +++ /dev/null @@ -1,11 +0,0 @@ -package gov.irs.directfile.submit.service.interfaces; - -import gov.irs.directfile.submit.actions.results.SubmissionFailureActionResult; -import gov.irs.directfile.submit.command.SubmissionFailureAction; -import gov.irs.directfile.submit.domain.SubmissionBatch; - -public interface ISubmissionFailureService extends IService { - void processFailedBatch(SubmissionBatch submissionBatch); - - SubmissionFailureActionResult handleCommand(SubmissionFailureAction submissionFailureActionCommand); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISynchronousDocumentStoreService.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISynchronousDocumentStoreService.java deleted file mode 100644 index 92053e5..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/interfaces/ISynchronousDocumentStoreService.java +++ /dev/null @@ -1,28 +0,0 @@ -package gov.irs.directfile.submit.service.interfaces; - -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.Optional; - -import gov.irs.directfile.submit.domain.DocumentStoreResource; - -public interface ISynchronousDocumentStoreService extends IService { - String write(String objectKey, InputStream payloadStream) throws IOException; - - String write(String objectKey, String content); - - Optional getMostRecentFolderForPrefix(String prefix); - - List getSubFolders(String objectKey); - - Optional getLeastRecentModifiedResourceForPrefix(String s); - - String getObjectAsString(String objectKey) throws IOException; - - List getObjectKeys(String prefix); - - void deleteObjects(List keys); - - void copyObject(DocumentStoreResource documentStoreResource, String destinationKey); -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/BatchProcessingApplicationStartRunner.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/BatchProcessingApplicationStartRunner.java deleted file mode 100644 index ebf555f..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/BatchProcessingApplicationStartRunner.java +++ /dev/null @@ -1,37 +0,0 @@ -package gov.irs.directfile.submit.service.startup.runners; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import gov.irs.directfile.submit.service.UserSubmissionBatchProcessor; - -@Component -@Slf4j -@Order(2) -/** - * When the application starts, this class calls processOldBatches() to pick up any unprocessed - * submissions in Document Storage - * - * The ApplicationRunner interface allows us to run one-time logic after an application has - * started. - * Reference Docs: - * https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.spring-application.command-line-runner - * - * In this case, we want to process any old batches in S3 after the application has started. - * */ -public class BatchProcessingApplicationStartRunner implements ApplicationRunner { - private final UserSubmissionBatchProcessor userSubmissionBatchProcessor; - - public BatchProcessingApplicationStartRunner(UserSubmissionBatchProcessor userSubmissionBatchProcessor) { - this.userSubmissionBatchProcessor = userSubmissionBatchProcessor; - } - - @Override - public void run(ApplicationArguments args) throws Exception { - log.info("=== Processing Old Batches now that application has started. ==="); - userSubmissionBatchProcessor.processOldBatches(); - } -} diff --git a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunner.java b/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunner.java deleted file mode 100644 index 96157e6..0000000 --- a/direct-file/submit/src/main/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunner.java +++ /dev/null @@ -1,29 +0,0 @@ -package gov.irs.directfile.submit.service.startup.runners; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.ApplicationArguments; -import org.springframework.boot.ApplicationRunner; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import gov.irs.directfile.submit.service.polling.MeFHealthPoller; - -@Component -@Slf4j -@Order(1) -public class MefConnectivityApplicationStartRunner implements ApplicationRunner { - private final MeFHealthPoller meFHealthPoller; - - public MefConnectivityApplicationStartRunner(MeFHealthPoller meFHealthPoller) { - this.meFHealthPoller = meFHealthPoller; - } - - @Override - public void run(ApplicationArguments args) throws Exception { - boolean isMefOnline = meFHealthPoller.performMefConnectivityCheck(); - - if (isMefOnline) { - log.info("MeF Client is online. Initial MeF login and logout were successful"); - } - } -} diff --git a/direct-file/submit/src/main/resources/application-development.yaml b/direct-file/submit/src/main/resources/application-development.yaml deleted file mode 100644 index 049f637..0000000 --- a/direct-file/submit/src/main/resources/application-development.yaml +++ /dev/null @@ -1,7 +0,0 @@ - -direct-file: - local-encryption: - local-wrapping-key: ${LOCAL_WRAPPING_KEY} - -server: - port: 8083 diff --git a/direct-file/submit/src/main/resources/application-docker.yaml b/direct-file/submit/src/main/resources/application-docker.yaml deleted file mode 100644 index 9ff3e14..0000000 --- a/direct-file/submit/src/main/resources/application-docker.yaml +++ /dev/null @@ -1,31 +0,0 @@ -spring: - datasource: - url: jdbc:postgresql://mef-apps-db:5432/directfile-submit - -submit: - toolkit: /mef-client-sdk-src - directories: - input: /mef-data/run/input/ - to-process: /mef-data/run/toprocess/ - processed: /mef-data/run/processed/ - batched: /mef-data/run/batched/ - to-batch: /mef-data/run/tobatch/ - submitted: /mef-data/run/submitted/ - intervals: - returns-to-process: 120000 - messagequeue: - endpoint: http://localstack:4566 - sns: - endpoint: http://localstack:4566 - submissionid: - variable-chars: ${SUBMIT_ID_VAR_CHARS:do} - batching: - batchSize: ${SUBMIT_APP_BATCH_SIZE:100} - errorPollingMilliseconds: ${SUBMIT_APP_ERROR_POLLING_MILLIS:60000} # 1000 milliseconds * 60 = 60 seconds - mef: - healthCheckMilliseconds: ${SUBMIT_APP_MEF_HEALTHCHECK_MILLIS:300000} # 1000 milliseconds * 60 seconds * 5 minutes -> 5 minutes - -# these defaults are to match the backend (update/remove once we're fully onto sqs) -direct-file: - local-encryption: - local-wrapping-key: ${LOCAL_WRAPPING_KEY:oE3Pm+fr1I+YbX2ZxEe/n9INqJjy00KSl7oXXW4p5Xw=} diff --git a/direct-file/submit/src/main/resources/application.yaml b/direct-file/submit/src/main/resources/application.yaml deleted file mode 100644 index f472cc8..0000000 --- a/direct-file/submit/src/main/resources/application.yaml +++ /dev/null @@ -1,112 +0,0 @@ -spring: - devtools: - restart: - enabled: false - datasource: - username: postgres - password: postgres - url: jdbc:postgresql://localhost:${MEF_APPS_DB_PORT:32768}/directfile-submit - jpa: - hibernate: - ddl-auto: none - properties: - hibernate: - dialect: org.hibernate.dialect.PostgreSQLDialect - liquibase: - change-log: classpath:db/changelog.yaml - url: ${spring.datasource.url} - user: ${spring.datasource.username} - password: ${spring.datasource.password} - hikari: - maximum-pool-size: 50 - max-lifetime: 450000 - minimum-idle: 30 - connection-timeout: 15000 - -server: - port: ${DF_SUBMIT_PORT:8083} - shutdown: graceful - -management: - endpoint: - health: - enabled: true - endpoints: - enabled-by-default: false - web: - discovery: - enabled: false - exposure: - include: health - -submit: - application-id: ${POD_NAME:dfsys-mef-submit-deployment-0}-${DF_AWS_REGION:us-gov-east-1} - etin: 11111 - asid: 22222222 - efin: 333333 - vendor-control-number: ${VENDOR_CONTROL_NUMBER_KEY:IRSDIRTAXFPRD001} # this is NOT the correct vendor control number just using a previous example - softwareId: ${MEF_SOFTWARE_ID_KEY:12345678} - softwareVersionNum: ${MEF_SOFTWARE_VERSION_NUM:2023.0.1} - prod: false - runner-disabled-for-testing: false - store-validation-results: ${DF_STORE_VALIDATION_RESULTS:false} - should-disable-mef-connectivity: ${DF_DISABLE_MEF_CONNECTIVITY:false} - submit-action-enabled: true - keystore: - keystore-base64: MISSING - keystore-password: MISSING - keystore-alias: MISSING - directories: - input: src/main/resources/test/run/input/ - to-process: src/main/resources/test/run/toprocess/ - processed: src/main/resources/test/run/processed/ - batched: src/main/resources/test/run/batched/ - to-batch: src/main/resources/test/run/tobatch/ - submitted: src/main/resources/test/run/submitted/ - intervals: - returns-to-process: 12000 - documentstore: - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - endpoint: http://s3.localhost.localstack.cloud:4566/ - bucket: direct-file-taxreturns - messagequeue: - endpoint: http://localhost:4566 - dispatch-queue: dispatch-queue - dlq-dispatch-queue: dlq-dispatch-queue - pending-submission-queue: pending-submission-queue - pending-submission-publish-enabled: false - submission-confirmation-queue: submission-confirmation-queue - submission-confirmation-publish-enabled: false - sqs-message-handling-enabled: true - region: us-west-2 - credentials: - accessKey: accessKey - secretKey: secretKey - sns: - endpoint: http://localhost:4566 - submission-confirmation-topic-arn: arn:aws:sns:us-west-2:000000000000:submission-confirmation-topic - submission-confirmation-publish-enabled: true - region: us-west-2 - credentials: - accessKey: accessKey - secretKey: secretKey - submissionid: - variable-chars: ${SUBMIT_ID_VAR_CHARS:xx} - batching: - batchSize: ${SUBMIT_APP_BATCH_SIZE:20} - batchTimeoutMilliseconds: ${SUBMIT_APP_BATCH_TIMEOUT_MILLIS:5000} # 1000 milliseconds * 5 = 5 seconds - errorPollingMilliseconds: ${SUBMIT_APP_ERROR_POLLING_MILLIS:60000} # 1000 milliseconds * 60 = 60 seconds - mef: - healthCheckMilliseconds: ${SUBMIT_APP_MEF_HEALTHCHECK_MILLIS:30000} # 1000 milliseconds * 60 seconds * 5 minutes -> 5 minutes -aws: - enabled: false - default-credentials-provider-chain-enabled: false - access-key: accessKey - secret-key: secretKey - region: us-west-2 - -direct-file: - local-encryption: - local-wrapping-key: lYIIKutUatfMwdEGB8qtUpQc3wMNtT5pfM+zW57qrv4= diff --git a/direct-file/submit/src/main/resources/banner.txt b/direct-file/submit/src/main/resources/banner.txt deleted file mode 100644 index 71185a9..0000000 --- a/direct-file/submit/src/main/resources/banner.txt +++ /dev/null @@ -1,32 +0,0 @@ - @@@@ - (..@ ( @ .@@@@ @@@@/*@#@@@. .@@(@&@@/&@ * * * . - . @ @@@@@@@@@ &@@@(@@@@@@ .@/@@@@@@./@@@*@(@@@. , - . @& &@&/@%@@@ ,&&@@&#@@@@ &%@@&. (@@@@(@@#@@(& - @@&@@#%& /@@@&@(@@% @@@@@@@@( @@@@@ @/&@@ #@@@@&&@ - @%@#%%@@@ @@@&&@@(&#%% . %&#(@& @@@@@( @@&@@ - @@&%@@#@@ @@%%@@ / # . %##@@@ @&&@@ %@@&@ &%@#@ - #&@%/@@%@ #&@ . @@@&@(#@&#@@@ @&@&#@@&&#(@&& #/@&@ ,@@@(# - @(@#(@@@ @& %@/*&( ,&%(@*@ #@%@@* @@@@(@*@@@( @@&@& - ((, @ @@&@ @@@@@@ @&(&/@&&@@@@/ , @&&% @&(@& @@@%@@@@%/ %@@(@ -,@@@ @@ #@@@@@#@@ @@&@. , .*@. @/@#@ .@@@@@@@@@ (#@*@ (/@@@ -@@(@&/ @@%@&/@%@@* #@@@%@@/*#@&@@ @@#@@, @@/@@ @/# @@@@@,@@@@@ -@*@(@@@% @@@(@@@@(@ . &@@@ @ @@(@@. @.&@&* *#@& &(@@@ #@@*@ - @@@/@/@@*@@@#@@@@ /@@@ &@@@* %@&@#. @@&@,,&@@@& @&(@ - @(@&@@@@@@@&@/ @ @ @@@@, * @@*/&%@@,@@( *@@/@@ @@@@@ @@@@ - &@@@@%@&%@ % . (@@# *@&*@(@&@@@ * @@@&@ &&#&@ &@@@ - @@@&@@@ &@@&@ ( &(@% * @#@#@@&%@ &@@@%, .@@@@@ #@@@ - *@@% ##@%@@ * @#@% ( / #@%&@&@ (#@#%@ #@&@@@ %@@@@ -@%& @ &@&@@@&@ @%@@&@@@&%@@%@&#@%@@%(&@ @@%@&@ (@@@@@% %#&&%# /#@@@@ - @#@@@ #@@&#(@@&( @&@#&#@(&&&@@@%%(#@@&&#%%@ @ ( &#%&% @@%@@@ %@@%@ - @@@(&&( @@&@@/@@@ @(@@@@@@ @@&@ @#@&@@@& &@%&/% &@@(@, @(*@* - (@#@@@@@@@@@@(@@ ,@&(@@.#@@&& &@@@ @#@@@@@@@& , @@@@( /@/@#( @@@@& - *@%@@@@@@&@&@@. @@#%@ @@@,@ ,@@#% @(%,@ . @@@@, @/,@(@ @@@@* - .(&&@/@%/@&@ @ @@@@@ @&@@@ (. @*@@ #@@@& ,(@@@, &@@@@# @@(@@ - &*@@@@@@@@# &@@@# . &@@%@ @*@@( .@@*@@ *@@@@@ @*@@( @#@@@ - /@@@&&@#& #@@&@%( @@@@* %@@@@# @@%@@ @@@@@& ,/@ - @@@@, /@@*@( /(&&@, &@@@@ @ @@&@( , @@@@@ . - . &(@%@@@@&@@&&&@@@&*@@@@@@*@@&&@@&#/@@@@@@ @&@/ . - ( &#@%#@#@%%# #@@@@#@&&#@ # - -${application.title} (${application.version}) -Spring Boot ${spring-boot.version} diff --git a/direct-file/submit/src/main/resources/db/changelog.yaml b/direct-file/submit/src/main/resources/db/changelog.yaml deleted file mode 100644 index 824a0e4..0000000 --- a/direct-file/submit/src/main/resources/db/changelog.yaml +++ /dev/null @@ -1,7 +0,0 @@ -databaseChangeLog: - - preConditions: - onFail: HALT - onError: HALT - - includeAll: - path: migrations/ - relativeToChangelogFile: true diff --git a/direct-file/submit/src/main/resources/db/migrations/000-initial-schema.yaml b/direct-file/submit/src/main/resources/db/migrations/000-initial-schema.yaml deleted file mode 100644 index 57783ec..0000000 --- a/direct-file/submit/src/main/resources/db/migrations/000-initial-schema.yaml +++ /dev/null @@ -1,19 +0,0 @@ -databaseChangeLog: -- changeSet: - id: 1705681978364-1 - author: irs-123 (generated) - preConditions: - - onFail: MARK_RAN - - not: - - tableExists: - - tableName: sub_id_temp - changes: - - createTable: - columns: - - column: - name: last - type: TIMESTAMP WITHOUT TIME ZONE - - column: - name: value - type: VARCHAR(6) - tableName: sub_id_temp diff --git a/direct-file/submit/src/main/resources/db/migrations/20240119123900-app-id-add.yaml b/direct-file/submit/src/main/resources/db/migrations/20240119123900-app-id-add.yaml deleted file mode 100644 index a2314a7..0000000 --- a/direct-file/submit/src/main/resources/db/migrations/20240119123900-app-id-add.yaml +++ /dev/null @@ -1,26 +0,0 @@ -databaseChangeLog: - - changeSet: - id: app-id-add - author: irs-123 (generated) - comment: add app ID to sub_id_temp - changes: - - renameColumn: - newColumnName: sub_id_value - oldColumnName: value - tableName: sub_id_temp - - addColumn: - tableName: sub_id_temp - columns: - - column: - name: app_id - type: VARCHAR(20) - rollback: - - dropColumn: - tableName: sub_id_temp - columns: - - column: - name: app_id - - renameColumn: - newColumnName: value - oldColumnName: sub_id_value - tableName: sub_id_temp diff --git a/direct-file/submit/src/main/resources/db/migrations/2024012395500-sub-app-table.yaml b/direct-file/submit/src/main/resources/db/migrations/2024012395500-sub-app-table.yaml deleted file mode 100644 index a5ad07b..0000000 --- a/direct-file/submit/src/main/resources/db/migrations/2024012395500-sub-app-table.yaml +++ /dev/null @@ -1,26 +0,0 @@ -databaseChangeLog: - - changeSet: - id: sub-app-table - author: irs-123 (generated) - comment: create submission_applications table - - changes: - - createTable: - columns: - - column: - name: last - type: TIMESTAMP WITHOUT TIME ZONE - - column: - name: submission_id - type: VARCHAR(6) - - column: - name: application_id - type: VARCHAR(20) - - column: - constraints: - nullable: false - primaryKey: true - primaryKeyName: submission_applications_pkey - name: id - type: UUID - tableName: submission_applications diff --git a/direct-file/submit/src/main/resources/db/migrations/202411151120000-add-pod-identifier-table.yaml b/direct-file/submit/src/main/resources/db/migrations/202411151120000-add-pod-identifier-table.yaml deleted file mode 100644 index b07ab2e..0000000 --- a/direct-file/submit/src/main/resources/db/migrations/202411151120000-add-pod-identifier-table.yaml +++ /dev/null @@ -1,29 +0,0 @@ -databaseChangeLog: - - changeSet: - id: pod-identifier-table - author: 123 (generated) - comment: create pod_identifier table - - changes: - - createTable: - columns: - - column: - name: id - type: serial - constraints: - nullable: false - primaryKey: true - primaryKeyName: pod_identifier_id_pkey - - column: - name: asid - type: VARCHAR(50) - - column: - name: region - type: VARCHAR(50) - - column: - name: pod_id - type: VARCHAR(255) - tableName: pod_identifier - rollback: - - dropTable: - tableName: pod_identifier diff --git a/direct-file/submit/src/main/resources/logback.xml b/direct-file/submit/src/main/resources/logback.xml deleted file mode 100644 index ec4691b..0000000 --- a/direct-file/submit/src/main/resources/logback.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - timestamp - [ignore] - [ignore] - [ignore] - - yyyy-MM-dd'T'HH:mm:ss.SSS'Z' - UTC - {"system":"DIRECTFILE","eventType":"SUBMIT","version":"${GIT_COMMIT_HASH}"} - - - - - - - - diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/ApplicationContextTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/ApplicationContextTest.java deleted file mode 100644 index 3fa785f..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/ApplicationContextTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package gov.irs.directfile.submit; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import gov.irs.directfile.submit.config.SnsClientTestConfiguration; -import gov.irs.directfile.submit.config.SynchronousS3TestConfiguration; -import gov.irs.directfile.submit.service.SqsConnectionSetupService; - -@SpringBootTest -@Import({SynchronousS3TestConfiguration.class, SnsClientTestConfiguration.class}) -public class ApplicationContextTest { - - @MockBean - SqsConnectionSetupService sqsConnectionSetupService; - - /** - * This empty test validates that the Spring Application - * will successfully start up. - * - * The @SpringBootTest loads in the application context - * for any test in the file. So this empty test is enough to validate - * if the app will start up. - * - * - * */ - @Test - public void contextLoads() {} -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/LibsProofOfConceptTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/LibsProofOfConceptTest.java deleted file mode 100644 index b41558e..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/LibsProofOfConceptTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package gov.irs.directfile.submit; - -import org.junit.jupiter.api.Test; - -import gov.irs.directfile.models.Dispatch; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -// TODO: Delete this class after libs story (https://git.irslabs.org/irslabs-prototypes/direct-file/-/issues/1625) is -// merged. -public class LibsProofOfConceptTest { - - @Test - public void useDispatchClassFromSharedLibs() { - Dispatch dispatch = new Dispatch(); - dispatch.setMefSubmissionId("111"); - - assertEquals("111", dispatch.getMefSubmissionId()); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandlerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandlerTest.java deleted file mode 100644 index 095aeed..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/BundleArchivesActionHandlerTest.java +++ /dev/null @@ -1,240 +0,0 @@ -package gov.irs.directfile.submit.actions; - -import java.util.List; -import java.util.Map; - -import ch.qos.logback.classic.Level; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; - -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.inputcomposition.PostmarkedSubmissionArchive; -import gov.irs.mef.inputcomposition.SubmissionBuilder; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.AuditService; -import gov.irs.directfile.audit.events.Event; -import gov.irs.directfile.audit.events.EventId; -import gov.irs.directfile.audit.events.EventStatus; -import gov.irs.directfile.audit.events.SystemEventPrincipal; -import gov.irs.directfile.audit.events.TaxPeriod; -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.audit.events.XXXCode; -import gov.irs.directfile.submit.actions.results.CreateArchiveActionResult; -import gov.irs.directfile.submit.command.BundleArchiveAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.SnsClientTestConfiguration; -import gov.irs.directfile.submit.config.SynchronousS3TestConfiguration; -import gov.irs.directfile.submit.domain.SubmissionArchiveContainer; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserContextData; -import gov.irs.directfile.submit.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; - -@SpringBootTest -@Import({SynchronousS3TestConfiguration.class, SnsClientTestConfiguration.class}) -public class BundleArchivesActionHandlerTest { - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - @Autowired - Config config; - - @RegisterExtension - public static LoggerExtension logVerifier = new LoggerExtension(Level.INFO, AuditService.class.getName()); - - // default test data - final UserContextData userContextData1 = new UserContextData( - "00000", - "00000000-0000-0000-0000-000000000000", - "11111111-1111-1111-1111-111111111111", - "111001111", - TinType.INDIVIDUAL, - "0.0.0.0", - "2024-01-01"); - final UserContextData userContextData2 = new UserContextData( - "11111", - "88888888-8888-8888-8888-888888888888", - "99999999-9999-9999-9999-999999999999", - "111002222", - TinType.INDIVIDUAL, - "1.1.1.1", - "2024-01-01"); - final PostmarkedSubmissionArchive mockSubmissionArchive1 = mock(PostmarkedSubmissionArchive.class); - final PostmarkedSubmissionArchive mockSubmissionArchive2 = mock(PostmarkedSubmissionArchive.class); - - final List submissionArchiveContainers = List.of( - new SubmissionArchiveContainer(userContextData1, mockSubmissionArchive1), - new SubmissionArchiveContainer(userContextData2, mockSubmissionArchive2)); - - @Test - void bundleArchivesActionLogsCreateBundleSuccessAuditEvent() throws ActionException { - // given - ActionContext actionContext = new ActionContext(config); - SubmissionBatch submissionBatch = new SubmissionBatch(0L, ""); - CreateArchiveActionResult createArchiveActionResult = - new CreateArchiveActionResult(submissionBatch, submissionArchiveContainers); - BundleArchivesActionHandler bundleArchivesActionHandler = new BundleArchivesActionHandler(actionContext); - - try (MockedStatic mockSubmissionBuilder = Mockito.mockStatic(SubmissionBuilder.class)) { - mockSubmissionBuilder - .when(() -> SubmissionBuilder.createPostmarkedSubmissionArchive(any(), any())) - .thenReturn(mockSubmissionArchive1) - .thenReturn(mockSubmissionArchive2); - - // when - bundleArchivesActionHandler.handleBundleCommand(new BundleArchiveAction(createArchiveActionResult)); - - // then verify 2 events were logged with expected values - logVerifier.verifyLogEvent( - generateCreateBundleSuccessAuditEvent("{directFileUserId=00000000-0000-0000-0000-000000000000}"), - 0, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "200", - AuditLogElement.mefSubmissionId, - userContextData1.getSubmissionId(), - AuditLogElement.taxPeriod, - TaxPeriod.TY2024, - AuditLogElement.taxReturnId, - userContextData1.getTaxReturnId(), - AuditLogElement.userTin, - userContextData1.getUserTin(), - AuditLogElement.userTinType, - userContextData1.getUserTinType(), - AuditLogElement.mftCode, - XXXCode.XXX_CODE, - AuditLogElement.remoteAddress, - userContextData1.getRemoteAddress())); - - logVerifier.verifyLogEvent( - generateCreateBundleSuccessAuditEvent("{directFileUserId=88888888-8888-8888-8888-888888888888}"), - 1, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "200", - AuditLogElement.mefSubmissionId, - userContextData2.getSubmissionId(), - AuditLogElement.taxPeriod, - TaxPeriod.TY2024, - AuditLogElement.taxReturnId, - userContextData2.getTaxReturnId(), - AuditLogElement.userTin, - userContextData2.getUserTin(), - AuditLogElement.userTinType, - userContextData2.getUserTinType(), - AuditLogElement.mftCode, - XXXCode.XXX_CODE, - AuditLogElement.remoteAddress, - userContextData2.getRemoteAddress())); - } - } - - @Test - void bundleArchivesActionLogsCreateBundleFailureAuditEvent() { - // given - ActionContext actionContext = new ActionContext(config); - SubmissionBatch submissionBatch = new SubmissionBatch(0L, ""); - CreateArchiveActionResult createArchiveActionResult = - new CreateArchiveActionResult(submissionBatch, submissionArchiveContainers); - BundleArchivesActionHandler bundleArchivesActionHandler = new BundleArchivesActionHandler(actionContext); - - try (MockedStatic mockSubmissionBuilder = Mockito.mockStatic(SubmissionBuilder.class)) { - mockSubmissionBuilder - .when(() -> SubmissionBuilder.createSubmissionContainer( - any(PostmarkedSubmissionArchive[].class), anyString())) - .thenThrow(new ToolkitException("test toolkit exception")); - - // when - bundleArchivesActionHandler.handleBundleCommand(new BundleArchiveAction(createArchiveActionResult)); - fail("expected it to throw an exception"); - } catch (ActionException actionException) { - // then verify 2 events were logged with expected values - logVerifier.verifyLogEvent( - generateCreateBundleFailureAuditEvent( - "gov.irs.mef.exception.ToolkitException", - "{directFileUserId=00000000-0000-0000-0000-000000000000, errorMessage=test toolkit exception}"), - 0, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "400", - AuditLogElement.mefSubmissionId, - userContextData1.getSubmissionId(), - AuditLogElement.taxPeriod, - TaxPeriod.TY2024, - AuditLogElement.taxReturnId, - userContextData1.getTaxReturnId(), - AuditLogElement.mftCode, - XXXCode.XXX_CODE, - AuditLogElement.remoteAddress, - userContextData1.getRemoteAddress())); - - logVerifier.verifyLogEvent( - generateCreateBundleFailureAuditEvent( - "gov.irs.mef.exception.ToolkitException", - "{directFileUserId=88888888-8888-8888-8888-888888888888, errorMessage=test toolkit exception}"), - 1, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "400", - AuditLogElement.mefSubmissionId, - userContextData2.getSubmissionId(), - AuditLogElement.taxPeriod, - TaxPeriod.TY2024, - AuditLogElement.taxReturnId, - userContextData2.getTaxReturnId(), - AuditLogElement.mftCode, - XXXCode.XXX_CODE, - AuditLogElement.remoteAddress, - userContextData2.getRemoteAddress())); - } - } - - private Event generateCreateBundleSuccessAuditEvent(String detail) { - return Event.builder() - .eventId(EventId.CREATE_BUNDLE) - .eventStatus(EventStatus.SUCCESS) - .eventPrincipal(new SystemEventPrincipal()) - .detail(detail) - .build(); - } - - private Event generateCreateBundleFailureAuditEvent(String eventErrorMessage, String detail) { - return Event.builder() - .eventId(EventId.CREATE_BUNDLE) - .eventStatus(EventStatus.FAILURE) - .eventErrorMessage(eventErrorMessage) - .eventPrincipal(new SystemEventPrincipal()) - .detail(detail) - .build(); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionActionExceptionTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionActionExceptionTest.java deleted file mode 100644 index fd5dcaf..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/actions/exception/BundleArchiveActionActionExceptionTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package gov.irs.directfile.submit.actions.exception; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.submit.domain.UserContextData; - -import static org.junit.jupiter.api.Assertions.*; - -class BundleArchiveActionActionExceptionTest { - - @Test - public void - whenUserContextDataTaxReturnIdsToString_thenShouldReturnStringContainingTaxReturnIdsFromUserContextDataList() { - UserContextData userContextData1 = new UserContextData("", "", "111", "", TinType.INDIVIDUAL, "", ""); - UserContextData userContextData2 = new UserContextData("", "", "222", "", TinType.INDIVIDUAL, "", ""); - List userContextDataList = List.of(userContextData1, userContextData2); - BundleArchiveActionException bundleArchiveActionException = - new BundleArchiveActionException(userContextDataList, null, new Exception()); - - String result = bundleArchiveActionException.userContextDataTaxReturnIdsToString(); - - assertEquals("UserContextData{TaxReturnIds=[111, 222]}", result); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/AWSCredentialsConfigTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/AWSCredentialsConfigTest.java deleted file mode 100644 index b480e8e..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/AWSCredentialsConfigTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class AWSCredentialsConfigTest { - - @Test - void staticCredentialProviderCreatedWhenApplicablePropertySetToFalse() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfig.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - }); - } - - @Test - void staticCredentialProviderCreatedWhenApplicablePropertyIsNotSet() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues("aws.accessKey=test", "aws.secretKey=test") - .withUserConfiguration(AWSCredentialsConfig.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - }); - } - - @Test - void defaultCredentialProviderCreatedWhenApplicablePropertySetToTrue() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfig.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isNotNull(); - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - }); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/EncryptionClientConfigTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/EncryptionClientConfigTest.java deleted file mode 100644 index f288f1b..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/EncryptionClientConfigTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import software.amazon.awssdk.services.kms.KmsClient; -import software.amazon.encryption.s3.materials.CryptographicMaterialsManager; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest(classes = {EncryptionClientConfig.class, AWSCredentialsConfig.class}) -class EncryptionClientConfigTest { - - @Autowired - EncryptionClientConfig encryptionClientConfig; - - @Test - void regionalKmsClientIsNotNull() { - KmsClient kmsClient = encryptionClientConfig.regionalKmsClient(); - assertNotNull(kmsClient); - } - - @Test - void kmsCryptoIsNotNull() { - String testKmsKeyArn = "test-kms-arn"; - CryptographicMaterialsManager cryptographicMaterialsManager = encryptionClientConfig.kmsCrypto(testKmsKeyArn); - assertNotNull(cryptographicMaterialsManager); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/S3StorageClientConfigTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/S3StorageClientConfigTest.java deleted file mode 100644 index b6e45dc..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/S3StorageClientConfigTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.encryption.s3.S3AsyncEncryptionClient; - -import static org.assertj.core.api.Assertions.assertThat; - -public class S3StorageClientConfigTest { - private final ApplicationContextRunner localContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "aws.region=us-east-1", - "aws.default-credentials-provider-chain-enabled=false", - "submit.documentstore.endpoint=http://test.com", - "submit.documentstore.region=us-east-1", - "direct-file.local-encryption.local-wrapping-key=test") - .withUserConfiguration( - S3StorageClientConfig.class, EncryptionClientConfig.class, AWSCredentialsConfig.class); - - @Test - void localS3EncryptionClientInstantiatesWithValidProperties() { - this.localContextRunner.run((context) -> - assertThat(context.getBean(S3AsyncEncryptionClient.class)).isNotNull()); - } - - @Test - void localS3EncryptionClientDoesNotInstantiateWithoutApplicableProperties() { - localContextRunner.withPropertyValues("submit.documentstore.endpoint=").run((context) -> assertThat(context) - .hasFailed()); - - localContextRunner.withPropertyValues("submit.documentstore.region=").run((context) -> assertThat(context) - .hasFailed()); - - localContextRunner.withPropertyValues("aws.accessKey=").run((context) -> assertThat(context) - .hasFailed()); - - localContextRunner.withPropertyValues("aws.secretKey=").run((context) -> assertThat(context) - .hasFailed()); - - localContextRunner - .withPropertyValues("direct-file.local-encryption.local-wrapping-key=") - .run((context) -> assertThat(context).hasFailed()); - } - - @Test - void kmsS3EncryptionClientDoesNotInstantiateWithoutApplicableProperties() { - // testing that the aws configuration fails if you only have a local wrapping key set, - // instead of the kms wrapping key - ApplicationContextRunner awsContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "spring.profiles.active=aws", - "aws.default-credentials-provider-chain-enabled=false", - "aws.accessKey=test", - "aws.secretKey=test", - "aws.region=us-east-1", - "aws.kmsEndpoint=http://test.com", - "submit.documentstore.region=us-east-1", - "submit.documentstore.endpoint=http://test.com", - "submit.documentstore.assume-role-duration-seconds=60", - "direct-file.local-encryption.local-wrapping-key=test") - .withUserConfiguration( - S3StorageClientConfig.class, EncryptionClientConfig.class, AWSCredentialsConfig.class); - - // no kms wrapping key - awsContextRunner.run((context) -> { - assertThat(context).hasFailed(); - assertThat(context.getStartupFailure().getMessage()) - .contains("kmsWrappingKeyArn is marked non-null but is null"); - }); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientConfigurationTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientConfigurationTest.java deleted file mode 100644 index 502d808..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientConfigurationTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class SnsClientConfigurationTest { - - @Test - void snsClientBeanCreatedWhenStaticCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "submit.sns.endpoint=http://directfile.test", - "submit.sns.region=us-west-2", - "submit.sns.submission-confirmation-publish-enabled=true", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfig.class, SnsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - assertThat(context.getBean(SnsClientConfiguration.class)).isNotNull(); - }); - } - - @Test - void snsClientBeanCreatedWhenDefaultCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "submit.sns.endpoint=http://directfile.test", - "submit.sns.region=us-west-2", - "submit.sns.submission-confirmation-publish-enabled=true", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfig.class, SnsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - assertThat(context.getBean(SnsClientConfiguration.class)).isNotNull(); - }); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientTestConfiguration.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientTestConfiguration.java deleted file mode 100644 index 8da20ae..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SnsClientTestConfiguration.java +++ /dev/null @@ -1,34 +0,0 @@ -package gov.irs.directfile.submit.config; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; -import software.amazon.awssdk.services.sns.SnsClient; -import software.amazon.awssdk.services.sns.model.ListSubscriptionsByTopicRequest; -import software.amazon.awssdk.services.sns.model.ListSubscriptionsByTopicResponse; -import software.amazon.awssdk.services.sns.model.Subscription; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@TestConfiguration -public class SnsClientTestConfiguration { - @Bean - @Primary - public SnsClient testSnsClient() { - ListSubscriptionsByTopicResponse listSubscriptionsByTopicResponse = - mock(ListSubscriptionsByTopicResponse.class); - List subscriptions = new ArrayList<>(); - subscriptions.add(mock(Subscription.class)); - when(listSubscriptionsByTopicResponse.subscriptions()).thenReturn(subscriptions); - - SnsClient snsClient = mock(SnsClient.class); - when(snsClient.listSubscriptionsByTopic(any(ListSubscriptionsByTopicRequest.class))) - .thenReturn(listSubscriptionsByTopicResponse); - return snsClient; - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SqsClientConfigurationTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SqsClientConfigurationTest.java deleted file mode 100644 index 2f55754..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SqsClientConfigurationTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; -import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; -import software.amazon.awssdk.services.sqs.SqsClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class SqsClientConfigurationTest { - - @Test - void sqsClientBeanCreatedWhenStaticCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "aws.accessKey=test", - "aws.secretKey=test", - "submit.message-queue.endpoint=http://directfile.test", - "submit.message-queue.region=us-west-2", - "aws.default-credentials-provider-chain-enabled=false") - .withUserConfiguration(AWSCredentialsConfig.class, SqsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(StaticCredentialsProvider.class); - assertThat(context.getBean(SqsClient.class)).isNotNull(); - }); - } - - @Test - void sqsClientBeanCreatedWhenDefaultCredentialProviderEnabled() { - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withPropertyValues( - "submit.message-queue.endpoint=http://directfile.test", - "submit.message-queue.region=us-west-2", - "aws.default-credentials-provider-chain-enabled=true") - .withUserConfiguration(AWSCredentialsConfig.class, SqsClientConfiguration.class); - applicationContextRunner.run((context) -> { - assertThat(context.getBean(AwsCredentialsProvider.class)).isInstanceOf(DefaultCredentialsProvider.class); - assertThat(context.getBean(SqsClient.class)).isNotNull(); - }); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SynchronousS3TestConfiguration.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SynchronousS3TestConfiguration.java deleted file mode 100644 index 5187e73..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/config/SynchronousS3TestConfiguration.java +++ /dev/null @@ -1,23 +0,0 @@ -package gov.irs.directfile.submit.config; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Primary; - -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -@TestConfiguration -public class SynchronousS3TestConfiguration { - - /** - * Tell Spring to use this fake implementation for the s3 storage service. - * - * - * */ - @Bean - @Primary - ISynchronousDocumentStoreService fakeSynchronousS3StorageService() { - return new FakeSynchronousDocumentStorageService(); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/SubmittedDataContainerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/SubmittedDataContainerTest.java deleted file mode 100644 index e5bd1a3..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/SubmittedDataContainerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.List; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.mef.services.transmitter.mtom.SendSubmissionsResult; - -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -class SubmittedDataContainerTest { - SubmittedDataContainer submittedDataContainer; - - UserContextData userContextData1 = new UserContextData( - "submissionId1", - "userId1", - "b30b08d1-d14d-49c5-b902-ddee26111111", - "userTin1", - TinType.INDIVIDUAL, - "remoteAddress1", - "signDate1"); - UserContextData userContextData2 = new UserContextData( - "submissionId2", - "userId2", - "b30b08d1-d14d-49c5-b902-ddee26222222", - "userTin", - TinType.INDIVIDUAL, - "remoteAddress2", - "signDate2"); - - @Mock - SendSubmissionsResult submissionsResult; - - @Mock - SendSubmissionsResultWrapper sendSubmissionsResultWrapper; - - @Mock - SubmissionReceiptGrpWrapper submissionReceiptGrpWrapper1; - - @Mock - SubmissionReceiptGrpWrapper submissionReceiptGrpWrapper2; - - XMLGregorianCalendar date1 = createXMLGregorianCalendar(); - XMLGregorianCalendar date2 = createXMLGregorianCalendar(); - - @BeforeEach - public void setup() { - List userContexts = List.of(userContextData1, userContextData2); - SubmissionBatch submissionBatch = null; - submittedDataContainer = - new SubmittedDataContainer(userContexts, sendSubmissionsResultWrapper, submissionBatch); - } - - @Test - public void - getTaxReturnIdAndSubmissionIds_givenUserContextData_mapsUserContextDataToListOfTaxReturnIdAndSubmissionId() { - List result = submittedDataContainer.getTaxReturnIdAndSubmissionIds(); - - assertEquals(2, result.size()); - assertEquals(userContextData1.getSubmissionId(), result.get(0).getSubmissionId()); - assertEquals( - userContextData1.getTaxReturnId(), String.valueOf(result.get(0).getTaxReturnId())); - - assertEquals(userContextData2.getSubmissionId(), result.get(1).getSubmissionId()); - assertEquals( - userContextData2.getTaxReturnId(), String.valueOf(result.get(1).getTaxReturnId())); - } - - @Test - public void getTaxReturnIdAndSubmissionIds_givenEmptyUserContextData_returnsEmptyList() { - submittedDataContainer.userContexts = List.of(); - List result = submittedDataContainer.getTaxReturnIdAndSubmissionIds(); - - assertEquals(0, result.size()); - } - - @Test - public void - getTaxReturnSubmissionReceipts_givenSendSubmissionsResultWrapper_mapsUserContextDataToListOfTaxReturnSubmissionReceipt() { - when(submissionReceiptGrpWrapper1.getReceiptId()).thenReturn("receiptId1"); - when(submissionReceiptGrpWrapper1.getSubmissionId()).thenReturn("submissionId1"); - when(submissionReceiptGrpWrapper1.getSubmissionReceivedTs()).thenReturn(date1); - - when(submissionReceiptGrpWrapper2.getReceiptId()).thenReturn("receiptId2"); - when(submissionReceiptGrpWrapper2.getSubmissionId()).thenReturn("submissionId2"); - when(submissionReceiptGrpWrapper2.getSubmissionReceivedTs()).thenReturn(date2); - - when(sendSubmissionsResultWrapper.getReceipts()) - .thenReturn(List.of(submissionReceiptGrpWrapper1, submissionReceiptGrpWrapper2)); - - List result = - submittedDataContainer.getSuccessSubmissionConfirmationPayloadV2Entries(); - - assertEquals(2, result.size()); - - SubmissionConfirmationPayloadV2Entry entry1 = result.getFirst(); - assertEquals("submissionId1", entry1.getTaxReturnSubmissionReceipt().getSubmissionId()); - assertEquals("receiptId1", entry1.getTaxReturnSubmissionReceipt().getReceiptId()); - assertEquals( - userContextData1.getTaxReturnId(), - String.valueOf(entry1.getTaxReturnSubmissionReceipt().getTaxReturnId())); - assertEquals( - date1.toGregorianCalendar().getTime(), - entry1.getTaxReturnSubmissionReceipt().getSubmissionReceivedAt()); - assertEquals(SubmissionEventTypeEnum.SUBMITTED, entry1.getEventType()); - assertTrue(entry1.getMetadata().isEmpty()); - - SubmissionConfirmationPayloadV2Entry entry2 = result.get(1); - assertEquals("submissionId2", entry2.getTaxReturnSubmissionReceipt().getSubmissionId()); - assertEquals("receiptId2", entry2.getTaxReturnSubmissionReceipt().getReceiptId()); - assertEquals( - userContextData2.getTaxReturnId(), - String.valueOf(entry2.getTaxReturnSubmissionReceipt().getTaxReturnId())); - assertEquals( - date2.toGregorianCalendar().getTime(), - entry2.getTaxReturnSubmissionReceipt().getSubmissionReceivedAt()); - assertEquals(SubmissionEventTypeEnum.SUBMITTED, entry2.getEventType()); - assertTrue(entry2.getMetadata().isEmpty()); - } - - @Test - public void getTaxReturnSubmissionReceipts_givenEmptySendSubmissionsResultWrapper_returnsEmptyList() { - when(sendSubmissionsResultWrapper.getReceipts()).thenReturn(List.of()); - List result = - submittedDataContainer.getSuccessSubmissionConfirmationPayloadV2Entries(); - - assertEquals(0, result.size()); - } - - private XMLGregorianCalendar createXMLGregorianCalendar() { - OffsetDateTime date = OffsetDateTime.now(); - // NOTE: ISO_OFFSET_DATE_TIME includes fractional seconds. - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX"); - var lex = date.format(formatter); - return DatatypeFactory.newDefaultInstance().newXMLGregorianCalendar(lex); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/UserSubmissionTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/UserSubmissionTest.java deleted file mode 100644 index 2d02418..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/UserSubmissionTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package gov.irs.directfile.submit.domain; - -import java.util.UUID; - -import org.junit.jupiter.api.Test; - -import gov.irs.directfile.models.Dispatch; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class UserSubmissionTest { - @Test - public void fromDispatch_success() { - Dispatch dispatch = new Dispatch( - UUID.randomUUID(), - UUID.randomUUID(), - "/path/to/manifest", - "/path/to/userContext", - "/path/to/submission", - "123456789"); - - UserSubmission userSubmission = UserSubmission.fromDispatch(dispatch); - - assertEquals(dispatch.getUserId().toString(), userSubmission.userId()); - assertEquals(dispatch.getTaxReturnId().toString(), userSubmission.taxReturnId()); - assertEquals(dispatch.getMefSubmissionId(), userSubmission.submissionId()); - assertEquals(dispatch.getPathToManifest(), userSubmission.manifestXmlPath()); - assertEquals(dispatch.getPathToSubmission(), userSubmission.submissionXmlPath()); - assertEquals(dispatch.getPathToUserContext(), userSubmission.userContextPath()); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilderTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilderTest.java deleted file mode 100644 index 08cd952..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/domain/storagelocations/StorageLocationBuilderTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package gov.irs.directfile.submit.domain.storagelocations; - -import java.util.UUID; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class StorageLocationBuilderTest { - @Test - public void givenTaxFilingYearAndTaxReturnIdAndSubmissionId_whenGetSubmissionLocation_thenShouldSucceed() { - // given - int taxFilingYear = 2020; - UUID taxReturnId = UUID.fromString("738fc2dc-88f9-4b5c-ace9-c602509ba161"); - String submissionId = "78126520231005000008"; - - // when - String actual = StorageLocationBuilder.getSubmissionLocation(taxFilingYear, taxReturnId, submissionId, "xml"); - - // then - assertEquals( - "2020/taxreturns/738fc2dc-88f9-4b5c-ace9-c602509ba161/submissions/78126520231005000008.xml", actual); - } - - @Test - public void givenTaxFilingYearAndTaxReturnId_whenGetSubmissionLocation_thenShouldSucceed() { - // given - int taxFilingYear = 2020; - UUID taxReturnId = UUID.fromString("738fc2dc-88f9-4b5c-ace9-c602509ba161"); - - // when - String actual = StorageLocationBuilder.getSubmissionLocation(taxFilingYear, taxReturnId); - - // then - assertEquals("2020/taxreturns/738fc2dc-88f9-4b5c-ace9-c602509ba161/submissions/", actual); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/extension/LoggerExtension.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/extension/LoggerExtension.java deleted file mode 100644 index c8a1583..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/extension/LoggerExtension.java +++ /dev/null @@ -1,96 +0,0 @@ -package gov.irs.directfile.submit.extension; - -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; -import org.junit.jupiter.api.extension.AfterEachCallback; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.slf4j.LoggerFactory; -import org.slf4j.event.KeyValuePair; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.events.Event; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -public class LoggerExtension implements BeforeEachCallback, AfterEachCallback { - private Logger logger; - private ListAppender appender; - private final String loggerName; - private final Level level; - - public LoggerExtension(Level level, String loggerName) { - this.loggerName = loggerName; - this.level = level; - } - - @Override - public void beforeEach(ExtensionContext context) { - logger = (Logger) LoggerFactory.getLogger(loggerName); - appender = new ListAppender<>(); - appender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); - logger.setLevel(level); - logger.addAppender(appender); - appender.start(); - } - - @Override - public void afterEach(ExtensionContext context) { - logger.detachAppender(appender); - } - - public void verifyLogEvent(Event event) { - verifyLogEvent(event, 0, null); - } - - public void verifyLogEvent(Event event, Map logPropertiesToAssert) { - verifyLogEvent(event, 0, logPropertiesToAssert); - } - - public void verifyLogEvent(Event event, int index) { - verifyLogEvent(event, index, null); - } - - public void verifyLogEvent(Event event, int index, Map logPropertiesToAssert) { - ILoggingEvent loggingEvent = appender.list.get(index); - - List keyValuePairs = loggingEvent.getKeyValuePairs(); - Map mdcPropertyMap = loggingEvent.getMDCPropertyMap(); - - HashMap combinedMap = new HashMap<>(mdcPropertyMap); - ListIterator keyValuePairListIterator = keyValuePairs.listIterator(); - while (keyValuePairListIterator.hasNext()) { - KeyValuePair next = keyValuePairListIterator.next(); - // a collision here causes logback to silently exclude all keyValuePairs from - // json output - assertFalse(combinedMap.containsKey(next.key)); - combinedMap.put(next.key, next.value == null ? null : next.value.toString()); - } - - assertEquals(combinedMap.get(AuditLogElement.cyberOnly.toString()), "true", "cyberOnly not set (XXXX flag)"); - assertEquals(event.getEventStatus().toString(), combinedMap.get(AuditLogElement.eventStatus.toString())); - assertEquals(event.getEventId().toString(), combinedMap.get(AuditLogElement.eventId.toString())); - assertEquals( - event.getEventPrincipal().getUserType().toString(), - combinedMap.get(AuditLogElement.userType.toString())); - assertEquals(event.getEventErrorMessage(), combinedMap.get(AuditLogElement.eventErrorMessage.toString())); - assertEquals(event.getDetail(), combinedMap.get(AuditLogElement.detail.toString())); - - if (logPropertiesToAssert != null) { - for (Map.Entry entry : logPropertiesToAssert.entrySet()) { - assertEquals( - entry.getValue().toString(), - combinedMap.get(entry.getKey().toString())); - } - } - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/FakeSynchronousDocumentStorageService.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/FakeSynchronousDocumentStorageService.java deleted file mode 100644 index 0293603..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/FakeSynchronousDocumentStorageService.java +++ /dev/null @@ -1,153 +0,0 @@ -package gov.irs.directfile.submit.mocks; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.time.Clock; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.*; -import java.util.stream.Collectors; - -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.DocumentStoreResource; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -public class FakeSynchronousDocumentStorageService implements ISynchronousDocumentStoreService { - Map prefixToContent = new HashMap<>(); - Map prefixToUniqueId = new HashMap<>(); - Map prefixToLastModified = new HashMap<>(); - // Get time since the current clock - private final Clock clock; - private final Instant initializationTime = Instant.now(); - - public FakeSynchronousDocumentStorageService() { - this.clock = new MutableTestClock(); - } - - public FakeSynchronousDocumentStorageService(Clock clock) { - this.clock = clock; - } - - @Override - public String write(String objectKey, InputStream payloadStream) throws IOException { - String contentString = - new BufferedReader(new InputStreamReader(payloadStream)).lines().collect(Collectors.joining("\n")); - - prefixToContent.put(objectKey, contentString); - prefixToLastModified.put( - objectKey, Instant.now(clock).plus(millisecondsSinceInitialization(), ChronoUnit.MILLIS)); - - if (!prefixToUniqueId.containsKey(objectKey)) { - String uniqueId = UUID.randomUUID().toString(); - prefixToUniqueId.put(objectKey, uniqueId); - } - return prefixToUniqueId.get(objectKey); - } - - @Override - public String write(String objectKey, String content) { - prefixToContent.put(objectKey, content); - prefixToLastModified.put( - objectKey, Instant.now(clock).plus(millisecondsSinceInitialization(), ChronoUnit.MILLIS)); - - if (!prefixToUniqueId.containsKey(objectKey)) { - String uniqueId = UUID.randomUUID().toString(); - prefixToUniqueId.put(objectKey, uniqueId); - } - return prefixToUniqueId.get(objectKey); - } - - @Override - public Optional getMostRecentFolderForPrefix(String prefix) { - List keysWithPrefix = prefixToContent.keySet().stream() - .filter(key -> key.startsWith(prefix)) - .toList(); - - if (keysWithPrefix.isEmpty()) { - return Optional.empty(); - } else { - String mostRecentlyModifiedObject = keysWithPrefix.stream() - .max(Comparator.comparing(key -> prefixToLastModified.get(key))) - .get(); - int lengthOfBatchNumber = - mostRecentlyModifiedObject.substring(prefix.length()).indexOf("/"); - - return Optional.of(mostRecentlyModifiedObject.substring(0, prefix.length() + lengthOfBatchNumber + 1)); - } - } - - @Override - public List getSubFolders(String objectKey) { - - List result = prefixToContent.keySet().stream() - .filter(key -> key.startsWith(objectKey)) - .map(key -> getNextFolderAfterKey(objectKey, key)) - .distinct() - .collect(Collectors.toList()); - return result; - } - - @Override - public Optional getLeastRecentModifiedResourceForPrefix(String s) { - List result = prefixToContent.keySet().stream() - .filter(key -> key.startsWith(s)) - .toList(); - - return result.stream() - .map(key -> new DocumentStoreResource(key, prefixToUniqueId.get(key), prefixToLastModified.get(key))) - .min(Comparator.comparing(DocumentStoreResource::getLastModified)); - } - - @Override - public String getObjectAsString(String objectKey) throws IOException { - return this.prefixToContent.get(objectKey); - } - - @Override - public List getObjectKeys(String prefix) { - return prefixToContent.keySet().stream() - .filter(key -> key.startsWith(prefix)) - .map(key -> new DocumentStoreResource(key, prefixToUniqueId.get(key), prefixToLastModified.get(key))) - .collect(Collectors.toList()); - } - - @Override - public void Setup(Config config) throws Throwable { - // Does nothing - } - - public void clear() { - prefixToContent.clear(); - prefixToUniqueId.clear(); - prefixToLastModified.clear(); - } - - @Override - public void copyObject(DocumentStoreResource documentStoreResource, String destinationKey) { - String contents = prefixToContent.get(documentStoreResource.getFullLocation()); - write(destinationKey, contents); - } - - @Override - public void deleteObjects(List keys) { - for (String key : keys) { - if (prefixToContent.containsKey(key)) { - prefixToContent.remove(key); - prefixToUniqueId.remove(key); - prefixToLastModified.remove(key); - } - } - } - - private String getNextFolderAfterKey(String prefix, String objectKey) { - int lengthOfBatchNumber = objectKey.substring(prefix.length()).indexOf("/"); - - return objectKey.substring(0, prefix.length() + lengthOfBatchNumber + 1); - } - - private long millisecondsSinceInitialization() { - return Instant.now().toEpochMilli() - initializationTime.toEpochMilli(); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/MutableTestClock.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/MutableTestClock.java deleted file mode 100644 index bd5b63e..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/MutableTestClock.java +++ /dev/null @@ -1,65 +0,0 @@ -package gov.irs.directfile.submit.mocks; - -import java.time.Clock; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.time.temporal.TemporalAmount; - -// Taken from: https://jonasg.io/posts/how-to-effectively-test-time-dependent-code/ -// This class should allow us to easily test moving forward in time for time based operations. -public class MutableTestClock extends Clock { - - private Instant instant; - - private final ZoneId zone; - - public MutableTestClock(Instant instant, ZoneId zone) { - this.instant = instant; - this.zone = zone; - } - - /** - * Default constructor that creates a clock at the current instant in the UTC timezone. - * - * */ - public MutableTestClock() { - this.instant = Instant.now(); - this.zone = ZoneId.of("UTC"); - } - - @Override - public ZoneId getZone() { - return zone; - } - - @Override - public Clock withZone(ZoneId zone) { - return new MutableTestClock(instant, zone); - } - - @Override - public Instant instant() { - return instant; - } - - public void fastForward(TemporalAmount temporalAmount) { - set(instant().plus(temporalAmount)); - } - - public void rewind(TemporalAmount temporalAmount) { - set(instant().minus(temporalAmount)); - } - - public void set(Instant instant) { - this.instant = instant; - } - - public static MutableTestClock fixed(Instant instant, ZoneId zone) { - return new MutableTestClock(instant, zone); - } - - public static MutableTestClock fixed(OffsetDateTime offsetDateTime) { - return fixed(offsetDateTime.toInstant(), offsetDateTime.getOffset()); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingBundleSubmissionActionHandler.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingBundleSubmissionActionHandler.java deleted file mode 100644 index 0173c8b..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingBundleSubmissionActionHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -package gov.irs.directfile.submit.mocks; - -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; -import gov.irs.directfile.submit.command.SubmitBundleAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.SubmittedDataContainer; -import gov.irs.directfile.submit.service.interfaces.IBundleSubmissionActionHandler; - -public class ThrowingBundleSubmissionActionHandler implements IBundleSubmissionActionHandler { - private boolean loginEnabled = true; - private boolean logoutEnabled = true; - - @Override - public boolean login() { - return loginEnabled; - } - - @Override - public boolean logout() { - return logoutEnabled; - } - - @Override - public SubmittedDataContainer submitBundles(BundledArchives bundledArchives, SubmissionBatch submissionBatch) - throws SubmissionFailureException { - throw new SubmissionFailureException(submissionBatch, bundledArchives, new RuntimeException("Can't submit")); - } - - @Override - public SubmittedDataContainer handleCommand(SubmitBundleAction command) throws SubmissionFailureException { - return this.submitBundles( - command.getBundleArchivesActionResult().getBundledArchives(), - command.getBundleArchivesActionResult().getBatch()); - } - - @Override - public void Setup(Config config) throws Throwable {} - - public void enableLogin() { - this.loginEnabled = true; - } - - public void disableLogin() { - this.logoutEnabled = false; - } - - public void enableLogout() { - this.logoutEnabled = true; - } - - public void disableLogout() { - this.logoutEnabled = false; - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingInformerException.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingInformerException.java deleted file mode 100644 index 28f0568..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/mocks/ThrowingInformerException.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.irs.directfile.submit.mocks; - -public class ThrowingInformerException extends Exception { - public ThrowingInformerException(String message) { - super(message); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ActionHandlerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ActionHandlerTest.java deleted file mode 100644 index f1597a4..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ActionHandlerTest.java +++ /dev/null @@ -1,588 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.*; - -import lombok.SneakyThrows; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; - -import gov.irs.a2a.mef.mefheader.TestCdType; -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.inputcomposition.PostmarkedSubmissionArchive; -import gov.irs.mef.inputcomposition.SubmissionBuilder; -import gov.irs.mef.services.ServiceContext; - -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.submit.Runner; -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.actions.BundleArchivesActionHandler; -import gov.irs.directfile.submit.actions.CleanupActionHandler; -import gov.irs.directfile.submit.actions.CreateArchiveActionHandler; -import gov.irs.directfile.submit.actions.exception.SubmissionFailureException; -import gov.irs.directfile.submit.actions.results.BundleArchivesActionResult; -import gov.irs.directfile.submit.actions.results.CreateArchiveActionResult; -import gov.irs.directfile.submit.command.ActionType; -import gov.irs.directfile.submit.command.BundleArchiveAction; -import gov.irs.directfile.submit.command.SubmitBundleAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DirectoriesConfig; -import gov.irs.directfile.submit.domain.*; -import gov.irs.directfile.submit.domain.model.PodIdentifier; -import gov.irs.directfile.submit.exception.LoginFailureException; -import gov.irs.directfile.submit.exception.LogoutFailureException; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; -import gov.irs.directfile.submit.repository.PodIdentifierRepository; -import gov.irs.directfile.submit.service.interfaces.IBundleSubmissionActionHandler; -import gov.irs.directfile.submit.service.interfaces.ISynchronousDocumentStoreService; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; - -@DataJpaTest -@ExtendWith(MockitoExtension.class) -public class ActionHandlerTest { - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - private Runner runner; - private String softwareId = "12345678"; - private String softwareVersionNum = "2023.0.1"; - - private static final String applicationId = "ApplicationId"; - - private ActionHandler actionHandler; - private ActionQueue actions = new ActionQueue(); - private Set inProgressBatches = new HashSet<>(); - private final Set inProgressSubmissions = new HashSet<>(); - - @Mock - private SqsConnectionSetupService sqsConnectionSetupService; - - @Mock - private SubmissionConfirmationMessageService submissionConfirmationMessageService; - - @Mock - private IBundleSubmissionActionHandler bundleSubmissionService; - - @Autowired - PodIdentifierRepository podIdentifierRepository; - - private OfflineModeService offlineModeService; - - private ISynchronousDocumentStoreService synchronousDocumentStoreService; - - @BeforeEach - public void setup() { - synchronousDocumentStoreService = new FakeSynchronousDocumentStorageService(); - ActionContext actionContext = new ActionContext(createConfig()); - offlineModeService = new OfflineModeService(); - actionHandler = new ActionHandler( - sqsConnectionSetupService, - submissionConfirmationMessageService, - actions, - actionContext, - bundleSubmissionService, - offlineModeService, - inProgressSubmissions, - new BundleArchivesActionHandler(actionContext), - new CleanupActionHandler(actionContext, synchronousDocumentStoreService), - new CreateArchiveActionHandler(actionContext, synchronousDocumentStoreService), - new DocumentStorageSubmissionFailureService( - synchronousDocumentStoreService, applicationId, new MutableTestClock()), - podIdentifierRepository); - runner = new Runner(actions, actionHandler, offlineModeService); - } - - @Test - public void itAddsSubmissionFailureActionToQueueWhenFailedSubmissionBatchHasMultipleSubmissions() throws Exception { - - // Arrange: Create a SubmitBundleAction, - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UserContextData userContextData = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - - UserContextData userContextData2 = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextData, userContextData2), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleAction = new SubmitBundleAction(bundleArchivesActionResult); - - when(bundleSubmissionService.handleCommand(any())) - .thenThrow(new SubmissionFailureException(batch, bundledArchives, new RuntimeException())); - // Act: Call handleAction(submitBundleAction) - actionHandler.handleAction(submitBundleAction); - - // Assert: Expect a SubmissionFailureAction was added to the queue - assertEquals(1, actions.getInProgressActions().size()); - assertEquals( - ActionType.SUBMISSION_FAILURE, - actions.getInProgressActions().peek().getType()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, never()).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itDoesNotRetryBatchWhenOnlySubmissionInABatch() throws Exception { - // Arrange: Create a SubmitBundleAction, only add one submission for the batch - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UUID taxReturnId = UUID.randomUUID(); - String submissionId = "submissionId"; - UserContextData userContextData = new UserContextData( - submissionId, "userId", taxReturnId.toString(), "userTin", TinType.INDIVIDUAL, "0.0.0", "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextData), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleAction = new SubmitBundleAction(bundleArchivesActionResult); - when(bundleSubmissionService.handleCommand(any())) - .thenThrow(new SubmissionFailureException(batch, bundledArchives, new RuntimeException())); - - // Act: Call handleAction(submitBundleAction) - actionHandler.handleAction(submitBundleAction); - // A cleanup action is added to the queue after submit bundle. Call handleAction() to cleanup the batch - actionHandler.handleAction(actions.getInProgressActions().take()); - - // Assert: Expect a SubmissionFailureAction was not added to the queue - assertEquals(0, actions.getInProgressActions().size()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, times(1)).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itEnablesOfflineModeWhenLoginFails() throws Exception { - // Arrange: Create a SubmitBundleAction, only add one submission for the batch - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UserContextData userContextData = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextData), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleAction = new SubmitBundleAction(bundleArchivesActionResult); - when(bundleSubmissionService.login()).thenThrow(new LoginFailureException("Login Failure")); - when(bundleSubmissionService.logout()).thenThrow(new LogoutFailureException("Logout Failure")); - // Act: Call handleAction(submitBundleAction) - actionHandler.handleAction(submitBundleAction); - - // Assert: Expect a OfflineMode to be enabled due to login failure - assertTrue(offlineModeService.isOfflineModeEnabled()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, never()).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itEnablesOfflineModeWhenLogoutFails() throws Exception { - // Arrange: Create a SubmitBundleAction, only add one submission for the batch - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UserContextData userContextData = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextData), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleActionCommand = new SubmitBundleAction(bundleArchivesActionResult); - when(bundleSubmissionService.logout()).thenThrow(new LogoutFailureException("Logout Failure")); - SendSubmissionsResultWrapper sendSubmissionsResultWrapper = null; - when(bundleSubmissionService.handleCommand(any())) - .thenReturn( - new SubmittedDataContainer(bundledArchives.UserContexts, sendSubmissionsResultWrapper, batch)); - // Act: Call handleAction(submitBundleAction) - actionHandler.handleAction(submitBundleActionCommand); - - // Assert: Expect a OfflineMode to be enabled due to login failure - assertTrue(offlineModeService.isOfflineModeEnabled()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, never()).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itEnablesOfflineModeWhenSubmissionFailsAndMefIsOffline() throws Exception { - // Arrange: Create a SubmitBundleAction, only add one submission for the batch - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UserContextData userContextData = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextData), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleActionCommand = new SubmitBundleAction(bundleArchivesActionResult); - // Throw Submission Failure Exception when we call submitBundle() - when(bundleSubmissionService.handleCommand(any())) - .thenThrow(new SubmissionFailureException( - batch, bundledArchives, new RuntimeException("Submission Failed"))); - when(bundleSubmissionService.logout()).thenThrow(LogoutFailureException.class); - - // Act: - actionHandler.handleAction(submitBundleActionCommand); - - // Assert: Expect a OfflineMode to be enabled due to login failure - assertTrue(offlineModeService.isOfflineModeEnabled()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, never()).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itRetriesFailedSubmissionWhenSubmissionFailsAndMefIsOnline() throws Exception { - // Arrange: Create a SubmitBundleAction with two submissions - SubmissionBatch batch = new SubmissionBatch(0L, "env/batches/0"); - UserContextData userContextDataA = new UserContextData( - "submissionId", - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - UserContextData userContextDataB = new UserContextData( - "B-submissionId", - "B-userId", - UUID.randomUUID().toString(), - "B-userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - BundledArchives bundledArchives = new BundledArchives(List.of(userContextDataA, userContextDataB), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleActionCommand = new SubmitBundleAction(bundleArchivesActionResult); - - // Throw Submission Failure Exception when we call submit bundles - when(bundleSubmissionService.handleCommand(any())) - .thenThrow(new SubmissionFailureException( - batch, bundledArchives, new RuntimeException("Submission Failed"))); - // Return true when attempting to log out. Indicating Mef is online - when(bundleSubmissionService.login()).thenReturn(true); - when(bundleSubmissionService.logout()).thenReturn(true); - - // Act: - actionHandler.handleAction(submitBundleActionCommand); - - // Assert: Expect a OfflineMode is not enable because MeF is online - assertFalse(offlineModeService.isOfflineModeEnabled()); - - // Expect a SubmissionFailureAction was added to the queue to process the failed submissions - assertEquals( - ActionType.SUBMISSION_FAILURE, - actions.getInProgressActions().peek().getType()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, never()).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - public void itSendsFailureMessageToSubmissionConfirmationQueueContaingInfoForAllTaxReturnsInTheBatch() - throws Exception { - // Arrange: Create a SubmitBundleAction with two submissions - final UserContextData userContextData1 = new UserContextData( - "00000", - "00000000-0000-0000-0000-000000000000", - "11111111-1111-1111-1111-111111111111", - "111001111", - TinType.INDIVIDUAL, - "0.0.0.0", - "2024-01-01"); - final UserContextData userContextData2 = new UserContextData( - "11111", - "88888888-8888-8888-8888-888888888888", - "99999999-9999-9999-9999-999999999999", - "111002222", - TinType.INDIVIDUAL, - "1.1.1.1", - "2024-01-01"); - final PostmarkedSubmissionArchive mockSubmissionArchive1 = mock(PostmarkedSubmissionArchive.class); - final PostmarkedSubmissionArchive mockSubmissionArchive2 = mock(PostmarkedSubmissionArchive.class); - - final List submissionArchiveContainers = List.of( - new SubmissionArchiveContainer(userContextData1, mockSubmissionArchive1), - new SubmissionArchiveContainer(userContextData2, mockSubmissionArchive2)); - - CreateArchiveActionResult createArchiveActionResult = - new CreateArchiveActionResult(new SubmissionBatch(0L, ""), submissionArchiveContainers); - - BundleArchiveAction bundleArchiveActionCommand = new BundleArchiveAction(createArchiveActionResult); - - try (MockedStatic mockSubmissionBuilder = Mockito.mockStatic(SubmissionBuilder.class)) { - mockSubmissionBuilder - .when(() -> SubmissionBuilder.createSubmissionContainer( - any(PostmarkedSubmissionArchive[].class), anyString())) - .thenThrow(new ToolkitException("test")); - - // Act: - actionHandler.handleAction(bundleArchiveActionCommand); - - // Assert - ArgumentCaptor> argumentCaptor = - ArgumentCaptor.forClass(List.class); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()) - .sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, times(1)) - .publishSubmissionConfirmationPayloadV2(argumentCaptor.capture()); - - assertEquals( - userContextData1.getTaxReturnId(), - argumentCaptor - .getValue() - .get(0) - .getTaxReturnSubmissionReceipt() - .getTaxReturnId() - .toString()); - assertEquals( - userContextData1.getSubmissionId(), - argumentCaptor - .getValue() - .get(0) - .getTaxReturnSubmissionReceipt() - .getSubmissionId()); - - assertEquals( - userContextData2.getTaxReturnId(), - argumentCaptor - .getValue() - .get(1) - .getTaxReturnSubmissionReceipt() - .getTaxReturnId() - .toString()); - assertEquals( - userContextData2.getSubmissionId(), - argumentCaptor - .getValue() - .get(1) - .getTaxReturnSubmissionReceipt() - .getSubmissionId()); - } - } - - @Test - @SneakyThrows - public void itCleansUpFileSystemForSubmissionFailureOfSingleSubmission() { - // Arrange: Create a batch, user object, and add manifest.xml, userContext.json, submission.xml to document - // storage - long batchId = 0L; - Long batchSubmissionNumber = 5L; - String submissionId = "submissionId"; - String errorBatchPath = String.format( - "pre-submission-batching/errors/dfsys-mef-submit-deployment-0-us-gov-east-1/2023/%s/%s/%s", - batchId, batchSubmissionNumber, submissionId); - SubmissionBatch batch = new SubmissionBatch(batchId, errorBatchPath); - UserContextData userContextDataA = new UserContextData( - submissionId, - "userId", - UUID.randomUUID().toString(), - "userTin", - TinType.INDIVIDUAL, - "0.0.0", - "2024-01-01"); - - String manifestXmlKey = errorBatchPath + "/manifest.xml"; - String userContextJsonKey = errorBatchPath + "/userContext.json"; - String submissionXmlKey = errorBatchPath + "/submission.xml"; - synchronousDocumentStoreService.write(manifestXmlKey, "My Tax Return Manifest "); - synchronousDocumentStoreService.write(userContextJsonKey, "{}"); - synchronousDocumentStoreService.write(submissionXmlKey, "My Tax Return Submission "); - // Expect document storage to have 3 files at the errorBatchPath. The 3 files we just added via - // synchronousDocumentStoreService.write() - assertEquals( - 3, synchronousDocumentStoreService.getObjectKeys(errorBatchPath).size()); - - // Arrange Part 2: Set up the bundleSubmissionService to throw an exception - BundledArchives bundledArchives = new BundledArchives(List.of(userContextDataA), null); - BundleArchivesActionResult bundleArchivesActionResult = - new BundleArchivesActionResult(new SubmissionBatch(0L, ""), bundledArchives); - - SubmitBundleAction submitBundleActionCommand = new SubmitBundleAction(bundleArchivesActionResult); - - // Throw Submission Failure Exception when we call submit bundles - when(bundleSubmissionService.handleCommand(any())) - .thenThrow(new SubmissionFailureException( - batch, bundledArchives, new RuntimeException("Submission Failed"))); - // Return true when attempting to log out. Indicating Mef is online - when(bundleSubmissionService.login()).thenReturn(true); - when(bundleSubmissionService.logout()).thenReturn(true); - - // Act: Call SubmitBundle via the ActionHandler and throw error when calling SubmitBundler - actionHandler.handleAction(submitBundleActionCommand); - // Call handleAction again to run the cleanup action that's in the queue - actionHandler.handleAction(actions.getInProgressActions().take()); - // Assert: Expect document storage is empty for files at the path of the error batch, because we clean up - // filesystem for failed submissions - assertEquals( - 0, synchronousDocumentStoreService.getObjectKeys(errorBatchPath).size()); - - // Verify calls to message queues/topics - verify(sqsConnectionSetupService, never()).sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(any()); - verify(submissionConfirmationMessageService, times(1)).publishSubmissionConfirmationPayloadV2(any()); - } - - @Test - void whenUpdateAsid_WithPodIdentifiers_ThenReturnsAsidFromDatabase_ThenCreatesCorrectServiceContext() { - Config config = createConfig(); - PodIdentifier p = createPodIdentifer("us-gov-east-1", config.getAsid(), 0); - podIdentifierRepository.save(p); - - String asid = podIdentifierRepository.findAsidByPodId(p.getPodId()).get(); - - actionHandler.updateAsid(config); - ServiceContext serviceContext = actionHandler.context.getServiceContext(); - Config updatedConfig = actionHandler.context.getConfig(); - assertNotNull(serviceContext); - assertNotNull(updatedConfig); - assertEquals(serviceContext.getAppSysID(), config.getAsid()); - assertEquals(serviceContext.getAppSysID(), asid); - assertEquals(serviceContext.getEtin().toString(), config.getEtin()); - assertEquals(serviceContext.getTestCdType(), TestCdType.T); - - assertEquals(updatedConfig.getAsid(), asid); - } - - @Test - void whenUpdateAsid_WithNoPodIdentifiers_ThenReturnsDefaultAsid_ThenCreatesCorrectServiceContext() { - Config config = createConfig(); - - Optional nonExistentAsid = podIdentifierRepository.findAsidByPodId(config.getApplicationId()); - assertTrue(nonExistentAsid.isEmpty()); - - actionHandler.updateAsid(config); - ServiceContext serviceContext = actionHandler.context.getServiceContext(); - Config updatedConfig = actionHandler.context.getConfig(); - assertNotNull(serviceContext); - assertNotNull(updatedConfig); - assertEquals(serviceContext.getAppSysID(), config.getAsid()); - assertEquals(serviceContext.getEtin().toString(), config.getEtin()); - assertEquals(serviceContext.getTestCdType(), TestCdType.T); - } - - @Test - void whenUpdateAsid_WithMultiplePodIdentifiers_ThenReturnsCorrectAsid_ThenCreatesCorrectServiceContext() { - Config config = createConfig(); - String ASID = "asid1235"; - - PodIdentifier p1 = createPodIdentifer("us-gov-east-1", ASID, 2); - PodIdentifier p2 = createPodIdentifer("us-gov-east-1", ASID + "2", 1); - PodIdentifier p3 = createPodIdentifer("us-gov-east-1", config.getAsid(), 0); - podIdentifierRepository.save(p1); - podIdentifierRepository.save(p2); - podIdentifierRepository.save(p3); - - String correctAsid = - podIdentifierRepository.findAsidByPodId(p3.getPodId()).get(); - actionHandler.updateAsid(config); - ServiceContext serviceContext = actionHandler.context.getServiceContext(); - Config updatedConfig = actionHandler.context.getConfig(); - - assertNotNull(serviceContext); - assertNotNull(updatedConfig); - assertEquals(serviceContext.getAppSysID(), config.getAsid()); - assertEquals(serviceContext.getAppSysID(), correctAsid); - assertEquals(serviceContext.getEtin().toString(), config.getEtin()); - assertEquals(serviceContext.getTestCdType(), TestCdType.T); - - assertEquals(updatedConfig.getAsid(), correctAsid); - } - - private PodIdentifier createPodIdentifer(String region, String asid, int index) { - PodIdentifier p = new PodIdentifier(); - p.setAsid(asid); - p.setRegion(region); - p.setPodId("dfsys-mef-status-deployment-" + String.valueOf(index) + "-" + region); - return p; - } - - private Config createConfig() { - boolean runnerDisabledForTesting = false; - DirectoriesConfig directoriesConfig = new DirectoriesConfig( - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test"); - return new Config( - "Test", - null, - null, - directoriesConfig, - null, - null, - "12345", - "12345", - "12345", - "", - runnerDisabledForTesting, - true, - true, - "12345", - softwareId, - softwareVersionNum, - "dfsys-mef-submit-deployment-0-us-gov-east-1"); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DispatchMessageRouterTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DispatchMessageRouterTest.java deleted file mode 100644 index bf2994d..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DispatchMessageRouterTest.java +++ /dev/null @@ -1,79 +0,0 @@ -package gov.irs.directfile.submit.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.Dispatch; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.dispatch.DispatchMessageVersion; -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; -import gov.irs.directfile.models.message.dispatch.payload.DispatchPayloadV1; -import gov.irs.directfile.models.message.exception.UnsupportedVersionException; -import gov.irs.directfile.submit.service.handlers.dispatch.DispatchV1Handler; -import gov.irs.directfile.submit.service.handlers.dispatch.UnsupportedMessageVersionHandler; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -public class DispatchMessageRouterTest { - - @Mock - public DispatchV1Handler dispatchV1Handler; - - @Mock - public UnsupportedMessageVersionHandler unsupportedMessageVersionHandler; - - private DispatchMessageRouter dispatchMessageRouter; - - @BeforeEach - public void setup() { - dispatchMessageRouter = new DispatchMessageRouter(unsupportedMessageVersionHandler, dispatchV1Handler); - } - - @Test - public void itGetsHandlerWhenProvidedAValidDispatchMessageVersion() { - // Arrange: Create a VersionedDispatchMessage, with a header specifying V1 - AbstractDispatchPayload payload = new DispatchPayloadV1(new Dispatch()); - VersionedDispatchMessage queueMessage = new VersionedDispatchMessage<>( - payload, - new QueueMessageHeaders() - .addHeader(MessageHeaderAttribute.VERSION, DispatchMessageVersion.V1.getVersion())); - - // Act: Call handleDispatchMessage() - assertDoesNotThrow(() -> { - dispatchMessageRouter.handleDispatchMessage(queueMessage); - - // Assert: Expect that an exception was not thrown, and that the - // DispatchV1Handler.handleDispatchMessage() was called - verify(dispatchV1Handler, times(1)).handleDispatchMessage(any()); - }); - } - - @Test - public void itHandlesUnsupportedVersions() { - // Arrange: Create a VersionedDispatchMessage, with a header specifying an unsupported version - AbstractDispatchPayload payload = new DispatchPayloadV1(new Dispatch()); - String unsupportedVersion = "9.0.EGG"; - - VersionedDispatchMessage messageWithUnsupportedVersion = - new VersionedDispatchMessage<>( - payload, - new QueueMessageHeaders().addHeader(MessageHeaderAttribute.VERSION, unsupportedVersion)); - - // Act: call handleDispatchMessage() - assertThrows(UnsupportedVersionException.class, () -> { - dispatchMessageRouter.handleDispatchMessage(messageWithUnsupportedVersion); - - // Assert: Check that we called the UnsupportedVersionHandler - verify(unsupportedMessageVersionHandler, times(1)).handleDispatchMessage(any()); - }); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageBatchRepositoryTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageBatchRepositoryTest.java deleted file mode 100644 index 60979b3..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageBatchRepositoryTest.java +++ /dev/null @@ -1,349 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.*; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.mef.inputcomposition.BinaryAttachment; -import gov.irs.mef.inputcomposition.SubmissionManifest; -import gov.irs.mef.inputcomposition.SubmissionXML; - -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.submit.BatchingProperties; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.SubmissionData; -import gov.irs.directfile.submit.domain.UserContextData; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; -import gov.irs.directfile.submit.repository.DocumentStorageBatchRepository; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class DocumentStorageBatchRepositoryTest { - private static final int MAX_BATCH_SIZE = 5; - private static final long BATCH_TIMEOUT_MILLISECONDS = 10; - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - private static final String APPLICATION_ID = "application-id-123"; - private DocumentStorageBatchRepository subject; - private BatchingProperties batchingProperties = BatchingProperties.builder() - .maxBatchSize(MAX_BATCH_SIZE) - .batchTimeoutMilliseconds(10_000) // 10 seconds - .build(); - - private MutableTestClock testClock; - - private FakeSynchronousDocumentStorageService documentStorageService; - - @BeforeEach - public void setup() { - // 1. Initialize services that need to be registered by the services container - var date = LocalDateTime.of(2050, 11, 5, 14, 1); - - var instant = date.toInstant(ZoneOffset.UTC); - testClock = new MutableTestClock(instant, ZoneId.of("UTC")); - documentStorageService = new FakeSynchronousDocumentStorageService(testClock); - subject = new DocumentStorageBatchRepository( - documentStorageService, APPLICATION_ID, batchingProperties, testClock); - } - - @AfterEach - public void teardown() { - documentStorageService.clear(); - } - - @Test - public void itReturnsZeroBatchIdWhenNoBatchesExist() { - // Arrange: Do nothing - no batches written - - // Act: Call get current writing batch - Long submissionBatchId = subject.getCurrentWritingBatch(APPLICATION_ID); - - // Assert: Expect the batch id to be 0 - assertEquals(0L, submissionBatchId); - - // Path /pre-submission-batching/taxYear/batchId - int bactchControlYear = getBatchControlYear(); - String expectedPath = String.format( - "pre-submission-batching/%s/%s/%s/", APPLICATION_ID, bactchControlYear, submissionBatchId); - - assertEquals( - expectedPath, - DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, submissionBatchId, getBatchControlYear())); - } - - @Test - public void itReturnsHighestBatchPlusOneWhenCurrentBatchTimeoutHasExpired() throws Exception { - // Arrange: Add data to document store for a batch - long previousBatchId = 100L; - int batchControlYear = getBatchControlYear(); - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, previousBatchId); - SubmissionBatch b = new SubmissionBatch(previousBatchId, submissionBatchObjectKey); - - SubmissionData fakeSubmissionData = mockSubmissionData(); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - subject.addSubmission( - b, new UserSubmission("userId", "taxReturnId", "123456", "/manifest", "/submission", "/userContext")); - - // Act: Update the clock to move forward by batchTimeout milliseconds and 1 second. Call get - // current batch - testClock.fastForward(Duration.of(batchingProperties.getBatchTimeoutMilliseconds() + 1000, ChronoUnit.MILLIS)); - Long currentBatchId = subject.getCurrentWritingBatch(APPLICATION_ID); - - // Assert: Expect the current batch will be 1 + current highest batch number - assertEquals(previousBatchId + 1, currentBatchId); - String expectedPath = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, currentBatchId); - assertEquals( - expectedPath, - DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, currentBatchId, getBatchControlYear())); - } - - @Test - public void itReturnsCurrentBatchWhenTimeoutHasNotExpired() throws Exception { - // Arrange: Add data to document store for a batch - long previousBatchId = 100L; - int batchControlYear = getBatchControlYear(); - String originalSubmissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, previousBatchId); - SubmissionBatch b = new SubmissionBatch(previousBatchId, originalSubmissionBatchObjectKey); - - SubmissionData fakeSubmissionData = mockSubmissionData(); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - subject.addSubmission( - b, new UserSubmission("userId", "taxReturnId", "123456", "/manifest", "/submission", "/userContext")); - - // Act: Update the clock to move forward by batchTimeout milliseconds minus 1 second. Call get - // current batch - testClock.fastForward(Duration.of(batchingProperties.getBatchTimeoutMilliseconds() - 1000, ChronoUnit.MILLIS)); - Long currentBatch = subject.getCurrentWritingBatch(APPLICATION_ID); - - // Assert: Expect the current batch will be previousBatchID because it's still within the same time window - assertEquals(previousBatchId, currentBatch.longValue()); - assertEquals( - originalSubmissionBatchObjectKey, - DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, currentBatch, getBatchControlYear())); - } - - @Test - public void itReturnsCurrentBatchWhenTimeoutIsReached() throws Exception { - // Arrange: Add data to document store for a batch - long previousBatchId = 100L; - int batchControlYear = getBatchControlYear(); - String originalSubmissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, previousBatchId); - SubmissionBatch b = new SubmissionBatch(previousBatchId, originalSubmissionBatchObjectKey); - - SubmissionData fakeSubmissionData = mockSubmissionData(); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - subject.addSubmission( - b, new UserSubmission("userId", "taxReturnId", "123456", "/manifest", "/submission", "/userContext")); - // Act: Update the clock to move forward by exactly batchTimeout milliseconds minus one millisecond. Call get - // current batch - testClock.fastForward(Duration.of(batchingProperties.getBatchTimeoutMilliseconds(), ChronoUnit.MILLIS)); - Long currentBatch = subject.getCurrentWritingBatch(APPLICATION_ID); - - // Assert: Expect the current batch will be previousBatchID because it's still within the same time window - assertEquals(previousBatchId, currentBatch); - assertEquals( - originalSubmissionBatchObjectKey, - DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, currentBatch, getBatchControlYear())); - } - - @Test - public void itReturnsEmptyOptionalWhenNoBatchFoundForBatchId() { - // Arrange: N/A - - // Act: Try to retrieve a batch, when no batches exist in the repository - Optional submissionBatchOptional = subject.getSubmissionBatch(APPLICATION_ID, 100L); - assertTrue(submissionBatchOptional.isEmpty()); - } - - @Test - public void itReturnsSubmissionBatchIfOneExists() throws Exception { - // Arrange: Add data to document store for a batch - long batchId = 100L; - int batchControlYear = getBatchControlYear(); - String originalSubmissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - SubmissionBatch b = new SubmissionBatch(batchId, originalSubmissionBatchObjectKey); - SubmissionData fakeSubmissionData = mockSubmissionData(); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - subject.addSubmission( - b, new UserSubmission("userId", "taxReturnId", "123456", "/manifest", "/submission", "/userContext")); - // Act: Call getSubmissionBatch - Optional submissionBatchOptional = subject.getSubmissionBatch(APPLICATION_ID, batchId); - - assertTrue(submissionBatchOptional.isPresent()); - SubmissionBatch batch = submissionBatchOptional.get(); - assertEquals(batchId, batch.batchId()); - assertEquals(originalSubmissionBatchObjectKey, batch.path()); - } - - @Test - public void itReturnsCurrentBatchIdPlusOneWhenMaxBatchSizeIsReached() throws Exception { - // Arrange: Create a batch, and add MAX_BATCH_SIZE submissions to the batch - Instant now = Instant.now(); - testClock.set(now); - - long batchId = 100L; - int batchControlYear = getBatchControlYear(); - String originalSubmissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - SubmissionBatch b = new SubmissionBatch(batchId, originalSubmissionBatchObjectKey); - - for (int i = 0; i < MAX_BATCH_SIZE; i++) { - String submissionId = UUID.randomUUID().toString(); - SubmissionData fakeSubmissionData = mockSubmissionData(submissionId); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - subject.addSubmission( - b, - new UserSubmission( - "userId", "taxReturnId", submissionId, "/manifest", "/submission", "/userContext")); - } - - // Act: Call getCurrentWritingBatch - Long submissionBatch = subject.getCurrentWritingBatch(APPLICATION_ID); - // Expect the batch id of the current writing batch is batchId + 1 because there are more than MAX_BATCH_SiZE - // submissions in the current batch - assertEquals(batchId + 1, submissionBatch); - } - - private SubmissionData mockSubmissionData() { - return mockSubmissionData("submissionId"); - } - - private SubmissionData mockSubmissionData(String submissionId) { - String userId = "UserId"; - String taxReturnId = "taxReturnId"; - String userTin = "userTin"; - TinType userTinType = TinType.INDIVIDUAL; - String remoteAddress = "0.0.0.0"; - String signDate = "2024-01-01"; - UserContextData userContextData = - new UserContextData(submissionId, userId, taxReturnId, userTin, userTinType, remoteAddress, signDate); - - int taxYear = getBatchControlYear(); - String manifestXmlString = "" + "" + taxYear + ""; - SubmissionManifest submissionManifest = mock(SubmissionManifest.class); - when(submissionManifest.getXmlData()).thenReturn(manifestXmlString); - - String submissionXMLString = "" + "" + taxYear + "" + ""; - SubmissionXML submissionXML = mock(SubmissionXML.class); - when(submissionXML.getXmlData()).thenReturn(submissionXMLString); - BinaryAttachment[] binaryAttachments = new BinaryAttachment[] {}; - return new SubmissionData(userContextData, submissionManifest, submissionXML, binaryAttachments); - } - - @Test - public void getUnprocessedBatches_filtersOutCurrentBatchFromResult() throws Exception { - long currentBatch = 101L; - long previousBatch = 100L; - int batchControlYear = getBatchControlYear(); - String currentSubmissionBatchKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, currentBatch); - String previousSubmissionBatchKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, previousBatch); - SubmissionBatch currentSubmissionBatch = new SubmissionBatch(currentBatch, currentSubmissionBatchKey); - SubmissionBatch previousSubmissionBatch = new SubmissionBatch(previousBatch, previousSubmissionBatchKey); - - SubmissionData fakeSubmissionData = mockSubmissionData(); - - // 2/6/2024: replaced the call to generate with pre-written data - documentStorageService.write("/manifest", fakeSubmissionData.Manifest.getXmlData()); - documentStorageService.write("/submission", fakeSubmissionData.Xml.getXmlData()); - documentStorageService.write("/userContext", fakeSubmissionData.UserContext.toString()); - - String submissionId = "123457abc"; - subject.addSubmission( - previousSubmissionBatch, - new UserSubmission("userId", "taxReturnId", submissionId, "/manifest", "/submission", "/userContext")); - - // Move clock forward to simulate time passing between each batch because the testClock uses fixed time. - testClock.fastForward(Duration.of(batchingProperties.getBatchTimeoutMilliseconds() + 1000, ChronoUnit.MILLIS)); - subject.addSubmission( - currentSubmissionBatch, - new UserSubmission("userId", "taxReturnId", submissionId, "/manifest", "/submission", "/userContext")); - - // Verify we identify the old batch that needs to be processed - List result = subject.getUnprocessedBatches(APPLICATION_ID); - assertEquals(1, result.size()); - assertEquals(100L, result.get(0).batchId()); - assertEquals( - DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, previousBatch, getBatchControlYear()), - result.get(0).path()); - - // Verify that the batch has one submission, and the path matches what we expect - List submissionsForOldBatch = - documentStorageService.getSubFolders(DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, previousBatch, getBatchControlYear())); - assertEquals(1, submissionsForOldBatch.size()); - - String expectedPathForSubmission = DocumentStorageBatchRepository.generateLocationForBatch( - APPLICATION_ID, previousBatch, getBatchControlYear()) - + submissionId + "/"; - assertEquals(expectedPathForSubmission, submissionsForOldBatch.get(0)); - } - - @Test - public void getUnprocessedBatches_givenNoSubFolders_returnsEmptyList() throws Exception { - List result = subject.getUnprocessedBatches(APPLICATION_ID); - assertEquals(0, result.size()); - } - - private int getBatchControlYear() { - return Year.now(testClock).getValue() - 1; - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureServiceTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureServiceTest.java deleted file mode 100644 index 2e14de3..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/DocumentStorageSubmissionFailureServiceTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Clock; -import java.time.Year; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@ExtendWith(MockitoExtension.class) -public class DocumentStorageSubmissionFailureServiceTest { - private static final String APPLICATION_ID = "APPLICATION_ID"; - private static final Clock clock = new MutableTestClock(); - DocumentStorageSubmissionFailureService subject; - FakeSynchronousDocumentStorageService fakeSynchronousDocumentStorageService = - new FakeSynchronousDocumentStorageService(); - - @BeforeEach - public void setup() { - subject = new DocumentStorageSubmissionFailureService( - fakeSynchronousDocumentStorageService, APPLICATION_ID, clock); - } - - @AfterEach - public void teardown() { - fakeSynchronousDocumentStorageService.clear(); - } - - @Test - public void itWritesSubmissionFilesToCorrectDocumentStoragePath() throws Exception { - int batchControlYear = Year.now(clock).getValue() - 1; - long batchId = 10L; - String submissionId = "subId-ABC"; - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - - addFakeSubmission(submissionBatchObjectKey, submissionId); - SubmissionBatch batch = new SubmissionBatch(batchId, submissionBatchObjectKey); - - // 2. Call the process error batch - subject.processFailedBatch(batch); - - // 3. We treat each submission as an individual batch. Validate all the files exist at a new error path for the - // 0th item of the batch - String errorPath = "pre-submission-batching/errors/APPLICATION_ID/" + batchControlYear + "/" + batch.batchId() - + "/" + 0 + "/" + submissionId + "/"; - List errorFolders = fakeSynchronousDocumentStorageService.getSubFolders(errorPath); - - Assertions.assertEquals(1, errorFolders.size()); - Assertions.assertEquals(errorPath, errorFolders.get(0)); - - // Validate that we created files at the new error file paths. We know there is one item in this batch, so it - // will be the 0th error batch of the original batch with batch id 10 - String submissionXmlErrorPath = String.format( - "pre-submission-batching/errors/APPLICATION_ID/%s/10/0/subId-ABC/submission.xml", batchControlYear); - String manifestXmlErrorPath = String.format( - "pre-submission-batching/errors/APPLICATION_ID/%s/10/0/subId-ABC/manifest.xml", batchControlYear); - String userContextJsonErrorPath = String.format( - "pre-submission-batching/errors/APPLICATION_ID/%s/10/0/subId-ABC/userContext.json", batchControlYear); - - assertNotNull(fakeSynchronousDocumentStorageService.getObjectAsString(submissionXmlErrorPath)); - assertNotNull(fakeSynchronousDocumentStorageService.getObjectAsString(manifestXmlErrorPath)); - assertNotNull(fakeSynchronousDocumentStorageService.getObjectAsString(userContextJsonErrorPath)); - } - - @Test - public void itCopiesEachSubmissionIntoAnErrorPathWithAUniqueBatchId() { - // 1. Add a batch with some paths to the fake synchronous store - int batchControlYear = Year.now(clock).getValue() - 1; - long batchId = 10L; - - List submissionIds = List.of("subId-ABC", "subId-DEF", "subId-GHI"); - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - - for (String submissionId : submissionIds) { - addFakeSubmission(submissionBatchObjectKey, submissionId); - } - - SubmissionBatch batch = new SubmissionBatch(batchId, submissionBatchObjectKey); - // 2. Call the process error batch - subject.processFailedBatch(batch); - - // 3. Because we'll treat each submission as an individual batch, we expect to find 3 subfolders for the path. - String errorPath = String.format( - "pre-submission-batching/errors/%s/%s/%s/", APPLICATION_ID, batchControlYear, batch.batchId()); - List errorFolders = fakeSynchronousDocumentStorageService.getSubFolders(errorPath); - - Assertions.assertEquals(3, errorFolders.size()); - } - - private void addFakeSubmission(String batchObjectKey, String submissionId) { - fakeSynchronousDocumentStorageService.write( - batchObjectKey + submissionId + "/submission.xml", "submission.xml"); - fakeSynchronousDocumentStorageService.write(batchObjectKey + submissionId + "/manifest.xml", "manifest.xml"); - fakeSynchronousDocumentStorageService.write( - batchObjectKey + submissionId + "/userContext.json", "userContext.json"); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerIntegrationTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerIntegrationTest.java deleted file mode 100644 index c0f0d0b..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerIntegrationTest.java +++ /dev/null @@ -1,174 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Clock; -import java.time.Year; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DirectoriesConfig; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; - -@ExtendWith(MockitoExtension.class) -public class ErrorBatchPollerIntegrationTest { - private static final String APPLICATION_ID = "APPLICATION_ID"; - private final ActionQueue actions = new ActionQueue(); - private final Set inProgresssBatches = new HashSet<>(); - - private final ActionContext context = new ActionContext(createConfig()); - private static final Clock sharedClock = new MutableTestClock(); - - DocumentStorageSubmissionFailureService submissionFailureService; - ErrorBatchPoller errorBatchPoller; - FakeSynchronousDocumentStorageService fakeSynchronousDocumentStorageService = - new FakeSynchronousDocumentStorageService(); - - private Config createConfig() { - boolean runnerDisabledForTesting = false; - DirectoriesConfig directoriesConfig = new DirectoriesConfig( - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test"); - return new Config( - "Test", - null, - null, - directoriesConfig, - null, - null, - "12345", - "12345", - "12345", - "", - runnerDisabledForTesting, - true, - true, - "12345", - "", - "", - "dfsys-mef-submit-deployment-0-us-gov-east-1"); - } - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - @BeforeEach - public void setup() { - submissionFailureService = new DocumentStorageSubmissionFailureService( - fakeSynchronousDocumentStorageService, APPLICATION_ID, sharedClock); - errorBatchPoller = new ErrorBatchPoller( - actions, - fakeSynchronousDocumentStorageService, - APPLICATION_ID, - inProgresssBatches, - context, - sharedClock); - } - - @AfterEach - public void teardown() { - actions.getInProgressActions().clear(); - actions.getNewActions().clear(); - inProgresssBatches.clear(); - fakeSynchronousDocumentStorageService.clear(); - } - - @Test - public void itPublishesErrorBatchesToActionQueue() { - // 1. Add a batch with some submissions to the fake synchronous store - int batchControlYear = Year.now(sharedClock).getValue() - 1; - long batchId = 10L; - - List submissionIds = List.of("subId-ABC", "subId-DEF", "subId-GHI"); - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - - for (String submissionId : submissionIds) { - addFakeSubmission(submissionBatchObjectKey, submissionId); - } - - SubmissionBatch batch = new SubmissionBatch(batchId, submissionBatchObjectKey); - - // 2. Call the process error batch, to create an inditivual batch for each submission - submissionFailureService.processFailedBatch(batch); - - // 3. Because we'll treat each submission as an individual batch, we expect to find 3 subfolders for the path. - String errorPath = String.format( - "pre-submission-batching/errors/%s/%s/%s/", APPLICATION_ID, batchControlYear, batch.batchId()); - List errorFolders = fakeSynchronousDocumentStorageService.getSubFolders(errorPath); - - Assertions.assertEquals(3, errorFolders.size()); - - // 4. Call ErrorBatchPoller.poll() - errorBatchPoller.poll(); - - // 5. Expect 3 actions were put onto the queue, one for each submission in the batch - Assertions.assertEquals(3, actions.getNewActions().size()); - Assertions.assertEquals(3, inProgresssBatches.size()); - } - - @Test - public void itDoesNotPublishInProgressErrorBatchesToTheQueue() { - // 1. Add a batch with some submissions to the fake synchronous store - int batchControlYear = Year.now(sharedClock).getValue() - 1; - long batchId = 10L; - - List submissionIds = List.of("subId-ABC", "subId-DEF", "subId-GHI"); - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - - for (String submissionId : submissionIds) { - addFakeSubmission(submissionBatchObjectKey, submissionId); - } - - SubmissionBatch batch = new SubmissionBatch(batchId, submissionBatchObjectKey); - - // 2. Call the process error batch, to create an inditivual batch for each submission - submissionFailureService.processFailedBatch(batch); - - // 3. Because we'll treat each submission as an individual batch, we expect to find 3 subfolders for the path. - String errorPath = String.format( - "pre-submission-batching/errors/%s/%s/%s/", APPLICATION_ID, batchControlYear, batch.batchId()); - List errorFolders = fakeSynchronousDocumentStorageService.getSubFolders(errorPath); - - Assertions.assertEquals(3, errorFolders.size()); - - // 4. Call ErrorBatchPoller.poll() twice. - errorBatchPoller.poll(); - errorBatchPoller.poll(); - - // 5. Expect 3 actions were put onto the queue, even though we called poll twice because they were already in - // progress - Assertions.assertEquals(3, actions.getNewActions().size()); - Assertions.assertEquals(3, inProgresssBatches.size()); - } - - private void addFakeSubmission(String batchObjectKey, String submissionId) { - fakeSynchronousDocumentStorageService.write( - batchObjectKey + submissionId + "/submission.xml", "submission.xml"); - fakeSynchronousDocumentStorageService.write(batchObjectKey + submissionId + "/manifest.xml", "manifest.xml"); - fakeSynchronousDocumentStorageService.write( - batchObjectKey + submissionId + "/userContext.json", "userContext.json"); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerTest.java deleted file mode 100644 index ff74629..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorBatchPollerTest.java +++ /dev/null @@ -1,141 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.Year; -import java.util.HashSet; -import java.util.Set; - -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.command.ActionType; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DirectoriesConfig; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.storagelocations.StorageLocationBuilder; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; - -@ExtendWith(MockitoExtension.class) -public class ErrorBatchPollerTest { - private static final String APPLICATION_ID = "application-id"; - private MutableTestClock testClock = new MutableTestClock(); - - private final ActionQueue actions = new ActionQueue(); - private final Set inProgresssBatches = new HashSet<>(); - private final FakeSynchronousDocumentStorageService fakeDocumentStoreService = - new FakeSynchronousDocumentStorageService(); - - private ErrorBatchPoller errorBatchPoller; - - ActionContext context = new ActionContext(createConfig()); - - private Config createConfig() { - boolean runnerDisabledForTesting = false; - DirectoriesConfig directoriesConfig = new DirectoriesConfig( - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test"); - return new Config( - "Test", - null, - null, - directoriesConfig, - null, - null, - "12345", - "12345", - "12345", - "", - runnerDisabledForTesting, - true, - true, - "12345", - "", - "", - "dfsys-mef-submit-deployment-0-us-gov-east-1"); - } - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - @BeforeEach - public void setup() { - errorBatchPoller = new ErrorBatchPoller( - actions, fakeDocumentStoreService, APPLICATION_ID, inProgresssBatches, context, testClock); - } - - @AfterEach - public void teardown() { - actions.getNewActions().clear(); - actions.getInProgressActions().clear(); - inProgresssBatches.clear(); - fakeDocumentStoreService.clear(); - } - - @Test - public void itReprocessesEachSubmissionOfAFailedBatchAsAsItsOwnBatch() { - // Arrange: Add 2 submissions to the error path - SubmissionBatch batch = new SubmissionBatch(2L, String.format("/path/%s", 2L)); - createFakeErrorBatchForSubmission(batch, "ABC-123", 0); // Assume there is a 0-th submission for the batch - createFakeErrorBatchForSubmission(batch, "XYZ-789", 1); // Assume there is a 1-th submission for the batch - - // Act: Call Poll - errorBatchPoller.poll(); - - // Assert: Expect two create archive actions on the queue - one for each submission in the original batch - Assertions.assertEquals(2, actions.getNewActions().size()); - Assertions.assertEquals(2, inProgresssBatches.size()); - } - - @Test - public void itDoesNotReprocessSubmissionsThatAreAlreadyInProgress() { - // Arrange: Add 2 submissions to the error path. Add a SubmissionBatch to inProgressBatches to represent it - // being in progress - int batchControlYear = Year.now(testClock).getValue() - 1; - SubmissionBatch batch = new SubmissionBatch(2L, String.format("/path/%s", 2L)); - createFakeErrorBatchForSubmission(batch, "ABC-123", 0); // Assume there is a 0-th submission for the batch - createFakeErrorBatchForSubmission(batch, "XYZ-789", 1); // Assume there is a 1-th submission for the batch - String path = String.format( - "%s%s/%s/", - StorageLocationBuilder.getErrorFolderLocation(APPLICATION_ID, batchControlYear), - batch.batchId(), - 0L // Creating a batch for the 0-th submission - ); - inProgresssBatches.add(new SubmissionBatch(0L, path)); - - // Act: Call Poll - errorBatchPoller.poll(); - - // Assert: Expect only 1 action was added to the queue, because the 0-th submission was in progress - Assertions.assertEquals(1, actions.getNewActions().size()); - Assertions.assertEquals( - ActionType.CREATE_ARCHIVE, - actions.getNewActions().stream().toList().get(0).getType()); - } - - private void createFakeErrorBatchForSubmission( - SubmissionBatch submissionBatch, String submissionId, int submissionNumber) { - int batchControlYear = Year.now(testClock).getValue() - 1; - String errorPath = StorageLocationBuilder.getErrorFolderLocation(APPLICATION_ID, batchControlYear); - String errorBatchPath = errorPath + submissionBatch.batchId() + "/" + submissionNumber + "/" + submissionId; - - fakeDocumentStoreService.write(errorBatchPath + "/" + "submission.xml", "submission xml"); - fakeDocumentStoreService.write(errorBatchPath + "/" + "manifest.xml", "manifest xml"); - fakeDocumentStoreService.write(errorBatchPath + "/" + "userContext.json", "user context json"); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorHandlingIntegrationTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorHandlingIntegrationTest.java deleted file mode 100644 index e90903c..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/ErrorHandlingIntegrationTest.java +++ /dev/null @@ -1,343 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.time.*; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import lombok.SneakyThrows; -import org.junit.jupiter.api.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.mef.inputcomposition.BinaryAttachment; -import gov.irs.mef.inputcomposition.SubmissionContainer; -import gov.irs.mef.inputcomposition.SubmissionManifest; -import gov.irs.mef.inputcomposition.SubmissionXML; - -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.submit.BatchingProperties; -import gov.irs.directfile.submit.Runner; -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.actions.BundleArchivesActionHandler; -import gov.irs.directfile.submit.actions.CleanupActionHandler; -import gov.irs.directfile.submit.actions.CreateArchiveActionHandler; -import gov.irs.directfile.submit.actions.results.BundleArchivesActionResult; -import gov.irs.directfile.submit.command.ActionType; -import gov.irs.directfile.submit.command.CreateArchiveAction; -import gov.irs.directfile.submit.command.SubmitBundleAction; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DirectoriesConfig; -import gov.irs.directfile.submit.domain.*; -import gov.irs.directfile.submit.mocks.FakeSynchronousDocumentStorageService; -import gov.irs.directfile.submit.mocks.MutableTestClock; -import gov.irs.directfile.submit.mocks.ThrowingBundleSubmissionActionHandler; -import gov.irs.directfile.submit.repository.DocumentStorageBatchRepository; -import gov.irs.directfile.submit.repository.PodIdentifierRepository; -import gov.irs.directfile.submit.service.interfaces.IBundleSubmissionActionHandler; -import gov.irs.directfile.submit.service.interfaces.ISubmissionFailureService; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -public class ErrorHandlingIntegrationTest { - - // NOTE: Needed because we're mocking MEF Classes. MeF SDK expects this env variable A2A_TOOLKIT_HOME to be defined - @BeforeAll - public static void setupSystemProperties() { - String userDirectory = System.getProperty("user.dir"); - System.setProperty("A2A_TOOLKIT_HOME", userDirectory + "/src/test/resources/"); - } - - @AfterAll - public static void cleanupSystemProperties() { - System.clearProperty("A2A_TOOLKIT_HOME"); - } - - @Mock - private SqsConnectionSetupService sqsConnectionSetupService; - - @Mock - private SubmissionConfirmationMessageService submissionConfirmationMessageService; - - private static final String APPLICATION_ID = "application-id"; - - private ActionQueue actions = new ActionQueue(); - private Set inProgressBatches = new HashSet<>(); - - private ActionHandler actionHandler; - private ISubmissionFailureService submissionFailureService; - - private FakeSynchronousDocumentStorageService documentStorageService; - private IBundleSubmissionActionHandler bundleSubmissionService; - private DocumentStorageBatchRepository documentStorageBatchRepository; - - private final Config config = createConfig(); - private ErrorBatchPoller subject; - - private Runner runner; - private OfflineModeService offlineMode; - - private final ActionContext context = new ActionContext(config); - private Clock sharedClock; - - @Mock - PodIdentifierRepository podIdentifierRepository; - - @BeforeEach - public void setup() { - // 1. Initialize services that need to be registered by the services container - var date = LocalDateTime.of(2050, 11, 5, 12, 12); - - var instant = date.toInstant(ZoneOffset.UTC); - sharedClock = new MutableTestClock(instant, ZoneId.of("UTC")); - - documentStorageService = new FakeSynchronousDocumentStorageService(sharedClock); - submissionFailureService = - new DocumentStorageSubmissionFailureService(documentStorageService, APPLICATION_ID, sharedClock); - bundleSubmissionService = new ThrowingBundleSubmissionActionHandler(); - - // 2. Initialize ErrorBatchPoller, and ActionHandler - SqsConnectionSetupService sqsConnectionSetupService = null; - ActionContext actionContext = new ActionContext(config); - documentStorageBatchRepository = new DocumentStorageBatchRepository( - documentStorageService, - APPLICATION_ID, - BatchingProperties.builder().build(), - sharedClock); - subject = new ErrorBatchPoller( - actions, documentStorageService, APPLICATION_ID, inProgressBatches, context, sharedClock); - offlineMode = new OfflineModeService(); - actionHandler = new ActionHandler( - sqsConnectionSetupService, - submissionConfirmationMessageService, - actions, - actionContext, - bundleSubmissionService, - offlineMode, - inProgressBatches, - new BundleArchivesActionHandler(actionContext), - new CleanupActionHandler(actionContext, documentStorageService), - new CreateArchiveActionHandler(actionContext, documentStorageService), - new DocumentStorageSubmissionFailureService(documentStorageService, APPLICATION_ID, sharedClock), - podIdentifierRepository); - runner = new Runner(actions, actionHandler, offlineMode); - } - - @AfterEach - public void teardown() { - actions.getInProgressActions().clear(); - actions.getNewActions().clear(); - inProgressBatches.clear(); - ; - } - - @Test - public void itPollsBatchesWithErrorsAndSubmitsThemForProcessing() throws Exception { - /** - * This test walks through the workflow of handling a batch of submissions - * that fails to submit to MeF. Note that submission failure is distinct from a submission being rejected. - * A submission failure means some error occured that prevented us from submitting to MeF entirely. - * - * Flow of this test: - * 1. Create a Batch that contains 2 submissions - * 2. Add a SubmitBundleAction to the queue, and let the actionHandler handle the Action. - * addendum: We've setup the BundleSubmissionService to throw an exception to trigger the SubmissionFailure flow - * 3. The SubmissionFailureAction is processed, copying over files to an error path to be processed later. - * - * 5. Manually call ErrorBatchPoller.poll(), polls the DocumentStore for any error batches. - * For failed batches, it enqueues 1 batch per submission. - * 6. Expect that the actionQueue now has 2 archive actions. 1 for each submission in the batch from step 1 - * */ - // Arrange: Create a batch, and add submission data for two submissions to it. - - // 1. Create a batch with two submissions and add them to document storage - long batchId = 100L; - int batchControlYear = Year.now(sharedClock).getValue() - 1; - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - SubmissionBatch submissionBatch = new SubmissionBatch(batchId, submissionBatchObjectKey); - - SubmissionBatch b = new SubmissionBatch(batchId, submissionBatchObjectKey); - - UserSubmission userASubmission = - new UserSubmission("ABC", "taxReturn-ABC", "ABC123", "/manifest", "/submission", "/userContext"); - SubmissionData userASubmissionData = mockSubmissionData("ABC"); - documentStorageService.write("/manifest", "something good"); - documentStorageService.write("/submission", "something even better"); - documentStorageService.write("/userContext", "something else"); - UserSubmission userBSubmission = - new UserSubmission("DEF", "taxReturn-DEF", "XYZ789", "/manifest2", "/submission2", "/userContext2"); - SubmissionData userBSubmissionData = mockSubmissionData("DEF"); - documentStorageService.write("/manifest2", "something obvious"); - documentStorageService.write("/submission2", "something submtted"); - documentStorageService.write("/userContext2", "some user"); - - documentStorageBatchRepository.addSubmission(b, userASubmission); - documentStorageBatchRepository.addSubmission(b, userBSubmission); - - // 2. Create a SubmitBundleAction for the batch in step 1, enqueue it to the action queue - SubmissionContainer submissionContainer = - null; // SubmissionContainer is a MeF SDK type. The type is used for successful submissions so we don't - // need it when testing error cases - BundleArchivesActionResult bundleArchivesActionResult = new BundleArchivesActionResult( - submissionBatch, - new BundledArchives( - List.of(userASubmissionData.UserContext, userBSubmissionData.UserContext), - submissionContainer)); - - SubmitBundleAction submitBundleAction = new SubmitBundleAction(bundleArchivesActionResult); - - // 3. Grab the action from the queue, and call actionHandler.handle() - actions.getInProgressActions().add(submitBundleAction); - actionHandler.handleAction(actions.getInProgressActions().take()); - - // 4. Expect that a SubmissionFailureAction was added to the queue b/c SubmitBundle Failed - assertEquals(1, actions.getInProgressActions().size()); - assertEquals( - ActionType.SUBMISSION_FAILURE, - actions.getInProgressActions().peek().getType()); - actionHandler.handleAction(actions.getInProgressActions().take()); - - // 5. Call poll(), which should add 2 new ArchiveAction events to the queue for each individual submission in - // the batch - subject.poll(); - - assertEquals(2, actions.getNewActions().size()); - // 6. Validate that files exist in the DocumentStore to process. There were 2 submissions in the batch, so we - // should now 2 batches. - List submisson0Files = documentStorageService.getObjectKeys( - String.format("pre-submission-batching/errors/application-id/%s/100/0/ABC123/", batchControlYear)); - List submission1Files = documentStorageService.getObjectKeys( - String.format("pre-submission-batching/errors/application-id/%s/100/1/XYZ789/", batchControlYear)); - /* Also validate each submission has 4 files associated with it. They are submission.xml, manifest.xml, userContext.json, factgraph.json */ - assertEquals(3, submisson0Files.size()); - assertEquals(3, submission1Files.size()); - } - - // When an error batch occurs, each submission in the error batch is processed without a FileNotFoundException - // The other test here would be to create an error batch poller that loops through more than 1 submission and - // verifies that each action for the first submission is processed before the 2 submission / batch - // CreateArchiveAction is - // processed - @Test - @SneakyThrows - public void itRunsActionsForEachIndividualBatchSequentially() { - // Arrange: Create a batch, and add submission data for two submissions to it. - - // 1. Create a batch with two submissions and add them to document storage - long batchId = 100L; - int batchControlYear = Year.now(sharedClock).getValue() - 1; - String submissionBatchObjectKey = - String.format("pre-submission-batching/%s/%s/%s/", APPLICATION_ID, batchControlYear, batchId); - SubmissionBatch submissionBatch = new SubmissionBatch(batchId, submissionBatchObjectKey); - - SubmissionBatch b = new SubmissionBatch(batchId, submissionBatchObjectKey); - - UserSubmission userASubmission = - new UserSubmission("ABC", "taxReturn-ABC", "ABC123", "/manifest", "/submission", "/userContext"); - SubmissionData userASubmissionData = mockSubmissionData("ABC"); - documentStorageService.write("/manifest", "something good"); - documentStorageService.write("/submission", "something even better"); - documentStorageService.write("/userContext", "something else"); - UserSubmission userBSubmission = - new UserSubmission("DEF", "taxReturn-DEF", "XYZ789", "/manifest2", "/submission2", "/userContext2"); - SubmissionData userBSubmissionData = mockSubmissionData("DEF"); - documentStorageService.write("/manifest2", "something obvious"); - documentStorageService.write("/submission2", "something submtted"); - documentStorageService.write("/userContext2", "some user"); - - documentStorageBatchRepository.addSubmission(b, userASubmission); - documentStorageBatchRepository.addSubmission(b, userBSubmission); - - // 2. Create a SubmitBundleAction for the batch in step 1, enqueue it to the action queue - SubmissionContainer submissionContainer = - null; // SubmissionContainer is a MeF SDK type. The type is used for successful submissions so we don't - // need it when testing error cases - BundleArchivesActionResult bundleArchivesActionResult = new BundleArchivesActionResult( - submissionBatch, - new BundledArchives( - List.of(userASubmissionData.UserContext, userBSubmissionData.UserContext), - submissionContainer)); - - SubmitBundleAction submitBundleAction = new SubmitBundleAction(bundleArchivesActionResult); - CreateArchiveAction createArchiveAction = new CreateArchiveAction(submissionBatch); - // 3. Add multiple new actions to the queue - actions.getNewActions().add(createArchiveAction); - actions.getNewActions().add(createArchiveAction); - actions.getInProgressActions().add(submitBundleAction); - // when runner.step() is called, the actionHandler will process the SubmitBundleAction and NOT the - // CreateArchiveAction - runner.step(); - - // 4. Expect that a SubmissionFailureAction was added to the queue b/c SubmitBundle Failed - assertEquals(1, actions.getInProgressActions().size()); - assertEquals( - ActionType.SUBMISSION_FAILURE, - actions.getInProgressActions().peek().getType()); - runner.step(); - assertEquals(2, actions.getNewActions().size()); - // Call the cleanup action - runner.step(); - - // 5. Call poll(), which should add 2 new ArchiveAction events to the queue for each individual submission in - // the batch - subject.poll(); - assertEquals(4, actions.getNewActions().size()); - assertEquals(0, actions.getInProgressActions().size()); - - // Next step pulls the next new action from the queue and processes it - // Need to mock the CreateArchiveAction to continue stepping through the actions here - // runner.step(); - // assertEquals(3, actions.getNewActions().size()); - // assertEquals(1, actions.getInProgressActions().size()); - // assertEquals("BundleArchivesAction", - // actions.getInProgressActions().peek().getClass().getSimpleName()); - } - - private Config createConfig() { - boolean runnerDisabledForTesting = false; - DirectoriesConfig directoriesConfig = new DirectoriesConfig( - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test", - "src/test/resources/test"); - return new Config( - "Test", - null, - null, - directoriesConfig, - null, - null, - "12345", - "12345", - "12345", - "", - runnerDisabledForTesting, - true, - true, - "12345", - "", - "", - "dfsys-mef-submit-deployment-0-us-gov-east-1"); - } - - private SubmissionData mockSubmissionData(String submissionId) { - String userId = "UserId"; - String taxReturnId = "taxReturnId"; - String userTin = "userTin"; - TinType userTinType = TinType.INDIVIDUAL; - UserContextData userContextData = - new UserContextData(submissionId, userId, taxReturnId, userTin, userTinType, "0.0.0.0", "2024-01-01"); - - SubmissionManifest submissionManifest = mock(SubmissionManifest.class); - - SubmissionXML submissionXML = mock(SubmissionXML.class); - BinaryAttachment[] binaryAttachments = new BinaryAttachment[] {}; - return new SubmissionData(userContextData, submissionManifest, submissionXML, binaryAttachments); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/MefBundleSubmissionServiceTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/MefBundleSubmissionServiceTest.java deleted file mode 100644 index 9f28a57..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/MefBundleSubmissionServiceTest.java +++ /dev/null @@ -1,188 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.List; -import java.util.Map; - -import ch.qos.logback.classic.Level; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.mockito.MockedConstruction; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import gov.irs.a2a.mef.mefheader.ErrorClassificationCdType; -import gov.irs.a2a.mef.mefheader.ErrorExceptionDetailType; -import gov.irs.a2a.mef.meftransmitterservicemtom.ErrorExceptionDetail; -import gov.irs.mef.exception.ServiceException; -import gov.irs.mef.exception.ToolkitException; -import gov.irs.mef.inputcomposition.SubmissionContainer; -import gov.irs.mef.services.transmitter.mtom.SendSubmissionsMTOMClient; -import gov.irs.mef.services.transmitter.mtom.SendSubmissionsResult; - -import gov.irs.directfile.audit.AuditLogElement; -import gov.irs.directfile.audit.AuditService; -import gov.irs.directfile.audit.events.Event; -import gov.irs.directfile.audit.events.EventId; -import gov.irs.directfile.audit.events.EventStatus; -import gov.irs.directfile.audit.events.SystemEventPrincipal; -import gov.irs.directfile.audit.events.TinType; -import gov.irs.directfile.submit.actions.ActionContext; -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.SnsClientTestConfiguration; -import gov.irs.directfile.submit.config.SynchronousS3TestConfiguration; -import gov.irs.directfile.submit.domain.BundledArchives; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.domain.UserContextData; -import gov.irs.directfile.submit.extension.LoggerExtension; - -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@SpringBootTest -@Import({SynchronousS3TestConfiguration.class, SnsClientTestConfiguration.class}) -public class MefBundleSubmissionServiceTest { - @Autowired - Config config; - - @MockBean - SqsConnectionSetupService sqsConnectionSetupService; - - @RegisterExtension - public static LoggerExtension loggerExtension = new LoggerExtension(Level.INFO, AuditService.class.getName()); - - final UserContextData userContextData = new UserContextData( - "00000", - "00000000-0000-0000-0000-000000000000", - "11111111-1111-1111-1111-111111111111", - "111001111", - TinType.INDIVIDUAL, - "0.0.0.0", - "2024-01-01"); - - @Test - void mefBundleSubmissionServiceLogsSubmitBatchSuccessAuditEvent() throws Exception { - // given - Event expectedEvent = Event.builder() - .eventId(EventId.SUBMIT_BATCH) - .eventStatus(EventStatus.SUCCESS) - .eventPrincipal(new SystemEventPrincipal()) - .detail("{mefSubmissionIds=00000}") - .build(); - - final SubmissionContainer submissionContainer = mock(SubmissionContainer.class); - final SendSubmissionsResult sendSubmissionsResult = mock(SendSubmissionsResult.class); - - BundledArchives bundledArchives = - new BundledArchives((List) List.of(userContextData), submissionContainer); - MefBundleSubmissionActionHandler mefBundleSubmissionService = - new MefBundleSubmissionActionHandler(config, new ActionContext(config)); - - try (MockedConstruction mockSendSubmissionsMTOClient = - Mockito.mockConstruction(SendSubmissionsMTOMClient.class, (sendSubmissionsMTOClient, context) -> { - when(sendSubmissionsMTOClient.invoke(any(), any())).thenReturn(sendSubmissionsResult); - })) { - - // when - mefBundleSubmissionService.submitBundles(bundledArchives, new SubmissionBatch(0L, "")); - - // then verify 1 event was logged with expected values - loggerExtension.verifyLogEvent( - expectedEvent, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "200", - AuditLogElement.remoteAddress, - userContextData.getRemoteAddress())); - } - } - - @Test - void submitBundleActionLogsSubmitBatchFailureAuditEvent() { - // given - final SubmissionContainer submissionContainer = mock(SubmissionContainer.class); - - BundledArchives bundledArchives = - new BundledArchives((List) List.of(userContextData), submissionContainer); - MefBundleSubmissionActionHandler mefBundleSubmissionService = - new MefBundleSubmissionActionHandler(config, new ActionContext(config)); - - // with ServiceException - try (MockedConstruction mockSendSubmissionsMTOClient = - Mockito.mockConstruction(SendSubmissionsMTOMClient.class, (sendSubmissionsMTOClient, context) -> { - ErrorExceptionDetailType errorExceptionDetailType = new ErrorExceptionDetailType(); - errorExceptionDetailType.setErrorClassificationCd(ErrorClassificationCdType.SYSTEM_ERROR); - final ServiceException serviceException = new ServiceException( - "test service exception", - new ErrorExceptionDetail("test error exception detail", errorExceptionDetailType), - java.util.logging.Level.SEVERE); - - when(sendSubmissionsMTOClient.invoke(any(), any())).thenThrow(serviceException); - })) { - - // when - mefBundleSubmissionService.submitBundles(bundledArchives, new SubmissionBatch(0L, "")); - fail("expected it to throw exception"); - } catch (Exception exception) { - Event expectedEvent = Event.builder() - .eventId(EventId.SUBMIT_BATCH) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .eventErrorMessage("java.lang.RuntimeException") - .detail( - "{mefSubmissionIds=00000, errorMessage=gov.irs.mef.exception.ServiceException: test service exception}") - .build(); - loggerExtension.verifyLogEvent( - expectedEvent, - 0, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "400", - AuditLogElement.eventErrorMessage, - exception.getCause().getClass().getName(), - AuditLogElement.remoteAddress, - userContextData.getRemoteAddress())); - } - - // with ToolkitException - try (MockedConstruction mockSendSubmissionsMTOClient = - Mockito.mockConstruction(SendSubmissionsMTOMClient.class, (sendSubmissionsMTOClient, context) -> { - when(sendSubmissionsMTOClient.invoke(any(), any())) - .thenThrow(new ToolkitException("test toolkit exception")); - })) { - - // when - mefBundleSubmissionService.submitBundles(bundledArchives, new SubmissionBatch(0L, "")); - fail("expected it to throw exception"); - } catch (Exception exception) { - Event expectedEvent = Event.builder() - .eventId(EventId.SUBMIT_BATCH) - .eventStatus(EventStatus.FAILURE) - .eventPrincipal(new SystemEventPrincipal()) - .eventErrorMessage("java.lang.RuntimeException") - .detail( - "{mefSubmissionIds=00000, errorMessage=gov.irs.mef.exception.ToolkitException: test toolkit exception}") - .build(); - loggerExtension.verifyLogEvent( - expectedEvent, - 1, - Map.of( - AuditLogElement.cyberOnly, - true, - AuditLogElement.responseStatusCode, - "400", - AuditLogElement.eventErrorMessage, - exception.getCause().getClass().getName(), - AuditLogElement.remoteAddress, - userContextData.getRemoteAddress())); - } - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SqsConnectionSetupServiceTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SqsConnectionSetupServiceTest.java deleted file mode 100644 index 6e77025..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SqsConnectionSetupServiceTest.java +++ /dev/null @@ -1,114 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.List; -import java.util.UUID; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; -import software.amazon.awssdk.http.SdkHttpResponse; -import software.amazon.awssdk.services.sqs.SqsClient; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; -import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; -import software.amazon.awssdk.services.sqs.model.SendMessageRequest; -import software.amazon.awssdk.services.sqs.model.SendMessageResponse; - -import gov.irs.directfile.models.TaxReturnIdAndSubmissionId; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.pending.PendingSubmissionMessageVersion; -import gov.irs.directfile.models.message.pending.VersionedPendingSubmissionMessage; -import gov.irs.directfile.models.message.pending.payload.AbstractPendingSubmissionPayload; -import gov.irs.directfile.models.message.pending.payload.PendingSubmissionPayloadV1; -import gov.irs.directfile.submit.config.MessageQueueConfig; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class SqsConnectionSetupServiceTest { - SqsConnectionSetupService sqsConnectionSetupService; - - @Mock - SqsClient sqsClient; - - @Mock - GetQueueUrlResponse getQueueUrlResponse; - - @Mock - MessageQueueConfig messageQueueConfig; - - String pendingSubmissionQueueUrl = "http://localhost:4566/000000000000/pending-submission-queue"; - - @BeforeEach - public void setup() { - // Turn on pending submission queue publishing by default - when(messageQueueConfig.isPendingSubmissionPublishEnabled()).thenReturn(true); - sqsConnectionSetupService = new SqsConnectionSetupService(sqsClient, messageQueueConfig); - } - - @Test - public void sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue_sendsListOfStringsUsingSqsClient() - throws JsonProcessingException { - when(sqsClient.getQueueUrl(any(GetQueueUrlRequest.class))).thenReturn(getQueueUrlResponse); - when(getQueueUrlResponse.queueUrl()).thenReturn(pendingSubmissionQueueUrl); - SendMessageResponse mockSendMessageResponse = Mockito.mock(SendMessageResponse.class); - SdkHttpResponse mockSdkHttpResponse = Mockito.mock(SdkHttpResponse.class); - when(sqsClient.sendMessage((SendMessageRequest) any())).thenReturn(mockSendMessageResponse); - when(mockSendMessageResponse.sdkHttpResponse()).thenReturn(mockSdkHttpResponse); - when(mockSdkHttpResponse.isSuccessful()).thenReturn(true); - - TaxReturnIdAndSubmissionId taxReturnIdAndSubmissionId1 = - new TaxReturnIdAndSubmissionId(UUID.randomUUID(), "111111"); - TaxReturnIdAndSubmissionId taxReturnIdAndSubmissionId2 = - new TaxReturnIdAndSubmissionId(UUID.randomUUID(), "222222"); - - List taxReturnIdAndSubmissionIds = - List.of(taxReturnIdAndSubmissionId1, taxReturnIdAndSubmissionId2); - - // Wrap the payload and add a version header since that's what ultimately gets sent - AbstractPendingSubmissionPayload payload = new PendingSubmissionPayloadV1(taxReturnIdAndSubmissionIds); - VersionedPendingSubmissionMessage queueMessage = - new VersionedPendingSubmissionMessage<>( - payload, - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - PendingSubmissionMessageVersion.V1.getVersion())); - - sqsConnectionSetupService.sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue( - taxReturnIdAndSubmissionIds); - - ObjectMapper mapper = new ObjectMapper(); - String jsonBody = mapper.writeValueAsString(queueMessage); - - SendMessageRequest sendMessageRequest = SendMessageRequest.builder() - .queueUrl(pendingSubmissionQueueUrl) - .messageBody(jsonBody) - .build(); - - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(SendMessageRequest.class); - verify(sqsClient, times(1)).sendMessage(argumentCaptor.capture()); - assertEquals(sendMessageRequest, argumentCaptor.getValue()); - } - - @Test - public void sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue_publishDisabled() - throws JsonProcessingException { - // Turn off pending submission queue publishing - when(messageQueueConfig.isPendingSubmissionPublishEnabled()).thenReturn(false); - sqsConnectionSetupService = new SqsConnectionSetupService(sqsClient, messageQueueConfig); - - sqsConnectionSetupService.sendListOfSubmissionAndTaxReturnIdsToPendingSubmissionQueue(List.of()); - - // Verify that the message was never sent - verify(sqsClient, never()).sendMessage(any(SendMessageRequest.class)); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageServiceTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageServiceTest.java deleted file mode 100644 index e19f28e..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SubmissionConfirmationMessageServiceTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.NullAndEmptySource; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.TaxReturnSubmissionReceipt; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.PublisherException; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.confirmation.SubmissionConfirmationMessageVersion; -import gov.irs.directfile.models.message.confirmation.VersionedSubmissionConfirmationMessage; -import gov.irs.directfile.models.message.confirmation.payload.AbstractSubmissionConfirmationPayload; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2; -import gov.irs.directfile.models.message.confirmation.payload.SubmissionConfirmationPayloadV2Entry; -import gov.irs.directfile.models.message.event.SubmissionEventTypeEnum; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class SubmissionConfirmationMessageServiceTest { - private SubmissionConfirmationMessageService submissionConfirmationMessageService; - - @Mock - private SubmissionConfirmationSqsPublisher sqsPublisher; - - @Mock - private SubmissionConfirmationSnsPublisher snsPublisher; - - private static final List v2Object; - private static final String v2Json; - - static { - ObjectMapper objectMapper = new ObjectMapper(); - - v2Object = List.of( - new SubmissionConfirmationPayloadV2Entry( - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "11111111", "22222222", new Date()), - SubmissionEventTypeEnum.SUBMITTED, - Map.of("key1", "value1")), - new SubmissionConfirmationPayloadV2Entry( - new TaxReturnSubmissionReceipt(UUID.randomUUID(), "33333333", "44444444", new Date()), - SubmissionEventTypeEnum.SUBMITTED, - Map.of("key2", "value2"))); - - VersionedSubmissionConfirmationMessage v2VersionedObject = - new VersionedSubmissionConfirmationMessage<>( - new SubmissionConfirmationPayloadV2(v2Object), - new QueueMessageHeaders() - .addHeader( - MessageHeaderAttribute.VERSION, - SubmissionConfirmationMessageVersion.V2.getVersion())); - - try { - v2Json = objectMapper.writeValueAsString(v2VersionedObject); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - @BeforeEach - public void setup() { - submissionConfirmationMessageService = - new SubmissionConfirmationMessageService(List.of(sqsPublisher, snsPublisher), new ObjectMapper()); - } - - @Test - public void publishSubmissionConfirmationPayloadV2_success() { - submissionConfirmationMessageService.publishSubmissionConfirmationPayloadV2(v2Object); - - ArgumentCaptor sqsPublishArgumentCaptor = ArgumentCaptor.forClass(String.class); - verify(sqsPublisher, times(1)).publish(sqsPublishArgumentCaptor.capture()); - assertEquals(v2Json, sqsPublishArgumentCaptor.getValue()); - - ArgumentCaptor snsPublishArgumentCaptor = ArgumentCaptor.forClass(String.class); - verify(snsPublisher, times(1)).publish(snsPublishArgumentCaptor.capture()); - assertEquals(v2Json, snsPublishArgumentCaptor.getValue()); - } - - @ParameterizedTest - @NullAndEmptySource - public void publishSubmissionConfirmationPayloadV2_nullOrEmptyPublishers( - List publishers) { - SubmissionConfirmationMessageService noPublishersService = - new SubmissionConfirmationMessageService(publishers, new ObjectMapper()); - noPublishersService.publishSubmissionConfirmationPayloadV2(v2Object); - verify(sqsPublisher, never()).publish(any()); - verify(snsPublisher, never()).publish(any()); - } - - @Test - public void publishSubmissionConfirmationPayloadV2_writeValueAsStringFails() throws JsonProcessingException { - ObjectMapper mockMapper = Mockito.mock(ObjectMapper.class); - SubmissionConfirmationMessageService testService = - new SubmissionConfirmationMessageService(List.of(sqsPublisher, snsPublisher), mockMapper); - doThrow(new JsonProcessingException("bad json") {}).when(mockMapper).writeValueAsString(any()); - - assertThrows(PublisherException.class, () -> testService.publishSubmissionConfirmationPayloadV2(v2Object)); - } - - @Test - public void publishSubmissionConfirmationPayloadV2_publishFails() { - doThrow(new PublisherException("could not publish")).when(snsPublisher).publish(any()); - - assertThrows( - PublisherException.class, - () -> submissionConfirmationMessageService.publishSubmissionConfirmationPayloadV2(v2Object)); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SynchronousS3StorageServiceTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SynchronousS3StorageServiceTest.java deleted file mode 100644 index 06d480e..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/SynchronousS3StorageServiceTest.java +++ /dev/null @@ -1,89 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import software.amazon.awssdk.services.s3.model.CommonPrefix; -import software.amazon.awssdk.services.s3.model.ListObjectsV2Request; -import software.amazon.awssdk.services.s3.model.ListObjectsV2Response; -import software.amazon.encryption.s3.S3EncryptionClient; - -import gov.irs.directfile.submit.config.Config; -import gov.irs.directfile.submit.config.DocumentStoreConfig; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class SynchronousS3StorageServiceTest { - @Mock - S3EncryptionClient s3EncryptionClient; - - @Mock - Config config; - - @Mock - DocumentStoreConfig documentStoreConfig; - - SynchronousS3StorageService s3StorageService; - String bucketName = "bucketName"; - - @BeforeEach - void setup() { - when(documentStoreConfig.getEnvironmentPrefix()).thenReturn("environmentPrefix"); - when(config.getDocumentStore()).thenReturn(documentStoreConfig); - - s3StorageService = new SynchronousS3StorageService(s3EncryptionClient, bucketName, config); - } - - @Test - public void getSubFolders_givenNonTruncatedResponseFromS3_returnsResults() { - CommonPrefix commonPrefix1 = CommonPrefix.builder().prefix("prefix1").build(); - - CommonPrefix commonPrefix2 = CommonPrefix.builder().prefix("prefix2").build(); - - ListObjectsV2Response response = ListObjectsV2Response.builder() - .isTruncated(false) - .commonPrefixes(List.of(commonPrefix1, commonPrefix2)) - .build(); - when(s3EncryptionClient.listObjectsV2(any(ListObjectsV2Request.class))).thenReturn(response); - - List result = s3StorageService.getSubFolders("objectKey"); - - assertEquals(List.of("prefix1", "prefix2"), result); - verify(s3EncryptionClient, times(1)).listObjectsV2(any(ListObjectsV2Request.class)); - } - - @Test - public void getSubFolders_givenTruncatedResponseFromS3_makesAdditionalCallToS3() { - CommonPrefix commonPrefix1 = CommonPrefix.builder().prefix("prefix1").build(); - - CommonPrefix commonPrefix2 = CommonPrefix.builder().prefix("prefix2").build(); - - CommonPrefix commonPrefix3 = CommonPrefix.builder().prefix("prefix3").build(); - - ListObjectsV2Response firstResponse = ListObjectsV2Response.builder() - .isTruncated(true) - .commonPrefixes(List.of(commonPrefix1, commonPrefix2)) - .build(); - - ListObjectsV2Response secondResponse = ListObjectsV2Response.builder() - .isTruncated(false) - .commonPrefixes(List.of(commonPrefix3)) - .build(); - - when(s3EncryptionClient.listObjectsV2(any(ListObjectsV2Request.class))) - .thenReturn(firstResponse) - .thenReturn(secondResponse); - - List result = s3StorageService.getSubFolders("objectKey"); - - assertEquals(List.of("prefix1", "prefix2", "prefix3"), result); - verify(s3EncryptionClient, times(2)).listObjectsV2(any(ListObjectsV2Request.class)); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssemblerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssemblerTest.java deleted file mode 100644 index ad03b65..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchAssemblerTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.UUID; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.submit.BatchingProperties; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.mocks.MutableTestClock; -import gov.irs.directfile.submit.repository.interfaces.IBatchRepository; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -class UserSubmissionBatchAssemblerTest { - @Mock - private IBatchRepository batchRepository; - - @Mock - private UserSubmissionBatchProcessor batchProcessor; - - private UserSubmissionBatchAssembler batchAssembler; - - @BeforeEach - public void setup() { - BatchingProperties batchProperties = new BatchingProperties(3, 100); - batchAssembler = new UserSubmissionBatchAssembler( - batchRepository, - batchProperties, - "dfsys-mef-submit-deployment-0-us-gov-east-1", - batchProcessor, - new MutableTestClock()); - } - - @Test - public void onTimeout_submitsEmptyBatch() { - batchAssembler.onTimeout(); - - verify(batchProcessor, times(0)).processBatch(any()); - } - - @Test - public void onTimeout_submitsNonEmptyBatch() throws Exception { - addSubmission(); - batchAssembler.onTimeout(); - - verify(batchProcessor, times(1)).processBatch(any()); - } - - @Test - public void addSubmission_doesNotSubmitBatch() throws Exception { - // Batch size is 3, so just add 1 submission. Should not process batch. - addSubmission(); - - verify(batchProcessor, times(0)).processBatch(any()); - } - - @Test - public void addSubmission_submitsBatch() throws Exception { - // Batch size is 3, so add 3 submissions. Should process batch. - addSubmission(); - addSubmission(); - addSubmission(); - - verify(batchProcessor, times(1)).processBatch(any()); - } - - private void addSubmission() throws Exception { - batchAssembler.addSubmission(new UserSubmission( - UUID.randomUUID().toString(), - UUID.randomUUID().toString(), - "123456789", - "/path/to/manifest", - "/path/to/submission", - "/path/to/context")); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessorTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessorTest.java deleted file mode 100644 index 3b555a6..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionBatchProcessorTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package gov.irs.directfile.submit.service; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import gov.irs.directfile.submit.command.ActionType; -import gov.irs.directfile.submit.domain.ActionQueue; -import gov.irs.directfile.submit.domain.SubmissionBatch; -import gov.irs.directfile.submit.repository.interfaces.IBatchRepository; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class UserSubmissionBatchProcessorTest { - private static final String APPLICATION_ID = "application-id"; - ActionQueue actionQueue; - Set inProgressBatches; - UserSubmissionBatchProcessor subject; - - IBatchRepository batchRepository = mock(IBatchRepository.class); - - OfflineModeService offlineModeService = new OfflineModeService(); - - @BeforeEach - public void setup() { - actionQueue = new ActionQueue(); - inProgressBatches = new HashSet<>(); - subject = new UserSubmissionBatchProcessor( - actionQueue, batchRepository, APPLICATION_ID, offlineModeService, inProgressBatches); - } - - @Test - public void itPublishesSubmissionToActionQueue() { - SubmissionBatch batch = new SubmissionBatch(0L, "path/to/files"); - - // Act: call process batch - subject.processBatch(batch); - - // Assert: Expect a Create Archive Action was added to the queue - assertEquals(1, actionQueue.getNewActions().size()); - assertEquals(1, inProgressBatches.size()); - } - - @Test - public void itPublishesOldBatchesThatExistToActionQueue() throws InterruptedException { - // Arrange: - when(batchRepository.getCurrentWritingBatch(eq(APPLICATION_ID))).thenReturn(3L); - - List submissionBatches = - List.of(new SubmissionBatch(1L, "path1"), new SubmissionBatch(2L, "path2")); - when(batchRepository.getUnprocessedBatches(eq(APPLICATION_ID))).thenReturn(submissionBatches); - - // Act: - subject.processOldBatches(); - - // Assert: Expect two CREATE_ARCHIVE actions were added to the queue - assertEquals(2, actionQueue.getNewActions().size()); - assertEquals( - ActionType.CREATE_ARCHIVE, actionQueue.getNewActions().take().getType()); - assertEquals( - ActionType.CREATE_ARCHIVE, actionQueue.getNewActions().take().getType()); - } - - @Test - public void itDoesNotPublishOldBatchesThatAreAlreadyBeingProcessedToActionQueue() { - // Arrange: Add a batch to the inProgressBatches object - SubmissionBatch inProgressBatch = new SubmissionBatch(1L, "/batchId/1"); - inProgressBatches.add(inProgressBatch); - - List submissionBatches = List.of(inProgressBatch); - when(batchRepository.getUnprocessedBatches(eq(APPLICATION_ID))).thenReturn(submissionBatches); - - // Act: Call process old batches - subject.processOldBatches(); - - // Assert: Expect the action queue to be empty because we do not add batches that are already being processed. - assertEquals(0, actionQueue.getNewActions().size()); - } - - @Test - public void itDoesNotProcessBatchesWHenOfflineModeEnabled() { - // Arrange: Enable offline mode - offlineModeService.enableOfflineMode(); - SubmissionBatch batch = new SubmissionBatch(0L, "path/to/files"); - - // Act: call process batch - subject.processBatch(batch); - - // Assert: Expect the action queue is empty because we do not publish actions when offline mode is enabled - assertTrue(actionQueue.getNewActions().isEmpty()); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionConsumerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionConsumerTest.java deleted file mode 100644 index 83375ef..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/UserSubmissionConsumerTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package gov.irs.directfile.submit.service; - -import com.amazon.sqs.javamessaging.message.SQSTextMessage; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.jms.JMSException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.mockito.Mockito.*; - -@ExtendWith(MockitoExtension.class) -class UserSubmissionConsumerTest { - @Mock - private DispatchMessageRouter dispatchMessageRouter; - - private UserSubmissionConsumer userSubmissionConsumer; - - String messageJson = - """ - { - "payload": { - "@type": "DispatchPayloadV1", - "dispatch": { - "id": "63ac8695-48e8-4078-81cb-85798f9023f6", - "userId": "d44d647b-ce88-4db3-9e5b-b69fb005d6fe", - "taxReturnId": "e3633e53-ae12-46e6-95bb-54838ad7b0d4", - "pathToManifest": "", - "pathToUserContext": "", - "pathToSubmission": "", - "mefSubmissionId": "12345" - } - }, - "headers": { - "headers": { - "VERSION": "1.0" - } - } - } - """; - - @BeforeEach - public void setup() { - userSubmissionConsumer = new UserSubmissionConsumer(dispatchMessageRouter, new ObjectMapper()); - } - - @Test - public void onMessage_success() throws JMSException { - SQSTextMessage mockMessage = mock(SQSTextMessage.class); - when(mockMessage.getText()).thenReturn(messageJson); - - assertDoesNotThrow(() -> { - userSubmissionConsumer.onMessage(mockMessage); - verify(dispatchMessageRouter, times(1)).handleDispatchMessage(any()); - verify(mockMessage, times(1)).acknowledge(); - }); - } - - @Test - public void onMessage_exceptionThrown() throws JMSException { - SQSTextMessage mockMessage = mock(SQSTextMessage.class); - when(mockMessage.getText()) - .thenReturn( - """ - {"some_key":"some_val_without_a_closing_string}\s - """); - - userSubmissionConsumer.onMessage(mockMessage); - - // Verify that message.acknowledge() is not called - verify(mockMessage, never()).acknowledge(); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1HandlerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1HandlerTest.java deleted file mode 100644 index a99ae35..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/handlers/dispatch/DispatchV1HandlerTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package gov.irs.directfile.submit.service.handlers.dispatch; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.models.Dispatch; -import gov.irs.directfile.models.message.MessageHeaderAttribute; -import gov.irs.directfile.models.message.QueueMessageHeaders; -import gov.irs.directfile.models.message.dispatch.DispatchMessageVersion; -import gov.irs.directfile.models.message.dispatch.VersionedDispatchMessage; -import gov.irs.directfile.models.message.dispatch.payload.AbstractDispatchPayload; -import gov.irs.directfile.models.message.dispatch.payload.DispatchPayloadV1; -import gov.irs.directfile.submit.domain.UserSubmission; -import gov.irs.directfile.submit.service.UserSubmissionBatchAssembler; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -class DispatchV1HandlerTest { - @Mock - private UserSubmissionBatchAssembler batchAssembler; - - private DispatchV1Handler handler; - private VersionedDispatchMessage queueMessage; - private Dispatch testDispatch; - - @BeforeEach - public void setup() { - handler = new DispatchV1Handler(batchAssembler); - - testDispatch = Dispatch.testObjectFactory(); - AbstractDispatchPayload payload = new DispatchPayloadV1(testDispatch); - queueMessage = new VersionedDispatchMessage<>( - payload, - new QueueMessageHeaders() - .addHeader(MessageHeaderAttribute.VERSION, DispatchMessageVersion.V1.getVersion())); - } - - @Test - public void handleDispatchMessage_success() throws Exception { - handler.handleDispatchMessage(queueMessage); - - UserSubmission userSubmission = UserSubmission.fromDispatch(testDispatch); - verify(batchAssembler, times(1)).addSubmission(eq(userSubmission)); - } -} diff --git a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunnerTest.java b/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunnerTest.java deleted file mode 100644 index 5e3e5dd..0000000 --- a/direct-file/submit/src/test/java/gov/irs/directfile/submit/service/startup/runners/MefConnectivityApplicationStartRunnerTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.irs.directfile.submit.service.startup.runners; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import gov.irs.directfile.submit.service.polling.MeFHealthPoller; - -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -class MefConnectivityApplicationStartRunnerTest { - MefConnectivityApplicationStartRunner mefConnectivityApplicationStartRunner; - - @Mock - MeFHealthPoller meFHealthPoller; - - @BeforeEach - public void setup() { - mefConnectivityApplicationStartRunner = new MefConnectivityApplicationStartRunner(meFHealthPoller); - } - - @Test - public void run_shouldCall_meFHealthPollerPerformMefConnectivityCheckMethod() throws Exception { - mefConnectivityApplicationStartRunner.run(null); - - verify(meFHealthPoller, times(1)).performMefConnectivityCheck(); - } -} diff --git a/direct-file/submit/src/test/resources/application-default.yml b/direct-file/submit/src/test/resources/application-default.yml deleted file mode 100644 index a70e5c0..0000000 --- a/direct-file/submit/src/test/resources/application-default.yml +++ /dev/null @@ -1,56 +0,0 @@ -spring: - datasource: - driver-class-name: org.h2.Driver - url: jdbc:h2:mem:directfile-submit;DB_CLOSE_DELAY=-1 - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.H2Dialect - hibernate: - ddl-auto: update - -submit: - application-id: "dfsys-mef-submit-deployment-0-us-gov-east-1" - etin: 11111 - asid: 22222222 - efin: 333333 - vendor-control-number: JUSTASTRING12345 - softwareId: 12345678 - softwareVersionNum: 2023.0.1 - prod: false - runner-disabled-for-testing: true - submit-action-enabled: true - directories: - input: src/test/resources/test - to-process: src/test/resources/test - processed: src/test/resources/test - batched: src/test/resources/test - to-batch: src/test/resources/test - submitted: src/test/resources/test - documentstore: - region: us-west-2 - accessKey: accessKey - secretKey: secretKey - endpoint: http://s3.localhost.localstack.cloud:4566/ - bucket: test-bucket - submissionid: - variable-chars: MC - intervals: - returns-to-process: 12000 - aws: - messagequeue: - dispatch-queue-url: http://localhost:4577/000000000000/dispatch-queue - pending-submission-queue-url: http://localhost:4577/000000000000/pending-submission-queue - submission-confirmation-queue-url: http://localhost:4577/000000000000/submission-confirmation-queue - batching: - batchSize: 20 - batchTimeoutMilliseconds: 5000 # 1000 milliseconds * 5 = 5 seconds -direct-file: - local-encryption: - local-wrapping-key: lYIIKutUatfMwdEGB8qtUpQc3wMNtT5pfM+zW57qrv4= - -aws: - default-credentials-provider-chain-enabled: false - accessKey: test - secretKey: test - kmsEndpoint: http://directfile.test diff --git a/direct-file/submit/src/test/resources/config/logging.properties b/direct-file/submit/src/test/resources/config/logging.properties deleted file mode 100644 index 62cb168..0000000 --- a/direct-file/submit/src/test/resources/config/logging.properties +++ /dev/null @@ -1,2 +0,0 @@ -# This is an empty logging properties file because the MeF SDK requires one -# Because we use some MeF Java classes in our code, it requires us to have this. \ No newline at end of file