Add custom service within camunda rest api

Hi, im trying to add my custom functionality for task assignment withing the camunda rest API,
i’m trying to follwot this:
https://docs.camunda.org/manual/7.13/reference/rest/overview/embeddability/
and this:

however, my endpoints are still not reachable.
To simplify things, i want just to add endpoint /task-config/ping to the engine path and call it via localhost:8080/engine-rest/task-config/ping

i have declared the following classes:

@Produces(MediaType.APPLICATION_JSON)
public interface TaskAssignmentConfigRestService {

    public static final String PATH = "/task-config";

    @GET
    @Path("/ping")
    @Produces(MediaType.APPLICATION_JSON)
    String ping();

}

impl:

public class TaskAssignmentConfigServiceImpl extends AbstractRestProcessEngineAware implements TaskAssignmentConfigRestService {

    @Override
    public String ping() {
        return "pong";
    }

}

CustomProcessEngineRestServiceImpl:

@Path("")
public class CustomProcessEngineRestServiceImpl extends AbstractProcessEngineRestServiceImpl {

    public static final String PATH = "";

    @Path(ProcessDefinitionRestService.PATH)
    public ProcessDefinitionRestService getProcessDefinitionService() {
        return super.getProcessDefinitionService(null);
    }

    @Path(TaskAssignmentConfigRestService.PATH)
    public TaskAssignmentConfigRestService getTaskAssignmentConfigService() {
        String rootResourcePath = getRelativeEngineUri(null).toASCIIString();
        TaskAssignmentConfigServiceImpl subResource = new TaskAssignmentConfigServiceImpl(getObjectMapper());
        subResource.setRelativeRootResourceUri(rootResourcePath);
        return subResource;
    }

    @Path(ProcessInstanceRestService.PATH)
    public ProcessInstanceRestService getProcessInstanceService() {
        return super.getProcessInstanceService(null);
    }
}

And registered everything in JerseyConfig

@Configuration
public class CamundaJerseyConfig extends CamundaJerseyResourceConfig {
    private static final Logger log = org.slf4j.LoggerFactory.getLogger(CamundaJerseyConfig.class);

    @Override
    public void afterPropertiesSet() throws Exception {
        registerCamundaRestResources();
        registerAdditionalResources();
    }

    @Override
    protected void registerCamundaRestResources() {
        log.info("Configuring camunda rest api.");
        CamundaRestResources.getResourceClasses().add(TaskAssignmentConfigServiceImpl.class);
        this.registerClasses(CamundaRestResources.getResourceClasses());
        this.registerClasses(CamundaRestResources.getConfigurationClasses());
        this.register(JacksonFeature.class);
        this.registerClasses(TaskAssignmentConfigServiceImpl.class);

        log.info("Finished configuring camunda rest api.");
    }

    @Override
    protected void registerAdditionalResources() {
        register(TaskAssignmentConfigServiceImpl.class);
        CamundaRestResources.getResourceClasses().add(TaskAssignmentConfigServiceImpl.class);
    }

}

also i have added bean definition for jersay config:

@AutoConfigureBefore({ JerseyAutoConfiguration.class })
@AutoConfigureAfter({ CamundaBpmAutoConfiguration.class })
public class CamundaRestJerseyAutoConfiguration extends CamundaBpmRestJerseyAutoConfiguration {

    @Override
    @Bean
    @ConditionalOnMissingBean(CamundaJerseyConfig.class)
    public CamundaJerseyConfig createRestConfig() {
        return new CamundaJerseyConfig();
    }

}

Probably i’m missing something simple, however i can not find what it is, could you help me out?

nevermind, figured it out, i mixed up two approaches.
To add custom api, do this:

  1. define interface:

     @Produces(MediaType.APPLICATION_JSON)
     public interface TaskAssignmentConfigRestService {
    
     public static final String PATH = "/task-config";
    
     @GET
     @Path("/ping")
     @Produces(MediaType.APPLICATION_JSON)
     String ping();
    
    }
    
  2. Implement it:

    public class TaskAssignmentConfigServiceImpl extends AbstractRestProcessEngineAware implements TaskAssignmentConfigRestService {
    
     public TaskAssignmentConfigServiceImpl(String name, ObjectMapper objectMapper) {
         super(name, objectMapper);
     }
    
     @Override
     public String ping() {
         return "pong";
     }
    }
    
  3. Create it:

    @Path(DefaultProcessEngineRestServiceImpl.PATH)
    public class TaskAssignmentConfigDefaultProcessEngineRestServiceImpl extends DefaultProcessEngineRestServiceImpl {
    
    
     @Path(TaskAssignmentConfigRestService.PATH)
     public TaskAssignmentConfigRestService getTaskAssignmentConfigService() {
         String rootResourcePath = getRelativeEngineUri(null).toASCIIString();
         TaskAssignmentConfigServiceImpl subResource = new TaskAssignmentConfigServiceImpl(null, getObjectMapper());
         subResource.setRelativeRootResourceUri(rootResourcePath);
         return subResource;
     }
    }
    
  4. register it:

     @Component
     public class CustomJerseyResourceConfiguration extends CamundaJerseyResourceConfig {
     private static final Logger log = org.slf4j.LoggerFactory.getLogger(CustomJerseyResourceConfiguration.class);
    
     @Override
     protected void registerCamundaRestResources() {
         log.info("Configuring camunda rest api.");
         this.registerClasses(TaskAssignmentConfigDefaultProcessEngineRestServiceImpl.class);
         this.registerClasses(CamundaRestResources.getConfigurationClasses());
         this.register(JacksonFeature.class);
         log.info("Finished configuring camunda rest api.");
     }
    }
    
  5. Easy profit! XD

4 Likes

Thanks for posting your solution!

Can you please share the complete URL to invoke this service?