Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import com.amplifyframework.annotations.InternalAmplifyApi;

/**
* Creates a {@link Gson} instance which may be used around the API plugin.
*/
final class GsonFactory {
@InternalAmplifyApi
public final class GsonFactory {
private static Gson gson = null;

private GsonFactory() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,25 @@
import java.util.ArrayList;
import java.util.List;

import com.amplifyframework.annotations.InternalAmplifyApi;

/**
* Converts JSON strings into models of a given type, using Gson.
*/
final class GsonGraphQLResponseFactory implements GraphQLResponse.Factory {
@InternalAmplifyApi
public final class GsonGraphQLResponseFactory implements GraphQLResponse.Factory {
private final Gson gson;

private final AWSApiSchemaRegistry schemaRegistry = new AWSApiSchemaRegistry();

GsonGraphQLResponseFactory() {
@InternalAmplifyApi
public GsonGraphQLResponseFactory() {
this(GsonFactory.instance());
}

@VisibleForTesting
GsonGraphQLResponseFactory(Gson gson) {
@InternalAmplifyApi
public GsonGraphQLResponseFactory(Gson gson) {
this.gson = gson;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@
import java.util.Date;
import java.util.Locale;

import com.amplifyframework.annotations.InternalAmplifyApi;

/**
* Utility to create a ISO 8601 compliant timestamps.
* This utility only created US-locale timestamps. It is intended for
* use as a protocol utility to talk between computer systems. The
* timestamp returned by this utility should not be displayed to end
* users in a UI, as it is not localized.
*/
final class Iso8601Timestamp {
@InternalAmplifyApi
public final class Iso8601Timestamp {
private Iso8601Timestamp() {}

static String now() {
@InternalAmplifyApi
public static String now() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US);
return formatter.format(new Date());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import androidx.annotation.NonNull;

import com.amplifyframework.AmplifyException;
import com.amplifyframework.annotations.InternalAmplifyApi;
import com.amplifyframework.api.ApiException;
import com.amplifyframework.api.ApiException.ApiAuthException;
import com.amplifyframework.api.aws.auth.ApiRequestDecoratorFactory;
Expand Down Expand Up @@ -152,7 +153,8 @@ private boolean hasAuthRelatedErrors(GraphQLResponse<R> response) {
return false;
}

static <R> Builder<R> builder() {
@InternalAmplifyApi
public static <R> Builder<R> builder() {
return new Builder<>();
}

Expand Down Expand Up @@ -202,7 +204,8 @@ public void onFailure(@NonNull Call call, @NonNull IOException exception) {
}
}

static final class Builder<R> {
@InternalAmplifyApi
public static final class Builder<R> {
private String endpoint;
private OkHttpClient client;
private GraphQLRequest<R> request;
Expand All @@ -213,53 +216,63 @@ static final class Builder<R> {
private ExecutorService executorService;
private String apiName;

Builder<R> endpoint(@NonNull String endpoint) {
@InternalAmplifyApi
public Builder<R> endpoint(@NonNull String endpoint) {
this.endpoint = Objects.requireNonNull(endpoint);
return this;
}

Builder<R> client(@NonNull OkHttpClient client) {
@InternalAmplifyApi
public Builder<R> client(@NonNull OkHttpClient client) {
this.client = Objects.requireNonNull(client);
return this;
}

Builder<R> request(@NonNull GraphQLRequest<R> request) {
@InternalAmplifyApi
public Builder<R> request(@NonNull GraphQLRequest<R> request) {
this.request = Objects.requireNonNull(request);
return this;
}

Builder<R> responseFactory(@NonNull GraphQLResponse.Factory responseFactory) {
@InternalAmplifyApi
public Builder<R> responseFactory(@NonNull GraphQLResponse.Factory responseFactory) {
this.responseFactory = Objects.requireNonNull(responseFactory);
return this;
}

Builder<R> onResponse(@NonNull Consumer<GraphQLResponse<R>> onResponse) {
@InternalAmplifyApi
public Builder<R> onResponse(@NonNull Consumer<GraphQLResponse<R>> onResponse) {
this.onResponse = Objects.requireNonNull(onResponse);
return this;
}

Builder<R> onFailure(@NonNull Consumer<ApiException> onFailure) {
@InternalAmplifyApi
public Builder<R> onFailure(@NonNull Consumer<ApiException> onFailure) {
this.onFailure = Objects.requireNonNull(onFailure);
return this;
}

Builder<R> apiRequestDecoratorFactory(ApiRequestDecoratorFactory apiRequestDecoratorFactory) {
@InternalAmplifyApi
public Builder<R> apiRequestDecoratorFactory(ApiRequestDecoratorFactory apiRequestDecoratorFactory) {
this.apiRequestDecoratorFactory = apiRequestDecoratorFactory;
return this;
}

Builder<R> executorService(ExecutorService executorService) {
@InternalAmplifyApi
public Builder<R> executorService(ExecutorService executorService) {
this.executorService = executorService;
return this;
}

Builder<R> apiName(String apiName) {
@InternalAmplifyApi
public Builder<R> apiName(String apiName) {
this.apiName = apiName;
return this;
}

@InternalAmplifyApi
@SuppressLint("SyntheticAccessor")
MultiAuthAppSyncGraphQLOperation<R> build() {
public MultiAuthAppSyncGraphQLOperation<R> build() {
return new MultiAuthAppSyncGraphQLOperation<>(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import com.amplifyframework.annotations.InternalAmplifyApi;
import com.amplifyframework.api.ApiException;
import com.amplifyframework.api.ApiException.ApiAuthException;
import com.amplifyframework.api.aws.auth.AuthRuleRequestDecorator;
Expand All @@ -37,7 +38,8 @@
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;

final class MultiAuthSubscriptionOperation<T> extends AWSGraphQLOperation<T> {
@InternalAmplifyApi
public final class MultiAuthSubscriptionOperation<T> extends AWSGraphQLOperation<T> {
private static final Logger LOG = Amplify.Logging.logger(CategoryType.API, "amplify:aws-api");

private final SubscriptionEndpoint subscriptionEndpoint;
Expand Down Expand Up @@ -68,7 +70,8 @@ private MultiAuthSubscriptionOperation(Builder<T> builder) {
}

@NonNull
static <T> Builder<T> builder() {
@InternalAmplifyApi
public static <T> Builder<T> builder() {
return new Builder<>();
}

Expand Down Expand Up @@ -197,7 +200,8 @@ Future<?> getSubscriptionFuture() {
return subscriptionFuture;
}

static final class Builder<T> {
@InternalAmplifyApi
public static final class Builder<T> {
private SubscriptionEndpoint subscriptionEndpoint;
private AppSyncGraphQLRequest<T> graphQlRequest;
private GraphQLResponse.Factory responseFactory;
Expand All @@ -210,65 +214,76 @@ static final class Builder<T> {
private String apiName;

@NonNull
@InternalAmplifyApi
public Builder<T> subscriptionEndpoint(@NonNull SubscriptionEndpoint subscriptionEndpoint) {
this.subscriptionEndpoint = Objects.requireNonNull(subscriptionEndpoint);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> graphQlRequest(@NonNull AppSyncGraphQLRequest<T> graphQlRequest) {
this.graphQlRequest = Objects.requireNonNull(graphQlRequest);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> responseFactory(@NonNull GraphQLResponse.Factory responseFactory) {
this.responseFactory = Objects.requireNonNull(responseFactory);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> executorService(@NonNull ExecutorService executorService) {
this.executorService = Objects.requireNonNull(executorService);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> onSubscriptionStart(@NonNull Consumer<String> onSubscriptionStart) {
this.onSubscriptionStart = Objects.requireNonNull(onSubscriptionStart);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> onNextItem(@NonNull Consumer<GraphQLResponse<T>> onNextItem) {
this.onNextItem = Objects.requireNonNull(onNextItem);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> onSubscriptionError(@NonNull Consumer<ApiException> onSubscriptionError) {
this.onSubscriptionError = Objects.requireNonNull(onSubscriptionError);
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> onSubscriptionComplete(@NonNull Action onSubscriptionComplete) {
this.onSubscriptionComplete = Objects.requireNonNull(onSubscriptionComplete);
return this;
}

@InternalAmplifyApi
public Builder<T> requestDecorator(AuthRuleRequestDecorator requestDecorator) {
this.requestDecorator = requestDecorator;
return this;
}

@NonNull
@InternalAmplifyApi
public Builder<T> apiName(String apiName) {
this.apiName = apiName;
return this;
}

@NonNull
@InternalAmplifyApi
public MultiAuthSubscriptionOperation<T> build() {
return new MultiAuthSubscriptionOperation<>(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

import com.amplifyframework.annotations.InternalAmplifyApi;

/**
* Manages the lifecycle of a single WebSocket connection,
* and multiple GraphQL subscriptions that work on top of it.
*/
final class SubscriptionEndpoint {
@InternalAmplifyApi
public final class SubscriptionEndpoint {
private static final Logger LOG = Amplify.Logging.logger(CategoryType.API, "amplify:aws-api");
private static final int CONNECTION_ACKNOWLEDGEMENT_TIMEOUT = 30 /* seconds */;
private static final int NORMAL_CLOSURE_STATUS = 1000;
Expand Down Expand Up @@ -104,7 +107,54 @@ final class SubscriptionEndpoint {
this.okHttpClient = okHttpClientBuilder.build();
}

<T> void requestSubscription(
/**
* Convenience constructor for standalone use outside the plugin. Builds the internal
* configuration and authorizer from raw parameters.
*
* @param endpoint The AppSync GraphQL endpoint URL.
* @param region The AWS region.
* @param authorizationType The default authorization type.
* @param apiKey The API key (required when authorizationType is API_KEY, null otherwise).
* @param configurator Optional OkHttp client configurator.
* @param responseFactory Factory for deserializing GraphQL responses.
* @param authProviders Optional auth providers for token/credential resolution.
*/
@InternalAmplifyApi
public SubscriptionEndpoint(
@NonNull String endpoint,
@NonNull String region,
@NonNull AuthorizationType authorizationType,
@Nullable String apiKey,
@Nullable OkHttpConfigurator configurator,
@NonNull GraphQLResponse.Factory responseFactory,
@Nullable ApiAuthProviders authProviders
) {
this(
ApiConfiguration.builder()
.endpoint(endpoint)
.region(region)
.endpointType(EndpointType.GRAPHQL)
.authorizationType(authorizationType)
.apiKey(apiKey)
.build(),
configurator,
responseFactory,
new SubscriptionAuthorizer(
ApiConfiguration.builder()
.endpoint(endpoint)
.region(region)
.endpointType(EndpointType.GRAPHQL)
.authorizationType(authorizationType)
.apiKey(apiKey)
.build(),
authProviders != null ? authProviders : ApiAuthProviders.noProviderOverrides()
),
null
);
}

@InternalAmplifyApi
public <T> void requestSubscription(
@NonNull GraphQLRequest<T> request,
@NonNull AuthorizationType authType,
@NonNull Consumer<String> onSubscriptionStarted,
Expand Down Expand Up @@ -261,7 +311,8 @@ private void notifySubscriptionData(String subscriptionId, String data) throws A
dispatcher.dispatchNextMessage(data);
}

void releaseSubscription(String subscriptionId) throws ApiException {
@InternalAmplifyApi
public void releaseSubscription(String subscriptionId) throws ApiException {
// First thing we should do is remove it from the pending subscription collection so
// the other methods can't grab a hold of the subscription.
final Subscription<?> subscription = subscriptions.get(subscriptionId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@

import androidx.annotation.NonNull;

import com.amplifyframework.annotations.InternalAmplifyApi;

/**
* An enumeration of the values that are possible in the "type" field
* of a subscription message.
* @see <a href="http://bit.ly/gql-ws-message-types">GraphQL Over WebSocket Message Types</a>
* @see <a href="http://bit.ly/gql-ws-protocol">GraphQL Over WebSocket Protocol</a>
*/
enum SubscriptionMessageType {
@InternalAmplifyApi
public enum SubscriptionMessageType {

/**
* Client requests initialization of a connection, to the server.
Expand Down
Loading
Loading