1

I am developing Spring Boot + Axon + CQRS example. In this example, while hitting to the

curl -H "Content-Type : application/json" -d '{"company" : "apple", "description" : "My Kep"}' http://localhost:8080

I have already started the below server(axonserver-4.0.jar), I don't see way to fixed the error. Please let me know if you need any other details?

-rw-r--r-- 1 user 1049089     6153 Oct 17 13:11 README.txt
-rw-r--r-- 1 user 1049089    16934 Oct 17 19:50 LICENSE.txt
drwxr-xr-x 1 user 1049089        0 Oct 22 22:26 kubernetes/
-rwxr-xr-x 1 user 1049089  3290320 Oct 22 22:26 axonserver-cli-4.0.jar*
-rwxr-xr-x 1 user 1049089 83303084 Oct 22 22:26 axonserver-4.0.jar*
drwxr-xr-x 1 user 1049089        0 Oct 22 22:26 ../
drwxr-xr-x 1 user 1049089        0 Oct 30 16:54 data/
-rw-r--r-- 1 user 1049089       13 Oct 30 16:54 AxonIQ.pid
drwxr-xr-x 1 user 1049089        0 Oct 30 16:54 ./

I get the below error:

org.axonframework.commandhandling.distributed.CommandDispatchException: The command [org.demo.DemoComplaintsApplication$FileComplaintCommand] does not contain a routing key.
    at org.axonframework.commandhandling.distributed.AbstractRoutingStrategy.getRoutingKey(AbstractRoutingStrategy.java:57) ~[axon-messaging-4.0.jar:4.0]
    at org.axonframework.axonserver.connector.command.AxonServerCommandBus.dispatch(AxonServerCommandBus.java:114) ~[axon-server-connector-4.0.jar:4.0]
    at org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:75) [axon-messaging-4.0.jar:4.0]
    at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:78) [axon-messaging-4.0.jar:4.0]
    at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:134) [axon-messaging-4.0.jar:4.0]
    at org.demo.DemoComplaintsApplication$ComplaintAPI.fileCompplaint(DemoComplaintsApplication.java:47) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_162]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_162]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_162]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.10.RELEASE.jar:5.0.10.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_162]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_162]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.34.jar:8.5.34]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0_162]

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.axonframework</groupId>
            <artifactId>axon-spring-boot-starter</artifactId>
            <version>4.0</version>
        </dependency>
        <dependency>
            <groupId>org.axonframework</groupId>
            <artifactId>axon-core</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

MainApp

@SpringBootApplication
public class DemoComplaintsApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoComplaintsApplication.class, args);
    }

    @RestController
    public static class ComplaintAPI {

        private final ComplaintQueryObjectRepository repostory;
        private final CommandGateway commandGateway;

        public ComplaintAPI(ComplaintQueryObjectRepository repostory, CommandGateway commandGateway) {
            this.repostory = repostory;
            this.commandGateway = commandGateway;
        }

        @PostMapping
        public CompletableFuture<String> fileCompplaint(@RequestBody Map<String, String> request) {
            String id = UUID.randomUUID().toString();
            return commandGateway
                    .send(new FileComplaintCommand(id, request.get("company"), request.get("description")));
        }

        @GetMapping
        public List<ComplaintQueryObject> findAll() {
            return repostory.findAll();
        }

        @GetMapping("/{id}")
        public ComplaintQueryObject find(@PathVariable String id) {
            //return repostory.findOne(id);
            return repostory.findById(id).get();
        }
    }

    @Aggregate
    public static class Complaint {
        @AggregateIdentifier
        private String complaintId;

        public Complaint() {
            super();
        }

        @CommandHandler
        public Complaint(FileComplaintCommand command) {
            apply(new ComplaintFileEvent(command.getId(), command.getCompany(), command.getDescription()));
        }

        @EventSourcingHandler
        public void on(ComplaintFileEvent event) {
            this.complaintId = event.getId();
        }
    }

    @Component
    public static class ComplaintQueryObjectUpdater {

        private final ComplaintQueryObjectRepository repository;

        public ComplaintQueryObjectUpdater(ComplaintQueryObjectRepository repository) {
            this.repository = repository;
        }

        @EventHandler
        public void on(ComplaintFileEvent event) {
            repository.save(new ComplaintQueryObject(event.getId(), event.getCompany(), event.getDescription()));
        }
    }

    public static class FileComplaintCommand {
        private String id;
        private String company;
        private String description;

        public FileComplaintCommand(String id, String company, String description) {
            super();
            this.id = id;
            this.company = company;
            this.description = description;
        }

        public String getId() {
            return id;
        }

        public String getCompany() {
            return company;
        }

        public String getDescription() {
            return description;
        }

    }

Curl commamnd

$ curl -H "Content-Type:application/json" -d '{"company" : "apple", "description" : "My Kep"}' localhost:8080 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 392 0 345 100 47 11129 1516 --:--:-- --:--:-- --:--:-- 12645{"timestamp":1540911397422,"status":500,"error":"Internal Server Error","exception":"java.util.concurrent.CompletionException","message":"AxonServerCommandDispatchException{message=The command [org.demo.DemoComplaintsApplication$FileComplaintCommand] does not contain a routing key., errorCode='AXONIQ-4003', server='10296@841DTN2'}","path":"/"}

1 Answer 1

6

The error The command [...] does not contain a routing key is caused by the absence of a field annotated @TargetAggregateIdentifier in your command. In an axon LocalCommandBus, this would only be necessary on commands targeting existing aggregates. In a distributed version, it's also necessary on a command creating an aggregate, since the Axon Server command bus looks at it to make routing decisions.

So add @TargetAggregateIdentifier to the id field in your FileComplaintCommand.

Sign up to request clarification or add additional context in comments.

1 Comment

@ Frans van Buul - Could you please guide here too stackoverflow.com/questions/53139869/… ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.