Skip to content
This repository has been archived by the owner on Feb 19, 2024. It is now read-only.

New API #297

Merged

Conversation

siy
Copy link
Contributor

@siy siy commented May 25, 2021

  • Deep refactoring of the whole subsystem
  • Endpoint configuration according to new specification
  • Most endpoints now using JSON RPC protocol
  • Each endpoint is individually configurable (enable/disable)
  • Enforced disabling of non-production endpoints (/faucet, /chaos)
  • Added handling of Radix-specific headers (X-Radixdlt-Method and X-Radixdlt-Correlation-Id)
  • Restored handling of unstake positions
  • Added support for configuration of binding address for Node and Archive HTTP servers

@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch 3 times, most recently from 564ac24 to 3f8b98c Compare May 31, 2021 09:31
@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch 2 times, most recently from b6aeec5 to 01b97cf Compare June 2, 2021 14:17
@rvelaz rvelaz changed the base branch from rc/1.0-beta.35 to rc/1.0-beta.36 June 2, 2021 15:35
@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch 7 times, most recently from 018b1c2 to 39e5f76 Compare June 11, 2021 08:10
Copy link
Member

@iamyulong iamyulong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid work! The new API is well organised and clean.

I only managed to review about 1/3 of it. Will find another time to continue with the remaining.


</details>

## New Organization of APIs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new organisation looks much better!!!

@Override
public void configureRoutes(final RoutingHandler handler) {
handler.get("/health", this::handleHealthRequest);
handler.get("/health/", this::handleHealthRequest);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: don't think we need both; it only causes confusion rather than does anything good.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes both paths accepted by server. Such a minor thing as trailing slash should not cause issues to client

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand your intention but not totally agree.

We should encourage clients to use the correct endpoint (less flexible), rather than to correct their mistakes.

handler.post("/rpc", this::handleRpc);
handler.post("/rpc/", this::handleRpc);
handler.get("/universe.json", this::handleUniverseRequest);
handler.get("/universe.json/", this::handleUniverseRequest);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly

radixdlt-core/docs/api-info.md Outdated Show resolved Hide resolved
Copy link
Member

@iamyulong iamyulong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments

RuntimeProperties properties
) {
this.port = properties.get("node_api.port", DEFAULT_PORT);
this.port = properties.get("api.node.port", DEFAULT_PORT);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might also consider making the binding network interface configurable, as suggested by #321

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good idea, but for other PR

private JSONObject constructBalanceEntry(REAddr rri, UInt384 amount) {
return clientApiStore.getTokenDefinition(rri)
.fold(
__ -> jsonObject().put("rri", "<unknown>").put("amount", amount),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to have RRI with no definition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a safety guard in case if there are any issues with DB which may prevent retrieving token definition

RADIXDLT_VALIDATION_API_ENABLE=true \
RADIXDLT_UNIVERSE_API_ENABLE=true \
RADIXDLT_VERSION_API_ENABLE=true \
RADIXDLT_ARCHIVE_API_PORT=8080
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These shouldn't all be enabled by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

- `/validation` - read-only methods which provide same information as available today via all `/node/*` endpoints
- `/system` - read-only methods which provide same information as available today via all `/system/*` endpoints

- The `/system`, `/account` and `/validator` endpoints are expected to be protected by firewall and/or require authentication/etc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be /validation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

- The `/system`, `/account` and `/validator` endpoints are expected to be protected by firewall and/or require authentication/etc.
(similar requirements/setup as we have today)

### REST APIs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should stop calling these REST endpoints as its not really RESTful: https://en.wikipedia.org/wiki/Representational_state_transfer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


private UniverseType universeType(UniverseModule universeModule) {
try {
return universeModule.universe(properties, DefaultSerialization.getInstance()).type();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have getters in Modules as this is the purpose of dependency injection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a workaround for the situation when I need to make configuration decision using already configured in "Guice map" information. Unfortunately, this information is not easily available via other means.

Perhaps we should consider configuring Guice in "layered" fashion, when initially we configure "startup" injector with core things (like runtime properties and universe) and then assemble a working injector using "startup" injector to inject core dependencies.

var nodeEndpoints = enabledNodeEndpoints(properties, universeType);

bind(new TypeLiteral<List<EndpointConfig>>() {}).annotatedWith(AtNode.class).toInstance(nodeEndpoints);
bind(new TypeLiteral<List<EndpointConfig>>() {}).annotatedWith(AtArchive.class).toInstance(archiveEndpoints);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems broken to me, we should not have bindings to objects which contain Modules. All information should be communicated via dependency injection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

private final String symbol;
private final String iconUrl;
private final String tokenUrl;
private final String description;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like its starting to become unweildy

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored.

import static com.radixdlt.api.JsonRpcUtil.jsonObject;
import static com.radixdlt.api.JsonRpcUtil.response;

@Singleton
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided early on not to use @singleton so that this can be managed only by Modules themselves.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was not involved in that decision. Anyway, fixed.

@Qualifier
@Target({ FIELD, PARAMETER, METHOD })
@Retention(RUNTIME)
public @interface Account {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Account name is too generic and should be changed to something more specific to the API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -33,6 +35,7 @@
/**
* High level JSON RPC client API store.
*/
@ImplementedBy(BerkeleyClientApiStore.class)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be managed by Modules and not the class itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

public AccountService(
RadixEngine<LedgerAndBFTProof> radixEngine,
@Self ECPublicKey bftKey,
ClientApiStore clientApiStore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccountService should not be dependent on ClientApiStore as we don't want all nodes to run another database

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch from 33bc496 to c4b8efc Compare June 14, 2021 11:17
@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch 5 times, most recently from 1c34379 to 72ec61b Compare June 21, 2021 07:10
@siy siy force-pushed the feature/rpnv1-1306-refactor-json-rpc-implementation branch from 6ec3b96 to a43fe68 Compare June 22, 2021 09:12
@sonarqubecloud
Copy link

@shambupujar shambupujar merged commit 4e96308 into rc/1.0-beta.36 Jun 22, 2021
@talekhinezh talekhinezh deleted the feature/rpnv1-1306-refactor-json-rpc-implementation branch August 13, 2021 16:20
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants