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

kalix.javasdk.impl.client.ViewCallValidator.scala Maven / Gradle / Ivy

There is a newer version: 1.4.1
Show newest version
/*
 * 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.javasdk.impl.client

import java.lang.reflect.Method

import kalix.javasdk.action.Action
import kalix.javasdk.annotations.Query
import kalix.javasdk.eventsourcedentity.EventSourcedEntity
import kalix.javasdk.valueentity.ValueEntity
import kalix.javasdk.workflow.Workflow
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestParam

object ViewCallValidator {

  def validate(method: Method): Unit = {
    val declaringClass = method.getDeclaringClass
    if (classOf[Action].isAssignableFrom(declaringClass)
      || classOf[ValueEntity[_]].isAssignableFrom(declaringClass)
      || classOf[EventSourcedEntity[_, _]].isAssignableFrom(declaringClass)
      || classOf[Workflow[_]].isAssignableFrom(declaringClass)) {
      throw new IllegalStateException(
        "Use dedicated builder for calling " + declaringClass.getSuperclass.getSimpleName
        + " component method " + declaringClass.getSimpleName + "::" + method.getName + ". This builder is meant for View component calls.")
    }

    if (!method.getAnnotations.toSeq.exists(annotation =>
        classOf[Query].isAssignableFrom(annotation.annotationType()))) {
      throw new IllegalStateException(
        s"A View query method [${method.getName}] should be annotated with @Query annotation.")
    }

    val paramsWithMissingAnnotations = method.getParameterAnnotations.toSeq
      .zip(method.getParameters)
      .filter { case (annotations, _) =>
        annotations.isEmpty || !annotations.toSeq.exists(annotation => {
          val annType = annotation.annotationType()
          classOf[PathVariable].isAssignableFrom(annType) ||
          classOf[RequestParam].isAssignableFrom(annType) ||
          classOf[RequestBody].isAssignableFrom(annType)
        })
      }
      .map(_._2)

    if (paramsWithMissingAnnotations.nonEmpty) {
      throw new IllegalStateException(
        s"When using ComponentClient each [${method.getName}] View query method parameter should be annotated with @PathVariable, @RequestParam or @RequestBody annotations. "
        + s"Missing annotations for params with types: [${paramsWithMissingAnnotations.map(_.getType.getSimpleName).mkString(", ")}]")
      // it would be nicer to have param names, but when using `resolveMethodRef` all param names are gone, we have only "arg0", "arg1", etc.
    }

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy