All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kalix.springsdk.impl.EntityDescriptorFactory.scala Maven / Gradle / Ivy

/*
 * Copyright 2021 Lightbend Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kalix.springsdk.impl

import kalix.EntityMethodOptions.Generator
import kalix.springsdk.annotations.EntityKey
import kalix.springsdk.annotations.GenerateEntityKey
import kalix.springsdk.impl.ComponentDescriptorFactory.buildJWTOptions
import kalix.springsdk.impl.reflection.KalixMethod
import kalix.springsdk.impl.reflection.NameGenerator
import kalix.springsdk.impl.reflection.RestServiceIntrospector
import kalix.springsdk.impl.reflection.ServiceIntrospectionException

private[impl] object EntityDescriptorFactory extends ComponentDescriptorFactory {

  override def buildDescriptorFor(
      component: Class[_],
      messageCodec: SpringSdkMessageCodec,
      nameGenerator: NameGenerator): ComponentDescriptor = {

    val entityKeysOnType = {
      val anno = component.getAnnotation(classOf[EntityKey])
      if (anno != null) anno.value()
      else Array.empty[String]
    }

    val kalixMethods =
      RestServiceIntrospector.inspectService(component).methods.map { restMethod =>

        val entityKeyOnMethod = restMethod.javaMethod.getAnnotation(classOf[EntityKey])
        val generateEntityKey = restMethod.javaMethod.getAnnotation(classOf[GenerateEntityKey])

        if (entityKeyOnMethod != null && generateEntityKey != null)
          throw ServiceIntrospectionException(
            restMethod.javaMethod,
            "Invalid annotation usage. Found both @EntityKey and @GenerateEntityKey annotations. " +
            "A method can only be annotated with one of them, but not both.")

        val kalixMethod =
          if (generateEntityKey != null) {
            val entityOptions = kalix.EntityMethodOptions.newBuilder().setKeyGenerator(Generator.VERSION_4_UUID)
            val methodOpts = kalix.MethodOptions.newBuilder().setEntity(entityOptions)
            KalixMethod(restMethod).withKalixOptions(methodOpts.build())

          } else {
            // keys defined on Method level get precedence
            val entityKeysToUse =
              if (entityKeyOnMethod != null) entityKeyOnMethod.value()
              else entityKeysOnType

            if (entityKeysToUse.isEmpty)
              throw ServiceIntrospectionException(
                restMethod.javaMethod,
                "Invalid command method. No @EntityKey nor @GenerateEntityKey annotations found. " +
                "A command method should be annotated with either @EntityKey or @GenerateEntityKey, or " +
                "an @EntityKey annotation should be present at class level.")

            KalixMethod(restMethod, entityKeys = entityKeysToUse.toIndexedSeq)
          }

        kalixMethod.withKalixOptions(buildJWTOptions(restMethod.javaMethod))
      }

    val serviceName = nameGenerator.getName(component.getSimpleName)
    ComponentDescriptor(
      nameGenerator,
      messageCodec,
      serviceName,
      serviceOptions = AclDescriptorFactory.serviceLevelAclAnnotation(component),
      component.getPackageName,
      kalixMethods)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy