diff --git a/app/src/main/java/eu/m724/vastapp/vastai/ApiFailure.kt b/app/src/main/java/eu/m724/vastapp/vastai/ApiFailure.kt deleted file mode 100644 index 15d6a76..0000000 --- a/app/src/main/java/eu/m724/vastapp/vastai/ApiFailure.kt +++ /dev/null @@ -1,6 +0,0 @@ -package eu.m724.vastapp.vastai - -data class ApiFailure( - /** user friendly error message */ - val errorMessage: String?, -) \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/ApiRoute.kt b/app/src/main/java/eu/m724/vastapp/vastai/ApiRoute.kt deleted file mode 100644 index f5e5fce..0000000 --- a/app/src/main/java/eu/m724/vastapp/vastai/ApiRoute.kt +++ /dev/null @@ -1,8 +0,0 @@ -package eu.m724.vastapp.vastai - -enum class ApiRoute(val path: String, val method: String) { - SHOW_USER("/users/current", "GET"), - GET_INSTANCES("/instances", "GET"), - INSTANCES_COUNT("/instances/count", "GET"), - MACHINES_MAINTENANCES("/machines/maintenances", "GET") -} \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/RequestMaker.kt b/app/src/main/java/eu/m724/vastapp/vastai/RequestMaker.kt new file mode 100644 index 0000000..df9243b --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/RequestMaker.kt @@ -0,0 +1,51 @@ +package eu.m724.vastapp.vastai + +import eu.m724.vastapp.BuildConfig +import org.chromium.net.CronetEngine +import org.chromium.net.UploadDataProvider +import org.chromium.net.UrlRequest +import java.util.concurrent.Executor + +class RequestMaker( + private val apiKey: String, + private val cronetEngine: CronetEngine, + private val executor: Executor +) { + + /** + * build an api request + * don't forget to call .start() on the returned [UrlRequest] + * + * @param endpoint the endpoint path starting with a slash like /users/current + * @param callback any callback for example [UserUrlRequestCallback] + * @param method request method, default GET + * @param headers additional request headers + * @param uploadDataProvider [UploadDataProvider] if request sends data + * @return an [UrlRequest] you must .start() yourself + */ + fun buildRequest( + endpoint: String, + callback: UrlRequest.Callback, + method: String = "GET", + headers: Map? = null, + uploadDataProvider: UploadDataProvider? = null + ): UrlRequest { + var requestBuilder = cronetEngine.newUrlRequestBuilder( + BuildConfig.VASIAI_API_ENDPOINT + endpoint, + callback, + executor + ).addHeader("Authorization", "Bearer $apiKey") + + requestBuilder = requestBuilder.setHttpMethod(method) + + headers?.forEach { e -> + requestBuilder = requestBuilder.addHeader(e.key, e.value) + } + + if (uploadDataProvider != null) { + requestBuilder = requestBuilder.setUploadDataProvider(uploadDataProvider, executor) + } + + return requestBuilder.build() + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/VastApi.kt b/app/src/main/java/eu/m724/vastapp/vastai/VastApi.kt index 4fe4d5a..717c6ab 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/VastApi.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/VastApi.kt @@ -1,57 +1,111 @@ package eu.m724.vastapp.vastai -import eu.m724.vastapp.BuildConfig +import eu.m724.vastapp.vastai.cronet.InstancesUrlRequestCallback +import eu.m724.vastapp.vastai.cronet.JsonUrlRequestCallback +import eu.m724.vastapp.vastai.cronet.UserUrlRequestCallback +import eu.m724.vastapp.vastai.cronet.upload.StringUploadDataProvider +import eu.m724.vastapp.vastai.data.RentedInstance +import eu.m724.vastapp.vastai.data.User +import eu.m724.vastapp.vastai.exceptions.ApiException +import kotlinx.coroutines.CompletableDeferred import org.chromium.net.CronetEngine -import org.chromium.net.UploadDataProvider -import org.chromium.net.UrlRequest import java.util.concurrent.Executor class VastApi( - var apiKey: String, // TODO make private? - private val cronetEngine: CronetEngine, - private val executor: Executor + apiKey: String, // TODO make private? + cronetEngine: CronetEngine, + executor: Executor ) { - /** - * build an api request - * don't forget to call .start() on the returned [UrlRequest] - * - * @param endpoint the endpoint path starting with a slash like /users/current - * @param callback any callback for example [UserUrlRequestCallback] - * @param method request method, default GET - * @param uploadDataProvider [UploadDataProvider] if request sends data - * @return an [UrlRequest] you must .start() yourself - */ - fun buildRequest( - endpoint: String, - callback: UrlRequest.Callback, - method: String = "GET", - uploadDataProvider: UploadDataProvider? - ): UrlRequest { - var requestBuilder = cronetEngine.newUrlRequestBuilder( - BuildConfig.VASIAI_API_ENDPOINT + endpoint, - callback, - executor - ).addHeader("Authorization", "Bearer $apiKey") + private val requestMaker = RequestMaker(apiKey, cronetEngine, executor) - requestBuilder = requestBuilder.setHttpMethod(method) + fun getUser(): CompletableDeferred { + val deferred = CompletableDeferred() - if (uploadDataProvider != null) { - requestBuilder = requestBuilder.setUploadDataProvider(uploadDataProvider, executor) - } + val request = requestMaker.buildRequest( + "/users/current", + UserUrlRequestCallback( + onSuccess = { deferred.complete(it) }, + onFailure = { deferred.completeExceptionally(it) } + ) + ) - return requestBuilder.build() + request.start() + return deferred } - /** - * build an api request - * don't forget to call .start() on the returned [UrlRequest] - * - * @param apiRoute the api route - * @param callback any callback for example [UserUrlRequestCallback] - * @param uploadDataProvider [UploadDataProvider] if request sends data - * @return an [UrlRequest] you must .start() yourself - */ - fun buildRequest(apiRoute: ApiRoute, callback: UrlRequest.Callback, uploadDataProvider: UploadDataProvider? = null): UrlRequest { - return buildRequest(apiRoute.path, callback, apiRoute.method, uploadDataProvider) + fun getRentedInstances(): CompletableDeferred> { + val deferred = CompletableDeferred>() + + val request = requestMaker.buildRequest( + "/instances", + InstancesUrlRequestCallback( + onSuccess = { deferred.complete(it) }, + onFailure = { deferred.completeExceptionally(it) } + ) + ) + + request.start() + return deferred + } // TODO maybe we could make a function that handles all that build stuff and just takes a type and path + + fun deleteInstance(rentalId: Int): CompletableDeferred { + val deferred = CompletableDeferred() + + val request = requestMaker.buildRequest( + "/instances/$rentalId", + JsonUrlRequestCallback( + onSuccess = { + if (it.getBoolean("success")) + deferred.complete(Unit) + else + deferred.completeExceptionally(ApiException("Failed to delete: $it")) + }, + onFailure = { deferred.completeExceptionally(it) } + ), + "DELETE" + ) + + request.start() + return deferred + } + + fun startInstance(rentalId: Int): CompletableDeferred { + val deferred = CompletableDeferred() + + val request = requestMaker.buildRequest( + "/instances/$rentalId", + JsonUrlRequestCallback( + onSuccess = { + deferred.complete(Unit) + }, + onFailure = { deferred.completeExceptionally(it) } + ), + "PUT", + mapOf(Pair("Content-Type", "application/json")), + StringUploadDataProvider("{\"state\": \"running\"}") + ) + + request.start() + return deferred + } + + fun stopInstance(rentalId: Int): CompletableDeferred { // TODO this too make one function that does all things + val deferred = CompletableDeferred() + + val request = requestMaker.buildRequest( + "/instances/$rentalId", + JsonUrlRequestCallback( + onSuccess = { + deferred.complete(Unit) + }, + onFailure = { deferred.completeExceptionally(it) } + ), + "PUT", + mapOf(Pair("Content-Type", "application/json")), + StringUploadDataProvider("{\"state\": \"stopped\"}") + ) + + request.start() + return deferred } } \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/InstancesUrlRequestCallback.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/InstancesUrlRequestCallback.kt similarity index 83% rename from app/src/main/java/eu/m724/vastapp/vastai/api/InstancesUrlRequestCallback.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/InstancesUrlRequestCallback.kt index edbbb67..6efa426 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/InstancesUrlRequestCallback.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/InstancesUrlRequestCallback.kt @@ -1,6 +1,6 @@ -package eu.m724.vastapp.vastai.api +package eu.m724.vastapp.vastai.cronet -import eu.m724.vastapp.vastai.api.exceptions.ApiException +import eu.m724.vastapp.vastai.exceptions.ApiException import eu.m724.vastapp.vastai.data.RentedInstance class InstancesUrlRequestCallback( diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/JsonUrlRequestCallback.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/JsonUrlRequestCallback.kt similarity index 77% rename from app/src/main/java/eu/m724/vastapp/vastai/api/JsonUrlRequestCallback.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/JsonUrlRequestCallback.kt index 181b265..8b91dcd 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/JsonUrlRequestCallback.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/JsonUrlRequestCallback.kt @@ -1,6 +1,6 @@ -package eu.m724.vastapp.vastai.api +package eu.m724.vastapp.vastai.cronet -import eu.m724.vastapp.vastai.api.exceptions.ApiException +import eu.m724.vastapp.vastai.exceptions.ApiException import org.json.JSONObject open class JsonUrlRequestCallback( diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/StringUrlRequestCallback.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/StringUrlRequestCallback.kt similarity index 87% rename from app/src/main/java/eu/m724/vastapp/vastai/api/StringUrlRequestCallback.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/StringUrlRequestCallback.kt index 2e421c3..a67c480 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/StringUrlRequestCallback.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/StringUrlRequestCallback.kt @@ -1,9 +1,9 @@ -package eu.m724.vastapp.vastai.api +package eu.m724.vastapp.vastai.cronet -import eu.m724.vastapp.vastai.api.exceptions.ApiException -import eu.m724.vastapp.vastai.api.exceptions.ClientException -import eu.m724.vastapp.vastai.api.exceptions.ServerError -import eu.m724.vastapp.vastai.api.exceptions.UnauthorizedException +import eu.m724.vastapp.vastai.exceptions.ApiException +import eu.m724.vastapp.vastai.exceptions.ClientException +import eu.m724.vastapp.vastai.exceptions.ServerError +import eu.m724.vastapp.vastai.exceptions.UnauthorizedException import org.chromium.net.CronetException import org.chromium.net.UrlRequest import org.chromium.net.UrlResponseInfo diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/UserUrlRequestCallback.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/UserUrlRequestCallback.kt similarity index 87% rename from app/src/main/java/eu/m724/vastapp/vastai/api/UserUrlRequestCallback.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/UserUrlRequestCallback.kt index 6e87550..1861aa4 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/UserUrlRequestCallback.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/UserUrlRequestCallback.kt @@ -1,6 +1,6 @@ -package eu.m724.vastapp.vastai.api +package eu.m724.vastapp.vastai.cronet -import eu.m724.vastapp.vastai.api.exceptions.ApiException +import eu.m724.vastapp.vastai.exceptions.ApiException import eu.m724.vastapp.vastai.data.User class UserUrlRequestCallback( diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/upload/JsonUploadDataProvider.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/JsonUploadDataProvider.kt similarity index 76% rename from app/src/main/java/eu/m724/vastapp/vastai/api/upload/JsonUploadDataProvider.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/JsonUploadDataProvider.kt index e14bbf7..742a824 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/upload/JsonUploadDataProvider.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/JsonUploadDataProvider.kt @@ -1,4 +1,4 @@ -package eu.m724.vastapp.vastai.api.upload +package eu.m724.vastapp.vastai.cronet.upload import org.json.JSONObject diff --git a/app/src/main/java/eu/m724/vastapp/vastai/api/upload/StringUploadDataProvider.kt b/app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/StringUploadDataProvider.kt similarity index 93% rename from app/src/main/java/eu/m724/vastapp/vastai/api/upload/StringUploadDataProvider.kt rename to app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/StringUploadDataProvider.kt index 1724866..a5b4752 100644 --- a/app/src/main/java/eu/m724/vastapp/vastai/api/upload/StringUploadDataProvider.kt +++ b/app/src/main/java/eu/m724/vastapp/vastai/cronet/upload/StringUploadDataProvider.kt @@ -1,4 +1,4 @@ -package eu.m724.vastapp.vastai.api.upload +package eu.m724.vastapp.vastai.cronet.upload import org.chromium.net.UploadDataProvider import org.chromium.net.UploadDataSink diff --git a/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ApiException.kt b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ApiException.kt new file mode 100644 index 0000000..ce27e6b --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ApiException.kt @@ -0,0 +1,6 @@ +package eu.m724.vastapp.vastai.exceptions + +open class ApiException( + override val message: String? = null, + override val cause: Throwable? = null +): Exception() \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ClientException.kt b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ClientException.kt new file mode 100644 index 0000000..7dc7229 --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ClientException.kt @@ -0,0 +1,6 @@ +package eu.m724.vastapp.vastai.exceptions + +open class ClientException( + message: String? = null, + cause: Throwable? = null +) : ApiException(message, cause) \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ServerError.kt b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ServerError.kt new file mode 100644 index 0000000..cf87501 --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/ServerError.kt @@ -0,0 +1,6 @@ +package eu.m724.vastapp.vastai.exceptions + +open class ServerError( + val statusCode: Int, + message: String?, +): ApiException(message, null) \ No newline at end of file diff --git a/app/src/main/java/eu/m724/vastapp/vastai/exceptions/UnauthorizedException.kt b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/UnauthorizedException.kt new file mode 100644 index 0000000..61fc887 --- /dev/null +++ b/app/src/main/java/eu/m724/vastapp/vastai/exceptions/UnauthorizedException.kt @@ -0,0 +1,5 @@ +package eu.m724.vastapp.vastai.exceptions + +class UnauthorizedException( + message: String? = null +) : ClientException(message, null) \ No newline at end of file