diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index d330260..65ddbaa 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.mymetaverse.sdk
java-sdk
- 2.4.0
+ 2.5.2
package install
${project.name}-${project.version}
diff --git a/pom.xml b/pom.xml
index 498cf4b..199b4c2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,8 @@
io.mymetaverse.sdk
java-sdk
- 2.4.0
+ 2.5.2
+
8
diff --git a/src/main/java/io/mymetavese/metaapi/api/RestAction.java b/src/main/java/io/mymetavese/metaapi/api/RestAction.java
index 6580a03..77acd5c 100644
--- a/src/main/java/io/mymetavese/metaapi/api/RestAction.java
+++ b/src/main/java/io/mymetavese/metaapi/api/RestAction.java
@@ -3,7 +3,9 @@
import io.mymetavese.metaapi.MetaAPIImpl;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
public interface RestAction {
@@ -23,7 +25,6 @@ public interface RestAction {
/**
* Submits a request for execution in asynchronous logic.
*
- *
* @param success The success callback from the request.
* @param failure The callback error from the request.
*/
@@ -32,7 +33,6 @@ public interface RestAction {
/**
* Submits a request for execution in asynchronous logic.
*
- *
* @param success The success callback from the request.
*/
default void queue(Consumer super T> success) {
@@ -46,6 +46,13 @@ default void queue(Consumer super T> success) {
*/
T complete();
+ /**
+ * Submits a Request in synchronous logic with a Timeout
+ *
+ * @return The response of the Request.
+ */
+ T complete(long timeout, TimeUnit timeUnit) throws ExecutionException, InterruptedException, TimeoutException;
+
/**
* Submits a request for execution after some time delay.
* @param time The time
diff --git a/src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLink.java b/src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLinkAction.java
similarity index 67%
rename from src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLink.java
rename to src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLinkAction.java
index 4756f98..92ca2ae 100644
--- a/src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLink.java
+++ b/src/main/java/io/mymetavese/metaapi/api/actions/GetLinkingLinkAction.java
@@ -3,5 +3,5 @@
import io.mymetavese.metaapi.api.RestAction;
import io.mymetavese.metaapi.api.entities.LinkingLink;
-public interface GetLinkingLink extends RestAction {
+public interface GetLinkingLinkAction extends RestAction {
}
diff --git a/src/main/java/io/mymetavese/metaapi/api/entities/v2/GameEntity.java b/src/main/java/io/mymetavese/metaapi/api/entities/v2/GameEntity.java
index 0118f4c..376dd5f 100644
--- a/src/main/java/io/mymetavese/metaapi/api/entities/v2/GameEntity.java
+++ b/src/main/java/io/mymetavese/metaapi/api/entities/v2/GameEntity.java
@@ -59,7 +59,7 @@ public interface GameEntity extends ApiEntity {
*
* @return An action that represents the linking link.
*/
- GetLinkingLink getLinkingLink();
+ GetLinkingLinkAction getLinkingLink();
/**
* Get the currently active metacitizen for this game entity.
diff --git a/src/main/java/io/mymetavese/metaapi/requests/RequestGenerator.java b/src/main/java/io/mymetavese/metaapi/requests/RequestGenerator.java
index 4edf7d4..f12ae14 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/RequestGenerator.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/RequestGenerator.java
@@ -8,7 +8,6 @@
import okhttp3.internal.http.HttpMethod;
import java.io.IOException;
-import java.util.Objects;
public class RequestGenerator {
@@ -29,6 +28,7 @@ public void asyncRequest(Request> request) {
}
public void request(Request> request) {
+
String route = request.getCompiledRoute();
okhttp3.Request.Builder builder = new okhttp3.Request.Builder();
@@ -52,28 +52,29 @@ else if(bodyObject != null)
if (request.getHeaders() != null && !request.getHeaders().isEmpty())
request.getHeaders().forEach(builder::addHeader);
- // Maybe should add attempts here.
- try(Response response = httpClient.newCall(builder.build()).execute()) {
+ try (Response response = httpClient.newCall(builder.build()).execute()) {
+
if (response.code() >= 500) {
- throw new IOException("Internal server error: " + Objects.requireNonNull(response.body()).string());
+ String responseBodyString = response.peekBody(Long.MAX_VALUE).string();
+ request.handleResponse(response);
+ throw new IOException("Internal server error: " + responseBodyString);
}
- if(response.code() == 401 && request.getAttempts() < 2) {
+ // Try to Re-authenticate if the token is invalid and the re-authentication has not been attempted for more
+ // than 2 times.
+ if (response.code() == 401 && request.getAttempts() < 2) {
+
request.addAttempt();
- api.getTokenHandler().reauthenticate();
+ api.getTokenHandler().authenticate();
this.request(request);
- return;
+
+ } else {
+ request.handleResponse(response);
}
- request.handleResponse(response);
} catch (IOException ex) {
ex.printStackTrace();
-
- if(request.getAttempts() < 2) {
- request.addAttempt();
- this.request(request);
- }
}
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/RestActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/RestActionImpl.java
index e64ea4c..544ceee 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/RestActionImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/RestActionImpl.java
@@ -15,6 +15,9 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
public abstract class RestActionImpl extends Transformable implements RestAction {
@@ -104,5 +107,11 @@ public void queue(Consumer super T> success, Consumer super RequestError> fa
public T complete() {
return submit().join();
}
+
+ @Override
+ public T complete(long timeout, TimeUnit timeUnit) throws ExecutionException, InterruptedException, TimeoutException {
+ return submit().get(timeout, timeUnit);
+ }
+
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/actions/GetLinkingLinkActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/actions/GetLinkingLinkActionImpl.java
index b606df5..54ecaf1 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/actions/GetLinkingLinkActionImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/actions/GetLinkingLinkActionImpl.java
@@ -1,14 +1,14 @@
package io.mymetavese.metaapi.requests.actions;
import io.mymetavese.metaapi.api.MetaAPI;
-import io.mymetavese.metaapi.api.actions.GetLinkingLink;
+import io.mymetavese.metaapi.api.actions.GetLinkingLinkAction;
import io.mymetavese.metaapi.api.entities.v2.GameEntity;
import io.mymetavese.metaapi.api.entities.LinkingLink;
import io.mymetavese.metaapi.requests.RestActionImpl;
import io.mymetavese.metaapi.requests.entities.LinkingLinkImpl;
import io.mymetavese.metaapi.requests.routes.Routes;
-public class GetLinkingLinkActionImpl extends RestActionImpl implements GetLinkingLink {
+public class GetLinkingLinkActionImpl extends RestActionImpl implements GetLinkingLinkAction {
private final GameEntity gameEntity;
diff --git a/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java
index e6a0995..02c7510 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/actions/drops/ConsumeDropActionImpl.java
@@ -1,6 +1,5 @@
package io.mymetavese.metaapi.requests.actions.drops;
-import com.google.gson.Gson;
import com.google.gson.JsonArray;
import io.mymetavese.metaapi.api.MetaAPI;
import io.mymetavese.metaapi.api.actions.drops.ConsumeDropAction;
@@ -11,12 +10,8 @@
import io.mymetavese.metaapi.requests.RestActionImpl;
import io.mymetavese.metaapi.requests.entities.drops.responses.DropConsumedResponseImpl;
import io.mymetavese.metaapi.requests.routes.Routes;
-import okhttp3.Response;
-import java.io.IOException;
-import java.io.Reader;
import java.util.List;
-import java.util.Objects;
public class ConsumeDropActionImpl extends RestActionImpl implements ConsumeDropAction {
@@ -31,24 +26,6 @@ public ConsumeDropActionImpl(MetaAPI api, String dropId, GameEntity dropReceiver
this.dropEntryRequirements = dropEntryRequirements;
}
- @Override
- public DropConsumedResponse transform(Response response) {
-
- if (response == null || response.body() == null) {
- throw new NullPointerException("Response cannot be null");
- }
-
- Gson gson = new Gson();
- try (Reader reader = Objects.requireNonNull(response.body()).charStream()) {
- return gson.fromJson(reader, DropConsumedResponseImpl.class);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
-
- return null;
-
- }
-
@Override
protected String compileRoute() {
return route.compileRoute(dropId);
diff --git a/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java b/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
index 65f5444..976737a 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/entities/GameEntityImpl.java
@@ -56,7 +56,7 @@ public CreateLinkingLinkAction createLinkingLink() {
}
@Override
- public GetLinkingLink getLinkingLink() {
+ public GetLinkingLinkAction getLinkingLink() {
return new GetLinkingLinkActionImpl(metaAPI, this);
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/StaticToken.java b/src/main/java/io/mymetavese/metaapi/requests/token/StaticToken.java
index d1fae2b..4c813df 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/token/StaticToken.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/StaticToken.java
@@ -15,5 +15,5 @@ public static StaticToken create(String token) {
}
@Override
- public void reauthenticate() { }
+ public void authenticate() { }
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/TokenHandler.java b/src/main/java/io/mymetavese/metaapi/requests/token/TokenHandler.java
index db4210d..85c3e93 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/token/TokenHandler.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/TokenHandler.java
@@ -4,6 +4,6 @@ public interface TokenHandler {
String getToken();
- void reauthenticate();
+ void authenticate();
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthToken.java b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthToken.java
new file mode 100644
index 0000000..6cd64d8
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthToken.java
@@ -0,0 +1,66 @@
+package io.mymetavese.metaapi.requests.token.oauth;
+
+import io.mymetavese.metaapi.requests.token.TokenHandler;
+import io.mymetavese.metaapi.requests.token.oauth.scopes.OAuthScope;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public interface OAuthToken extends TokenHandler {
+
+ List getOAuthScopes();
+
+ String getBaseAuthUrl();
+
+ final class Builder {
+
+ private String clientID;
+ private String clientSecret;
+ private String authenticationAddress = "cloud.mymetaverse.io";
+ private final List scopes = new ArrayList<>();
+
+ private Builder() { }
+
+ public static OAuthToken.Builder createBuilder() {
+ return new OAuthToken.Builder();
+ }
+
+ public OAuthToken.Builder withClientID(String clientID) {
+ this.clientID = clientID;
+ return this;
+ }
+
+ public OAuthToken.Builder withClientSecret(String clientSecret) {
+ this.clientSecret = clientSecret;
+ return this;
+ }
+
+ public OAuthToken.Builder withAuthenticationAddress(String authenticationAddress) {
+ this.authenticationAddress = authenticationAddress;
+ return this;
+ }
+
+ public OAuthToken.Builder useScopes(OAuthScope... scopes) {
+ Arrays.stream(scopes).forEach(scope -> this.scopes.add(scope.getScope()));
+ return this;
+ }
+
+ public OAuthToken.Builder useScopes(String... scopes) {
+ this.scopes.addAll(Arrays.asList(scopes));
+ return this;
+ }
+
+ public OAuthTokenImpl build() {
+ return new OAuthTokenImpl(clientID, clientSecret, authenticationAddress, scopes);
+ }
+
+ public OAuthTokenImpl buildAuthenticated() {
+ OAuthTokenImpl oAuthToken = new OAuthTokenImpl(clientID, clientSecret, authenticationAddress, scopes);
+ oAuthToken.authenticate();
+ return oAuthToken;
+ }
+
+ }
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/OAuthToken.java b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenImpl.java
similarity index 54%
rename from src/main/java/io/mymetavese/metaapi/requests/token/OAuthToken.java
rename to src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenImpl.java
index c8969b3..8dffd63 100644
--- a/src/main/java/io/mymetavese/metaapi/requests/token/OAuthToken.java
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenImpl.java
@@ -1,55 +1,52 @@
-package io.mymetavese.metaapi.requests.token;
+package io.mymetavese.metaapi.requests.token.oauth;
import com.google.gson.Gson;
-import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
import okhttp3.*;
import java.io.IOException;
-import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
-public class OAuthToken implements TokenHandler {
+public class OAuthTokenImpl implements OAuthToken {
- private final static MediaType JSON_MEDIA_TYPE = MediaType.get("application/x-www-form-urlencoded; charset=utf-8");
- private static final RequestBody EMPTY_BODY = RequestBody.create(new byte[0], JSON_MEDIA_TYPE);
- // Data to generate token
private final OkHttpClient httpClient;
- private final Gson gson;
private final String clientId;
private final String clientSecret;
- private final String[] oAuthScopes;
- private final String baseAuthUrl;
+ @Getter private final List oAuthScopes;
+ @Getter private final String baseAuthUrl;
- private OAuthToken(final String clientId, final String clientSecret, final String baseAuthUrl) {
+ private long tokenExpireTime = 0;
+ private String accessToken;
+ private String refreshToken;
+
+ OAuthTokenImpl(final String clientId, final String clientSecret, final String baseAuthUrl, final List oAuthScopes) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseAuthUrl = baseAuthUrl;
- this.oAuthScopes = new String[] {"wallet.read", "p2e.read", "p2e.add", "linkinglink.create", "linkinglink.read", "linkinglink.implicit"};
+ this.oAuthScopes = oAuthScopes;
this.httpClient = new OkHttpClient();
- this.gson = new Gson();
}
- // WalletIndex Hybrid
- private long tokenExpireTime = 0;
- private String accessToken;
- private String refreshToken;
-
private boolean shouldUpdateToken() {
long currentTime = System.currentTimeMillis();
-
return this.tokenExpireTime - currentTime <= 0;
}
private void requestToken(boolean withCredentials) {
- Request.Builder builder = new Request.Builder();
+ Gson gson = new Gson();
+ Request.Builder builder = new Request.Builder();
HttpUrl.Builder urlBuilder = new HttpUrl.Builder();
+ if (this.oAuthScopes == null || this.oAuthScopes.isEmpty())
+ throw new RuntimeException("OAuth scopes are not available, please provide at least one OAuth Scope.");
+
urlBuilder
.scheme("https")
.host(baseAuthUrl)
@@ -76,19 +73,19 @@ private void requestToken(boolean withCredentials) {
}
builder.url(urlBuilder.build());
-
builder.post(formBody.build());
try (Response response = httpClient.newCall(builder.build()).execute()) {
+
if (response.code() != 200) {
throw new IOException("Internal server error: " + Objects.requireNonNull(response.body()).string());
}
- TokenResponse tokenResponse = this.gson.fromJson(Objects.requireNonNull(response.body()).charStream(), TokenResponse.class);
+ TokenResponse tokenResponse = gson.fromJson(Objects.requireNonNull(response.body()).charStream(), TokenResponse.class);
- this.accessToken = tokenResponse.accessToken;
- this.refreshToken = tokenResponse.refreshToken;
- this.tokenExpireTime = System.currentTimeMillis() + (tokenResponse.expiresIn * 1000L);
+ this.accessToken = tokenResponse.getAccessToken();
+ this.refreshToken = tokenResponse.getRefreshToken();
+ this.tokenExpireTime = System.currentTimeMillis() + (tokenResponse.getExpiresIn() * 1000L);
} catch (IOException ex) {
ex.printStackTrace();
@@ -96,30 +93,11 @@ private void requestToken(boolean withCredentials) {
}
- public static OAuthToken create(final String clientId, final String clientSecret) {
- OAuthToken tokenHandler = new OAuthToken(clientId, clientSecret, "cloud.mymetaverse.io");
- tokenHandler.requestToken(true);
- return tokenHandler;
- }
-
- public static OAuthToken create(final String clientId, final String clientSecret, final String baseAuthUrl) {
- OAuthToken tokenHandler = new OAuthToken(clientId, clientSecret, baseAuthUrl);
- tokenHandler.requestToken(true);
- return tokenHandler;
- }
-
- @Override
- public String getToken() {
- if (shouldUpdateToken())
- this.requestToken(false);
- return accessToken;
- }
-
- public String getOAuthScopesAsString() {
+ private String getOAuthScopesAsString() {
StringBuilder oAuthScopesStringBuilder = new StringBuilder();
- Arrays.stream(this.oAuthScopes).forEach(scope -> {
+ this.oAuthScopes.forEach(scope -> {
oAuthScopesStringBuilder.append(scope);
oAuthScopesStringBuilder.append(" ");
});
@@ -129,19 +107,15 @@ public String getOAuthScopesAsString() {
}
@Override
- public void reauthenticate() {
- this.requestToken(true);
+ public String getToken() {
+ if (shouldUpdateToken())
+ this.requestToken(false);
+ return accessToken;
}
- private static class TokenResponse {
- @SerializedName("access_token")
- private String accessToken;
- @SerializedName("token_type")
- private String tokenType;
- @SerializedName("expires_in")
- private int expiresIn;
- @SerializedName("refresh_token")
- private String refreshToken;
+ @Override
+ public void authenticate() {
+ this.requestToken(true);
}
}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/oauth/TokenResponse.java b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/TokenResponse.java
new file mode 100644
index 0000000..8081765
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/TokenResponse.java
@@ -0,0 +1,18 @@
+package io.mymetavese.metaapi.requests.token.oauth;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+@Data
+public class TokenResponse {
+
+ @SerializedName("access_token")
+ private String accessToken;
+ @SerializedName("token_type")
+ private String tokenType;
+ @SerializedName("expires_in")
+ private int expiresIn;
+ @SerializedName("refresh_token")
+ private String refreshToken;
+
+}
diff --git a/src/main/java/io/mymetavese/metaapi/requests/token/oauth/scopes/OAuthScope.java b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/scopes/OAuthScope.java
new file mode 100644
index 0000000..13e19f6
--- /dev/null
+++ b/src/main/java/io/mymetavese/metaapi/requests/token/oauth/scopes/OAuthScope.java
@@ -0,0 +1,20 @@
+package io.mymetavese.metaapi.requests.token.oauth.scopes;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+
+@RequiredArgsConstructor
+@Getter
+@ToString
+public enum OAuthScope {
+
+ WALLET_READ("wallet.read"),
+ P2E_READ("p2e.read"),
+ P2E_ADD("p2e.add"),
+ LINKING_CREATE("linkinglink.create"),
+ LINKING_READ("linkinglink.read");
+
+ private final String scope;
+
+}
diff --git a/src/test/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenTest.java b/src/test/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenTest.java
new file mode 100644
index 0000000..3d1ddb6
--- /dev/null
+++ b/src/test/java/io/mymetavese/metaapi/requests/token/oauth/OAuthTokenTest.java
@@ -0,0 +1,39 @@
+package io.mymetavese.metaapi.requests.token.oauth;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class OAuthTokenTest {
+
+ @Test
+ @DisplayName("Test OAuthTokenBuilder")
+ void testOAuthTokenBuilder() {
+
+ String clientID = "dummyClientID";
+ String clientSecret = "dummyClientSecret";
+ String authenticationAddress = "dummyAuthenticationAddress";
+ String[] scopes = new String[] {"dummyScope1", "dummyScope2"};
+
+ OAuthToken oAuthToken = OAuthToken.Builder.createBuilder()
+ .withClientID(clientID)
+ .withClientSecret(clientSecret)
+ .withAuthenticationAddress(authenticationAddress)
+ .useScopes(scopes)
+ .build();
+
+ assertThat(oAuthToken)
+ .isNotNull()
+ .isInstanceOf(OAuthTokenImpl.class)
+ .hasFieldOrPropertyWithValue("clientId", clientID)
+ .hasFieldOrPropertyWithValue("clientSecret", clientSecret)
+ .hasFieldOrPropertyWithValue("baseAuthUrl", authenticationAddress);
+
+ assertThat(oAuthToken.getOAuthScopes())
+ .hasSize(2)
+ .containsExactly(scopes);
+
+ }
+
+}
\ No newline at end of file