3
0
mirror of https://github.com/Qortal/qortal.git synced 2025-02-11 17:55:50 +00:00

FATJAR packaging + block explorer changes

Switched from maven-assembly-plugin to maven-shade-plugin for
building FATJAR.
When running from FATJAR, class-path is ". .." to help find
log4j2.properties file.

Swagger-UI can now be served direct from inside FATJAR instead
of requiring resources in filesystem.

Default package Start now controller/Controller

block-explorer.html now served via Jetty and modified to use
relative URLs instead of absolute http://localhost:9085/... style

Improved shutdown code in controller

/admin/stop API call disabled for now

Highly permissive settings.json added
This commit is contained in:
catbref 2018-12-05 11:32:55 +00:00
parent ad9fa9bf9d
commit 28c2cdaf5b
8 changed files with 182 additions and 85 deletions

View File

@ -88,7 +88,7 @@
document.body.innerHTML = html;
XHR({
url: "http://localhost:9085/transactions/address/" + address,
url: "/transactions/address/" + address,
onload: renderAddressTransactions,
responseType: "json"
});
@ -96,7 +96,7 @@
function fetchAddressInfo(address) {
XHR({
url: "http://localhost:9085/addresses/assets/" + address,
url: "/addresses/assets/" + address,
onload: renderAddressInfo,
responseType: "json"
});
@ -181,7 +181,7 @@
// Fetch block's transactions
XHR({
url: "http://localhost:9085/transactions/block/" + blockData.signature,
url: "/transactions/block/" + blockData.signature,
onload: renderBlockTransactions,
responseType: "json"
});
@ -189,7 +189,7 @@
function fetchBlockInfo(height) {
XHR({
url: "http://localhost:9085/blocks/byheight/" + height,
url: "/blocks/byheight/" + height,
onload: renderBlockInfo,
responseType: "json"
});
@ -227,7 +227,7 @@
function shutdownAPI() {
XHR({
url: "http://localhost:9085/admin/stop",
url: "/admin/stop",
onload: showShutdown,
responseType: "json"
});
@ -247,7 +247,7 @@
for (var h = height; h > 0 && h >= height - 20; --h)
XHR({
url: "http://localhost:9085/blocks/byheight/" + h,
url: "/blocks/byheight/" + h,
onload: listBlock,
responseType: "json"
});
@ -264,7 +264,7 @@
function windowOnLoad() {
XHR({
url: "http://localhost:9085/blocks/height",
url: "/blocks/height",
onload: initialBlocks,
responseType: "json"
});

88
pom.xml
View File

@ -4,6 +4,7 @@
<groupId>org.qora</groupId>
<artifactId>qora-core</artifactId>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<swagger-ui.version>3.19.0</swagger-ui.version>
@ -20,36 +21,6 @@
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
Start
</mainClass>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>. ..</Class-Path>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>Qora</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
<!-- unpack swagger-ui to target folder -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
@ -118,6 +89,63 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<artifactSet>
<excludes>
<!-- Don't include original swagger-UI as we're including our own modified version -->
<exclude>org.webjars:swagger-ui</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>controller.Controller</mainClass>
<manifestEntries>
<Class-Path>. ..</Class-Path>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>

6
settings.json Normal file
View File

@ -0,0 +1,6 @@
{
"rpcallowed": [
"::/0",
"0.0.0.0/0"
]
}

View File

@ -1,25 +0,0 @@
import api.ApiService;
import repository.DataException;
import repository.RepositoryFactory;
import repository.RepositoryManager;
import repository.hsqldb.HSQLDBRepositoryFactory;
public class Start {
private static final String connectionUrl = "jdbc:hsqldb:file:db/test;create=true";
public static void main(String args[]) throws DataException {
RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(connectionUrl);
RepositoryManager.setRepositoryFactory(repositoryFactory);
ApiService apiService = ApiService.getInstance();
apiService.start();
//// testing the API client
//ApiClient client = ApiClient.getInstance();
//String test = client.executeCommand("GET blocks/first");
//System.out.println(test);
}
}

View File

@ -15,8 +15,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import repository.DataException;
import repository.RepositoryManager;
import controller.Controller;
@Path("admin")
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@ -95,20 +95,14 @@ public class AdminResource {
public String shutdown() {
Security.checkApiCallAllowed("GET admin/stop", request);
try {
RepositoryManager.closeRepositoryFactory();
} catch (DataException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
ApiService.getInstance().stop();
Controller.shutdown();
}
}).start();
}); // disabled for now: .start();
return "true";
return "false";
}
}

View File

@ -2,7 +2,6 @@ package api;
import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.rewrite.handler.RedirectPatternRule;
@ -26,32 +25,33 @@ public class ApiService {
private final Set<Class<?>> resources;
public ApiService() {
// resources to register
// Resources to register
this.resources = new HashSet<Class<?>>();
this.resources.add(AddressesResource.class);
this.resources.add(AdminResource.class);
this.resources.add(BlocksResource.class);
this.resources.add(TransactionsResource.class);
this.resources.add(BlockExplorerResource.class);
this.resources.add(OpenApiResource.class); // swagger
this.resources.add(ApiDefinition.class); // for API definition
this.resources.add(AnnotationPostProcessor.class); // for API resource annotations
ResourceConfig config = new ResourceConfig(this.resources);
// create RPC server
// Create RPC server
this.server = new Server(Settings.getInstance().getRpcPort());
// whitelist
// IP address based access control
InetAccessHandler accessHandler = new InetAccessHandler();
for (String pattern : Settings.getInstance().getRpcAllowed()) {
accessHandler.include(pattern);
}
this.server.setHandler(accessHandler);
// url rewriting
// URL rewriting
RewriteHandler rewriteHandler = new RewriteHandler();
accessHandler.setHandler(rewriteHandler);
// context
// Context
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
context.setContextPath("/");
rewriteHandler.setHandler(context);
@ -69,9 +69,8 @@ public class ApiService {
// Swagger-UI static content
ClassLoader loader = this.getClass().getClassLoader();
File swaggerUIResourceLocation = new File(loader.getResource("resources/swagger-ui/").getFile());
ServletHolder swaggerUIServlet = new ServletHolder("static-swagger-ui", DefaultServlet.class);
swaggerUIServlet.setInitParameter("resourceBase", swaggerUIResourceLocation.getAbsolutePath());
swaggerUIServlet.setInitParameter("resourceBase", loader.getResource("resources/swagger-ui/").toString());
swaggerUIServlet.setInitParameter("dirAllowed", "true");
swaggerUIServlet.setInitParameter("pathInfoOnly", "true");
context.addServlet(swaggerUIServlet, "/api-documentation/*");
@ -96,19 +95,20 @@ public class ApiService {
public void start() {
try {
// START RPC
// Start server
server.start();
} catch (Exception e) {
// FAILED TO START RPC
// Failed to start
throw new RuntimeException("Failed to start API", e);
}
}
public void stop() {
try {
// STOP RPC
// Stop server
server.stop();
} catch (Exception e) {
// FAILED TO STOP RPC
// Failed to stop
}
}
}

View File

@ -0,0 +1,35 @@
package api;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
@Path("/")
@Produces({ MediaType.TEXT_HTML })
public class BlockExplorerResource {
@Context
HttpServletRequest request;
public BlockExplorerResource() {
}
@GET
@Path("/block-explorer.html")
public String getBlockExplorer() {
try {
byte[] htmlBytes = Files.readAllBytes(FileSystems.getDefault().getPath("block-explorer.html"));
return new String(htmlBytes, "UTF-8");
} catch (IOException e) {
return "block-explorer.html not found";
}
}
}

View File

@ -0,0 +1,59 @@
package controller;
import api.ApiService;
import repository.DataException;
import repository.RepositoryFactory;
import repository.RepositoryManager;
import repository.hsqldb.HSQLDBRepositoryFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Controller {
private static final Logger LOGGER = LogManager.getLogger(Controller.class);
private static final String connectionUrl = "jdbc:hsqldb:file:db/test;create=true";
private static final Object shutdownLock = new Object();
private static boolean isStopping = false;
public static void main(String args[]) throws DataException {
LOGGER.info("Starting up...");
LOGGER.info("Starting repository");
RepositoryFactory repositoryFactory = new HSQLDBRepositoryFactory(connectionUrl);
RepositoryManager.setRepositoryFactory(repositoryFactory);
LOGGER.info("Starting API");
ApiService apiService = ApiService.getInstance();
apiService.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
Controller.shutdown();
}
});
}
public static void shutdown() {
synchronized (shutdownLock) {
if (!isStopping) {
isStopping = true;
LOGGER.info("Shutting down API");
ApiService.getInstance().stop();
try {
LOGGER.info("Shutting down repository");
RepositoryManager.closeRepositoryFactory();
} catch (DataException e) {
e.printStackTrace();
}
LOGGER.info("Shutdown complete!");
}
}
}
}