Skip to content

Commit

Permalink
More HTTP refactoring for different content types
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Sep 21, 2024
1 parent 14332c2 commit 213ed52
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 37 deletions.
2 changes: 0 additions & 2 deletions convex-java/src/main/java/convex/java/Convex.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.core5.concurrent.FutureCallback;
import org.apache.hc.core5.http.ContentType;

import convex.core.ErrorCodes;
Expand Down
27 changes: 27 additions & 0 deletions convex-peer/src/main/java/convex/api/ContentTypes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package convex.api;

/**
* MIME content types used for peer-to=peer communication
*/
public class ContentTypes {

/**
* Content type for plain test
*/
public static final String TEXT="text/plain";

/**
* Content type for JSON
*/
public static final String JSON="application/json";

/**
* Content type for CVX Readable format
*/
public static final String CVX="application/cvx";

/**
* Content type for CVX raw encoding
*/
public static final String CVX_RAW="application/cvx-raw";
}
78 changes: 43 additions & 35 deletions convex-restapi/src/main/java/convex/restapi/api/ChainAPI.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package convex.restapi.api;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import convex.api.ContentTypes;
import convex.api.Convex;
import convex.core.Coin;
import convex.core.ErrorCodes;
Expand Down Expand Up @@ -98,7 +101,12 @@ public void addRoutes(Javalin app) {
summary = "Get data from the server with the specified hash",
operationId = "data",
pathParams = {
@OpenApiParam(name = "hash", description = "Data hash as a hex string. Leading '0x' is optional but discouraged.", required = true, type = String.class, example = "0x1234567812345678123456781234567812345678123456781234567812345678") })
@OpenApiParam(
name = "hash",
description = "Data hash as a hex string. Leading '0x' is optional but discouraged.",
required = true,
type = String.class,
example = "0x1234567812345678123456781234567812345678123456781234567812345678") })
public void getData(Context ctx) {
String hashParam = ctx.pathParam("hash");
Hash h = Hash.parse(hashParam);
Expand Down Expand Up @@ -202,7 +210,7 @@ public void queryAccount(Context ctx) throws InterruptedException {
throw new BadRequestResponse(jsonError("Invalid address: " + addrParam));
}

Result r = doQuery(Lists.of(Symbols.ACCOUNT, addr));
Result r = convex.querySync(Lists.of(Symbols.ACCOUNT, addr));

if (r.isError()) {
prepareResult(ctx,r);
Expand Down Expand Up @@ -241,7 +249,7 @@ public void queryPeer(Context ctx) throws InterruptedException {
throw new BadRequestResponse(jsonError("Invalid peer key: " + addrParam));
}

Result r = doQuery(Reader.read("(get-in *state* [:peers " + addr + "])"));
Result r = convex.querySync(Reader.read("(get-in *state* [:peers " + addr + "])"));

if (r.isError()) {
prepareResult(ctx,r);
Expand All @@ -258,33 +266,6 @@ public void queryPeer(Context ctx) throws InterruptedException {
ctx.result(JSON.toPrettyString(hm));
}

/**
* Runs a query, wrapping exceptions
*
* @param form
* @return
* @throws InterruptedException
*/
private Result doQuery(ACell form) throws InterruptedException {
return convex.querySync(form);
}

/**
* Runs a transaction, wrapping exceptions
*
* @param form
* @return
*/
private Result doTransaction(SignedData<ATransaction> signedTransaction) {
try {
return convex.transactSync(signedTransaction);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new InternalServerErrorResponse("Failed to execute transaction: " + e);
}
}


private static Keyword K_FAUCET=Keyword.create("faucet");

@OpenApi(path = ROUTE + "faucet",
Expand Down Expand Up @@ -516,7 +497,7 @@ public void runTransact(Context ctx) throws InterruptedException, IOException {
AKeyPair kp = AKeyPair.create(seed.toFlatBlob());
SignedData<ATransaction> sd = kp.signData(trans);

Result r = doTransaction(sd);
Result r = convex.transactSync(sd);
prepareResult(ctx,r);
}

Expand Down Expand Up @@ -559,7 +540,7 @@ private static ACell readCode(Object srcValue) {
description = "Transaction service unavailable" )
}
)
public void runTransactionSubmit(Context ctx) {
public void runTransactionSubmit(Context ctx) throws InterruptedException {
Map<String, Object> req = getJSONBody(ctx);

// Get the transaction hash
Expand Down Expand Up @@ -607,7 +588,7 @@ public void runTransactionSubmit(Context ctx) {
ASignature sig = Ed25519Signature.fromBlob(sigData);

SignedData<ATransaction> sd = SignedData.create(key, sig, trans.getRef());
Result r = doTransaction(sd);
Result r = convex.transactSync(sd);
prepareResult(ctx,r);
}

Expand Down Expand Up @@ -664,9 +645,36 @@ public void runQuery(Context ctx) throws InterruptedException {
}

private void prepareResult(Context ctx, Result r) {
HashMap<String, Object> resultJSON = r.toJSON();
ctx.status(r.isError()?422:200);
ctx.result(JSON.toPrettyString(resultJSON));
Enumeration<String> accepts=ctx.req().getHeaders("Accept");
String accept=ContentTypes.JSON;
if (accepts!=null) {
for (String a:Collections.list(accepts)) {
if (a.contains(ContentTypes.CVX_RAW)) {
accept=ContentTypes.CVX_RAW;
break;
}
if (a.contains(ContentTypes.CVX)) {
accept=ContentTypes.CVX;
}
}
}

if (accept.equals(ContentTypes.JSON)) {
ctx.contentType(ContentTypes.JSON);
HashMap<String, Object> resultJSON = r.toJSON();
ctx.result(JSON.toPrettyString(resultJSON));
} else if (accept.equals(ContentTypes.CVX)) {
ctx.contentType(ContentTypes.CVX);
ctx.result(RT.print(r).toString());
} else if (accept.equals(ContentTypes.CVX_RAW)) {
ctx.contentType(ContentTypes.CVX_RAW);
ctx.result(Format.encodeMultiCell(r, true).getBytes());
} else {
ctx.contentType(ContentTypes.TEXT);
ctx.status(400);
ctx.result("Unsupported content type: "+accept);
}
}

}

0 comments on commit 213ed52

Please sign in to comment.