diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 00000000..7c883b63 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/examples.iml b/.idea/examples.iml new file mode 100644 index 00000000..d6ebd480 --- /dev/null +++ b/.idea/examples.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 00000000..9a13d784 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 00000000..fdc392fe --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..639900d1 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..704ff0e8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Run.xml b/.idea/runConfigurations/Run.xml new file mode 100644 index 00000000..de1f5de1 --- /dev/null +++ b/.idea/runConfigurations/Run.xml @@ -0,0 +1,21 @@ + + + + + + + true + true + false + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/java/AppwriteCollectionWiper/.gitignore b/java/AppwriteCollectionWiper/.gitignore new file mode 100644 index 00000000..8d482b58 --- /dev/null +++ b/java/AppwriteCollectionWiper/.gitignore @@ -0,0 +1,3 @@ +# OS +## Mac +.DS_Store diff --git a/java/AppwriteCollectionWiper/Index.java b/java/AppwriteCollectionWiper/Index.java new file mode 100644 index 00000000..64f7c4be --- /dev/null +++ b/java/AppwriteCollectionWiper/Index.java @@ -0,0 +1,92 @@ +import java.util.Map; +import java.util.HashMap; +import java.util.*; +import io.openruntimes.java.*; +import com.google.gson.Gson; +import io.appwrite.Client; +import io.appwrite.exceptions.AppwriteException; +import io.appwrite.services.Databases; +import kotlin.Result; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.EmptyCoroutineContext; +import org.jetbrains.annotations.NotNull; +import okhttp3.Response; +import com.google.gson.JsonParser; +import com.google.gson.JsonObject; + +final Gson gson = new Gson(); + + +public RuntimeResponse main(RuntimeRequest req, RuntimeResponse res) throws Exception { + + + + // Initialize the Appwrite client and databases service + var client = new Client(); + var databases = new Databases(client); + var variables = req.getVariables(); + var payloadString = req.getPayload(); + + // Check if the required environment variables are set + if (variables == null + || !variables.containsKey("APPWRITE_FUNCTION_ENDPOINT") + || !variables.containsKey("APPWRITE_FUNCTION_API_KEY") + || !variables.containsKey("APPWRITE_FUNCTION_PROJECT_ID") + || variables.get("APPWRITE_FUNCTION_ENDPOINT") == null + || variables.get("APPWRITE_FUNCTION_API_KEY") == null + || variables.get("APPWRITE_FUNCTION_PROJECT_ID") == null) { + return res.json(Map.of("Environment variables are not set. Function cannot use Appwrite SDK.", false)); + } else { + // Set the Appwrite client properties + client + .setEndpoint(variables.get("APPWRITE_FUNCTION_ENDPOINT")) + .setProject(variables.get("APPWRITE_FUNCTION_PROJECT_ID")) + .setKey(variables.get("APPWRITE_FUNCTION_API_KEY")); + } + + try { + // Parse the payload data into a Map + + Map payload = gson.fromJson(payloadString, Map.class); + String databaseId = (String) payload.get("databaseId"); + String collectionId = (String) payload.get("collectionId"); + if (payload == null || databaseId == null || collectionId == null) { + return res.json(Map.of("Invalid payload.", false)); + } + + + + databases.deleteCollection( + databaseId, + collectionId, + new Continuation() { + @NotNull + @Override + public CoroutineContext getContext() { + return EmptyCoroutineContext.INSTANCE; + } + + @Override + public void resumeWith(@NotNull Object o) { + String json = ""; + try { + if (o instanceof Result.Failure) { + Result.Failure failure = (Result.Failure) o; + throw failure.exception; + } else { + Response response = (Response) o; + } + } catch (Throwable th) { + System.out.println("ERROR: " + th.toString()); + } + } + } + ); + return res.json(Map.of("Success", true)); + + }catch (AppwriteException e) { + + return res.json(Map.of("Collection not found", false)); + } +} diff --git a/java/AppwriteCollectionWiper/README.md b/java/AppwriteCollectionWiper/README.md new file mode 100644 index 00000000..ecbaa463 --- /dev/null +++ b/java/AppwriteCollectionWiper/README.md @@ -0,0 +1,45 @@ +# AppwriteCollectionWiper + +Welcome to the documentation of this function 👋 We strongly recommend keeping this file in sync with your function's logic to make sure anyone can easily understand your function in the future. If you don't need documentation, you can remove this file. + +## 🤖 Documentation + +Simple function similar to typical "hello world" example, but instead, we return a simple JSON that tells everyone how awesome developers are. + + + +_Example input:_ + +This function expects no input + + + +_Example output:_ + + + +```json +{ + "areDevelopersAwesome": true +} +``` + +## 📝 Environment Variables + +List of environment variables used by this cloud function: + +- No special environment variables are required for the cloud function. + +## 🚀 Deployment + +There are two ways of deploying the Appwrite function, both having the same results, but each using a different process. We highly recommend using CLI deployment to achieve the best experience. + +### Using CLI + +Make sure you have [Appwrite CLI](https://appwrite.io/docs/command-line#installation) installed, and you have successfully logged into your Appwrite server. To make sure Appwrite CLI is ready, you can use the command `appwrite client --debug` and it should respond with green text `✓ Success`. + +Make sure you are in the same folder as your `appwrite.json` file and run `appwrite deploy function` to deploy your function. You will be prompted to select which functions you want to deploy. + +### Manual using tar.gz + +Manual deployment has no requirements and uses Appwrite Console to deploy the tag. First, enter the folder of your function. Then, create a tarball of the whole folder and gzip it. After creating `.tar.gz` file, visit Appwrite Console, click on the `Deploy Tag` button and switch to the `Manual` tab. There, set the `entrypoint` to `src/Index.java`, and upload the file we just generated. diff --git a/java/AppwriteCollectionWiper/deps.gradle b/java/AppwriteCollectionWiper/deps.gradle new file mode 100644 index 00000000..4702e593 --- /dev/null +++ b/java/AppwriteCollectionWiper/deps.gradle @@ -0,0 +1,4 @@ +dependencies { + implementation 'io.appwrite:sdk-for-kotlin:1.2.0' + implementation 'com.google.code.gson:gson:2.9.0' +} \ No newline at end of file diff --git a/java/appwrite.json b/java/appwrite.json new file mode 100644 index 00000000..bbe45396 --- /dev/null +++ b/java/appwrite.json @@ -0,0 +1,20 @@ +{ + "projectId": "649f0fde61b9f6d9d83c", + "projectName": "CodeDay Open Source", + "functions": [ + { + "$id": "64b036a92b2e743106ca", + "name": "AppwriteCollectionWiper", + "runtime": "java-17.0", + "path": "AppwriteCollectionWiper", + "entrypoint": "src/Index.java", + "ignore": [ + "build" + ], + "execute": [], + "events": [], + "schedule": "", + "timeout": 15 + } + ] +} \ No newline at end of file diff --git a/java/appwrite/.env b/java/appwrite/.env new file mode 100644 index 00000000..c1074cb4 --- /dev/null +++ b/java/appwrite/.env @@ -0,0 +1,94 @@ +_APP_ENV=production +_APP_LOCALE=en +_APP_OPTIONS_ABUSE=enabled +_APP_OPTIONS_FORCE_HTTPS=disabled +_APP_OPENSSL_KEY_V1=Rik +_APP_DOMAIN=localhost +_APP_DOMAIN_TARGET=localhost +_APP_CONSOLE_WHITELIST_ROOT=enabled +_APP_CONSOLE_WHITELIST_EMAILS= +_APP_CONSOLE_WHITELIST_IPS= +_APP_SYSTEM_EMAIL_NAME=Appwrite +_APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io +_APP_SYSTEM_RESPONSE_FORMAT= +_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=certs@appwrite.io +_APP_USAGE_STATS=enabled +_APP_LOGGING_PROVIDER= +_APP_LOGGING_CONFIG= +_APP_USAGE_AGGREGATION_INTERVAL=30 +_APP_USAGE_TIMESERIES_INTERVAL=30 +_APP_USAGE_DATABASE_INTERVAL=900 +_APP_WORKER_PER_CORE=6 +_APP_REDIS_HOST=redis +_APP_REDIS_PORT=6379 +_APP_REDIS_USER= +_APP_REDIS_PASS= +_APP_DB_HOST=mariadb +_APP_DB_PORT=3306 +_APP_DB_SCHEMA=appwrite +_APP_DB_USER=user +_APP_DB_PASS=password +_APP_DB_ROOT_PASS=rootsecretpassword +_APP_INFLUXDB_HOST=influxdb +_APP_INFLUXDB_PORT=8086 +_APP_STATSD_HOST=telegraf +_APP_STATSD_PORT=8125 +_APP_SMTP_HOST= +_APP_SMTP_PORT= +_APP_SMTP_SECURE= +_APP_SMTP_USERNAME= +_APP_SMTP_PASSWORD= +_APP_SMS_PROVIDER= +_APP_SMS_FROM= +_APP_STORAGE_LIMIT=30000000 +_APP_STORAGE_PREVIEW_LIMIT=20000000 +_APP_STORAGE_ANTIVIRUS=disabled +_APP_STORAGE_ANTIVIRUS_HOST=clamav +_APP_STORAGE_ANTIVIRUS_PORT=3310 +_APP_STORAGE_DEVICE=local +_APP_STORAGE_S3_ACCESS_KEY= +_APP_STORAGE_S3_SECRET= +_APP_STORAGE_S3_REGION=us-east-1 +_APP_STORAGE_S3_BUCKET= +_APP_STORAGE_DO_SPACES_ACCESS_KEY= +_APP_STORAGE_DO_SPACES_SECRET= +_APP_STORAGE_DO_SPACES_REGION=us-east-1 +_APP_STORAGE_DO_SPACES_BUCKET= +_APP_STORAGE_BACKBLAZE_ACCESS_KEY= +_APP_STORAGE_BACKBLAZE_SECRET= +_APP_STORAGE_BACKBLAZE_REGION=us-west-004 +_APP_STORAGE_BACKBLAZE_BUCKET= +_APP_STORAGE_LINODE_ACCESS_KEY= +_APP_STORAGE_LINODE_SECRET= +_APP_STORAGE_LINODE_REGION=eu-central-1 +_APP_STORAGE_LINODE_BUCKET= +_APP_STORAGE_WASABI_ACCESS_KEY= +_APP_STORAGE_WASABI_SECRET= +_APP_STORAGE_WASABI_REGION=eu-central-1 +_APP_STORAGE_WASABI_BUCKET= +_APP_FUNCTIONS_SIZE_LIMIT=30000000 +_APP_FUNCTIONS_TIMEOUT=900 +_APP_FUNCTIONS_BUILD_TIMEOUT=900 +_APP_FUNCTIONS_CONTAINERS=10 +_APP_FUNCTIONS_CPUS=0 +_APP_FUNCTIONS_MEMORY=0 +_APP_FUNCTIONS_MEMORY_SWAP=0 +_APP_FUNCTIONS_RUNTIMES=php-8.0,python-3.9,ruby-3.0,java-17.0 +_APP_EXECUTOR_SECRET=your-secret-key +_APP_EXECUTOR_HOST=http://appwrite-executor/v1 +_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes +_APP_FUNCTIONS_ENVS=php-7.4,python-3.9,ruby-3.0,java-17.0 +_APP_FUNCTIONS_INACTIVE_THRESHOLD=60 +DOCKERHUB_PULL_USERNAME= +DOCKERHUB_PULL_PASSWORD= +DOCKERHUB_PULL_EMAIL= +OPEN_RUNTIMES_NETWORK=appwrite_runtimes +_APP_MAINTENANCE_INTERVAL=86400 +_APP_MAINTENANCE_RETENTION_CACHE=2592000 +_APP_MAINTENANCE_RETENTION_EXECUTION=1209600 +_APP_MAINTENANCE_RETENTION_AUDIT=1209600 +_APP_MAINTENANCE_RETENTION_ABUSE=86400 +_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000 +_APP_GRAPHQL_MAX_BATCH_SIZE=10 +_APP_GRAPHQL_MAX_COMPLEXITY=250 +_APP_GRAPHQL_MAX_DEPTH=3 diff --git a/java/appwrite/docker-compose.yml b/java/appwrite/docker-compose.yml new file mode 100644 index 00000000..d456023c --- /dev/null +++ b/java/appwrite/docker-compose.yml @@ -0,0 +1,674 @@ +x-logging: &x-logging + logging: + driver: 'json-file' + options: + max-file: '5' + max-size: '10m' +version: '3' + +services: + traefik: + image: traefik:2.7 + container_name: appwrite-traefik + <<: *x-logging + command: + - --providers.file.directory=/storage/config + - --providers.file.watch=true + - --providers.docker=true + - --providers.docker.exposedByDefault=false + - --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`appwrite`) + - --entrypoints.appwrite_web.address=:80 + - --entrypoints.appwrite_websecure.address=:443 + restart: unless-stopped + ports: + - 80:80 + - 443:443 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-config:/storage/config:ro + - appwrite-certificates:/storage/certificates:ro + depends_on: + - appwrite + networks: + - gateway + - appwrite + + appwrite: + image: appwrite/appwrite:1.3.7 + container_name: appwrite + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + labels: + - traefik.enable=true + - traefik.constraint-label-stack=appwrite + - traefik.docker.network=appwrite + - traefik.http.services.appwrite_api.loadbalancer.server.port=80 + #http + - traefik.http.routers.appwrite_api_http.entrypoints=appwrite_web + - traefik.http.routers.appwrite_api_http.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite_api_http.service=appwrite_api + # https + - traefik.http.routers.appwrite_api_https.entrypoints=appwrite_websecure + - traefik.http.routers.appwrite_api_https.rule=PathPrefix(`/`) + - traefik.http.routers.appwrite_api_https.service=appwrite_api + - traefik.http.routers.appwrite_api_https.tls=true + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + - appwrite-functions:/storage/functions:rw + depends_on: + - mariadb + - redis +# - clamav + - influxdb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_LOCALE + - _APP_CONSOLE_WHITELIST_ROOT + - _APP_CONSOLE_WHITELIST_EMAILS + - _APP_CONSOLE_WHITELIST_IPS + - _APP_SYSTEM_EMAIL_NAME + - _APP_SYSTEM_EMAIL_ADDRESS + - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_SYSTEM_RESPONSE_FORMAT + - _APP_OPTIONS_ABUSE + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_SMTP_HOST + - _APP_SMTP_PORT + - _APP_SMTP_SECURE + - _APP_SMTP_USERNAME + - _APP_SMTP_PASSWORD + - _APP_USAGE_STATS + - _APP_INFLUXDB_HOST + - _APP_INFLUXDB_PORT + - _APP_STORAGE_LIMIT + - _APP_STORAGE_PREVIEW_LIMIT + - _APP_STORAGE_ANTIVIRUS + - _APP_STORAGE_ANTIVIRUS_HOST + - _APP_STORAGE_ANTIVIRUS_PORT + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - _APP_FUNCTIONS_SIZE_LIMIT + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_BUILD_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + - _APP_FUNCTIONS_CPUS + - _APP_FUNCTIONS_MEMORY + - _APP_FUNCTIONS_MEMORY_SWAP + - _APP_FUNCTIONS_RUNTIMES + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + - _APP_STATSD_HOST + - _APP_STATSD_PORT + - _APP_MAINTENANCE_INTERVAL + - _APP_MAINTENANCE_RETENTION_EXECUTION + - _APP_MAINTENANCE_RETENTION_CACHE + - _APP_MAINTENANCE_RETENTION_ABUSE + - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY + - _APP_SMS_PROVIDER + - _APP_SMS_FROM + - _APP_GRAPHQL_MAX_BATCH_SIZE + - _APP_GRAPHQL_MAX_COMPLEXITY + - _APP_GRAPHQL_MAX_DEPTH + + appwrite-realtime: + image: appwrite/appwrite:1.3.7 + entrypoint: realtime + container_name: appwrite-realtime + <<: *x-logging + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.constraint-label-stack=appwrite" + - "traefik.docker.network=appwrite" + - "traefik.http.services.appwrite_realtime.loadbalancer.server.port=80" + #ws + - traefik.http.routers.appwrite_realtime_ws.entrypoints=appwrite_web + - traefik.http.routers.appwrite_realtime_ws.rule=PathPrefix(`/v1/realtime`) + - traefik.http.routers.appwrite_realtime_ws.service=appwrite_realtime + # wss + - traefik.http.routers.appwrite_realtime_wss.entrypoints=appwrite_websecure + - traefik.http.routers.appwrite_realtime_wss.rule=PathPrefix(`/v1/realtime`) + - traefik.http.routers.appwrite_realtime_wss.service=appwrite_realtime + - traefik.http.routers.appwrite_realtime_wss.tls=true + - traefik.http.routers.appwrite_realtime_wss.tls.certresolver=dns + networks: + - appwrite + depends_on: + - mariadb + - redis + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPTIONS_ABUSE + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_USAGE_STATS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-audits: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-audits + <<: *x-logging + container_name: appwrite-worker-audits + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-webhooks: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-webhooks + <<: *x-logging + container_name: appwrite-worker-webhooks + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-deletes: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-deletes + <<: *x-logging + container_name: appwrite-worker-deletes + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-uploads:/storage/uploads:rw + - appwrite-cache:/storage/cache:rw + - appwrite-functions:/storage/functions:rw + - appwrite-builds:/storage/builds:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + + appwrite-worker-databases: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-databases + <<: *x-logging + container_name: appwrite-worker-databases + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-builds: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-builds + <<: *x-logging + container_name: appwrite-worker-builds + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-certificates: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-certificates + <<: *x-logging + container_name: appwrite-worker-certificates + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + volumes: + - appwrite-config:/storage/config:rw + - appwrite-certificates:/storage/certificates:rw + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_SYSTEM_SECURITY_EMAIL_ADDRESS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-functions: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-functions + <<: *x-logging + container_name: appwrite-worker-functions + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + - appwrite-executor + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_FUNCTIONS_TIMEOUT + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_USAGE_STATS + - DOCKERHUB_PULL_USERNAME + - DOCKERHUB_PULL_PASSWORD + + appwrite-executor: + image: appwrite/appwrite:1.3.7 + entrypoint: executor + <<: *x-logging + container_name: appwrite-executor + restart: unless-stopped + stop_signal: SIGINT + networks: + appwrite: + runtimes: + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-functions:/storage/functions:rw + - appwrite-builds:/storage/builds:rw + - /tmp:/tmp:rw + depends_on: + - redis + - mariadb + - appwrite + environment: + - _APP_ENV + - _APP_VERSION + - _APP_FUNCTIONS_TIMEOUT + - _APP_FUNCTIONS_BUILD_TIMEOUT + - _APP_FUNCTIONS_CONTAINERS + - _APP_FUNCTIONS_RUNTIMES + - _APP_FUNCTIONS_CPUS + - _APP_FUNCTIONS_MEMORY + - _APP_FUNCTIONS_MEMORY_SWAP + - _APP_FUNCTIONS_INACTIVE_THRESHOLD + - _APP_EXECUTOR_SECRET + - OPEN_RUNTIMES_NETWORK + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - DOCKERHUB_PULL_USERNAME + - DOCKERHUB_PULL_PASSWORD + + appwrite-worker-mails: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-mails + <<: *x-logging + container_name: appwrite-worker-mails + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_SYSTEM_EMAIL_NAME + - _APP_SYSTEM_EMAIL_ADDRESS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_SMTP_HOST + - _APP_SMTP_PORT + - _APP_SMTP_SECURE + - _APP_SMTP_USERNAME + - _APP_SMTP_PASSWORD + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-worker-messaging: + image: appwrite/appwrite:1.3.7 + entrypoint: worker-messaging + <<: *x-logging + container_name: appwrite-worker-messaging + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_SMS_PROVIDER + - _APP_SMS_FROM + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-maintenance: + image: appwrite/appwrite:1.3.7 + entrypoint: maintenance + <<: *x-logging + container_name: appwrite-maintenance + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_DOMAIN_TARGET + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_MAINTENANCE_INTERVAL + - _APP_MAINTENANCE_RETENTION_EXECUTION + - _APP_MAINTENANCE_RETENTION_CACHE + - _APP_MAINTENANCE_RETENTION_ABUSE + - _APP_MAINTENANCE_RETENTION_AUDIT + - _APP_MAINTENANCE_RETENTION_USAGE_HOURLY + + appwrite-usage: + image: appwrite/appwrite:1.3.7 + entrypoint: usage + container_name: appwrite-usage + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - influxdb + - mariadb + environment: + - _APP_ENV + - _APP_OPENSSL_KEY_V1 + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_INFLUXDB_HOST + - _APP_INFLUXDB_PORT + - _APP_USAGE_AGGREGATION_INTERVAL + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_LOGGING_PROVIDER + - _APP_LOGGING_CONFIG + + appwrite-schedule: + image: appwrite/appwrite:1.3.7 + entrypoint: schedule + container_name: appwrite-schedule + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + environment: + - _APP_ENV + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + + mariadb: + image: mariadb:10.7 # fix issues when upgrading using: mysql_upgrade -u root -p + container_name: appwrite-mariadb + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-mariadb:/var/lib/mysql:rw + environment: + - MYSQL_ROOT_PASSWORD=${_APP_DB_ROOT_PASS} + - MYSQL_DATABASE=${_APP_DB_SCHEMA} + - MYSQL_USER=${_APP_DB_USER} + - MYSQL_PASSWORD=${_APP_DB_PASS} + command: 'mysqld --innodb-flush-method=fsync' + + redis: + image: redis:7.0.4-alpine + container_name: appwrite-redis + <<: *x-logging + restart: unless-stopped + command: > + redis-server + --maxmemory 512mb + --maxmemory-policy allkeys-lru + --maxmemory-samples 5 + networks: + - appwrite + volumes: + - appwrite-redis:/data:rw + + # clamav: + # image: appwrite/clamav:1.2.0 + # container_name: appwrite-clamav + # restart: unless-stopped + # networks: + # - appwrite + # volumes: + # - appwrite-uploads:/storage/uploads + + influxdb: + image: appwrite/influxdb:1.5.0 + container_name: appwrite-influxdb + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + volumes: + - appwrite-influxdb:/var/lib/influxdb:rw + + telegraf: + image: appwrite/telegraf:1.4.0 + container_name: appwrite-telegraf + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + environment: + - _APP_INFLUXDB_HOST + - _APP_INFLUXDB_PORT + +networks: + gateway: + appwrite: + runtimes: + +volumes: + appwrite-mariadb: + appwrite-redis: + appwrite-cache: + appwrite-uploads: + appwrite-certificates: + appwrite-functions: + appwrite-builds: + appwrite-influxdb: + appwrite-config: + appwrite-executor: diff --git a/java/collection_wiper/Index.java b/java/collection_wiper/Index.java new file mode 100644 index 00000000..da6e0295 --- /dev/null +++ b/java/collection_wiper/Index.java @@ -0,0 +1,113 @@ +import io.appwrite.Client; +import io.appwrite.services.Databases; +import io.appwrite.exceptions.AppwriteException; +import io.appwrite.models.DocumentList; +import kotlin.Result; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.EmptyCoroutineContext; +import okhttp3.Response; +import org.jetbrains.annotations.NotNull; +import io.openruntimes.java.*; +import java.util.*; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.Gson; + +public RuntimeResponse main(RuntimeRequest req, RuntimeResponse res) { + // Validate that values present in the request are not empty (payload, variables) + RuntimeResponse errorResponse=checkEmptyPayloadAndVariables(req,res); + if(errorResponse!=null){ + return errorResponse; + } + String endpoint = req.getVariables().get("APPWRITE_FUNCTION_ENDPOINT"); + String apiKey = req.getVariables().get("APPWRITE_FUNCTION_API_KEY"); + String projectId = req.getVariables().get("APPWRITE_FUNCTION_PROJECT_ID"); + + Map responseData = new HashMap<>(); + if (endpoint == null || apiKey == null || projectId == null) { + responseData.put("success",false); + responseData.put("message","Variables missing."); + return res.json(responseData); + } + + Client client = new Client(); + client + .setEndpoint(endpoint) + .setProject(projectId) + .setKey(apiKey); + + Databases databases = new Databases(client); + Gson gson=new Gson(); + try { + String payloadString = req.getPayload().toString(); + + Map payload = gson.fromJson(payloadString, Map.class); + // Get file url from payload + + String databaseId = payload.get("databaseId"); + String collectionId = payload.get("collectionId"); + if ( databaseId == null || collectionId == null) { + responseData.put("success",false); + responseData.put("message","Invalid payload."); + return res.json(responseData); + } + databases.deleteCollection(databaseId, collectionId, + new Continuation() { + @NotNull + @Override + public CoroutineContext getContext() { + return EmptyCoroutineContext.INSTANCE; + } + + @Override + public void resumeWith(@NotNull Object o) { + String json = ""; + try { + if (o instanceof Result.Failure) { + Result.Failure failure = (Result.Failure) o; + throw failure.exception; + } else { + Response response = (Response) o; + } + } catch (Throwable th) { + System.out.println("ERROR: " + th.toString()); + } + } + } + ); + + responseData.put("success",true); + return res.json(responseData); + } catch (AppwriteException e) { + responseData.put("success",true); + responseData.put("message","Unexpected error: " + e.getMessage()); + return res.json(responseData); + } +} + +/** + * This function will validate that the payload and variables are non-empty in the request + * + * @param req is the received POST request + * @return null is nothing is empty, otherwise an error response + */ +private RuntimeResponse checkEmptyPayloadAndVariables(RuntimeRequest req,RuntimeResponse res){ + + Map responseData=new HashMap<>(); + + if(req.getPayload()==null||req.getPayload().trim().isEmpty()||req.getPayload().trim().equals("{}")){ + responseData.put("success",false); + responseData.put("message","Payload is empty, expected a payload with provider and URL"); + return res.json(responseData); + + } + if(req.getVariables()==null){ + responseData.put("success",false); + responseData.put("message","Empty function variables found. You need to pass an API key for the provider"); + return res.json(responseData); + } + + return null; +} \ No newline at end of file diff --git a/java/collection_wiper/README.md b/java/collection_wiper/README.md new file mode 100644 index 00000000..e4046266 --- /dev/null +++ b/java/collection_wiper/README.md @@ -0,0 +1,61 @@ +# 💻 Collection Wiper + +A Java Cloud Function for generating a Short URL using [tinyurl](https://tinyurl.com/app) and [bitly](https://bitly.com/) + +Supported providers: tinyurl, bitly + +_Bitly Example input:_ + + + +```json +{"databaseId":"stage","collectionId":"profiles"} +``` + +_Example output:_ + + +```json +{"success":true} +``` + +_Error Example output:_ + +```json +{"success":false,"message":"Collection not found."} +``` + + +## 📝 Environment Variables + +List of environment variables used by this cloud function. These must be passed within 'variables' section of the request: + +**BITLY_API_KEY** - Pass this API key if the requested provider is bitly. This API key would be the access token used by bitly for generating a short URL. + +**TINYURL_API_KEY** - Pass this API key if the requested provider is tinyurl. This API key would be the access token used by tinyurl for generating a short URL. + +## 🚀 Deployment + +1. Clone this repository, and enter this function folder: + +``` +$ git clone https://github.com/open-runtimes/examples.git && cd examples +$ cd java/short_url_generator +``` + +2. Enter this function folder and build the code: +``` +docker run -e INTERNAL_RUNTIME_ENTRYPOINT=Index.java --rm -it -v ${PWD}:/usr/code openruntimes/java:v2-11.0 sh /usr/local/src/build.sh +``` +As a result, a `code.tar.gz` file will be generated. + +3. Start the Open Runtime: +``` +docker run -p 3000:3000 -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/java:v2-11.0 sh /usr/local/src/start.sh +``` + +Your function is now listening on port `3000`, and you can execute it by sending `POST` request with appropriate authorization headers. To learn more about runtime, you can visit Java runtime [README](https://github.com/open-runtimes/open-runtimes/tree/main/runtimes/java-11.0). + +## 📝 Notes + - This function is designed for use with Appwrite Cloud Functions. You can learn more about it in [Appwrite docs](https://appwrite.io/docs/functions). + - This example is compatible with Java 11.0. Other versions may work but are not guarenteed to work as they haven't been tested. \ No newline at end of file diff --git a/java/collection_wiper/deps.gradle b/java/collection_wiper/deps.gradle new file mode 100644 index 00000000..68565d1e --- /dev/null +++ b/java/collection_wiper/deps.gradle @@ -0,0 +1,8 @@ +dependencies { + implementation 'com.google.code.gson:gson:2.9.0' + implementation 'com.squareup.okhttp3:okhttp:4.9.0' + implementation 'io.appwrite:sdk-for-kotlin:1.2.0' + implementation "org.rapidoid:rapidoid-http-server:5.5.5" + implementation 'org.bstats:bstats-bukkit:2.2.1' + implementation 'org.jetbrains.kotlin:kotlin-script-runtime:1.9.0' +} \ No newline at end of file diff --git a/java/wipe_appwrite_collection/Index.java b/java/wipe_appwrite_collection/Index.java new file mode 100644 index 00000000..9220290f --- /dev/null +++ b/java/wipe_appwrite_collection/Index.java @@ -0,0 +1,86 @@ +import java.util.Map; +import java.util.HashMap; +import java.util.*; +import io.openruntimes.java.*; +import com.google.gson.Gson; +import io.appwrite.Client; +import io.appwrite.exceptions.AppwriteException; +import io.appwrite.services.Databases; +import kotlin.Result; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.EmptyCoroutineContext; +import org.jetbrains.annotations.NotNull; +import okhttp3.Response; +import com.google.gson.JsonParser; +import com.google.gson.JsonObject; + +final Gson gson = new Gson(); + +public RuntimeResponse main(RuntimeRequest req, RuntimeResponse res) throws Exception { + // Initialize the Appwrite client and databases service + Client client = new Client(); + var variables = req.getVariables(); + String payloadString = req.getPayload().toString(); + Map responseData = new HashMap<>(); + + // Check if the required environment variables are set + if (variables == null + || !variables.containsKey("APPWRITE_FUNCTION_ENDPOINT") + || !variables.containsKey("APPWRITE_FUNCTION_API_KEY") + || !variables.containsKey("APPWRITE_FUNCTION_PROJECT_ID") + || variables.get("APPWRITE_FUNCTION_ENDPOINT") == null + || variables.get("APPWRITE_FUNCTION_API_KEY") == null + || variables.get("APPWRITE_FUNCTION_PROJECT_ID") == null) { + return res.json(Map.of("Environment variables are not set. Function cannot use Appwrite SDK.", false)); + } else { + // Set the Appwrite client properties + client + .setEndpoint(variables.get("APPWRITE_FUNCTION_ENDPOINT")) + .setProject(variables.get("APPWRITE_FUNCTION_PROJECT_ID")) + .setKey(variables.get("APPWRITE_FUNCTION_API_KEY")); + } + + try { + // Parse the payload data into a Map + Databases databases = new Databases(client); + Map payload = gson.fromJson(payloadString, Map.class); + String databaseId = (String) payload.get("databaseId"); + String collectionId = (String) payload.get("collectionId"); + + if (databaseId == null || collectionId == null) { + return res.json(Map.of("Invalid payload.", false)); + } + + databases.deleteCollection( + databaseId, + collectionId, + new Continuation() { + @NotNull + @Override + public CoroutineContext getContext() { + return EmptyCoroutineContext.INSTANCE; + } + + @Override + public void resumeWith(@NotNull Object o) { + String json = ""; + try { + if (o instanceof Result.Failure) { + Result.Failure failure = (Result.Failure) o; + throw failure.exception; + } else { + Response response = (Response) o; + } + } catch (Throwable th) { + System.out.print("ERROR: " + th.toString()); + } + } + } + ); + + return res.json(Map.of("success", true)); + } catch (AppwriteException e) { + return res.json(Map.of("Collection not found.", false)); + } +} diff --git a/java/wipe_appwrite_collection/README.md b/java/wipe_appwrite_collection/README.md new file mode 100644 index 00000000..5398f972 --- /dev/null +++ b/java/wipe_appwrite_collection/README.md @@ -0,0 +1,70 @@ +# Appwrite Collection Wiper + +Welcome to the documentation of this function 👋 We strongly recommend keeping this file in sync with your function's logic to make sure anyone can easily understand your function in the future. If you don't need documentation, you can remove this file. + +## 🤖 Documentation + +A Java Cloud Function that wipes all the documents inside a collection. + +_Example input:_ + +```json +{ +"databaseId": "stage", +"collectionId": "profiles" +} +``` + +_Example output (_sucess_):_ + +```json +{ +"success": true, +} +``` + +_Example output (_failure_):_ + +```json +{ +"success": false, +"message": "Collection not found." +} +``` + +## 📝 Environment Variables + + APPWRITE_FUNCTION_ENDPOINT - Endpoint of your Appwrite server + APPWRITE_FUNCTION_API_KEY - Appwrite API Key + APPWRITE_FUNCTION_PROJECT_ID - Appwrite project ID. If running on Appwrite, this variable is provided automatically. + +## 🚀 Deployment + +1. Clone this repository, and enter this function folder: + + $ git clone https://github.com/open-runtimes/examples.git && cd examples + $ cd java/wipe_appwrite_collection + +2. Enter this function folder and build the code: + + docker run -e INTERNAL_RUNTIME_ENTRYPOINT=Index.java --rm --interactive --tty --volume $PWD:/usr/code openruntimes/java:v2-18.0 sh /usr/local/src/build.sh + As a result, a code.tar.gz file will be generated. + +3. Start the Open Runtime: + + docker run -p 3000:3000 -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume $PWD/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/java:v2-18.0 sh /usr/local/src/start.sh + Your function is now listening on port 3000, and you can execute it by sending POST request with appropriate authorization headers. To learn more about runtime, you can visit Java runtime README. + +4. Execute function: + + curl http://localhost:3000/ -d '{"variables":{"APPWRITE_FUNCTION_ENDPOINT":"YOUR_ENDPOINT","APPWRITE_FUNCTION_PROJECT_ID":"YOUR_PROJECT_ID","APPWRITE_FUNCTION_API_KEY":"YOUR_API_KEY"},"payload":"{\"databaseId\":\"stage\",\"collectionId\":\"profiles\"}"}' -H "X-Internal-Challenge: secret-key" -H "Content-Type: application/json" + +### Using CLI + + Make sure you have [Appwrite CLI](https://appwrite.io/docs/command-line#installation) installed, and you have successfully logged into your Appwrite server. To make sure Appwrite CLI is ready, you can use the command `appwrite client --debug` and it should respond with green text `✓ Success`. + + Make sure you are in the same folder as your `appwrite.json` file and run `appwrite deploy function` to deploy your function. You will be prompted to select which functions you want to deploy. + +### Manual using tar.gz + + Manual deployment has no requirements and uses Appwrite Console to deploy the tag. First, enter the folder of your function. Then, create a tarball of the whole folder and gzip it. After creating `.tar.gz` file, visit Appwrite Console, click on the `Deploy Tag` button and switch to the `Manual` tab. There, set the `entrypoint` to `src/Index.java`, and upload the file we just generated. diff --git a/java/wipe_appwrite_collection/deps.gradle b/java/wipe_appwrite_collection/deps.gradle new file mode 100644 index 00000000..7bfc5b25 --- /dev/null +++ b/java/wipe_appwrite_collection/deps.gradle @@ -0,0 +1,4 @@ +dependencies { + implementation 'com.google.code.gson:gson:2.9.0' + implementation 'io.appwrite:sdk-for-kotlin:1.2.0' +} \ No newline at end of file