Kotlin Serverless Framework

Overview

Kotless Icon Kotless

JetBrains incubator project KotlinLang slack

Kotless stands for Kotlin serverless framework.

Its focus lies in reducing the routine of serverless deployment creation by generating it straight from the code of the application itself.

So, simply speaking, Kotless gives you one magic button to deploy your Web application as a serverless application on AWS and Azure!

Kotless consists of two main parts:

  • DSL provides a way of defining serverless applications. There are three DSLs supported:
    • Kotless DSL — Kotless own DSL that provides annotations to declare routing, scheduled events, etc.
    • Ktor — Ktor engine that is introspected by Kotless. Use standard Ktor syntax and Kotless will generate deployment.
    • Spring Boot — Spring Boot serverless container that is introspected by Kotless. Use standard Spring syntax and Kotless will generate deployment.
  • Kotless Gradle Plugin provides a way of deploying serverless application. For that, it:
    • performs the tasks of generating Terraform code from the application code and, subsequently, deploying it to AWS or Azure;
    • runs application locally, emulates the AWS environment (if necessary) and provides the possibility for IDE debugging.

One of the key features of Kotless is its ability to embed into existing applications. Kotless makes super easy deployment of existing Spring and Ktor applications to AWS and Microsoft Azure serverless platforms.

Getting started

Setting up project

Kotless uses Gradle to wrap around the existing building process and insert the deployment into it.

Consider using one of the latest versions of Gradle, starting with the 7.2 version.

Basically, if you already use Gradle, you only need to do two things.

Firstly, set up the Kotless Gradle plugin.

You will have to tell Gradle where to find the plugin by editing settings.gradle.kts:

pluginManagement {
    resolutionStrategy {
        this.eachPlugin {
            if (requested.id.id == "io.kotless") {
                useModule("io.kotless:gradle:${this.requested.version}")
            }
        }
    }

    repositories {
        maven(url = uri("https://packages.jetbrains.team/maven/p/ktls/maven"))
        gradlePluginPortal()
        mavenCentral()
    }
}

And apply the plugin:

//Imports are necessary, for this example
import io.kotless.plugin.gradle.dsl.Webapp.Route53
import io.kotless.plugin.gradle.dsl.kotless

//Group may be used by Kotless DSL to reduce the number of introspected classes by package
//So, don't forget to set it
group = "org.example"
version = "0.1.0"


plugins {
    //Version of Kotlin should be 1.3.72+
    kotlin("jvm") version "1.5.31" apply true

    id("io.kotless") version "0.2.0" apply true
}

Secondly, add Kotless DSL (or Ktor, or Spring Boot) as a library to your application:

repositories {
    mavenCentral()
    //Kotless repository
    maven(url = uri("https://packages.jetbrains.team/maven/p/ktls/maven"))
}

dependencies {
    implementation("io.kotless", "kotless-lang", "0.2.0")
    implementation("io.kotless", "kotless-lang-aws", "0.2.0")
//    if you want to deploy to Microsoft Azure, just replace -aws with -azure    
//    implementation("io.kotless", "ktor-lang-azure", "0.2.0")


    //or for Ktor (Note, that `ktor-lang` depends on Ktor version 1.5.0)
    //implementation("io.kotless", "ktor-lang", "0.2.0")
    //implementation("io.kotless", "ktor-lang-aws", "0.2.0")
    //implementation("io.kotless", "ktor-lang-azure", "0.2.0")

    //or for Spring Boot (Note, that `spring-boot-lang` depends on Spring Boot version 2.3.0.RELEASE)
    //implementation("io.kotless", "spring-boot-lang", "0.2.0")
    //implementation("io.kotless", "spring-boot-lang-aws", "0.2.0")
    //implementation("io.kotless", "spring-boot-lang-azure", "0.2.0")
}

Please note that if you use Ktor or Spring Boot you will need to replace existing in your project dependency with a special Kotless *-lang dependency. Also, after that you will need to align version of dependent libraries (like Spring Security) with version bundled in *-lang (see this paragraph)

This gives you access to DSL interfaces in your code and sets up a Lambda dispatcher inside your application.

Deploying to the cloud

Depending on a use case, you may want to deploy application either in an AWS or Microsoft Azure.

Note, that if you even don't have a cloud account, you can still use Kotless locally to run and debug your application -- just use local Gradle task.

Deploying to AWS

If you don't have an AWS account, you can create it following simple instruction by Hadi Hariri.

If you have an AWS account and want to perform the real deployment — let's set up everything for it! It's rather simple:

kotless {
    config {

        aws {
            storage {
                bucket = "kotless.s3.example.com"
            }

            profile = "example"
            region = "eu-west-1"
        }
    }

    webapp {
        dns("kotless", "example.com")
    }
}

Here we set up the config of Kotless itself:

  • the bucket, which will be used to store lambdas and configs;
  • Terraform configuration with the name of the profile to access AWS.

Then we set up a specific application to deploy:

  • Route53 alias for the resulting application (you need to pre-create an ACM certificate for the DNS record).

And that's the whole setup!

Deploying to Azure

Deployment to Microsoft Azure is also pretty straightforward and simple:

kotless {
    config {
        azure {
            storage {
                storageAccount = "your-storage-account"
                container = "container-which-kotless-would-use"
            }

            terraform {
                backend {
                    resourceGroup = "your-resource-group"
                }
            }
        }
    }

    webapp {
        dns("kotless", "example.com")
    }
}

Here we set up the config of Kotless itself:

  • the storage, which will be used to store lambdas and configs;
  • Terraform configuration with the name of the profile to access Azure.

Then we set up a specific application to deploy:

  • Azure DNS alias for the resulting application (you need to pre-create certificate for the DNS record).

And that's the whole setup!

Creating application

Now you can create your first serverless application with Kotless DSL:

@Get("/")
fun main() = "Hello world!"

Or with Ktor:

class Server : Kotless() {
    override fun prepare(app: Application) {
        app.routing {
            get("/") {
                call.respondText { "Hello World!" }
            }
        }
    }
}

Or with Spring Boot:

@SpringBootApplication
open class Application : Kotless() {
    override val bootKlass: KClass<*> = this::class
}

@RestController
object Pages {
    @GetMapping("/")
    fun main() = "Hello World!"
}

Local start

Kotless-based applications can start locally as an HTTP server. This functionality is supported by all DSLs.

Moreover, Kotless local start may spin up an AWS emulation (docker required). Just instantiate your AWS service client using override for Kotless local starts:

val client = AmazonDynamoDBClientBuilder.standard().withKotlessLocal(AwsResource.DynamoDB).build()

And enable it in Gradle:

kotless {
    //<...>
    extensions {
        local {
            //enables AWS emulation (disabled by default)
            useAWSEmulation = true
        }
    }
}

During the local run, LocalStack will be started and all clients will be pointed to its endpoint automatically.

Local start functionality does not require any access to cloud provider, so you may check how your application behaves without an AWS account. Also, it gives you the possibility to debug your application locally from your IDE.

Integration with existing applications

Kotless is able to deploy existing Spring Boot or Ktor application to AWS serverless platform. To do it, you'll need to set up a plugin and replace existing dependency with the appropriate Kotless DSL.

For Ktor, you should replace existing engine ( e.g. implementation("io.ktor", "ktor-server-netty", "1.5.0")) with implementation("io.kotless", "ktor-lang", "0.1.6"). Note that this dependency bundles Ktor of version 1.5.0, so you may need to upgrade other Ktor libraries (like ktor-html-builder) to this version.

For Spring Boot you should replace the starter you use ( e.g. implementation("org.springframework.boot", "spring-boot-starter-web", "2.3.0.RELASE)) with implementation("io.kotless", "spring-boot-lang", "0.1.6"). Note that this dependency bundles Spring Boot of version 2.4.2, so you also may need to upgrade other Spring Boot libraries to this version.

Once it is done, you may hit deploy task and make your application serverless. Note, that you will still be able to run application locally via local Gradle task.

Advanced features

While Kotless can be used as a framework for the rapid creation of serverless applications, it has many more features covering different areas of application.

Including, but not limited to:

  • Lambdas auto-warming — Kotless creates schedulers to execute warming sequences to never leave your lambdas cold. As a result, applications under moderate load are not vulnerable to cold-start problem.
  • Permissions management — you can declare which permissions to which AWS resources are required for application via annotations on Kotlin functions, classes or objects. Permissions will be granted automatically.
  • Static resources — Kotless will deploy static resources to S3 and set up CDN for them. It may greatly improve the response time of your application and is supported by all DSLs.
  • Scheduled events — Kotless sets up timers to execute @Scheduled jobs on schedule;
  • Terraform extensions — Kotless-generated code can be extended by custom Terraform code;

Kotless is in active development, so we are currently working on extending this list with such features as:

  • Support of other clouds — Kotless is based on a cloud-agnostic schema, so we are working on support of other clouds.
  • Support of multiplatform applications — Kotless will not use any platform-specific libraries to give you a choice of a Lambda runtime (JVM/JS/Native).
  • Versioned deployment — Kotless will be able to deploy several versions of the application and maintain one of them as active.
  • Implicit permissions granting — Kotless will be able to deduce permissions from AWS SDK function calls.
  • Events handlers support — Kotless will generate events subscriptions for properly annotated events handlers.

Examples

Any explanation becomes much better with a proper example.

In the repository's examples folder, you can find example projects built with Kotless DSL:

  • kotless/site — a site about Kotless written with Kotless DSL (site.kotless.io). This example demonstrates @StaticGet and @Get (static and dynamic routes) usage, as well as Link API.
  • kotless/shortener — a simple URL shortener written with Kotless DSL (short.kotless.io). This example demonstrates @Get ( dynamic routes), @Scheduled (scheduled lambdas), Permissions API (for DynamoDB access), and Terraform extensions.

Similar examples exist for Ktor:

  • ktor/site — a site about Kotless written with Ktor (ktor.site.kotless.io). This example demonstrates static {...} and routing {...} usage.
  • ktor/shortener — a simple URL shortener written with Ktor (ktor.short.kotless.io). This example demonstrates routing { ... } (dynamic routes), Permissions API (for DynamoDB access), and Terraform extensions.

And for Spring Boot:

  • spring/site — a site about Kotless written with Spring Boot (spring.site.kotless.io). This example demonstrates usage of statics and @RestController.
  • spring/shortener — a simple URL shortener written with Spring Boot (spring.short.kotless.io). This example demonstrates usage of @RestController (dynamic routes), Permissions API (for DynamoDB access), and Terraform extensions.

Want to know more?

You may take a look at Wiki where the client documentation on Kotless is located.

Apart from that, the Kotless code itself is widely documented, and you can take a look into its interfaces to get to know Kotless better.

You may ask questions and participate in discussions on #kotless channel in KotlinLang slack.

Acknowledgements

Special thanks to:

  • Alexandra Pavlova (aka sunalex) for our beautiful logo;
  • Yaroslav Golubev for help with documentation;
  • Gregor Billing for help with the Gradle plugin and more.
Comments
  • Gradle configuration fails because of implicit dependency on ShadowJar

    Gradle configuration fails because of implicit dependency on ShadowJar

    No template, so I will just freestyle the issue report to the best of my abilities!

    OS: Manjaro Linux 18.1.4 / Kernel 5.4.2 amd64 Java: 1.8.0_232 Gradle: 6.0.1 (wrapper via gradlew)

    Expected behaviour

    When following the steps on the Quickstart guide in the README.md file, I can incorporate the Gradle plugin id("io.kotless") into my existing build without breaking the project.

    Actual behaviour

    Upon following the instructions on how to include Kotless in my own Gradle project, Gradle fails during configuration stage with the following error message:

    FAILURE: Build failed with an exception.
    
    * Where:
    Build file '/home/suushie_maniac/jvdocs/tnoodle/webscrambles/build.gradle.kts' line: 27
    
    * What went wrong:
    An exception occurred applying plugin request [id: 'io.kotless', version: '0.1.2']
    > Failed to apply plugin [id 'io.kotless']
       > Task with name 'shadowJar' not found in project ':webscrambles'.
    

    The failure occurs even for simple commands such as ./gradlew tasks.

    In particular, my buildscript file uses the Kotlin DSL. I have installed Kotless as id("io.kotless").version("0.1.2") as determined by the Quickstart guide. The plugins {} block also includes johnrengelman's shadow plugin indenpendently of Kotless, because it is needed as part of my project.

    Steps to reproduce

    The entire codebase of the project where this fail occurs is open-source at https://github.com/suushiemaniac/tnoodle/tree/feature/kotless.

    To reproduce, simply clone and check out the feature/kotless branch that is linked above and execute ./gradlew tasks in the project directory.

    The relevant build file is in the cloudscrambles folder, found at cloudscrambles/build.gradle.kts

    bug 
    opened by gregorbg 15
  • Can't start local server

    Can't start local server

    No doubt pilot error, but...

    When I use implementation("io.kotless", "lang", "0.1.3") I get Error: Could not find or load main class io.kotless.local.MainKt

    Changing to implementation("io.kotless", "lang-local", "0.1.3") I get Exception in thread "main" java.lang.IllegalStateException: System.getenv(Constants.Local.serverPort) must not be null at io.kotless.local.MainKt.main(Main.kt:6) at io.kotless.local.MainKt.main(Main.kt)

    This is all with a default port number.

    Thanks for any help.

    opened by hchesley 8
  • Scanner FieldAnnotationsScanner was not configured

    Scanner FieldAnnotationsScanner was not configured

    Looks like in the new version of Kotless a bug has been introduced in relation with the reflection capabilities.

    With a simple code like:

    import io.kotless.dsl.lang.http.Get
    
    @Get("/hello")
    fun sayHello() = "Say Hello!"
    

    When the endpoint is hit the following exception is thrown:

    org.reflections.ReflectionsException: Scanner FieldAnnotationsScanner was not configured
            at org.reflections.Store.get(Store.java:39)
            at org.reflections.Store.get(Store.java:61)
            at org.reflections.Store.get(Store.java:46)
            at org.reflections.Reflections.getFieldsAnnotatedWith(Reflections.java:546)
            at io.kotless.dsl.reflection.ReflectionScanner.fieldsWithAnnotation(ReflectionScanner.kt:43)
            at io.kotless.local.handler.StaticHandler$fields$2.invoke(StaticHandler.kt:38)
            at io.kotless.local.handler.StaticHandler$fields$2.invoke(StaticHandler.kt:14)
            at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
            at io.kotless.local.handler.StaticHandler.getFields(StaticHandler.kt)
            at io.kotless.local.handler.StaticHandler.handle(StaticHandler.kt:19)
            at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)
            at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
            at org.eclipse.jetty.server.Server.handle(Server.java:501)
            at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
            at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556)
            at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
            at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
            at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
            at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
            at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
            at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
            at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
            at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
            at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
            at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:375)
            at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
            at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
            at java.base/java.lang.Thread.run(Thread.java:832)
    

    Going back to version 0.1.3 solves the problem (using diverse versions of Kotlin: 1.3.61 and 1.3.72)

    Note: The problem is reproducible in local

    bug 
    opened by diegomarzo 6
  • Ktor features missing?!

    Ktor features missing?!

    Hello,

    first of all: Kotless is awesome 👍

    As I'm using the ktor-lang for development I wonder if it is planned to support ktor Locations (afaik those are not added to the API Gateway in AWS).

    In addition I wonder if it would be possible to add something like the Events API to the ktor-lang?! So it is possible to define additional periodic "tasks" in my project (e.g. download some kind of daily generated content to be cached in a S3 bucket, instead of fetching it everytime a lambda is called).

    Regards

    opened by BlackHornet 5
  • Java 11 Support

    Java 11 Support

    Hello, I tried to deploy a simple function and I initialized my Gradle project using Java 11, which is the latest supported runtime for Java in AWS Lambda.

    Everything got deployed correctly, except the AWS lambda runtime was set to java8 and I got this error at runtime:

    /HelloserverlessApplication has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
    

    I'm using kotless 0.1.5 and the spring-boot-lang dsl.

    bug 
    opened by onema 4
  • (window10) Cannot get property 'kotless' on extra properties extension as it does not exist

    (window10) Cannot get property 'kotless' on extra properties extension as it does not exist

    ref : #21

    on linux, ./gradlew works good but on window10 is not.

    how can i build my kotless app on window10?

    (capture1 - build.gradle.kts) capture1 - build gradle kts

    (capture2 - gradlew) capture2 - gradlew

    (capture3 - cannot get property kotless) capture3 - cannot get property kotless

    (capture4 - package cannot be imported) capture4 - package cannot be imported

    opened by anpaul0615 4
  • Allow headless plugin usage

    Allow headless plugin usage

    Currently, it is only possible to use the kotless Gradle plugin if one exactly follows the build file setup outlined in the readme. This means that stuff(TM) explodes when applying the plugin without a corresponding kotless configuration block.

    In my opinion, the plugin should ship with reasonable defaults that allow the build script compilation to succeed, while still allowing the user to override defaults with their own configurations (like for example in the README.md) if they so desire.

    This PR aims to provide such defaults. Please provide feedback on whether they are reasonable.

    opened by gregorbg 4
  • Error: No certificate for domain

    Error: No certificate for domain "foo.com" found in this region

    I might be completely off base, but it seems like the ACM certificate needs to be in us-east-1? This caught me a bit by surprise as the region specified in the terraform block was respected for everything else.

    https://github.com/JetBrains/kotless/blob/ab31b2dab87f4b6263a9aa429626deef75934bd7/engine/src/main/kotlin/io/kotless/gen/factory/route53/CertificateFactory.kt#L20

    opened by dustinconrad 3
  • MergeLambda.All creates a function called

    MergeLambda.All creates a function called "merged-0"

    By default the deployment uses MergeLambda.All and when there are more than one endpoint, it generates a function called merged-0 which says nothing about the actual application I'm deploying. The name should really be the application name.

    For example when using MergeLambda.None the following functions and names are created:

    • com-example-helloserverless-hello-serverless-tasks-get
    • com-example-helloserverless-hello-serverless-overview-get
    • ...

    Ideally when using MergeLambda.All the name of the function would be something like

    • com-example-helloserverless

    Using kotless 0.1.5 and spring-boot-lang 0.1.5

    bug 
    opened by onema 3
  • Deploy to aws error

    Deploy to aws error

    `1:14:17 p.m.: Executing task 'deploy'...

    Task :download_terraform Downloading terraform version 0.11.14 for OS darwin_amd64 Terraform version 0.11.14 for OS darwin_amd64 successfully downloaded

    Task :generate Task :compileKotlin Task :compileJava NO-SOURCE Task :processResources NO-SOURCE Task :classes UP-TO-DATE Task :shadowJar There are some problems with the configuration, described below.

    The Terraform configuration must be valid before initialization so that Terraform can determine which modules and providers need to be installed.

    Error: Error loading /Users/malcolmjrosse/Desktop/Kotlin-Devs/UpApp-Server/build/kotless-gen/UpApp-Server.tf: Error reading config for aws_cloudwatch_event_target[autowarm_{name}_get]: parse error at 1:38: expected "}" but found invalid sequence "{"

    Task :initialize

    Error: Error loading /Users/malcolmjrosse/Desktop/Kotlin-Devs/UpApp-Server/build/kotless-gen/UpApp-Server.tf: Error reading config for aws_cloudwatch_event_target[autowarm_{name}_get]: parse error at 1:38: expected "}" but found invalid sequence "{"

    Task :deploy`

    opened by MalcolmJRosse 3
  • Cannot get property 'kotless' on extra properties extension as it does not exist

    Cannot get property 'kotless' on extra properties extension as it does not exist

    Screenshot at Jan 07 17-09-23
    A problem occurred configuring root project 'GoUpApp-Server'.
    > Cannot get property 'kotless' on extra properties extension as it does not exist
    

    mac os -> gradle-5.2.1

    opened by MalcolmJRosse 3
  • spring - jpa data support

    spring - jpa data support

    I wasn't able to add jpa properly to the project, it works locally but when deployed there were missing beans and it kept on failing. eventually i removed the jpa and defined the data source bean manually.

    (note the System.getEnv is an additional hack since loading application.yaml isnt working as well - i opened a diff issue on that matter)

    @Bean
        open fun dataSource(): DataSource {
            val hikariConfig = HikariConfig().apply {
                this.isAutoCommit = true
                this.driverClassName = "com.mysql.cj.jdbc.Driver"
                this.jdbcUrl = System.getenv()["MYSQL_HOST"]
                this.username = System.getenv()["MYSQL_USER"]
                this.password = System.getenv()["MYSQL_PASS"]
                this.connectionTimeout = 60000
                this.validationTimeout = 60000
                this.maximumPoolSize = 50
            }
    
            return HikariDataSource(hikariConfig)
        }
    
    opened by mamaorha 0
  • How to get prs out

    How to get prs out

    There are some nice PRs That would be really nice to get in the main releases. F ex Ktor2.

    Would be very useful to get merged.

    Appreciating the work done here so far!

    opened by devdavidkarlsson 0
  • Update localstack to 1.17.5

    Update localstack to 1.17.5

    Getting an error when running local with aws emulation enabled on a M2 Apple Silicon Macbook Air,

    ❯ gradle local
    > Task :kotless:shortener:localstack_start FAILED
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':kotless:shortener:localstack_start'.
    > Previous attempts to find a Docker environment failed. Will not retry. Please see logs and check configuration
    
    * Try:
    > Run with --stacktrace option to get the stack trace.
    > Run with --info or --debug option to get more log output.
    > Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
    
    You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
    
    See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings
    
    BUILD FAILED in 398ms
    4 actionable tasks: 1 executed, 3 up-to-date
    

    I'm guessing its related to this issue, https://github.com/testcontainers/testcontainers-java/issues/5266

    opened by pyrossh 0
  • Kotless doesn't work with Kotlin 1.6.21

    Kotless doesn't work with Kotlin 1.6.21

    I tried upgrading Kotlin to 1.6.21 in and found out, that kotless 0.2.0 doesn't work with that. Kotlin 1.6.10 works perfectly fine in the same project.

    The issue is gradle task generate, it fails with following stack trace:

    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':generate'.
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:188)
            at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:186)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:174)
            at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
            at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
            at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
            at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
            at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
            at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
            at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:408)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:395)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:388)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:374)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
            at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
            at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
            at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.NoSuchMethodError: 'org.jetbrains.kotlin.analyzer.AnalysisResult org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(org.jetbrains.kotlin.com.intellij.openapi.project.Project, java.util.Collection, org.jetbrains.kotlin.resolve.BindingTrace, org.jetbrains.kotlin.config.CompilerConfi
    guration, kotlin.jvm.functions.Function1, kotlin.jvm.functions.Function2, org.jetbrains.kotlin.com.intellij.psi.search.GlobalSearchScope, java.util.List, java.util.List, java.util.List, int, java.lang.Object)'
            at io.kotless.parser.utils.psi.analysis.ResolveUtil.analyze(ResolveUtil.kt:26)
            at io.kotless.parser.utils.psi.analysis.ResolveUtil.analyze$default(ResolveUtil.kt:22)
            at io.kotless.parser.utils.psi.analysis.ResolveUtil.analyze(ResolveUtil.kt:19)
            at io.kotless.parser.utils.psi.analysis.ResolveUtil.analyze(ResolveUtil.kt:15)
            at io.kotless.parser.Parser.parse(Parser.kt:31)
            at io.kotless.plugin.gradle.tasks.gen.KotlessGenerateTask.parseSources(KotlessGenerateTask.kt:85)
            at io.kotless.plugin.gradle.tasks.gen.KotlessGenerateTask.act(KotlessGenerateTask.kt:64)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
            at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
            at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:58)
            at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
            at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$2.run(ExecuteActionsTaskExecuter.java:506)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:74)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:74)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:491)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:474)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:106)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:271)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:249)
            at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:83)
            at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:37)
            at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:50)
            at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:47)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:47)
            at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:37)
            at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:68)
            at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:38)
            at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:50)
            at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:36)
            at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
            at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
            at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
            at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
            at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:29)
            at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:54)
            at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:35)
            at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:60)
            at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:27)
            at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:174)
            at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:74)
            at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:45)
            at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:40)
            at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:29)
            at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
            at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:99)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:92)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:52)
            at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:36)
            at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:85)
            at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:42)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
            at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:91)
            at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
            at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:106)
            at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:51)
            at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:72)
            at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:46)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:86)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
            at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:32)
            at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
            at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:43)
            at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:31)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution$2.withWorkspace(ExecuteActionsTaskExecuter.java:284)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
            at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
            at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
            at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
            at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
            at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
            at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:185)
            at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:174)
            at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
            at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
            at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
            at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
            at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
            at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
            at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
            at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
            at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
            at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
            at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
            at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:408)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:395)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:388)
            at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:374)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
            at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
            at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
            at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
            at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    
    
    opened by kejml 0
  • S3Bucket permission doesn't support ListObjects

    S3Bucket permission doesn't support ListObjects

    Kotless S3Bucket permission annotation generates terraform incorrectly for the ListObjects operation.

    ListObjects requires the s3:ListBucket permission to be applied to the s3 arn without a trailing "/". i.e. the arn needs to look like this arn:aws:s3:::my-bucket instead of arn:aws:s3:::my-bucket/

    In other words, we need a new statement in the generated aws_iam_policy_document for Permission.Read or Permission.ReadWrite for the s3 bucket that looks something like this:

    statement { actions = ["s3:List*"] effect = "Allow" resources = ["arn:aws:s3:::my-bucket"] }

    opened by bdueck 0
Releases(0.2.0)
  • 0.2.0(Oct 19, 2021)

  • 0.1.6(Aug 25, 2020)

    Added

    • Support for different runtimes: Java 8 and Java 11

    Changed

    • Migrate to Terraform 12 by default

    Fixed

    • Problem with LocalStack not stopping after a run
    Source code(tar.gz)
    Source code(zip)
  • 0.1.5(Jun 2, 2020)

    Fixed

    • Reflections dependency reverted to older version because of critical bug in it
    • Fix for HTTPRequest -- sometimes user-agent can miss in APIGateway request
    Source code(tar.gz)
    Source code(zip)
  • 0.1.4(May 31, 2020)

    Added

    • Spring Boot DSL -- Spring Boot serverless container and parser of it. Support dynamic and static routes, warming of lambda, granular permissions. Does not support Scheduled.
    • Support local run for Spring Boot DSL via tomcat starter
    • Spring Boot examples: shortener and site

    Changed

    • Examples were reworked into one project
    • workDirectory is now called staticsRoot

    Fixed

    • Improvements in all parsers -- now all of them should work a lot faster
    • Fixes to documentation in code
    Source code(tar.gz)
    Source code(zip)
  • 0.1.3(Feb 9, 2020)

    Added

    • Output to console URL of deployed application
    • Support local start for Kotless DSL
    • Support @Scheduled execution for local starts
    • Use AWS Local Stack for mocking of AWS services during local start
      • Extension files will be automatically applied to LocalStack instance

    Fixed

    • Support deployment without Route53 record -- will use generated by API Gateway DNS record. Note: Usage of generated record may lead to problems with hardcoded links, Kotless Links API works with them correctly.
    • Support headless mode -- without any configuration Gradle project should successfully import and local starts will work. Still configuration is required for actual deployment.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.2(Nov 3, 2019)

    Added

    • Ktor DSL -- Ktor Engine and parser for it. Support dynamic and static routes, warming of lambda, granular permissions. Does not support Scheduled.
    • Add local run task for Ktor DSL -- now you can run server locally.
    • Support of all remaining HTTP methods in Kotless and Ktor DSL
    • Ktor examples: add shortener and site
    Source code(tar.gz)
    Source code(zip)
  • v0.1.1(Oct 19, 2019)

    Added

    • Support of binary responses for binary MimeTypes
    • Scheduled events -- just annotate function with @Scheduled
    • Extensions API -- now it is possible to use custom Terraform code along with Kotless generated during deployment.
    • URL shortener example -- simple URL shortener written with Kotless

    Changed

    • Separate Terraform synthesizing into Terraform DSL, Generators and Optimizers
    • Minor style changes in Gradle DSL

    Fixed

    • Multiregionality -- now Kotless can be deployed to any region
    • Default parameters in functions now back to working
    • Format of S3 resource arn in permissions
    • Deploy-time check of signatures of annotated functions
    Source code(tar.gz)
    Source code(zip)
Owner
JetBrains
JetBrains open source projects
JetBrains
A framework for writing composable parsers based on Kotlin Coroutines.

Parsus A framework for writing composable parsers based on Kotlin Coroutines. val booleanGrammar = object : Grammar<BooleanExpression>() { val ws

Aleksei Semin 28 Nov 1, 2022
Kotlin Multiplatform lifecycle-aware business logic components (aka BLoCs) with routing functionality and pluggable UI (Jetpack Compose, SwiftUI, JS React, etc.), inspired by Badoos RIBs fork of the Uber RIBs framework

Decompose Please see the project website for documentation and APIs. Decompose is a Kotlin Multiplatform library for breaking down your code into life

Arkadii Ivanov 819 Dec 29, 2022
Kotlin Multiplatform Mobile + Mobile Declarative UI Framework (Jetpack Compose and SwiftUI)

Kotlin Multiplatform Mobile + Mobile Declarative UI Framework (Jetpack Compose and SwiftUI)

Kotchaphan Muangsan 3 Nov 15, 2022
Framework for quickly creating connected applications in Kotlin with minimal effort

Ktor is an asynchronous framework for creating microservices, web applications and more. Written in Kotlin from the ground up. import io.ktor.server.n

ktor.io 10.7k Jan 9, 2023
A modular object storage framework for Kotlin multiplatform projects.

ObjectStore A modular object storage framework for Kotlin multiplatform projects. Usage ObjectStore provides a simple key/value storage interface whic

Drew Carlson 4 Nov 10, 2022
This is powerful android framework

FlairFramework This is an android framework for build complex application with different architectures (MVC ready/MVP/MVVM/MVI ets). It's create on to

Alexandr Minkin 31 Nov 29, 2021
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Jan 8, 2023
General purpose parsing framework. Simplify parsing of text

General purpose parsing framework. Simplify parsing of text. Allows capture complex nested formats with simple and human-readable syntax.

Roman 1 Nov 16, 2021
Flutter plugin that leverages Storage Access Framework (SAF) API to get access and perform the operations on files and folders

Flutter plugin that leverages Storage Access Framework (SAF) API to get access and perform the operations on files and folders.

Vehement 8 Nov 26, 2022
Ivy FRP is a Functional Reactive Programming framework for declarative-style programming for Android

FRP (Functional Reactive Programming) framework for declarative-style programming for Andorid. :rocket: (compatible with Jetpack Compose)

null 8 Nov 24, 2022
A sample application that build with combine use Clean Architecture framework and Github API

The Github Example Introduction This is a sample application that build with combine use Clean Architecture framework and Github API (https://develope

Nguyễn Hùng An 2 Aug 12, 2022
Run Kotlin/JS libraries in Kotlin/JVM and Kotlin/Native programs

Zipline This library streamlines using Kotlin/JS libraries from Kotlin/JVM and Kotlin/Native programs. It makes it possible to do continuous deploymen

Cash App 1.5k Dec 30, 2022
A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

common sense OSS 0 Jan 20, 2022
Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in Kotlin with Jetpack Compose and a backed in Kotlin hosted on AppEngine.

Conferences4Hall Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in K

Gérard Paligot 98 Dec 15, 2022
Android + Kotlin + Github Actions + ktlint + Detekt + Gradle Kotlin DSL + buildSrc = ❤️

kotlin-android-template ?? A simple Github template that lets you create an Android/Kotlin project and be up and running in a few seconds. This templa

Nicola Corti 1.5k Jan 3, 2023
LifecycleMvp 1.2 0.0 Kotlin is MVP architecture implementation with Android Architecture Components and Kotlin language features

MinSDK 14+ Download Gradle Add to project level build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' }

Robert 20 Nov 9, 2021
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
👋 A common toolkit (utils) ⚒️ built to help you further reduce Kotlin boilerplate code and improve development efficiency. Do you think 'kotlin-stdlib' or 'android-ktx' is not sweet enough? You need this! 🍭

Toolkit [ ?? Work in progress ⛏ ?? ??️ ?? ] Snapshot version: repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") }

凛 35 Jul 23, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022