Error 400 for POST with JSON parameter since update to CAMUNDA

Hi all,

I’m kinda new to Camunda since I just started on a new project that’s using it.

We got a plugin with this architecture:

RootResource

@ Path(“plugin/” + PluginTestPlugin.ID)
public class PluginTestPluginRootResource extends AbstractCockpitPluginRootResource {
[…]

@ Path("{engineName}/actionOne")
public MyPluginInstanceResource getMyPlugin(@ PathParam("engineName") String engineName) {
           return  subResource(new MyPluginInstanceResource(engineName),engineName);
}

@ Path("{engineName}/actionTwo")
public MyPluginInstanceResource addMyPlugin(@ PathParam("engineName") String engineName
                           ,@ QueryParam("param1") String param1
                           ,@ QueryParam("param2") String param2
                           ,@ QueryParam("param3") String param3
                           ,@ QueryParam("param4") String param4) {
           [...]
           return  subResource(new MyPluginInstanceResource(engineName,randomObject),engineName);
}

@ Path("{engineName}/actionThree")
public MyPluginInstanceResource deleteMyPlugin(@ PathParam("engineName") String engineName
                           ,@ QueryParam("param1") String param1
                           ,@ QueryParam("param2") String param2
                           ,@ QueryParam("param3") String param3
                           ,@ QueryParam("param4") String param4) {
           [...]
           return  subResource(new MyPluginInstanceResource(engineName, randomObject),engineName);
}

@ Consumes(MediaType.APPLICATION_JSON)
@ Path("{engineName}/actionFour")
public MyPluginInstanceResource changeAction(
                           MyObject obj,
                           @ PathParam("engineName") String engineName) {
           return subResource(new MyPluginInstanceResource(
                                                           engineName,
                                                           obj.getParam1(),
                                                           obj.getParam2(), 
                                                           obj.getParam3()),
                                           engineName);
}

}

InstanceResource

public class MyPluginInstanceResource extends AbstractCockpitPluginResource {

            private String param1;
            
            private String param2;
            
            private String param3;

            public MyPluginInstanceResource(
                                           String engineName
                                           String param1,
                                           String param2,
                                           String param3) {

                           super(engineName);
            
                           this.param1=param1;
                           this.param2=param2;
                           this.param3 = param3;
            }


           @ POST
            public String changeAction() {
                           Command<String> command = new Command<String>() {

                                                           public String execute(CommandContext commandContext) {
                                                                           [...]
                                                           }
                                           };
                           return getCommandExecutor().executeCommand(command);
            }
           
            @ GET
            public List<AbsencesDto> getMyPlugin() {
                           Command<List<AbsencesDto>> command = new Command<>() {
                                           [...]
                           };
                           return getCommandExecutor().executeCommand(command);
            
            }

            @ PUT
            public String addMyPlugin() {
                           Command<String> command = new Command<>() {
                                           [...]
                           };
                           return getCommandExecutor().executeCommand(command);

            }
            
            @ DELETE
            public String deleteMyPlugin() {
                           Command<String> command = new Command<>() {
                                           [...]
                           };
                           return getCommandExecutor().executeCommand(command);

            }

}

We are currently using camunda 7.11 and it’s working fine, we’ve got multiple InstanceResource with the same architecture.
We had to update camunda to 7.13 on one of our environments (we followed the guide 7.11->7.12 and 7.12->7.13) and did the same for my local dev environment.
We ended up with the same issue on local and our server and they are both using the same database (it still might be an error during the update process though):

For every endpoint like “{engineName}/actionFour” that’s passing an object in json to the back, we now have an html error 400. All the end point using path param like actionOne/Two/Three are working just fine.

I tried multiple modifications, tried different mediatypes but as soon as I add a parameter, I’ve got an error 400.

If I put an annotation “@ POST” right before “@ Consumes(MediaType.APPLICATION_JSON)” for “changeAction“ in the RootResource, I can enter my end point and I’ve got my parameter mapped right. The problem is after the “subResource(“ I end up in my “getMyPlugin()” (the @ GET) on the InstanceResource instead of my “addMyPlugin()” (the @ PUT).

Does anyone know which modification between 7.11 and 7.13 can cause this error or if it might be some errors with the update of our environments?

EDIT: I added a space after each “@” because it was detected as i was trying to mention someone.

Thanks.

After a week, I come back to this post to give the solution we found.
We still don’t really understand why this happened to us after the upgrade but we found how to make it behave like before.

The first solution was to put the three parameters in the url but one of them is a list of a string that can be really long so it added a limitation.

The solution we found after that was:

@ Path("{engineName}/actionFour")
public MyPluginInstanceResource changeAction(
                           @ PathParam("engineName") String engineName) {
           return subResource(new MyPluginInstanceResource(
                                                           engineName),
                                           engineName);
}

Delete the parameter from the RootResource and delete the consumes

 @ POST
 public String changeAction() {
             Command<String> command = new Command<String>(MyObject obj) {
                         public String execute(CommandContext commandContext) {
                                     [...]
                         }
             };
             return getCommandExecutor().executeCommand(command);
 }

Add the parameter on the InstanceResource.