diff --git a/Makefile b/Makefile index 4a2750d..b42286b 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,9 @@ lint: ## Run Apache Spotless linter .PHONY: create-local-client create-local-client: ## Create ResourceTracker local directory for client - @mkdir -p $(HOME)/.repoachiever/config +.PHONY: create-local-client +create-local-client: ## Create ResourceTracker local directory for client + @mkdir -p $(HOME)/.repoachiever/config/swap .PHONY: create-local-api-server create-local-api-server: ## Create ResourceTracker local directory for API Server diff --git a/api-server/src/main/java/com/repoachiever/repository/facade/RepositoryFacade.java b/api-server/src/main/java/com/repoachiever/repository/facade/RepositoryFacade.java index 2be0d2e..d07d3c9 100644 --- a/api-server/src/main/java/com/repoachiever/repository/facade/RepositoryFacade.java +++ b/api-server/src/main/java/com/repoachiever/repository/facade/RepositoryFacade.java @@ -103,57 +103,6 @@ public List retrieveLocations( return result; } - /** - * Checks if content location is present in content repository with the help of the given properties. - * - * @param location given content location. - * @param provider given content provider. - * @param credentials given content credentials. - * @return result of the check. - * @throws ContentValidationFailureException if content validation fails. - */ - public Boolean isContentLocationValid( - String location, Provider provider, CredentialsFieldsFull credentials) throws ContentValidationFailureException { - ProviderEntity rawProvider; - - try { - rawProvider = providerRepository.findByName(provider.toString()); - } catch (RepositoryOperationFailureException e) { - throw new ContentValidationFailureException(e.getMessage()); - } - - Optional rawCredentials = RepositoryConfigurationHelper.getExternalCredentials( - provider, credentials.getExternal()); - - try { - if (!secretRepository.isPresentBySessionAndCredentials( - credentials.getInternal().getId(), rawCredentials)) { - return false; - } - } catch (RepositoryOperationFailureException e) { - throw new ContentValidationFailureException(e.getMessage()); - } - - SecretEntity secret; - - try { - secret = secretRepository.findBySessionAndCredentials( - credentials.getInternal().getId(), - rawCredentials); - } catch (RepositoryOperationFailureException e) { - throw new ContentValidationFailureException(e.getMessage()); - } - - try { - return contentRepository - .findByProviderAndSecret(rawProvider.getId(), secret.getId()) - .stream() - .anyMatch(element -> Objects.equals(element.getLocation(), location)); - } catch (RepositoryOperationFailureException e) { - throw new ContentValidationFailureException(e); - } - } - /** * Retrieves all the data from content repository in a form of content applications. * diff --git a/api-server/src/main/java/com/repoachiever/service/cluster/facade/ClusterFacade.java b/api-server/src/main/java/com/repoachiever/service/cluster/facade/ClusterFacade.java index e7e9627..ebe8b02 100644 --- a/api-server/src/main/java/com/repoachiever/service/cluster/facade/ClusterFacade.java +++ b/api-server/src/main/java/com/repoachiever/service/cluster/facade/ClusterFacade.java @@ -76,6 +76,17 @@ public ContentRetrievalResult retrieveContent(ContentRetrievalApplication conten throw new ClusterContentRetrievalFailureException(e.getMessage()); } + List repositoryContentLocations; + + try { + repositoryContentLocations = + repositoryFacade.retrieveLocations(contentRetrievalApplication); + } catch (ContentLocationsRetrievalFailureException e) { + StateService.getTopologyStateGuard().unlock(); + + throw new ClusterContentRetrievalFailureException(e.getMessage()); + } + ContentRetrievalResult result = new ContentRetrievalResult(); for (String locationUnit : locationUnits) { @@ -89,6 +100,7 @@ public ContentRetrievalResult retrieveContent(ContentRetrievalApplication conten throw new ClusterContentRetrievalFailureException(e.getMessage()); } + List additionalContentUnits; try { @@ -100,15 +112,10 @@ public ContentRetrievalResult retrieveContent(ContentRetrievalApplication conten throw new ClusterContentRetrievalFailureException(e.getMessage()); } - Boolean active = false; - - try { - active = repositoryFacade.isContentLocationValid( - locationUnit, - contentRetrievalApplication.getProvider(), - contentRetrievalApplication.getCredentials()); - } catch (ContentValidationFailureException ignored) { - } + Boolean active = + repositoryContentLocations + .stream() + .anyMatch(element -> Objects.equals(element.getLocation(), locationUnit)); result.addLocationsItem( ContentRetrievalUnit.of( @@ -118,6 +125,23 @@ public ContentRetrievalResult retrieveContent(ContentRetrievalApplication conten ContentRetrievalUnitAdditional.of(additionalContentUnits))); } + for (RepositoryContentLocationUnitDto repositoryContentLocation : repositoryContentLocations) { + if (!result + .getLocations() + .stream() + .anyMatch(element -> + Objects.equals( + element.getName(), repositoryContentLocation.getLocation()))) { + result.addLocationsItem( + ContentRetrievalUnit.of( + repositoryContentLocation.getLocation(), + true, + ContentRetrievalUnitRaw.of(new ArrayList<>()), + ContentRetrievalUnitAdditional.of(new ArrayList<>()))); + + } + } + StateService.getTopologyStateGuard().unlock(); return result; diff --git a/api-server/src/main/openapi/openapi.yml b/api-server/src/main/openapi/openapi.yml index 03e98be..adc9c78 100644 --- a/api-server/src/main/openapi/openapi.yml +++ b/api-server/src/main/openapi/openapi.yml @@ -246,6 +246,7 @@ components: ContentRetrievalUnit: required: - name + - active - raw - additional properties: @@ -258,12 +259,16 @@ components: additional: $ref: "#/components/schemas/ContentRetrievalUnitAdditional" ContentRetrievalUnitRaw: + required: + - versions properties: versions: type: array items: type: string ContentRetrievalUnitAdditional: + required: + - versions properties: versions: type: array diff --git a/cli/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java b/cli/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java index e12b238..fb42c75 100644 --- a/cli/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java +++ b/cli/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java @@ -7,7 +7,9 @@ import com.repoachiever.model.ContentDownload; import com.repoachiever.model.ContentWithdrawal; import com.repoachiever.service.client.common.IClient; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientRequestException; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -23,6 +25,10 @@ public class DownloadContentClientService implements IClient codecs.defaultCodecs() + .maxInMemorySize(-1)) + .build()) .clientConnector(new ReactorClientHttpConnector( HttpClient.create().followRedirect(true))) .build()) diff --git a/cli/src/main/java/com/repoachiever/service/command/external/download/DownloadExternalCommandService.java b/cli/src/main/java/com/repoachiever/service/command/external/download/DownloadExternalCommandService.java index b305372..c311da0 100644 --- a/cli/src/main/java/com/repoachiever/service/command/external/download/DownloadExternalCommandService.java +++ b/cli/src/main/java/com/repoachiever/service/command/external/download/DownloadExternalCommandService.java @@ -14,6 +14,7 @@ import com.repoachiever.service.visualization.state.VisualizationState; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.stereotype.Service; import java.io.File; diff --git a/cluster/src/main/java/com/repoachiever/resource/communication/ClusterCommunicationResource.java b/cluster/src/main/java/com/repoachiever/resource/communication/ClusterCommunicationResource.java index dfdb875..f0cae0c 100644 --- a/cluster/src/main/java/com/repoachiever/resource/communication/ClusterCommunicationResource.java +++ b/cluster/src/main/java/com/repoachiever/resource/communication/ClusterCommunicationResource.java @@ -68,7 +68,7 @@ public void performServe() throws RemoteException { */ @Override public void performRetrievalReset() throws RemoteException { - StateService.resetContentUpdatesHeadCounter(); +// StateService.resetContentUpdatesHeadCounter(); } /** diff --git a/cluster/src/main/java/com/repoachiever/service/apiserver/resource/ApiServerCommunicationResource.java b/cluster/src/main/java/com/repoachiever/service/apiserver/resource/ApiServerCommunicationResource.java index 889e75b..1ed78af 100644 --- a/cluster/src/main/java/com/repoachiever/service/apiserver/resource/ApiServerCommunicationResource.java +++ b/cluster/src/main/java/com/repoachiever/service/apiserver/resource/ApiServerCommunicationResource.java @@ -12,6 +12,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.stereotype.Service; import java.io.InputStream; @@ -72,16 +74,18 @@ private IApiServerCommunicationService retrieveAllocation() throws ApiServerOper * @param name given content name. * @throws ApiServerOperationFailureException if RepoAchiever API Server operation fails. */ - public void performRawContentUpload(String location, String name, InputStream content) throws ApiServerOperationFailureException { + public void performRawContentUpload(String location, String name, DataBuffer content) throws ApiServerOperationFailureException { IApiServerCommunicationService allocation = retrieveAllocation(); RemoteInputStream contentWrapped; try { - contentWrapped = new SimpleRemoteInputStream(content) + contentWrapped = new SimpleRemoteInputStream(content.asInputStream()) .export(); } catch (RemoteException e) { - throw new RuntimeException(e); + DataBufferUtils.release(content); + + throw new ApiServerOperationFailureException(e.getMessage()); } try { @@ -91,8 +95,12 @@ public void performRawContentUpload(String location, String name, InputStream co name, contentWrapped); } catch (RemoteException e) { + DataBufferUtils.release(content); + throw new ApiServerOperationFailureException(e.getMessage()); } + + DataBufferUtils.release(content); } /** diff --git a/cluster/src/main/java/com/repoachiever/service/integration/scheduler/SchedulerConfigService.java b/cluster/src/main/java/com/repoachiever/service/integration/scheduler/SchedulerConfigService.java index ec5370e..6fe9bb4 100644 --- a/cluster/src/main/java/com/repoachiever/service/integration/scheduler/SchedulerConfigService.java +++ b/cluster/src/main/java/com/repoachiever/service/integration/scheduler/SchedulerConfigService.java @@ -12,9 +12,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.stereotype.Component; -import java.io.InputStream; import java.util.Objects; import java.util.concurrent.*; @@ -70,59 +70,39 @@ private void process() throws SchedulerPeriodRetrievalFailureException { ScheduledFuture execution = operationScheduledExecutorService.scheduleWithFixedDelay(() -> { if (StateService.getSuspended().get()) { - return; - } - - StateService.resetSuspenderByName(element.getName()); - - CountDownLatch awaiter = StateService.getSuspenderAwaiterByName(element.getName()); - - if (!vendorFacade.isVendorAvailable()) { logger.info( LoggingConfigurationHelper.getTransferableMessage( - String.format("Remote provider '%s' is not available: '%s'", - configService.getConfig().getService().getProvider().toString(), + String.format("Skipping execution for '%s' location due to suspension", element.getName()) )); - awaiter.countDown(); - return; } - StateService.getVendorAvailability().set(true); - - Integer commitAmount; - try { - commitAmount = vendorFacade.getRecordAmount(element.getName()); - } catch (LocationDefinitionsAreNotValidException e) { logger.info( LoggingConfigurationHelper.getTransferableMessage( - String.format( - "Skipping retrieval of content for '%s' location: %s", - element.getName(), - e.getMessage()))); + String.format("Entering execution for '%s' location", element.getName()))); - StateService.removeSuspenderByName(element.getName()); + StateService.resetSuspenderByName(element.getName()); - closable.countDown(); + CountDownLatch awaiter = StateService.getSuspenderAwaiterByName(element.getName()); - return; - } catch (GitHubContentRetrievalFailureException e) { - logger.info( - LoggingConfigurationHelper.getTransferableMessage( - String.format( - "Failed to retrieve content for '%s' location: %s", - element.getName(), - e.getMessage()))); + if (!vendorFacade.isVendorAvailable()) { + logger.info( + LoggingConfigurationHelper.getTransferableMessage( + String.format("Remote provider '%s' is not available: '%s'", + configService.getConfig().getService().getProvider().toString(), + element.getName()) + )); - awaiter.countDown(); + awaiter.countDown(); - return; - } + return; + } + + StateService.getVendorAvailability().set(true); - if (StateService.isContentUpdateHeadCounterBelow(element.getName(), commitAmount)) { String record; try { @@ -170,7 +150,7 @@ record = vendorFacade.getLatestRecord(element.getName()); element.getName(), record))); - InputStream contentStream; + DataBuffer contentStream; try { contentStream = vendorFacade.getRecordRawContent(element.getName(), record); @@ -229,85 +209,87 @@ record = vendorFacade.getLatestRecord(element.getName()); "Raw content transfer finished for '%s' location and '%s' record", element.getName(), record))); - - StateService.setContentUpdatesHeadCounter(element.getName(), commitAmount); } - } - - AdditionalContentDto additionalContent; - - try { - additionalContent = vendorFacade.getAdditionalContent(element.getName()); - } catch (LocationDefinitionsAreNotValidException e) { - logger.info( - LoggingConfigurationHelper.getTransferableMessage( - String.format( - "Skipping retrieval of content for '%s' location: %s", - element.getName(), - e.getMessage()))); - - StateService.removeSuspenderByName(element.getName()); - - closable.countDown(); - - return; - } catch (GitHubContentRetrievalFailureException e) { - logger.info( - LoggingConfigurationHelper.getTransferableMessage( - String.format( - "Failed to retrieve content for '%s' location: %s", - element.getName(), - e.getMessage()))); - awaiter.countDown(); + AdditionalContentDto additionalContent; - return; - } + try { + additionalContent = vendorFacade.getAdditionalContent(element.getName()); + } catch (LocationDefinitionsAreNotValidException e) { + logger.info( + LoggingConfigurationHelper.getTransferableMessage( + String.format( + "Skipping retrieval of content for '%s' location: %s", + element.getName(), + e.getMessage()))); - if (Objects.nonNull(additionalContent)) { - Boolean additionalContentPresent = false; + StateService.removeSuspenderByName(element.getName()); - try { - additionalContentPresent = - apiServerCommunicationResource.retrieveAdditionalContentPresent( - element.getName(), additionalContent.getHash()); - } catch (ApiServerOperationFailureException ignored) { - } + closable.countDown(); - if (!additionalContentPresent) { + return; + } catch (GitHubContentRetrievalFailureException e) { logger.info( LoggingConfigurationHelper.getTransferableMessage( String.format( - "Transferring downloaded additional content for '%s' location and '%s' hash", + "Failed to retrieve content for '%s' location: %s", element.getName(), - additionalContent.getHash()))); + e.getMessage()))); + + awaiter.countDown(); + + return; + } + + if (Objects.nonNull(additionalContent)) { + Boolean additionalContentPresent = false; try { - apiServerCommunicationResource.performAdditionalContentUpload( - element.getName(), additionalContent.getHash(), additionalContent.getData()); - } catch (ApiServerOperationFailureException e) { + additionalContentPresent = + apiServerCommunicationResource.retrieveAdditionalContentPresent( + element.getName(), additionalContent.getHash()); + } catch (ApiServerOperationFailureException ignored) { + } + + if (!additionalContentPresent) { logger.info( LoggingConfigurationHelper.getTransferableMessage( String.format( - "Failed to perform additional content uploading for '%s' location: %s", + "Transferring downloaded additional content for '%s' location and '%s' hash", element.getName(), - e.getMessage()))); + additionalContent.getHash()))); - awaiter.countDown(); + try { + apiServerCommunicationResource.performAdditionalContentUpload( + element.getName(), additionalContent.getHash(), additionalContent.getData()); + } catch (ApiServerOperationFailureException e) { + logger.info( + LoggingConfigurationHelper.getTransferableMessage( + String.format( + "Failed to perform additional content uploading for '%s' location: %s", + element.getName(), + e.getMessage()))); - return; - } + awaiter.countDown(); - logger.info( - LoggingConfigurationHelper.getTransferableMessage( - String.format( - "Additional content transfer finished for '%s' location and '%s' hash", - element.getName(), - additionalContent.getHash()))); + return; + } + + logger.info( + LoggingConfigurationHelper.getTransferableMessage( + String.format( + "Additional content transfer finished for '%s' location and '%s' hash", + element.getName(), + additionalContent.getHash()))); + } } - } - awaiter.countDown(); + awaiter.countDown(); + } finally { + logger.info( + LoggingConfigurationHelper.getTransferableMessage( + String.format("Exiting execution for '%s' location", element.getName()))); + } }, 0, period, TimeUnit.MILLISECONDS); try { diff --git a/cluster/src/main/java/com/repoachiever/service/state/StateService.java b/cluster/src/main/java/com/repoachiever/service/state/StateService.java index 32eb94b..536d1fb 100644 --- a/cluster/src/main/java/com/repoachiever/service/state/StateService.java +++ b/cluster/src/main/java/com/repoachiever/service/state/StateService.java @@ -97,37 +97,37 @@ public static CountDownLatch getSuspenderAwaiterByName(String name) { @Getter private final static ReentrantLock suspendGuard = new ReentrantLock(); - /** - * Represents a set of content updates head counter, pointing at the latest scanned head of the stream for the - * provided content locations. As keys there are used provided location names and as values commit amounts are used. - */ - private final static Map contentUpdatesHeadCounterSet = new HashMap<>(); - - /** - * Adds current content update head counter for the given location name with the given value. - * - * @param location given content location. - * @param value given content value. - */ - public static void setContentUpdatesHeadCounter(String location, Integer value) { - contentUpdatesHeadCounterSet.put(location, value); - } - - /** - * Checks if current content update head counter for the given location name is below or equal to the given value. - * - * @return result of the check. - */ - public static Boolean isContentUpdateHeadCounterBelow(String location, Integer value) { - return contentUpdatesHeadCounterSet.getOrDefault(location, 0) < value; - } - - /** - * Resets current content update head counter. - */ - public static void resetContentUpdatesHeadCounter() { - contentUpdatesHeadCounterSet.clear(); - } +// /** +// * Represents a set of content updates head counter, pointing at the latest scanned head of the stream for the +// * provided content locations. As keys there are used provided location names and as values commit amounts are used. +// */ +// private final static Map contentUpdatesHeadCounterSet = new HashMap<>(); +// +// /** +// * Adds current content update head counter for the given location name with the given value. +// * +// * @param location given content location. +// * @param value given content value. +// */ +// public static void setContentUpdatesHeadCounter(String location, Integer value) { +// contentUpdatesHeadCounterSet.put(location, value); +// } + +// /** +// * Checks if current content update head counter for the given location name is below or equal to the given value. +// * +// * @return result of the check. +// */ +// public static Boolean isContentUpdateHeadCounterBelow(String location, Integer value) { +// return contentUpdatesHeadCounterSet.getOrDefault(location, 0) < value; +// } + +// /** +// * Resets current content update head counter. +// */ +// public static void resetContentUpdatesHeadCounter() { +// contentUpdatesHeadCounterSet.clear(); +// } /** * Represents log message queue used to handle RepoAchiever API Server log message transfer. diff --git a/cluster/src/main/java/com/repoachiever/service/vendor/VendorFacade.java b/cluster/src/main/java/com/repoachiever/service/vendor/VendorFacade.java index 24dd44d..f26ef1b 100644 --- a/cluster/src/main/java/com/repoachiever/service/vendor/VendorFacade.java +++ b/cluster/src/main/java/com/repoachiever/service/vendor/VendorFacade.java @@ -14,6 +14,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.stereotype.Service; import java.io.InputStream; @@ -127,7 +128,7 @@ public Integer getRecordAmount(String location) throws * @throws LocationDefinitionsAreNotValidException if given location definitions are not valid. * @throws GitHubContentRetrievalFailureException if GitHub client content retrieval fails. */ - public InputStream getRecordRawContent(String location, String record) throws + public DataBuffer getRecordRawContent(String location, String record) throws LocationDefinitionsAreNotValidException, GitHubContentRetrievalFailureException { return switch (configService.getConfig().getService().getProvider()) { diff --git a/cluster/src/main/java/com/repoachiever/service/vendor/git/github/GitGitHubVendorService.java b/cluster/src/main/java/com/repoachiever/service/vendor/git/github/GitGitHubVendorService.java index 3ea0b72..3c4a3db 100644 --- a/cluster/src/main/java/com/repoachiever/service/vendor/git/github/GitGitHubVendorService.java +++ b/cluster/src/main/java/com/repoachiever/service/vendor/git/github/GitGitHubVendorService.java @@ -9,31 +9,19 @@ import com.repoachiever.exception.GitHubContentRetrievalFailureException; import com.repoachiever.exception.GitHubGraphQlClientDocumentNotFoundException; import com.repoachiever.exception.GitHubServiceNotAvailableException; -import com.repoachiever.logging.common.LoggingConfigurationHelper; import com.repoachiever.service.config.ConfigService; -import com.repoachiever.service.integration.communication.cluster.ClusterCommunicationConfigService; -import com.repoachiever.service.integration.scheduler.SchedulerConfigService; import com.repoachiever.service.state.StateService; import com.repoachiever.service.vendor.common.VendorConfigurationHelper; import jakarta.annotation.PostConstruct; import jakarta.ws.rs.core.HttpHeaders; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.web.client.ClientHttpRequestFactories; -import org.springframework.boot.web.client.ClientHttpRequestFactorySettings; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.buffer.DataBuffer; +import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.graphql.client.HttpGraphQlClient; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.http.client.reactive.JdkClientHttpConnector; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientRequestException; @@ -42,9 +30,6 @@ import reactor.netty.http.client.HttpClient; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; import java.nio.charset.Charset; import java.time.Duration; import java.util.HashMap; @@ -266,10 +251,10 @@ public Integer getCommitAmount(String owner, String name, String branch) throws * @param name given repository name. * @param commitHash given commit hash. * @param format given content format type. - * @return retrieved raw content from the repository with the given name and given commit hash as an input stream. + * @return retrieved raw content from the repository with the given name and given commit hash. * @throws GitHubContentRetrievalFailureException if GitHub REST API client content retrieval fails. */ - public InputStream getCommitContent(String owner, String name, String format, String commitHash) throws + public DataBuffer getCommitContent(String owner, String name, String format, String commitHash) throws GitHubContentRetrievalFailureException { AtomicReference dataBufferAtomic = new AtomicReference<>(null); @@ -302,6 +287,8 @@ public InputStream getCommitContent(String owner, String name, String format, St } if (!StateService.getVendorAvailability().get()) { + DataBufferUtils.release(dataBufferAtomic.get()); + task.interrupt(); awaiter.countDown(); @@ -320,7 +307,7 @@ public InputStream getCommitContent(String owner, String name, String format, St throw new GitHubContentRetrievalFailureException(new GitHubContentIsEmptyException().getMessage()); } - return dataBufferAtomic.get().asInputStream(); + return dataBufferAtomic.get(); } /** @@ -329,10 +316,10 @@ public InputStream getCommitContent(String owner, String name, String format, St * @param owner given repository owner. * @param name given repository name. * @param commitHash given commit hash. - * @return retrieved raw content from the repository with the given name and given commit hash as an input stream. + * @return retrieved raw content from the repository with the given name and given commit hash. * @throws GitHubContentRetrievalFailureException if GitHub REST API client content retrieval fails. */ - public InputStream getCommitContentAsZip(String owner, String name, String commitHash) throws + public DataBuffer getCommitContentAsZip(String owner, String name, String commitHash) throws GitHubContentRetrievalFailureException { return getCommitContent(owner, name, "zipball", commitHash); } @@ -343,10 +330,10 @@ public InputStream getCommitContentAsZip(String owner, String name, String commi * @param owner given repository owner. * @param name given repository name. * @param commitHash given commit hash. - * @return retrieved raw content from the repository with the given name and given commit hash as an input stream. + * @return retrieved raw content from the repository with the given name and given commit hash. * @throws GitHubContentRetrievalFailureException if GitHub REST API client content retrieval fails. */ - public InputStream getCommitContentAsTar(String owner, String name, String commitHash) throws + public DataBuffer getCommitContentAsTar(String owner, String name, String commitHash) throws GitHubContentRetrievalFailureException { return getCommitContent(owner, name, "tarball", commitHash); } diff --git a/gui/src/main/java/com/repoachiever/converter/ContentRetrievalUnitToJsonConverter.java b/gui/src/main/java/com/repoachiever/converter/ContentRetrievalUnitToJsonConverter.java new file mode 100644 index 0000000..2db4f9c --- /dev/null +++ b/gui/src/main/java/com/repoachiever/converter/ContentRetrievalUnitToJsonConverter.java @@ -0,0 +1,32 @@ +package com.repoachiever.converter; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.repoachiever.exception.ContentRetrievalUnitToJsonConversionFailureException; +import com.repoachiever.model.ContentRetrievalUnit; + +/** + * Represents content retrieval unit to Json converter. + */ +public class ContentRetrievalUnitToJsonConverter { + + /** + * Converts given content retrieval unit to Json. + * + * @param content given content retrieval unit to be converted. + * @return converted content retrieval unit. + * @throws ContentRetrievalUnitToJsonConversionFailureException if content retrieval unit to Json operation fails. + */ + public static String convert(ContentRetrievalUnit content) throws ContentRetrievalUnitToJsonConversionFailureException { + ObjectMapper mapper = + new ObjectMapper() + .configure(SerializationFeature.INDENT_OUTPUT, true); + + try { + return mapper.writeValueAsString(content); + } catch (JsonProcessingException e) { + throw new ContentRetrievalUnitToJsonConversionFailureException(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/converter/ContentUnitsToJsonConverter.java b/gui/src/main/java/com/repoachiever/converter/ContentUnitsToJsonConverter.java deleted file mode 100644 index 2c97ae9..0000000 --- a/gui/src/main/java/com/repoachiever/converter/ContentUnitsToJsonConverter.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.repoachiever.converter; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectReader; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.repoachiever.exception.ContentUnitsToJsonConversionFailureException; -import com.repoachiever.model.ContentUnit; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -/** - * Represents content units to Json converter. - */ -public class ContentUnitsToJsonConverter { - private static final Logger logger = LogManager.getLogger(ContentUnitsToJsonConverter.class); - - /** - * Converts given content units to Json. - * - * @param content given content to be converted. - * @return converted content units. - * @throws ContentUnitsToJsonConversionFailureException if content units to Json operation fails. - */ - public static String convert(List content) throws ContentUnitsToJsonConversionFailureException { - ObjectMapper mapper = - new ObjectMapper() - .configure(SerializationFeature.INDENT_OUTPUT, true); - - try { - return mapper.writeValueAsString(content); - } catch (JsonProcessingException e) { - throw new ContentUnitsToJsonConversionFailureException(e.getMessage()); - } - } -} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/converter/TopologyInfoUnitsToJsonConverter.java b/gui/src/main/java/com/repoachiever/converter/TopologyInfoUnitsToJsonConverter.java new file mode 100644 index 0000000..2f39ded --- /dev/null +++ b/gui/src/main/java/com/repoachiever/converter/TopologyInfoUnitsToJsonConverter.java @@ -0,0 +1,35 @@ +package com.repoachiever.converter; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.repoachiever.exception.TopologyInfoUnitsToJsonConversionFailureException; +import com.repoachiever.model.TopologyInfoUnit; + +import java.util.List; + +/** + * Represents topology info units to Json converter. + */ +public class TopologyInfoUnitsToJsonConverter { + + /** + * Converts given content units to Json. + * + * @param content given content to be converted. + * @return converted content units. + * @throws TopologyInfoUnitsToJsonConversionFailureException if topology info units to Json operation fails. + */ + public static String convert(List content) throws + TopologyInfoUnitsToJsonConversionFailureException { + ObjectMapper mapper = + new ObjectMapper() + .configure(SerializationFeature.INDENT_OUTPUT, true); + + try { + return mapper.writeValueAsString(content); + } catch (JsonProcessingException e) { + throw new TopologyInfoUnitsToJsonConversionFailureException(e.getMessage()); + } + } +} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/dto/DownloadExternalCommandDto.java b/gui/src/main/java/com/repoachiever/dto/DownloadExternalCommandDto.java index be53db8..d44c313 100644 --- a/gui/src/main/java/com/repoachiever/dto/DownloadExternalCommandDto.java +++ b/gui/src/main/java/com/repoachiever/dto/DownloadExternalCommandDto.java @@ -12,7 +12,5 @@ public class DownloadExternalCommandDto { private ConfigEntity config; - private String outputLocation; - private String location; } diff --git a/gui/src/main/java/com/repoachiever/dto/ListVisualizerCellInputDto.java b/gui/src/main/java/com/repoachiever/dto/ListVisualizerCellInputDto.java index 5bf7c2e..4346950 100644 --- a/gui/src/main/java/com/repoachiever/dto/ListVisualizerCellInputDto.java +++ b/gui/src/main/java/com/repoachiever/dto/ListVisualizerCellInputDto.java @@ -13,18 +13,20 @@ public class ListVisualizerCellInputDto { private final Boolean active; - private Boolean empty = false; + private final Boolean empty; + + private Boolean stub = false; /** - * Creates empty instance. + * Creates stub instance. * - * @return created empty instance. + * @return created stub instance. */ - public static ListVisualizerCellInputDto empty() { + public static ListVisualizerCellInputDto stub() { ListVisualizerCellInputDto result = - ListVisualizerCellInputDto.of(null, null); + ListVisualizerCellInputDto.of(null, null, null); - result.empty = true; + result.stub = true; return result; } diff --git a/gui/src/main/java/com/repoachiever/entity/PropertiesEntity.java b/gui/src/main/java/com/repoachiever/entity/PropertiesEntity.java index 9479d1f..3065a25 100644 --- a/gui/src/main/java/com/repoachiever/entity/PropertiesEntity.java +++ b/gui/src/main/java/com/repoachiever/entity/PropertiesEntity.java @@ -224,6 +224,9 @@ public class PropertiesEntity { @Value(value = "${alert.withdrawal-finished.message}") private String alertWithdrawalFinishedMessage; + @Value(value = "${alert.download-finished.message}") + private String alertDownloadFinishedMessage; + @Value(value = "${alert.version-mismatch.message}") private String alertVersionMismatchMessage; diff --git a/gui/src/main/java/com/repoachiever/exception/ContentRetrievalUnitToJsonConversionFailureException.java b/gui/src/main/java/com/repoachiever/exception/ContentRetrievalUnitToJsonConversionFailureException.java new file mode 100644 index 0000000..8db57a0 --- /dev/null +++ b/gui/src/main/java/com/repoachiever/exception/ContentRetrievalUnitToJsonConversionFailureException.java @@ -0,0 +1,22 @@ +package com.repoachiever.exception; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Formatter; + +/** + * Represents exception used when content retrieval unit to Json conversion operation fails. + */ +public class ContentRetrievalUnitToJsonConversionFailureException extends IOException { + public ContentRetrievalUnitToJsonConversionFailureException() { + this(""); + } + + public ContentRetrievalUnitToJsonConversionFailureException(Object... message) { + super( + new Formatter() + .format("Content retrieval unit to Json conversion operation failed: %s", + Arrays.stream(message).toArray()) + .toString()); + } +} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/exception/ContentUnitsToJsonConversionFailureException.java b/gui/src/main/java/com/repoachiever/exception/ContentUnitsToJsonConversionFailureException.java deleted file mode 100644 index ccda6c9..0000000 --- a/gui/src/main/java/com/repoachiever/exception/ContentUnitsToJsonConversionFailureException.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.repoachiever.exception; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Formatter; - -/** - * Represents exception used when content units to Json conversion operation fails. - */ -public class ContentUnitsToJsonConversionFailureException extends IOException { - public ContentUnitsToJsonConversionFailureException() { - this(""); - } - - public ContentUnitsToJsonConversionFailureException(Object... message) { - super( - new Formatter() - .format("Content units to Json conversion operation failed: %s", Arrays.stream(message).toArray()) - .toString()); - } -} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/exception/DefaultConfigurationFailureException.java b/gui/src/main/java/com/repoachiever/exception/DefaultConfigurationFailureException.java new file mode 100644 index 0000000..ca39a34 --- /dev/null +++ b/gui/src/main/java/com/repoachiever/exception/DefaultConfigurationFailureException.java @@ -0,0 +1,17 @@ +package com.repoachiever.exception; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Formatter; + +/** + * Represents exception used when default configuration file processing fails. + */ +public class DefaultConfigurationFailureException extends IOException { + public DefaultConfigurationFailureException(Object... message) { + super( + new Formatter() + .format("Default configuration file processing failed: %s", Arrays.stream(message).toArray()) + .toString()); + } +} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/exception/TopologyInfoUnitsToJsonConversionFailureException.java b/gui/src/main/java/com/repoachiever/exception/TopologyInfoUnitsToJsonConversionFailureException.java new file mode 100644 index 0000000..3625142 --- /dev/null +++ b/gui/src/main/java/com/repoachiever/exception/TopologyInfoUnitsToJsonConversionFailureException.java @@ -0,0 +1,22 @@ +package com.repoachiever.exception; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Formatter; + +/** + * Represents exception used when topology info units to Json conversion operation fails. + */ +public class TopologyInfoUnitsToJsonConversionFailureException extends IOException { + public TopologyInfoUnitsToJsonConversionFailureException() { + this(""); + } + + public TopologyInfoUnitsToJsonConversionFailureException(Object... message) { + super( + new Formatter() + .format("Topology info units to Json conversion operation failed: %s", + Arrays.stream(message).toArray()) + .toString()); + } +} \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java b/gui/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java index aedaca3..0b2e808 100644 --- a/gui/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java +++ b/gui/src/main/java/com/repoachiever/service/client/content/download/DownloadContentClientService.java @@ -6,7 +6,9 @@ import com.repoachiever.exception.ApiServerOperationFailureException; import com.repoachiever.model.ContentDownload; import com.repoachiever.service.client.common.IClient; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClientRequestException; import org.springframework.web.reactive.function.client.WebClientResponseException; @@ -20,6 +22,10 @@ public class DownloadContentClientService implements IClient codecs.defaultCodecs() + .maxInMemorySize(-1)) + .build()) .clientConnector(new ReactorClientHttpConnector( HttpClient.create().followRedirect(true))) .build()) diff --git a/gui/src/main/java/com/repoachiever/service/element/image/view/common/WithdrawImageView.java b/gui/src/main/java/com/repoachiever/service/element/image/view/common/WithdrawImageView.java index abbb85e..991692e 100644 --- a/gui/src/main/java/com/repoachiever/service/element/image/view/common/WithdrawImageView.java +++ b/gui/src/main/java/com/repoachiever/service/element/image/view/common/WithdrawImageView.java @@ -7,6 +7,7 @@ import com.repoachiever.service.element.text.common.IElementActualizable; import com.repoachiever.service.element.text.common.IElementResizable; import com.repoachiever.service.event.payload.ApplyEvent; +import com.repoachiever.service.event.payload.WithdrawEvent; import ink.bluecloud.css.CssResources; import ink.bluecloud.css.ElementButton; import ink.bluecloud.css.ElementButtonKt; @@ -41,7 +42,7 @@ public WithdrawImageView( button.getStylesheets().add(CssResources.textFieldCssFile); button.setOnMouseClicked( - event -> applicationEventPublisher.publishEvent(new ApplyEvent())); + event -> applicationEventPublisher.publishEvent(new WithdrawEvent())); InputStream imageSource = getClass().getClassLoader().getResourceAsStream(properties.getImageWithdrawName()); diff --git a/gui/src/main/java/com/repoachiever/service/element/list/ListVisualizer.java b/gui/src/main/java/com/repoachiever/service/element/list/ListVisualizer.java index 457e770..e9ac179 100644 --- a/gui/src/main/java/com/repoachiever/service/element/list/ListVisualizer.java +++ b/gui/src/main/java/com/repoachiever/service/element/list/ListVisualizer.java @@ -3,12 +3,14 @@ import com.repoachiever.dto.ListVisualizerCellInputDto; import com.repoachiever.entity.PropertiesEntity; import com.repoachiever.model.ContentRetrievalResult; +import com.repoachiever.model.ContentRetrievalUnit; import com.repoachiever.service.element.list.cell.ListVisualizerCell; import com.repoachiever.service.element.scene.main.deployment.MainDeploymentScene; import com.repoachiever.service.element.storage.ElementStorage; import com.repoachiever.service.element.text.common.IElement; import com.repoachiever.service.element.text.common.IElementActualizable; import com.repoachiever.service.element.text.common.IElementResizable; +import com.repoachiever.service.event.payload.ContentSwapEvent; import com.repoachiever.service.state.StateService; import java.util.*; @@ -32,7 +34,8 @@ public class ListVisualizer private final UUID id = UUID.randomUUID(); @Lazy - @Autowired private MainDeploymentScene deploymentScene; + @Autowired + private MainDeploymentScene deploymentScene; public ListVisualizer( @Autowired PropertiesEntity properties, @@ -46,17 +49,25 @@ public ListVisualizer( listView.setOnMouseClicked( event -> { if (Objects.nonNull(listView.getSelectionModel().getSelectedItem())) { - System.out.println(listView.getSelectionModel().getSelectedItem().getName()); + ContentRetrievalResult content = StateService.getContent(); + + applicationEventPublisher.publishEvent( + new ContentSwapEvent( + content + .getLocations() + .stream() + .filter( + element -> + element + .getName() + .equals( + listView + .getSelectionModel() + .getSelectedItem() + .getName())) + .toList() + .getFirst())); } -// applicationEventPublisher.publishEvent( -// new SwapFileOpenWindowEvent( -// LocalState.getDeploymentState().getResult().stream() -// .filter( -// element -> -// element -// .getName() -// .equals(listView.getSelectionModel().getSelectedItem())) -// .toList())); }); ElementStorage.setElement(id, listView); @@ -104,8 +115,13 @@ public void handleBackgroundUpdates() { content .getLocations() .stream() + .sorted(Comparator.comparing(ContentRetrievalUnit::getName)) .map(element -> - ListVisualizerCellInputDto.of(element.getName(), element.getActive())) + ListVisualizerCellInputDto.of( + element.getName(), + element.getActive(), + element.getAdditional().getVersions().isEmpty() + && element.getRaw().getVersions().isEmpty())) .toList(); observableList = @@ -114,9 +130,7 @@ public void handleBackgroundUpdates() { getContent().setMouseTransparent(false); getContent().setFocusTraversable(true); } else { - List items = - Stream.of(ListVisualizerCellInputDto.empty()) - .toList(); + List items = Stream.of(ListVisualizerCellInputDto.stub()).toList(); observableList = FXCollections.observableList(items); diff --git a/gui/src/main/java/com/repoachiever/service/element/list/cell/ListVisualizerCell.java b/gui/src/main/java/com/repoachiever/service/element/list/cell/ListVisualizerCell.java index 0666b81..799bbb7 100644 --- a/gui/src/main/java/com/repoachiever/service/element/list/cell/ListVisualizerCell.java +++ b/gui/src/main/java/com/repoachiever/service/element/list/cell/ListVisualizerCell.java @@ -57,8 +57,10 @@ public ListVisualizerCell( protected void updateItem(ListVisualizerCellInputDto item, boolean empty) { super.updateItem(item, empty); - setText(null); - setGraphic(null); +// if (hbox != null) { +// getItem +// System.out.println(String.format("%d-%b", hbox.hashCode(), empty)); +// } if (!empty) { if (Objects.isNull(StateService.getConfigLocation())) { @@ -71,7 +73,7 @@ protected void updateItem(ListVisualizerCellInputDto item, boolean empty) { hbox.getChildren().addAll(label); } - } else if (item.getEmpty()) { + } else if (item.getStub()) { if (Objects.isNull(label)) { label = new Label(properties.getListViewEmptyName()); } @@ -89,35 +91,62 @@ protected void updateItem(ListVisualizerCellInputDto item, boolean empty) { hbox.getChildren().addAll(label); } - } else { - if (Objects.isNull(cleanImageView)) { - this.cleanImageView = new CleanImageView( - properties, applicationEventPublisher, item.getName()); + } else if (item.getEmpty()) { + if (Objects.isNull(label)) { + label = new Label(item.getName()); } - if (Objects.isNull(downloadImageView)) { - this.downloadImageView = new DownloadImageView( - properties, applicationEventPublisher, deploymentScene, item.getName()); + if (!label.getText().equals(item.getName())) { + label.setText(item.getName()); } + if (Objects.isNull(hbox)) { + hbox = new HBox(); + + hbox.getChildren().addAll(label); + } + + if (hbox.getChildren().size() > 1) { + hbox.getChildren().clear(); + + hbox.getChildren().addAll(label); + } + } else { if (Objects.isNull(label)) { label = new Label(item.getName()); } if (!label.getText().equals(item.getName())) { label.setText(item.getName()); + } - if (Objects.isNull(hbox)) { - hbox = new HBox(); - } + if (Objects.isNull(hbox)) { + hbox = new HBox(); + } - hbox.getChildren().addAll(pane, cleanImageView.getContent(), downloadImageView.getContent()); + if (Objects.isNull(cleanImageView)) { + this.cleanImageView = new CleanImageView( + properties, applicationEventPublisher, item.getName()); + } + + if (Objects.isNull(downloadImageView)) { + this.downloadImageView = new DownloadImageView( + properties, applicationEventPublisher, deploymentScene, item.getName()); + } + + if (hbox.getChildren().size() < 3) { + hbox.getChildren().clear(); + + hbox.getChildren().addAll(label, pane, cleanImageView.getContent(), downloadImageView.getContent()); } } - } - HBox.setHgrow(pane, Priority.ALWAYS); + HBox.setHgrow(pane, Priority.ALWAYS); - setGraphic(hbox); + setGraphic(hbox); + } else { + setText(null); + setGraphic(null); + } } } diff --git a/gui/src/main/java/com/repoachiever/service/element/scene/main/start/MainStartScene.java b/gui/src/main/java/com/repoachiever/service/element/scene/main/start/MainStartScene.java index 1ff14fd..4760506 100644 --- a/gui/src/main/java/com/repoachiever/service/element/scene/main/start/MainStartScene.java +++ b/gui/src/main/java/com/repoachiever/service/element/scene/main/start/MainStartScene.java @@ -7,6 +7,8 @@ import com.repoachiever.service.element.storage.ElementStorage; import com.repoachiever.service.element.text.common.IElement; import java.util.UUID; + +import com.repoachiever.service.state.StateService; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; diff --git a/gui/src/main/java/com/repoachiever/service/element/stage/MainStage.java b/gui/src/main/java/com/repoachiever/service/element/stage/MainStage.java index b4d4be6..9d8c3ad 100644 --- a/gui/src/main/java/com/repoachiever/service/element/stage/MainStage.java +++ b/gui/src/main/java/com/repoachiever/service/element/stage/MainStage.java @@ -10,7 +10,10 @@ import com.repoachiever.service.event.payload.MainWindowHeightUpdateEvent; import com.repoachiever.service.event.payload.MainWindowWidthUpdateEvent; import com.repoachiever.service.scheduler.SchedulerConfigurationHelper; + import java.util.UUID; + +import com.repoachiever.service.state.StateService; import javafx.application.Platform; import javafx.geometry.Point2D; import javafx.geometry.Rectangle2D; @@ -20,83 +23,85 @@ import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; -/** MainStage represents main window. */ +/** + * MainStage represents main window. + */ @Service public class MainStage implements IElement { - private final UUID id = UUID.randomUUID(); - - public MainStage( - @Autowired PropertiesEntity properties, - @Autowired MainStartScene startScene, - @Autowired MainStartCircleProgressBar mainCircleProgressBar, - @Autowired IconImageView iconImageView, - @Autowired ApplicationEventPublisher applicationEventPublisher) { - Platform.runLater( - () -> { - Stage mainStage = new Stage(); - mainStage.setTitle(properties.getWindowMainName()); - mainStage.getIcons().add(iconImageView.getContent()); - - Rectangle2D defaultBounds = Screen.getPrimary().getVisualBounds(); - - Rectangle2D windowMin = - ElementHelper.getSizeWithScale( - defaultBounds.getWidth(), - defaultBounds.getHeight(), - properties.getWindowMainScaleMinWidth(), - properties.getWindowMainScaleMinHeight()); - - mainStage.setWidth(windowMin.getWidth()); - mainStage.setHeight(windowMin.getHeight()); - mainStage.setMinWidth(windowMin.getWidth()); - mainStage.setMinHeight(windowMin.getHeight()); - - Rectangle2D windowMax = - ElementHelper.getSizeWithScale( - defaultBounds.getWidth(), - defaultBounds.getHeight(), - properties.getWindowMainScaleMaxWidth(), - properties.getWindowMainScaleMaxHeight()); - - mainStage.setMaxWidth(windowMax.getWidth()); - mainStage.setMaxHeight(windowMax.getHeight()); - - Point2D centralPoint = - ElementHelper.getCentralPoint(mainStage.getWidth(), mainStage.getHeight()); - mainStage.setX(centralPoint.getX()); - mainStage.setY(centralPoint.getY()); - - mainStage.setScene(startScene.getContent()); - - mainStage - .widthProperty() - .addListener( - (obs, oldVal, newVal) -> { - applicationEventPublisher.publishEvent( - new MainWindowWidthUpdateEvent(newVal.doubleValue())); - }); - mainStage - .heightProperty() - .addListener( - (obs, oldVal, newVal) -> { - applicationEventPublisher.publishEvent( - new MainWindowHeightUpdateEvent(newVal.doubleValue())); - }); - - mainStage.setOnShown( - event -> { - ElementHelper.toggleElementVisibility(mainCircleProgressBar.getContent()); - - SchedulerConfigurationHelper.scheduleTimer( - () -> ElementHelper.toggleElementVisibility(mainCircleProgressBar.getContent()), - properties.getSpinnerInitialDelay()); - }); - - ElementStorage.setElement(id, mainStage); - }); - } - - public Stage getContent() { - return ElementStorage.getElement(id); - } + private final UUID id = UUID.randomUUID(); + + public MainStage( + @Autowired PropertiesEntity properties, + @Autowired MainStartScene startScene, + @Autowired MainStartCircleProgressBar mainCircleProgressBar, + @Autowired IconImageView iconImageView, + @Autowired ApplicationEventPublisher applicationEventPublisher) { + Platform.runLater( + () -> { + Stage mainStage = new Stage(); + mainStage.setTitle(properties.getWindowMainName()); + mainStage.getIcons().add(iconImageView.getContent()); + + Rectangle2D defaultBounds = Screen.getPrimary().getVisualBounds(); + + Rectangle2D windowMin = + ElementHelper.getSizeWithScale( + defaultBounds.getWidth(), + defaultBounds.getHeight(), + properties.getWindowMainScaleMinWidth(), + properties.getWindowMainScaleMinHeight()); + + mainStage.setWidth(windowMin.getWidth()); + mainStage.setHeight(windowMin.getHeight()); + mainStage.setMinWidth(windowMin.getWidth()); + mainStage.setMinHeight(windowMin.getHeight()); + + Rectangle2D windowMax = + ElementHelper.getSizeWithScale( + defaultBounds.getWidth(), + defaultBounds.getHeight(), + properties.getWindowMainScaleMaxWidth(), + properties.getWindowMainScaleMaxHeight()); + + mainStage.setMaxWidth(windowMax.getWidth()); + mainStage.setMaxHeight(windowMax.getHeight()); + + Point2D centralPoint = + ElementHelper.getCentralPoint(mainStage.getWidth(), mainStage.getHeight()); + mainStage.setX(centralPoint.getX()); + mainStage.setY(centralPoint.getY()); + + mainStage.setScene(startScene.getContent()); + + mainStage + .widthProperty() + .addListener( + (obs, oldVal, newVal) -> { + applicationEventPublisher.publishEvent( + new MainWindowWidthUpdateEvent(newVal.doubleValue())); + }); + mainStage + .heightProperty() + .addListener( + (obs, oldVal, newVal) -> { + applicationEventPublisher.publishEvent( + new MainWindowHeightUpdateEvent(newVal.doubleValue())); + }); + + mainStage.setOnShown( + event -> { + ElementHelper.toggleElementVisibility(mainCircleProgressBar.getContent()); + + SchedulerConfigurationHelper.scheduleTimer( + () -> ElementHelper.toggleElementVisibility(mainCircleProgressBar.getContent()), + properties.getSpinnerInitialDelay()); + }); + + ElementStorage.setElement(id, mainStage); + }); + } + + public Stage getContent() { + return ElementStorage.getElement(id); + } } diff --git a/gui/src/main/java/com/repoachiever/service/event/common/EventType.java b/gui/src/main/java/com/repoachiever/service/event/common/EventType.java index 00b616f..6bd0f6e 100644 --- a/gui/src/main/java/com/repoachiever/service/event/common/EventType.java +++ b/gui/src/main/java/com/repoachiever/service/event/common/EventType.java @@ -9,10 +9,10 @@ public enum EventType { DOWNLOAD_EVENT, CLEAN_EVENT, CLEAN_ALL_EVENT, - TOPOLOGY_EVENT, + TOPOLOGY_SWAP_EVENT, + DETAILS_SWAP_EVENT, EDIT_EVENT, OPEN_EVENT, - SWAP_EVENT, MAIN_WINDOW_HEIGHT_UPDATE_EVENT, MAIN_WINDOW_WIDTH_UPDATE_EVENT, } diff --git a/gui/src/main/java/com/repoachiever/service/event/payload/ContentSwapEvent.java b/gui/src/main/java/com/repoachiever/service/event/payload/ContentSwapEvent.java new file mode 100644 index 0000000..165488d --- /dev/null +++ b/gui/src/main/java/com/repoachiever/service/event/payload/ContentSwapEvent.java @@ -0,0 +1,27 @@ +package com.repoachiever.service.event.payload; + +import com.repoachiever.model.ContentRetrievalResult; +import com.repoachiever.model.ContentRetrievalUnit; +import com.repoachiever.service.event.common.EventType; +import com.repoachiever.service.event.common.IEvent; +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +/** Represents details swap file open window event used for state management. */ +@Getter +public class ContentSwapEvent extends ApplicationEvent implements IEvent { + private final ContentRetrievalUnit content; + + public ContentSwapEvent(ContentRetrievalUnit content) { + super(content); + + this.content = content; + } + + /** + * @see IEvent + */ + public EventType getEventType() { + return EventType.DETAILS_SWAP_EVENT; + } +} diff --git a/gui/src/main/java/com/repoachiever/service/event/payload/SwapEvent.java b/gui/src/main/java/com/repoachiever/service/event/payload/SwapEvent.java deleted file mode 100644 index 8b60223..0000000 --- a/gui/src/main/java/com/repoachiever/service/event/payload/SwapEvent.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.repoachiever.service.event.payload; - -import com.repoachiever.model.ContentUnit; -import com.repoachiever.service.event.common.EventType; -import com.repoachiever.service.event.common.IEvent; -import java.util.List; -import lombok.Getter; -import org.springframework.context.ApplicationEvent; - -/** Represents swap file open window event used for state management. */ -@Getter -public class SwapEvent extends ApplicationEvent implements IEvent { - private final List content; - - public SwapEvent(List content) { - super(content); - - this.content = content; - } - - /** - * @see IEvent - */ - public EventType getEventType() { - return EventType.SWAP_EVENT; - } -} diff --git a/gui/src/main/java/com/repoachiever/service/event/payload/TopologyEvent.java b/gui/src/main/java/com/repoachiever/service/event/payload/TopologyEvent.java deleted file mode 100644 index 42a969e..0000000 --- a/gui/src/main/java/com/repoachiever/service/event/payload/TopologyEvent.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.repoachiever.service.event.payload; - -import com.repoachiever.service.event.common.EventType; -import com.repoachiever.service.event.common.IEvent; -import lombok.Getter; -import org.springframework.context.ApplicationEvent; - -/** Represents topology event used for state management. */ -@Getter -public class TopologyEvent extends ApplicationEvent implements IEvent { - public TopologyEvent() { - super(new Object()); - } - - /** - * @see IEvent - */ - public EventType getEventType() { - return EventType.TOPOLOGY_EVENT; - } -} diff --git a/gui/src/main/java/com/repoachiever/service/event/payload/TopologySwapEvent.java b/gui/src/main/java/com/repoachiever/service/event/payload/TopologySwapEvent.java new file mode 100644 index 0000000..61f20aa --- /dev/null +++ b/gui/src/main/java/com/repoachiever/service/event/payload/TopologySwapEvent.java @@ -0,0 +1,28 @@ +package com.repoachiever.service.event.payload; + +import com.repoachiever.model.TopologyInfoUnit; +import com.repoachiever.service.event.common.EventType; +import com.repoachiever.service.event.common.IEvent; +import lombok.Getter; +import org.springframework.context.ApplicationEvent; + +import java.util.List; + +/** Represents topology swap file open window event used for state management. */ +@Getter +public class TopologySwapEvent extends ApplicationEvent implements IEvent { + private final List content; + + public TopologySwapEvent(List content) { + super(content); + + this.content = content; + } + + /** + * @see IEvent + */ + public EventType getEventType() { + return EventType.TOPOLOGY_SWAP_EVENT; + } +} diff --git a/gui/src/main/java/com/repoachiever/service/hand/external/download/DownloadExternalCommandService.java b/gui/src/main/java/com/repoachiever/service/hand/external/download/DownloadExternalCommandService.java index c44664e..7e7d913 100644 --- a/gui/src/main/java/com/repoachiever/service/hand/external/download/DownloadExternalCommandService.java +++ b/gui/src/main/java/com/repoachiever/service/hand/external/download/DownloadExternalCommandService.java @@ -16,12 +16,12 @@ * Represents download external command service. */ @Service -public class DownloadExternalCommandService implements ICommand { +public class DownloadExternalCommandService implements ICommand { /** * @see ICommand */ @Override - public InputStream process(DownloadExternalCommandDto downloadExternalCommand) throws ApiServerOperationFailureException { + public byte[] process(DownloadExternalCommandDto downloadExternalCommand) throws ApiServerOperationFailureException { DownloadContentClientService downloadContentClientService = new DownloadContentClientService(downloadExternalCommand.getConfig().getApiServer().getHost()); @@ -33,8 +33,6 @@ public InputStream process(DownloadExternalCommandDto downloadExternalCommand) t downloadExternalCommand.getConfig().getService().getProvider(), downloadExternalCommand.getConfig().getService().getCredentials())); - byte[] contentDownloadResult = downloadContentClientService.process(request); - - return new ByteArrayInputStream(contentDownloadResult); + return downloadContentClientService.process(request); } } \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/service/integration/event/EventConfigService.java b/gui/src/main/java/com/repoachiever/service/integration/event/EventConfigService.java index eb9dc44..9ec1e68 100644 --- a/gui/src/main/java/com/repoachiever/service/integration/event/EventConfigService.java +++ b/gui/src/main/java/com/repoachiever/service/integration/event/EventConfigService.java @@ -1,12 +1,15 @@ package com.repoachiever.service.integration.event; +import com.repoachiever.converter.ContentRetrievalUnitToJsonConverter; import com.repoachiever.dto.CleanExternalCommandDto; +import com.repoachiever.dto.DownloadExternalCommandDto; import com.repoachiever.entity.PropertiesEntity; import com.repoachiever.exception.*; import com.repoachiever.model.ContentRetrievalResult; import com.repoachiever.model.HealthCheckResult; import com.repoachiever.model.VersionInfoResult; import com.repoachiever.service.command.config.open.OpenConfigCommandService; +import com.repoachiever.service.command.swap.open.OpenSwapCommandService; import com.repoachiever.service.config.ConfigService; import com.repoachiever.service.element.alert.ErrorAlert; import com.repoachiever.service.element.alert.InformationAlert; @@ -23,10 +26,13 @@ import com.repoachiever.service.hand.external.version.VersionExternalCommandService; import com.repoachiever.service.hand.external.withdraw.WithdrawExternalCommandService; import com.repoachiever.service.hand.internal.health.HealthCheckInternalCommandService; +import com.repoachiever.service.integration.event.common.EventConfigurationHelper; import com.repoachiever.service.scheduler.SchedulerConfigurationHelper; import com.repoachiever.service.state.StateService; +import jakarta.annotation.PostConstruct; import javafx.geometry.Rectangle2D; import javafx.stage.Screen; +import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.event.ContextRefreshedEvent; @@ -34,7 +40,11 @@ import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.stereotype.Component; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Objects; import process.SProcessExecutor; @@ -93,6 +103,61 @@ public class EventConfigService { @Autowired private ErrorAlert errorAlert; + @Autowired + private EventConfigurationHelper eventConfigurationHelper; + + /** + * Attempts to perform configuration setup. + */ + @PostConstruct + private void configure() { + SchedulerConfigurationHelper.scheduleOnce( + () -> { + try { + StateService.getStartupGuard().await(); + } catch (InterruptedException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + + return; + } + + ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); + + try { + try { + configService.configure(new File(properties.getConfigDefaultLocation())); + } catch (ConfigFileNotFoundException | ConfigFileReadingFailureException | + ConfigValidationException | ConfigFileClosureFailureException e) { + ElementHelper.showAlert( + errorAlert.getContent(), + new DefaultConfigurationFailureException(e.getMessage()).getMessage()); + + return; + } + + StateService.setConfigLocation(new File(properties.getConfigDefaultLocation())); + + ContentRetrievalResult contentRetrievalResult; + + try { + contentRetrievalResult = + contentExternalCommandService.process(configService.getConfig()); + } catch (ApiServerOperationFailureException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + + return; + } + + if (!contentRetrievalResult.getLocations().isEmpty()) { + StateService.setContent(contentRetrievalResult); + } else { + StateService.setContent(null); + } + } finally { + ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); + } + }); + } /** * Provides initial window resolution setup. @@ -100,7 +165,7 @@ public class EventConfigService { * @param contextRefreshedEvent embedded context refreshed event. */ @EventListener(classes = {ContextRefreshedEvent.class}) - public void eventListener(ContextRefreshedEvent contextRefreshedEvent) { + private void eventListener(ContextRefreshedEvent contextRefreshedEvent) { Rectangle2D defaultBounds = Screen.getPrimary().getVisualBounds(); Rectangle2D window = @@ -112,6 +177,8 @@ public void eventListener(ContextRefreshedEvent contextRefreshedEvent) { applicationEventPublisher.publishEvent(new MainWindowWidthUpdateEvent(window.getWidth())); applicationEventPublisher.publishEvent(new MainWindowHeightUpdateEvent(window.getHeight())); + + StateService.getStartupGuard().countDown(); } /** @@ -120,7 +187,7 @@ public void eventListener(ContextRefreshedEvent contextRefreshedEvent) { * @param event given health check event. */ @EventListener - public void handleHealthCheckEvent(HealthCheckEvent event) { + private void handleHealthCheckEvent(HealthCheckEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { HealthCheckResult healthCheckResult; @@ -147,7 +214,7 @@ public void handleHealthCheckEvent(HealthCheckEvent event) { * @param event given apply event. */ @EventListener - public void handleApplyEvent(ApplyEvent event) { + private void handleApplyEvent(ApplyEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { if (Objects.isNull(StateService.getConfigLocation())) { @@ -209,7 +276,7 @@ public void handleApplyEvent(ApplyEvent event) { * @param event given withdraw event. */ @EventListener - public void handleWithdrawEvent(WithdrawEvent event) { + private void handleWithdrawEvent(WithdrawEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { if (Objects.isNull(StateService.getConfigLocation())) { @@ -257,7 +324,22 @@ public void handleWithdrawEvent(WithdrawEvent event) { return; } - StateService.setContent(null); + ContentRetrievalResult contentRetrievalResult; + + try { + contentRetrievalResult = + contentExternalCommandService.process(configService.getConfig()); + } catch (ApiServerOperationFailureException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + + return; + } + + if (!contentRetrievalResult.getLocations().isEmpty()) { + StateService.setContent(contentRetrievalResult); + } else { + StateService.setContent(null); + } ElementHelper.showAlert( informationAlert.getContent(), properties.getAlertWithdrawalFinishedMessage()); @@ -273,7 +355,7 @@ public void handleWithdrawEvent(WithdrawEvent event) { * @param event given retrieve content event. */ @EventListener - public void handleRetrieveContentEvent(RetrieveContentEvent event) { + private void handleRetrieveContentEvent(RetrieveContentEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { if (Objects.isNull(StateService.getConfigLocation())) { @@ -326,6 +408,8 @@ public void handleRetrieveContentEvent(RetrieveContentEvent event) { if (!contentRetrievalResult.getLocations().isEmpty()) { StateService.setContent(contentRetrievalResult); + } else { + StateService.setContent(null); } } finally { ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); @@ -339,7 +423,7 @@ public void handleRetrieveContentEvent(RetrieveContentEvent event) { * @param event given download event. */ @EventListener - synchronized void handleDownloadEvent(DownloadEvent event) { + private void handleDownloadEvent(DownloadEvent event) { SchedulerConfigurationHelper.scheduleOnce(() -> { if (!StateService.getConnectionEstablished()) { ElementHelper.showAlert( @@ -370,7 +454,29 @@ synchronized void handleDownloadEvent(DownloadEvent event) { return; } - Path.of(event.getDestination().getPath(), event.getLocation()); + byte[] contentDownloadResult; + + try { + contentDownloadResult = downloadExternalCommandService.process( + DownloadExternalCommandDto.of(configService.getConfig(), event.getLocation())); + } catch (ApiServerOperationFailureException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + + return; + } + + try { + FileUtils.writeByteArrayToFile( + new File( + eventConfigurationHelper.getOutputLocation( + Path.of(event.getDestination().getPath(), event.getLocation()).toString())), + contentDownloadResult); + } catch (IOException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + } + + ElementHelper.showAlert( + informationAlert.getContent(), properties.getAlertDownloadFinishedMessage()); } finally { ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); } @@ -383,7 +489,7 @@ synchronized void handleDownloadEvent(DownloadEvent event) { * @param event given clean event. */ @EventListener - synchronized void handleCleanEvent(CleanEvent event) { + private void handleCleanEvent(CleanEvent event) { SchedulerConfigurationHelper.scheduleOnce(() -> { if (!StateService.getConnectionEstablished()) { ElementHelper.showAlert( @@ -431,7 +537,7 @@ synchronized void handleCleanEvent(CleanEvent event) { * @param event given cleanall event. */ @EventListener - synchronized void handleCleanAllEvent(CleanAllEvent event) { + private void handleCleanAllEvent(CleanAllEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { if (Objects.isNull(StateService.getConfigLocation())) { @@ -468,6 +574,29 @@ synchronized void handleCleanAllEvent(CleanAllEvent event) { ElementHelper.showAlert( errorAlert.getContent(), properties.getAlertVersionMismatchMessage()); } + + try { + cleanAllExternalCommandService.process(configService.getConfig()); + } catch (ApiServerOperationFailureException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + } + + ContentRetrievalResult contentRetrievalResult; + + try { + contentRetrievalResult = + contentExternalCommandService.process(configService.getConfig()); + } catch (ApiServerOperationFailureException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + + return; + } + + if (!contentRetrievalResult.getLocations().isEmpty()) { + StateService.setContent(contentRetrievalResult); + } else { + StateService.setContent(null); + } } finally { ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); } @@ -480,7 +609,7 @@ synchronized void handleCleanAllEvent(CleanAllEvent event) { * @param event given edit event. */ @EventListener - synchronized void handleEditEvent(EditEvent event) { + private void handleEditEvent(EditEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { if (Objects.isNull(StateService.getConfigLocation())) { @@ -528,7 +657,7 @@ synchronized void handleEditEvent(EditEvent event) { * @param event given open event. */ @EventListener - synchronized void handleOpenEvent(OpenEvent event) { + private void handleOpenEvent(OpenEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); @@ -558,6 +687,8 @@ synchronized void handleOpenEvent(OpenEvent event) { if (!contentRetrievalResult.getLocations().isEmpty()) { StateService.setContent(contentRetrievalResult); + } else { + StateService.setContent(null); } } finally { ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); @@ -571,44 +702,60 @@ synchronized void handleOpenEvent(OpenEvent event) { * @param event given swap event. */ @EventListener - synchronized void handleSwapEvent(SwapEvent event) { + private void handleDetailsSwapEvent(ContentSwapEvent event) { SchedulerConfigurationHelper.scheduleOnce( () -> { -// ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); -// -// String swapFilePath = null; -// -// try { -// try { -// swapFilePath = swapService.createSwapFile( -// Paths.get(properties.getSwapRoot()).toString(), event.getContent()); -// } catch (SwapFileCreationFailureException e) { -// ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); -// return; -// } -// -// OpenSwapFileEditorCommandService openSwapFileEditorCommandService = -// new OpenSwapFileEditorCommandService(swapFilePath); + ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); // -// if (commandExecutorService.getOSType() == SProcessExecutor.OS.MAC) { -// ElementHelper.showAlert( -// informationAlert.getContent(), properties.getAlertEditorCloseReminderMessage()); -// } + String swapLocation = eventConfigurationHelper.getSwapLocation(); // -// try { -// commandExecutorService.executeCommand(openSwapFileEditorCommandService); -// } catch (CommandExecutorException e) { -// ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); -// } -// } finally { -// try { -// swapService.deleteSwapFile(swapFilePath); -// } catch (SwapFileDeletionFailureException e) { -// ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); -// } finally { -// ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); -// } -// } + try { + String contentRetrievalUnitRaw; + + try { + contentRetrievalUnitRaw = + ContentRetrievalUnitToJsonConverter.convert(event.getContent()); + } catch (ContentRetrievalUnitToJsonConversionFailureException e) { + ElementHelper.showAlert( + errorAlert.getContent(), + new SwapFileCreationFailureException(e.getMessage()).getMessage()); + + return; + } + + try { + Files.writeString(Path.of(swapLocation), contentRetrievalUnitRaw); + } catch (IOException e) { + ElementHelper.showAlert( + errorAlert.getContent(), + new SwapFileCreationFailureException(e.getMessage()).getMessage()); + + return; + } + + OpenSwapCommandService openSwapCommandService = new OpenSwapCommandService(swapLocation); + + if (commandExecutorService.getOSType() == SProcessExecutor.OS.MAC) { + ElementHelper.showAlert( + informationAlert.getContent(), properties.getAlertEditorCloseReminderMessage()); + } + + try { + commandExecutorService.executeCommand(openSwapCommandService); + } catch (CommandExecutorException e) { + ElementHelper.showAlert(errorAlert.getContent(), e.getMessage()); + } + } finally { + try { + Files.deleteIfExists(Paths.get(swapLocation)); + } catch (IOException e) { + ElementHelper.showAlert( + errorAlert.getContent(), + new SwapFileDeletionFailureException(e.getMessage()).getMessage()); + } finally { + ElementHelper.toggleElementVisibility(mainDeploymentCircleProgressBar.getContent()); + } + } }); } @@ -618,7 +765,7 @@ synchronized void handleSwapEvent(SwapEvent event) { * @param event main window height update event, which contains new window height. */ @EventListener - synchronized void handleMainWindowHeightUpdateEvent(MainWindowHeightUpdateEvent event) { + private void handleMainWindowHeightUpdateEvent(MainWindowHeightUpdateEvent event) { StateService.setMainWindowHeight(event.getHeight()); if (StateService.getMainWindowHeightUpdateMutex().getCount() > 0) { @@ -632,7 +779,7 @@ synchronized void handleMainWindowHeightUpdateEvent(MainWindowHeightUpdateEvent * @param event main window width update event, which contains new window width. */ @EventListener - synchronized void handleMainWindowWidthUpdateEvent(MainWindowWidthUpdateEvent event) { + private void handleMainWindowWidthUpdateEvent(MainWindowWidthUpdateEvent event) { StateService.setMainWindowWidth(event.getWidth()); if (StateService.getMainWindowWidthUpdateMutex().getCount() > 0) { diff --git a/gui/src/main/java/com/repoachiever/service/integration/event/common/EventConfigurationHelper.java b/gui/src/main/java/com/repoachiever/service/integration/event/common/EventConfigurationHelper.java index 7f94764..a29d244 100644 --- a/gui/src/main/java/com/repoachiever/service/integration/event/common/EventConfigurationHelper.java +++ b/gui/src/main/java/com/repoachiever/service/integration/event/common/EventConfigurationHelper.java @@ -1,10 +1,37 @@ package com.repoachiever.service.integration.event.common; -import java.util.Optional; +import com.repoachiever.entity.PropertiesEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.UUID; /** * Contains helpful tools used for event configuration. */ +@Component public class EventConfigurationHelper { + @Autowired + private PropertiesEntity properties; + + /** + * Formats output location with the given base. + * + * @param base given output location base. + * @return formatted output location. + */ + public String getOutputLocation(String base) { + return String.format("%s-%s", base, UUID.randomUUID()); + } + /** + * Formats swap output location. + * + * @return formatted swap output location. + */ + public String getSwapLocation() { + return Paths.get(properties.getSwapRoot(), String.format("%s.swp", UUID.randomUUID())).toString(); + } } \ No newline at end of file diff --git a/gui/src/main/java/com/repoachiever/service/state/StateService.java b/gui/src/main/java/com/repoachiever/service/state/StateService.java index de9f007..5e4c999 100644 --- a/gui/src/main/java/com/repoachiever/service/state/StateService.java +++ b/gui/src/main/java/com/repoachiever/service/state/StateService.java @@ -29,12 +29,24 @@ public class StateService { @Setter private static Double mainWindowWidth; + /** + * + */ @Getter private static final CountDownLatch mainWindowWidthUpdateMutex = new CountDownLatch(1); + /** + * + */ @Getter private static final CountDownLatch mainWindowHeightUpdateMutex = new CountDownLatch(1); + /** + * + */ + @Getter + private static final CountDownLatch startupGuard = new CountDownLatch(1); + /** * Represents state when connection with RepoAchiever API Server is established or not. */ diff --git a/gui/src/main/java/com/repoachiever/service/swap/SwapConfigurationHelper.java b/gui/src/main/java/com/repoachiever/service/swap/SwapConfigurationHelper.java index c2ffbd3..bf3b72c 100644 --- a/gui/src/main/java/com/repoachiever/service/swap/SwapConfigurationHelper.java +++ b/gui/src/main/java/com/repoachiever/service/swap/SwapConfigurationHelper.java @@ -20,17 +20,6 @@ /** Represents service responsible for temporate swap file creation. */ @Service public class SwapConfigurationHelper { -// /** -// * Creates swap key for swap file. -// * -// * @return created key for swap file. -// */ -// @SneakyThrows -// public static String createKey() { -// MessageDigest md = MessageDigest.getInstance("SHA3-256"); -// return DatatypeConverter.printHexBinary(md.digest(String.join(".", segments).getBytes())); -// } - /** * Creates temporate swap file with the given properties. * @@ -62,29 +51,4 @@ public String createSwapFile(String swapRoot, String content) return null; } -// -// /** -// * Composes name for RepoAchiever Cluster using pre-defined prefix and UUID. -// * -// * @param prefix given name prefix. -// * @return composed RepoAchiever Cluster name. -// */ -// public static String getName(String prefix) { -// return String.format("%s-%s", prefix, UUID.randomUUID()); -// } - - - /** - * Deletes previously created temporate swap file. - * - * @param swapLocation given location of the swap file to be removed. - * @throws SwapFileDeletionFailureException if swap file deletion failed. - */ - public static void deleteSwapFile(String swapLocation) throws SwapFileDeletionFailureException { - try { - Files.deleteIfExists(Paths.get(swapLocation)); - } catch (IOException e) { - throw new SwapFileDeletionFailureException(e.getMessage()); - } - } } diff --git a/gui/src/main/resources/application.properties b/gui/src/main/resources/application.properties index 2044f68..6559105 100644 --- a/gui/src/main/resources/application.properties +++ b/gui/src/main/resources/application.properties @@ -208,6 +208,9 @@ alert.application-finished.message=Application has been finished! # Describes info message related to configuration withdrawal finish. alert.withdrawal-finished.message=Withdrawal has been finished! +# Describes info message related to download operation finish. +alert.download-finished.message=Download operation has been finished! + # Describes error message related to RepoAchiever API Server version mismatch. alert.version-mismatch.message=RepoAchiever API Server version is different from the version of the client