Skip to content

Commit

Permalink
chore: validate components are public
Browse files Browse the repository at this point in the history
  • Loading branch information
efgpinto committed Jan 4, 2024
1 parent ac19d3a commit 87c2e89
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,24 @@ object Validations {
}

def validate(component: Class[_]): Validation =
componentMustBePublic(component) ++
validateAction(component) ++
validateView(component) ++
validateValueEntity(component) ++
validateEventSourcedEntity(component) ++
validateWorkflow(component)

private def componentMustBePublic(component: Class[_]): Validation = {
if (component.isPublic) {
Valid
} else {
Invalid(
errorMessage(
component,
s"${component.getSimpleName} is not marked with `public` modifier. Components must be public."))
}
}

private def validateCompoundIdsOrder(component: Class[_]): Validation = {
val restService = RestServiceIntrospector.inspectService(component)
component.getMethods.toIndexedSeq
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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;

import kalix.javasdk.action.Action;
import kalix.javasdk.annotations.*;
import kalix.javasdk.eventsourcedentity.EventSourcedEntity;
import kalix.javasdk.valueentity.ValueEntity;
import kalix.javasdk.view.View;
import kalix.javasdk.workflow.Workflow;
import kalix.spring.testmodels.Message;
import kalix.spring.testmodels.valueentity.User;
import kalix.spring.testmodels.valueentity.UserEntity;
import kalix.spring.testmodels.workflow.StartWorkflow;
import kalix.spring.testmodels.workflow.WorkflowState;
import org.springframework.web.bind.annotation.*;

// below components are not public and thus need to be in the same package as the corresponding test
public class NotPublicComponents {
static class NotPublicAction extends Action {
@GetMapping("/message")
public Action.Effect<Message> message() {
return effects().ignore();
}
}

@Id("counter_id")
@TypeId("counter")
static class NotPublicEventSourced extends EventSourcedEntity<Integer, Object> {
@GetMapping("/eventsourced/{counter_id}")
public Integer test() {
return 0;
}
}

@Id("id")
@TypeId("user")
@RequestMapping("/user/{id}")
static class NotPublicValueEntity extends ValueEntity<User> {

@GetMapping
public ValueEntity.Effect<String> ok() {
return effects().reply("ok");
}
}

@Table(value = "users_view")
@Subscribe.ValueEntity(UserEntity.class)
static class NotPublicView extends View<User> {
@Query("SELECT * FROM users_view WHERE email = :email")
@GetMapping("/users/{email}")
public User getUser(@PathVariable String email) {
return null;
}
}

@TypeId("transfer-workflow")
@Id("transferId")
@RequestMapping("/transfer/{transferId}")
static class NotPublicWorkflow extends Workflow<WorkflowState> {
@Override
public WorkflowDef<WorkflowState> definition() {
return null;
}

@PutMapping
public Effect<String> startTransfer(@RequestBody StartWorkflow startWorkflow) {
return null;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,15 @@ import scala.jdk.CollectionConverters.CollectionHasAsScala

class ActionDescriptorFactorySpec extends AnyWordSpec with ComponentDescriptorSuite {

// missing public modifier
"Action descriptor factory" should {

"validate an Action must be declared as public" in {
intercept[InvalidComponentException] {
Validations.validate(classOf[NotPublicComponents.NotPublicAction]).failIfInvalid
}.getMessage should include("NotPublicAction is not marked with `public` modifier. Components must be public.")
}

"generate mappings for an Action with GET without path param" in {
assertDescriptor[GetWithoutParam] { desc =>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ import scala.jdk.CollectionConverters.CollectionHasAsScala
class EventSourcedEntityDescriptorFactorySpec extends AnyWordSpec with ComponentDescriptorSuite {

"EventSourced descriptor factory" should {

"validate an ESE must be declared as public" in {
intercept[InvalidComponentException] {
Validations.validate(classOf[NotPublicComponents.NotPublicEventSourced]).failIfInvalid
}.getMessage should include("NotPublicEventSourced is not marked with `public` modifier. Components must be public.")
}

"generate mappings for a Event Sourced with entity ids in path" in {
assertDescriptor[CounterEventSourcedEntity] { desc =>
val method = desc.commandHandlers("GetInteger")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ import scala.jdk.CollectionConverters.CollectionHasAsScala
class ValueEntityDescriptorFactorySpec extends AnyWordSpec with ComponentDescriptorSuite {

"ValueEntity descriptor factory" should {
"validate a ValueEntity must be declared as public" in {
intercept[InvalidComponentException] {
Validations.validate(classOf[NotPublicComponents.NotPublicValueEntity]).failIfInvalid
}.getMessage should include("NotPublicValueEntity is not marked with `public` modifier. Components must be public.")
}

"generate mappings for a Value Entity with entity ids in path" in {
assertDescriptor[PostWithIds] { desc =>
val method = desc.commandHandlers("CreateEntity")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ class ViewDescriptorFactorySpec extends AnyWordSpec with ComponentDescriptorSuit

"View descriptor factory" should {

"validate a View must be declared as public" in {
intercept[InvalidComponentException] {
Validations.validate(classOf[NotPublicComponents.NotPublicView]).failIfInvalid
}.getMessage should include("NotPublicView is not marked with `public` modifier. Components must be public.")
}

"generate ACL annotations at service level" in {
assertDescriptor[ViewWithServiceLevelAcl] { desc =>
val extension = desc.serviceDescriptor.getOptions.getExtension(kalix.Annotations.service)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ import scala.jdk.CollectionConverters.CollectionHasAsScala
class WorkflowEntityDescriptorFactorySpec extends AnyWordSpec with ComponentDescriptorSuite {

"Workflow descriptor factory" should {
"validate a Workflow must be declared as public" in {
intercept[InvalidComponentException] {
Validations.validate(classOf[NotPublicComponents.NotPublicWorkflow]).failIfInvalid
}.getMessage should include("NotPublicWorkflow is not marked with `public` modifier. Components must be public.")
}

"generate mappings for a Workflow with entity ids in path" in {
assertDescriptor[WorkflowWithTypeLevelKey] { desc =>
val method = desc.commandHandlers("StartTransfer")
Expand Down

0 comments on commit 87c2e89

Please sign in to comment.