Skip to content
Snippets Groups Projects
ArtifactoryClient.java 3.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • package de.tobias.playwall.service;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
    import de.tobias.playwall.infrastructure.ArtifactoryConfigurationProperties;
    
    Tobias Ullerich's avatar
    Tobias Ullerich committed
    import de.tobias.playwall.model.Plugin;
    
    import de.tobias.playwall.model.PluginDescription;
    import de.tobias.playwall.model.PluginManifest;
    import de.tobias.playwall.model.artifactory.Folder;
    import de.tobias.playwall.model.artifactory.Version;
    import jakarta.annotation.PostConstruct;
    import lombok.AllArgsConstructor;
    import lombok.SneakyThrows;
    
    import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
    
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Service;
    import org.springframework.web.reactive.function.client.WebClient;
    
    Tobias Ullerich's avatar
    Tobias Ullerich committed
    import reactor.core.publisher.Mono;
    
    
    import java.util.Comparator;
    import java.util.List;
    
    @Service
    @AllArgsConstructor
    
    @RegisterReflectionForBinding({PluginDescription.class, PluginManifest.class, Folder.class, Folder.FolderItem.class,
    		ArtifactoryClient.ArchiveViewSourceRequest.class, ArtifactoryClient.ArchiveViewSourceResponse.class})
    
    public class ArtifactoryClient
    {
    	private final WebClient webClient;
    	private final ArtifactoryConfigurationProperties configurationProperties;
    
    	private final VersionTokenizer versionTokenizer;
    
    	private ObjectMapper mapper;
    
    	@PostConstruct
    	private void init()
    	{
    		mapper = new ObjectMapper(new YAMLFactory());
    		mapper.findAndRegisterModules();
    	}
    
    	public Version getLatestVersion(PluginDescription plugin)
    	{
    		final ResponseEntity<Folder> folderResponse = webClient.get()
    				.uri("/artifactory/api/storage/%s/%s/%s".formatted(configurationProperties.getRepository(), configurationProperties.getGroupId().replace(".", "/"), plugin.getName()))
    				.retrieve()
    				.toEntity(Folder.class)
    				.block();
    		if(folderResponse == null || folderResponse.getBody() == null)
    		{
    			return null;
    		}
    		final List<Version> version = folderResponse.getBody().getChildren().stream()
    				.filter(Folder.FolderItem::isFolder)
    				.map(child -> versionTokenizer.getVersion(child.getUri()))
    				.sorted(Comparator.comparing(Version::major).thenComparing(Version::minor).thenComparing(Version::patch))
    				.toList();
    
    Tobias Ullerich's avatar
    Tobias Ullerich committed
    		if (version.isEmpty()) {
    			return null;
    		}
    		return version.get(version.size() - 1);
    
    	record ArchiveViewSourceRequest(String archivePath, String repoKey, String sourcePath)
    
    	record ArchiveViewSourceResponse(String source)
    
    	{
    	}
    
    	@SneakyThrows
    	public PluginManifest getPluginManifest(PluginDescription description, Version version)
    	{
    		final ResponseEntity<ArchiveViewSourceResponse> response = webClient.post()
    				.uri("/ui/api/v1/ui/archiveViewSource")
    				.header("X-Requested-With", "XMLHttpRequest")
    				.bodyValue(new ArchiveViewSourceRequest(
    						"%s/%s/%s/%s-%s.jar".formatted(
    								configurationProperties.getGroupId().replace(".", "/"),
    								description.getName(),
    								version.toVersionString(),
    								description.getName(),
    								version.toVersionString()
    						),
    						configurationProperties.getRepository(),
    						"plugin.yml"
    				))
    				.retrieve()
    				.toEntity(ArchiveViewSourceResponse.class)
    				.block();
    
    		if(response == null || response.getBody() == null)
    		{
    			return null;
    		}
    		return mapper.readValue(response.getBody().source(), PluginManifest.class);
    	}
    
    Tobias Ullerich's avatar
    Tobias Ullerich committed
    
    	public Mono<byte[]> downloadArtifact(Plugin plugin)
    	{
    		return webClient.get()
    				.uri("/artifactory/%s/%s/%s/%s/%s-%s.jar".formatted(
    						configurationProperties.getRepository(),
    						configurationProperties.getGroupId().replace(".", "/"),
    						plugin.getName(),
    						plugin.getVersion(),
    						plugin.getName(),
    						plugin.getVersion()
    				))
    				.retrieve()
    				.bodyToMono(byte[].class);
    	}