Skip to content

Commit

Permalink
WIP plugin management service
Browse files Browse the repository at this point in the history
  • Loading branch information
derTobsch committed Mar 22, 2020
1 parent ab73610 commit aa926c2
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 29 deletions.
12 changes: 12 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@
<version>0.8.0</version>
</dependency>

<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.89</version>
</dependency>

<!-- Persistence -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand All @@ -91,6 +97,12 @@
<artifactId>spring-boot-devtools</artifactId>
</dependency>

<!-- Configuration processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package coffee.synyx.frontpage.plugin.management;

/**
* @author Tobias Schneider
*/
class AvailablePluginAssets {

private final String name;
private final String url;

AvailablePluginAssets(String name, String url) {
this.name = name;
this.url = url;
}

public String getName() {
return name;
}

public String getUrl() {
return url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package coffee.synyx.frontpage.plugin.management;

import java.util.List;

/**
* @author Tobias Schneider
*/
public class AvailablePlugins {

private final String name;
private final List<AvailablePluginAssets> versions;

public AvailablePlugins(String name, List<AvailablePluginAssets> versions) {
this.name = name;
this.versions = versions;
}

public String getName() {
return name;
}

public List<AvailablePluginAssets> getVersions() {
return versions;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package coffee.synyx.frontpage.installer;
package coffee.synyx.frontpage.plugin.management;

import org.kohsuke.github.GitHubBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
* @author Tobias Schneider
Expand All @@ -14,4 +16,16 @@ PluginConfigurationProperties pluginConfigurationProperties() {

return new PluginConfigurationProperties();
}

@Bean
GitHubBuilder gitHubBuilder() {

return new GitHubBuilder();
}

@Bean
RestTemplate restTemplate(){

return new RestTemplate();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package coffee.synyx.frontpage.plugin.management;

import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import java.util.List;

/**
* @author Tobias Schneider
*/
@Validated
@ConfigurationProperties("frontpage.plugins")
public class PluginConfigurationProperties {

@NotEmpty
private String directory = "./plugins";

private List<Resource> resource;

@Validated
public static class Resource {

@NotEmpty
private String repositoryName;

public String getRepositoryName() {
return repositoryName;
}

public void setRepositoryName(String repositoryName) {
this.repositoryName = repositoryName;
}
}

public String getDirectory() {
return directory;
}

public void setDirectory(String directory) {
this.directory = directory;
}

public List<Resource> getResource() {
return resource;
}

public void setResource(List<Resource> resource) {
this.resource = resource;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coffee.synyx.frontpage.installer;
package coffee.synyx.frontpage.plugin.management;

/**
* @author Tobias Schneider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coffee.synyx.frontpage.installer;
package coffee.synyx.frontpage.plugin.management;

/**
* @author Tobias Schneider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package coffee.synyx.frontpage.plugin.management;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Optional;

import static java.util.Collections.emptyList;

@Controller
public class PluginManagementController {

private final PluginManagementService pluginManagementService;
private final PluginInstallerService pluginInstallerService;

@Autowired
public PluginManagementController(PluginManagementService pluginManagementService, PluginInstallerService pluginInstallerService) {

this.pluginManagementService = pluginManagementService;
this.pluginInstallerService = pluginInstallerService;
}

@GetMapping("/plugins-install")
public String getPlugins(Model model) {

List<AvailablePlugins> availablePlugins = emptyList();

Optional<List<AvailablePlugins>> listOfAvailablePlugins = pluginManagementService.getListOfAvailablePlugins();
if (listOfAvailablePlugins.isPresent()) {
availablePlugins = listOfAvailablePlugins.get();
}

model.addAttribute("availablePlugins", availablePlugins);
return "management/plugins";
}

@PutMapping("/plugins-install")
public String installPlugin(@RequestParam String url) {

pluginInstallerService.installPlugin(url);

return "redirect:/plugins-install";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package coffee.synyx.frontpage.plugin.management;

/**
* @author Tobias Schneider
*/
public class PluginManagementException extends RuntimeException {

PluginManagementException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package coffee.synyx.frontpage.plugin.management;

import coffee.synyx.frontpage.plugin.management.PluginConfigurationProperties.Resource;
import org.kohsuke.github.GHRelease;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

import static java.lang.String.format;
import static java.util.stream.Collectors.toList;

/**
* @author Tobias Schneider
*/
@Service
public class PluginManagementService {

private final PluginConfigurationProperties pluginConfigurationProperties;
private final GitHubBuilder gitHubBuilder;

@Autowired
public PluginManagementService(PluginConfigurationProperties pluginConfigurationProperties, GitHubBuilder gitHubBuilder) {

this.pluginConfigurationProperties = pluginConfigurationProperties;
this.gitHubBuilder = gitHubBuilder;
}


Optional<List<AvailablePlugins>> getListOfAvailablePlugins() {

List<Resource> pluginResources = pluginConfigurationProperties.getResource();

if (pluginResources == null) {
return Optional.empty();
}

List<AvailablePlugins> availablePlugins = new ArrayList<>();

for (Resource pluginResource : pluginResources) {
GHRelease latestRelease = getLatestRelease(pluginResource);
List<AvailablePluginAssets> latestReleaseAssets = getAvailablePluginAssets(latestRelease);

availablePlugins.add(new AvailablePlugins(pluginResource.getRepositoryName(), latestReleaseAssets));
}

return Optional.of(availablePlugins);
}

private List<AvailablePluginAssets> getAvailablePluginAssets(GHRelease release) {
try {

if (release == null) {
return Collections.emptyList();
}

return release.getAssets()
.stream()
.map(ghAsset -> new AvailablePluginAssets(ghAsset.getName(), ghAsset.getBrowserDownloadUrl()))
.collect(toList());
} catch (IOException e) {
throw new PluginManagementException("");
}
}

private GHRelease getLatestRelease(Resource resource) {
try {
GitHub github = gitHubBuilder.build();
return github.getRepository(resource.getRepositoryName()).getLatestRelease();
} catch (IOException e) {
throw new PluginManagementException(format("Could not retrieve lists of release from %s", resource.getRepositoryName()));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coffee.synyx.frontpage.installer;
package coffee.synyx.frontpage.plugin.management;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ spring:
password: frontpage
authentication-database: admin
database: frontpage

frontpage:
plugins:
resource:
- repositoryName: coffeenet/coffeenet-frontpage-plugin-feed
- repositoryName: coffeenet/coffeenet-frontpage-plugin-influx
28 changes: 28 additions & 0 deletions src/main/resources/templates/management/plugins.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
lang="en"
layout:decorator="layout">

<body>
<section layout:fragment="frontpage-main" class="frontpage--plugin-container">

<th:block th:each="availablePlugin : ${availablePlugins}">

<h1 th:text="${availablePlugin.name}">pluginTitle</h1>

<th:block th:each="version : ${availablePlugin.versions}">

<span th:text="${version.name}"></span>

<form style="display: inline-block" th:action="@{/plugins-install}" th:method="put">
<input type="hidden" name="url" th:value="${version.url}"/>
<button type="submit" th:title="${version.name}">Install</button>
</form>
</th:block>

</th:block>

</section>

</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coffee.synyx.frontpage.installer;
package coffee.synyx.frontpage.plugin.management;


import org.junit.After;
Expand Down

0 comments on commit aa926c2

Please sign in to comment.