Apply code review suggestions part 2

This commit is contained in:
chimp1984 2022-06-06 21:18:11 +02:00
parent 27b78b6217
commit 593c0b8bb5
No known key found for this signature in database
GPG Key ID: 9801B4EC591F90E3
17 changed files with 22 additions and 674 deletions

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode;
package bisq.daonode;
import bisq.core.app.TorSetup;

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode;
package bisq.daonode;
import bisq.common.config.Config;
@ -28,17 +28,17 @@ import lombok.extern.slf4j.Slf4j;
import bisq.daoNode.endpoints.ProofOfBurnApi;
import bisq.daoNode.error.CustomExceptionMapper;
import bisq.daoNode.error.StatusException;
import bisq.daoNode.util.StaticFileHandler;
import bisq.daonode.endpoints.ProofOfBurnApi;
import bisq.daonode.error.CustomExceptionMapper;
import bisq.daonode.error.StatusException;
import bisq.daonode.util.StaticFileHandler;
import com.sun.net.httpserver.HttpServer;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
/**
* Application to start and config the rest service.
* This creates and rest service at BASE_URL for clients to connect and for users to browse the documentation.
* This creates a rest service for clients to connect and for users to browse the documentation.
* <p>
* Swagger doc are available at <a href="http://localhost:8082/doc/v1/index.html">REST API documentation</a>
*/

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode;
package bisq.daonode;
import lombok.extern.slf4j.Slf4j;
@ -60,9 +60,9 @@ public class SwaggerResolution {
Reader reader = new Reader(configuration);
OpenAPI openAPI = reader.read(application.getClasses());
swaggerJson = Json.pretty(openAPI);
} catch (RuntimeException e) {
log.error(e.getMessage(), e);
throw e;
} catch (Exception exception) {
log.error("", exception);
throw new RuntimeException(exception);
}
}

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.dto;
package bisq.daonode.dto;
import lombok.Getter;

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.endpoints;
package bisq.daonode.endpoints;
import bisq.core.dao.state.model.blockchain.Tx;
@ -31,9 +31,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
import bisq.daoNode.DaoNode;
import bisq.daoNode.DaoNodeRestApiApplication;
import bisq.daoNode.dto.ProofOfBurnDto;
import bisq.daonode.DaoNode;
import bisq.daonode.DaoNodeRestApiApplication;
import bisq.daonode.dto.ProofOfBurnDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
@ -53,7 +53,7 @@ import jakarta.ws.rs.core.MediaType;
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Proof of burn API")
public class ProofOfBurnApi {
public static final String DESC_BLOCK_HEIGHT = "The block height from which we request the proof of burn data";
private static final String DESC_BLOCK_HEIGHT = "The block height from which we request the proof of burn data";
private final DaoNode daoNode;
public ProofOfBurnApi(@Context Application application) {

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.error;
package bisq.daonode.error;
import lombok.extern.slf4j.Slf4j;
@ -30,7 +30,7 @@ import jakarta.ws.rs.ext.Provider;
public class CustomExceptionMapper implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception exception) {
log.error(exception.getMessage(), exception);
log.error("", exception);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(new ErrorMessage(exception.getMessage()))
.build();

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.error;
package bisq.daonode.error;
import lombok.Getter;

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.error;
package bisq.daonode.error;
import lombok.Getter;
import lombok.Setter;

View File

@ -15,7 +15,7 @@
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daoNode.util;
package bisq.daonode.util;
import java.net.URI;

View File

@ -1,59 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.service;
import bisq.core.dao.state.DaoStateService;
import lombok.extern.slf4j.Slf4j;
import bisq.daonodeOld.web.WebServer;
import bisq.daonodeOld.web.jdk.JdkServer;
// Todo We should limit usage to localhost as its not intended at that stage to be used
// as a public API, but rather be used by Bisq 2 bridge clients or BSQ explorer nodes,
// both running in a localhost environment. As long that holds, we do not require a high
// level of protection against malicious usage.
// TODO This JDK http server is a super simple implementation. We might use some other
// lightweight REST server framework.
@Slf4j
public class DaoNodeService {
private WebServer webServer;
private DaoStateService daoStateService;
public DaoNodeService(DaoStateService daoStateService) {
this.daoStateService = daoStateService;
}
public void start(int port) {
try {
webServer = new JdkServer(port, daoStateService);
webServer.start();
} catch (Throwable t) {
log.error(t.toString());
}
}
public void shutDown() {
if (webServer != null) {
webServer.stop(0);
}
}
}

View File

@ -1,25 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web;
public interface WebServer {
void start();
void stop(int delay);
}

View File

@ -1,149 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk;
import bisq.core.dao.state.DaoStateService;
import bisq.common.util.Utilities;
import java.net.InetSocketAddress;
import java.io.IOException;
import java.util.concurrent.Executor;
import lombok.extern.slf4j.Slf4j;
import static bisq.daonodeOld.web.jdk.handler.ResourcePathElement.DAONODE;
import bisq.daonodeOld.web.WebServer;
import bisq.daonodeOld.web.jdk.handler.RestHandler;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
// https://dev.to/piczmar_0/framework-less-rest-api-in-java-1jbl
// https://doc.networknt.com/getting-started/light-rest-4j
// https://github.com/piczmar/pure-java-rest-api
// https://stackoverflow.com/questions/3732109/simple-http-server-in-java-using-only-java-se-api
// https://www.programcreek.com/java-api-examples/index.php?api=com.sun.net.httpserver.HttpServer
/**
* From https://stackoverflow.com/questions/3732109/simple-http-server-in-java-using-only-java-se-api
*
* Note that this is, in contrary to what some developers think, absolutely not forbidden
* by the well known FAQ Why Developers Should Not Write Programs That Call 'sun' Packages.
* That FAQ concerns the sun.* package (such as sun.misc.BASE64Encoder) for internal usage
* by the Oracle JRE (which would thus kill your application when you run it on a different
* JRE), not the com.sun.* package. Sun/Oracle also just develop software on top of the
* Java SE API themselves like as every other company such as Apache and so on. Moreover,
* this specific HttpServer must be present in every JDK so there is absolutely no means
* of "portability" issue like as would happen with sun.* package. Using com.sun.* classes
* is only discouraged (but not forbidden) when it concerns an implementation of a certain
* Java API, such as GlassFish (Java EE impl), Mojarra (JSF impl), Jersey (JAX-RS impl), etc.
*/
@Slf4j
public class JdkServer extends HttpServer implements WebServer {
public static void main(String[] args) throws InterruptedException {
WebServer webServer = new JdkServer(8080, null);
webServer.start();
Thread.sleep(40000);
webServer.stop(0);
}
private final int port;
private final DaoStateService daoStateService;
private HttpServer server;
public JdkServer(int port, DaoStateService daoStateService) {
this.port = port;
this.daoStateService = daoStateService;
configure();
}
private void configure() {
try {
this.server = HttpServer.create(new InetSocketAddress(port), 0);
// As use case is intended for a 1 client environment we can stick with a single thread.
setExecutor(Utilities.getSingleThreadExecutor("DaoNode-API"));
// Map all request URLs starting with "/daonode" to a single RestHandler.
// The RestHandler will pass valid requests on to an appropriate handler.
createContext("/" + DAONODE, new RestHandler(daoStateService));
} catch (IOException ex) {
log.error(ex.toString());
throw new RuntimeException(ex);
}
}
@Override
public void bind(InetSocketAddress addr, int backlog) throws IOException {
server.bind(addr, backlog);
}
@Override
public void start() {
server.start();
}
@Override
public void setExecutor(Executor executor) {
server.setExecutor(executor);
}
@Override
public Executor getExecutor() {
return server.getExecutor();
}
@Override
public HttpContext createContext(String path, HttpHandler handler) {
return server.createContext(path, handler);
}
@Override
public HttpContext createContext(String path) {
return server.createContext(path);
}
@Override
public void removeContext(String path) throws IllegalArgumentException {
server.removeContext(path);
}
@Override
public void removeContext(HttpContext context) {
server.removeContext(context);
}
@Override
public InetSocketAddress getAddress() {
return server.getAddress();
}
@Override
public void stop(int delay) {
if (server != null) {
server.stop(0);
}
}
}

View File

@ -1,115 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk.handler;
import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.Tx;
import bisq.common.util.Hex;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.toJson;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.wrapErrorResponse;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.wrapResponse;
import static bisq.daonodeOld.web.jdk.handler.ResourcePathElement.BLOCKHEIGHT;
import bisq.daoNode.dto.ProofOfBurnDto;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
/**
* Handles daonode/proofofburn requests. Request URLs must match:
* http://localhost:<port>/daonode/proofofburn/blockheight/<blockheight-value>
*
* Example: http://localhost:8080/daonode/proofofburn/blockheight/731270
*/
@Slf4j
public class GetProofOfBurnHandler implements HttpHandler {
private final DaoStateService daoStateService;
private final RequestSpec requestSpec;
/**
* A new handler instance must be used for each request. We do not want to parse
* details from each request URI more than once; they are passed to this constructor
* from the RestHandler via the RequestSpec argument.
*
* @param daoStateService DaoStateService singleton
* @param requestSpec RESTful request details, including parsed URL parameters
*/
public GetProofOfBurnHandler(DaoStateService daoStateService, RequestSpec requestSpec) {
this.daoStateService = daoStateService;
this.requestSpec = requestSpec;
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
try {
if (daoStateService == null) {
log.warn("DAO Node daoStateService is null; OK during web server dev/test.");
HandlerUtil.sendResponse(httpExchange, wrapResponse("[]"));
} else {
int blockHeight = requestSpec.getIntParam(BLOCKHEIGHT);
log.info("Requesting POB for blockheight {}.", blockHeight);
List<ProofOfBurnDto> list = getProofOfBurnDtoList(blockHeight);
if (list != null) {
HandlerUtil.sendResponse(httpExchange, toJson(list));
} else {
log.error("DAO Node Proof of Burn data for blockHeight {} is null.", blockHeight);
HandlerUtil.sendResponse(500,
httpExchange,
wrapErrorResponse(toJson("DAO Node proof of burn data is null.")));
}
}
} catch (RuntimeException ex) {
HandlerUtil.sendResponse(500,
httpExchange,
wrapErrorResponse(toJson(ex.getMessage())));
}
}
private List<ProofOfBurnDto> getProofOfBurnDtoList(int fromBlockHeight) {
return daoStateService.getProofOfBurnTxs().stream()
.filter(tx -> tx.getBlockHeight() >= fromBlockHeight)
.map(tx -> new ProofOfBurnDto(tx.getId(),
tx.getBurntBsq(),
tx.getBlockHeight(),
tx.getTime(),
getHash(tx)))
.collect(Collectors.toList());
}
// We strip out the version bytes
private String getHash(Tx tx) {
byte[] opReturnData = tx.getLastTxOutput().getOpReturnData();
if (opReturnData == null) {
return "";
}
return Hex.encode(Arrays.copyOfRange(opReturnData, 2, 22));
}
}

View File

@ -1,68 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.OutputStream;
import lombok.SneakyThrows;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.sun.net.httpserver.HttpExchange;
public class HandlerUtil {
public static void setDefaultResponseHeaders(HttpExchange httpExchange) {
httpExchange.getResponseHeaders().set("Content-Type", "application/json; charset=utf-8");
}
public static void sendResponse(HttpExchange httpExchange, String response) throws IOException {
sendResponse(200, httpExchange, response);
}
public static void sendResponse(int status, HttpExchange httpExchange, String response) throws IOException {
setDefaultResponseHeaders(httpExchange);
byte[] responseBytes = response.getBytes(UTF_8);
httpExchange.sendResponseHeaders(status, responseBytes.length);
OutputStream os = httpExchange.getResponseBody();
os.write(responseBytes);
os.close();
}
// TODO make as function toWhat?
public static String wrapResponse(String jsonData) {
return format("{\"data\":%s}", jsonData);
}
// TODO make as function toErrorWhat?
public static String wrapErrorResponse(String jsonError) {
return format("{\"error\":%s}", jsonError);
}
@SneakyThrows
public static String toJson(Object object) {
return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(object);
}
}

View File

@ -1,134 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk.handler;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import static java.lang.String.format;
import static java.lang.System.arraycopy;
import com.sun.net.httpserver.HttpExchange;
/**
* REST request URI parser to extract parameter names and values from an HttpExchange.
*
* Splits the HttpExchange's request URI into a String[] of pathElements identifying a
* (REST) service name, a resource name, and any parameter/value pairs.
*
* This class is limited to URIs adhering a specific pattern:
* pathElements[0] = service-name, e.g., daonode
* pathElements[1] = resource-name, e.g., proofofburn
* pathElements[2, 3...N, N+1] = param-name/value pairs.
*
* For example, request URL http://localhost:8080/daonode/proofofburn/blockheight/731270
* identifies service-name "daonode", resource-name "proofofburn", and one parameter
* "blockheight" with value 731270.
*/
@Getter
@Slf4j
public class RequestSpec {
private final HttpExchange httpExchange;
private final String method;
private final URI requestURI;
private final String[] pathElements;
private final String serviceName;
private final String resourceName;
private final Map<String, String> parametersByName;
public RequestSpec(HttpExchange httpExchange) {
this.httpExchange = httpExchange;
this.method = httpExchange.getRequestMethod();
this.requestURI = httpExchange.getRequestURI();
this.pathElements = toPathElements.apply(requestURI);
this.serviceName = pathElements[0];
this.resourceName = pathElements[1];
try {
this.parametersByName = getParametersByName();
} catch (URISyntaxException ex) {
// OK to throw ex in this constructor?
log.error(ex.toString());
throw new IllegalArgumentException(ex.toString());
}
}
public boolean isRequestingResource(String resourceName) {
return this.resourceName.equalsIgnoreCase(resourceName);
}
public String getStringParam(String paramName) {
if (parametersByName.containsKey(paramName))
return parametersByName.get(paramName);
else
throw new IllegalArgumentException(format("Parameter '%s' not found.", paramName));
}
public int getIntParam(String paramName) {
if (parametersByName.containsKey(paramName)) {
var value = parametersByName.get(paramName);
try {
return Integer.parseInt(value);
} catch (NumberFormatException ex) {
throw new IllegalArgumentException(
format("Parameter '%s' value '%s' is not a number.",
paramName,
value));
}
} else {
throw new IllegalArgumentException(format("Parameter '%s' not found.", paramName));
}
}
private final Function<URI, String[]> toPathElements = (uri) -> {
String[] raw = uri.getPath().split("/");
String[] elements = new String[raw.length - 1];
arraycopy(raw, 1, elements, 0, elements.length);
return elements;
};
private Map<String, String> getParametersByName() throws URISyntaxException {
Map<String, String> params = new HashMap<>();
if (pathElements.length == 2)
return params; // There are no parameter name/value pairs in url.
// All pathElements beyond index 1 should be param-name/value pairs, and
// a param-value must follow each param-name.
Predicate<Integer> paramValueExists = (i) -> (i + 1) < pathElements.length;
for (int i = 2; i < pathElements.length; i++) {
String name = pathElements[i];
if (paramValueExists.test(i))
params.put(name, pathElements[++i]);
else
throw new URISyntaxException(requestURI.getPath(),
format("No value found for parameter with name '%s'.", name),
-1);
}
return params;
}
}

View File

@ -1,24 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk.handler;
public class ResourcePathElement {
public static String DAONODE = "daonode";
public static final String BLOCKHEIGHT = "blockheight";
public static final String PROOFOFBURN = "proofofburn";
}

View File

@ -1,78 +0,0 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/
package bisq.daonodeOld.web.jdk.handler;
import bisq.core.dao.state.DaoStateService;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.sendResponse;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.toJson;
import static bisq.daonodeOld.web.jdk.handler.HandlerUtil.wrapErrorResponse;
import static bisq.daonodeOld.web.jdk.handler.ResourcePathElement.PROOFOFBURN;
import static java.util.Objects.requireNonNull;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
/**
* All HTTP requests are routed to a singleton RestHandler, then passed on to
* appropriate sub handler instances.
*/
@Slf4j
public class RestHandler implements HttpHandler {
private final DaoStateService daoStateService;
public RestHandler(DaoStateService daoStateService) {
this.daoStateService = daoStateService;
}
@Override
public void handle(HttpExchange httpExchange) throws IOException {
try {
requireNonNull(httpExchange, "HttpExchange cannot be null.");
// Parse the request URI details here, and pass them to a new
// sub handler instance.
RequestSpec requestSpec = new RequestSpec(httpExchange);
// Atm we only use GET, no plans yet for allow POST for DaoNode API.
if (!requestSpec.getMethod().equals("GET")) {
sendResponse(405,
httpExchange,
wrapErrorResponse(toJson("Forbidden HTTP method " + requestSpec.getMethod())));
} else if (requestSpec.isRequestingResource(PROOFOFBURN)) {
new GetProofOfBurnHandler(daoStateService, requestSpec).handle(httpExchange);
} else {
sendResponse(404, httpExchange, wrapErrorResponse(toJson("Not Found")));
}
} catch (RuntimeException ex) {
sendResponse(500,
httpExchange,
wrapErrorResponse(toJson(ex.getMessage())));
} finally {
httpExchange.close();
}
}
}