Camunda Rest API Assign Task Group - bpmn

We are using Camunda in our application for approval flow. As per the below documentation from Camunda we can create the task and assign it to user.
I wanted to know if we can assign the task to a group instead of individual user
Request parameters - I tried with "candidateGroups" : {"value"} but no luck.
{
"id": "aTaskId",
"name": "My Task",
"description": "This have to be done very urgent",
"priority" : 30,
"assignee" : "peter",
"owner" : "mary",
"delegationState" : "PENDING",
"due" : "2014-08-30T10:00:00",
"followUp" : "2014-08-25T10:00:00",
"parentTaskId" : "aParentTaskId",
"caseInstanceId" : "aCaseInstanceId"
}

You can't assign a task to a group. But you can define candidate groups into your BPMN process. This can also be a service/query.
The candidateGroups attribute: this custom extension allows you to
make a group a candidate for a task.
<userTask id="theTask" name="my task" camunda:candidateGroups="management, accountancy" />
This is exactly
the same as using a potentialOwner construct as defined above. Note
that it is not required to use the group(management) declaration as is
the case with the potential owner construct, since this attribute can
only be used for groups.
https://docs.camunda.org/manual/7.6/reference/bpmn20/tasks/user-task/#candidate-groups

Related

Karate- how to check the particular word contains in json array. and how to write the contains inside json

iam getting below response from api.
{
"error": {
"serverTime": 1564066755618,
"id": "VALIDATION_EXCEPTION",
"category": "system",
"message": "errors: [property: username; value: ; constraint: EMAIL_INLINE_ERROR_MESSAGE_1; property: username; value: ; constraint: EMAIL_INLINE_ERROR_MESSAGE_1; property: username; value: ; constraint: EMAIL_INLINE_ERROR_MESSAGE_1"
}
}
and iam checking the assertion using below way.
{"error":
{"serverTime":"#notnull",
"id":"VALIDATION_EXCEPTION",
"category":"system",
"message":"#notnull"
}
}
now I want to write a assertion for the above respose, like I want to check for field message contains the words "EMAIL_INLINE_ERROR_MESSAGE_1" and how many time it came.
Use Java interop. Then you can figure out the solution on your own. Normally no one needs this kind of validation, so it is not built in.
Please read the documentation: https://github.com/intuit/karate#calling-java

PredictionIO Universal Recommender

I am quite new to predictionIO/universal recommender and wondering is there any way to model events between multiple entities like I want one event courseTaken between user and courses. O there I want is workingIn which will be between user and project. So far I haven't seen that this thing is possible in predictionIO. Can anyone please guide me in this regard?
Coming from docs:
When sending usage events it is required that the entityType is "user" and targetEntityType is "item". The type of the item is inferred from the event names, which must be one of the eventNames in the engine.json
Note that a usage event always is a user and has a user id. Also the "targetEntityType" is always "item". The actual target entity is implied by the event name. So to create a "category-preference" event you would send something like this:
{
"event" : "category-preference",
"entityType" : "user",
"entityId" : "1243617",
"targetEntityType" : "item",
"targetEntityId" : "electronics",
"properties" : {},
"eventTime" : "2015-10-05T21:02:49.228Z"
}
To attach properties to items use a $set event like this:
{
"event" : "$set",
"entityType" : "item",
"entityId" : "ipad",
"properties" : {
"category": ["electronics", "mobile-phones"],
"expireDate": "2016-10-05T21:02:49.228Z",
"availableDate": "2015-10-05T21:02:49.228Z"
},
"eventTime" : "2015-10-05T21:02:49.228Z"
}
Based on above, secondary events are just like items, we need to do the following:
1. Add secondary events in configs, say ownProject
2. Add event with item id pointing to say the project, social, relation e.g.:
{
"event" : "own-Project",
"entityType" : "user",
"entityId" : "1243617",
"targetEntityType" : "item",
"targetEntityId" : "project-id",
"properties" : {},
"eventTime" : "2015-10-05T21:02:49.228Z"
}

Combining results of multiple API calls

I am invoking an API operation to fetch a list of objects and then, for each object in that list, I am invoking another API operation to fetch additional details of that object and adding those details into the object. The goal is to return a list of objects with all the properties (or details) that I need. In the example below, the /allObjects call will get a list of all objects with 2 properties - id and k1. But my application needs 3 properties, id, k1 and k4. So I invoke another API method to get detailed information for each object, which includes the k4 property. I copy that detailed property into the original result-set's object and return the "enriched" result-set. But the latency cost of this can be high. What is the best way of achieving this without slowing down the application too much? In the real world, I am dealing with 500-2000 objects.
GET /allObjects yields JSON results =>
{
"data" : [
{
"id" : "123",
"k1" : "v1"
}, {
"id" : "456",
"k1" : "v1"
}
]
}
for (obj in results.data) {
GET /object/{obj.id} yields JSON result =>
{
"data" : {
"id" : "123",
"k1" : "v1",
"k2" : "v2",
"k3" : "v3",
"k4" : "v4"
}
}
// Add k4 property to original result-set object, and assign
// it the value of the k4 property in the individual result object.
obj.k4 = result.data.k4;
}
return results.data;
Your requirement is such that, you have no other option but to go for a mash-up(unless you can convince the API developers to combine the two API).
You could, however, opt to make a mashup service with a low latency cost to stand in between your application to abstract out the mashup logic, conversely, you could opt to use a language that is custom made for this kind of work to program your application. Both of these options can be accommodated with Ballerina, I've written a post here showing how easy it is to do that using it.

Design pattern - update join table through REST API

I'm struggling with a REST API design concept. I have these classes:
user:
- first_name
- last_name
metadata_fields:
- field_name
user_metadata:
- user_id
- field_id
- value
- unique index on [user_id, field_id]
Ok, so users have many metadata and the type of metadata is defined in metadata_fields. Typical HABTM with extra data in the join table.
If I were to update user_metadata through a Rails form, the data would look like this:
user_metadata: {
id: 1,
user_id: 2,
field_id: 3,
value: 'foo'
}
If I posted to the user#update controller, the data would look like this:
user: {
user_metadata: {
id: 1,
field_id: 3,
value: 'foo'
}
}
The trouble with this approach is that we're ignoring the uniqueness of the user_id/field_id relationship. If I change the field_id in either update, I'm not just changing data, I'm changing the meaning of that data. This tends to work fine in Rails because it's somewhat of a walled garden, but it breaks down when you open up an API endpoint.
If I allow this:
PATCH /api/user_metadata
Then I'm opening myself up to someone modifying the user_id or field_id or both. Similarly with this:
PATCH /api/user/:user_id/metadata
Now user_id is set but field_id can still change. So really the only way to solve this is to limit the update to a single field:
PATCH /api/user/:user_id/metadata/:field_id
Or a bulk update:
PATCH /api/user/:user_id/metadata
But with that call, we have to modify the data structure so that the uniqueness of the user_id/field_id relationship is intact:
user_metadata: {
field_id1: 'value1',
field_id2: 'value2',
...
}
I'd love to hear thoughts here. I've scoured Google and found absolutely nothing. Any recommendations?
As metadata belongs to a certain user /api/user/{userId}/metadata/{metadataId} is probably the clean URI for a single metadata resource of a user. The URI of your resource is already the unique-key you are looking for. There can't be 2 resources with the same URI! Furthermore, the URI already contains the user and field IDs.
A request like GET /api/user/1 HTTP/1.1 could return a HAL-like representation like the one below:
{
"user" : {
"id": "1",
"firstName": "Max",
"lastName": "Sample",
...
"_links": {
"self" : {
"href": "/api/user/1"
}
},
"_embedded": {
"metadata" : {
"fields" : [{
"id": "1",
"type": "string",
"value": "foo",
"_links": {
"self": {
"href": "/api/user/1/metadata/1"
}
}
}, {
"id": "2",
"type": "string",
"value": "bar",
"_links": {
"self": {
"href": "/api/user/1/metadata/2"
}
}
}],
"_links": {
"self": {
"href": "/api/user/1/metadata"
}
}
}
}
}
}
Of course you could send a PUT or a PATCH request to modify an existing metadata field. Though, the URI of the resource will still be the same (unless you move or delete a resource within a PATCH request).
You also have the possibility to ignore certain fields on incomming PUT requests which prevents modification of certain fields like id or _link. I'll assume this should also be valid for PATCH requests, though will have to re-read the spec again therefore.
Therefore, I'd suggest to ignore any id or _link fields contained in requests and update the remaining fields. But you also have the option to return a 403 Forbidden or 409 Conflict response if someone tries to update an ID-field.
UPDATE
If you want to update multiple fields within a single request, you have two options:
Using PUT and replace the current set of fields with the new version
Using PATCH and send the server the necessary steps to transform the current field-set to the new field-set
Example PUT:
PUT /api/user/1/metadata HTTP/1.1
{
"metadata": {
"fields": [{
"type": "string",
"value": "newFoo"
}, {
"type": "string",
"value": "newBar"
}]
}
}
This request would first delete every stored metadata field of the user the metadata belong to and afterwards create a new resoure for each contained field in the request. While this still guarantees unique URIs, there are a couple of drawbacks to this approach however:
all the data which should be available after the update, even fields that do not change, need to be transmitted
clients which have a URI pointing to a certain resource may point to a false representation. F.e. a client has retrieved /user/1/metadata/2right before a further client updated all the metadata, the IDs are dispatched via auto-increment, the update however introduced a new second item and therefore moved the former 2 to position 3, client1 has now a reference to /user/1/metadata/2 while the actual data is /user/1/metadata/3 however. To prevent this, unique UUIDs could be used instead of autoincrement IDs. If client 1 later on tries to retrieve or update former resource 2, his can be notified that the resource is not available anymore, even a redirect to the new location could be created.
Example PATCH:
A PATCH request contains the necessary steps to transform the state of a resource to the new state. The request itself can affect multiple resources at the same time and even create or delete other resources as needed.
The following example is in json-patch+json format:
PATCH /api/user/1/metadata HTTP/1.1
[
{
"op": "add",
"path": "/0/value",
"value": "newFoo"
},
{
"op": "add",
"path": "/2",
"value": { "type": "string", "value": "totally new entry" }
},
{
"op": "remove",
"path": "/1"
},
]
The path is defined as a JSON Pointer for the invoked resource.
The add operation of the JSON-Patch type is defined as:
If the target location specifies an array index, a new value is inserted into the array at the specified index.
If the target location specifies an object member that does not already exist, a new member is added to the object.
If the target location specifies an object member that does exist, that member's value is replaced.
For the removal case however, the spec states:
If removing an element from an array, any elements above the specified index are shifted one position to the left.
Therefore the newly added entry would end up in position 2 in the array. If not an auto-increment value is used for the ID, this should not be a big problem though.
Besindes add, and remove the spec also contains definitions for replace, move, copy and test.
The PATCH should be transactional - either all operations succeed or none. The spec states:
If a normative requirement is violated by a JSON Patch document, or if an operation is not successful, evaluation of the JSON Patch document SHOULD terminate and application of the entire patch document SHALL NOT be deemed successful.
I'll interpret this lines as, if it tries to update a field which it is not supposed to update, you should return an error for the whole PATCH request and therefore do not alter any resources.
Drawback to the PATCH approach is clearly the transactional requirement as well as the JSON Pointer notation, which might not be that popular (at least I haven't used it often and had to look it up again). Same as with PUT, PATCH allows to add new resources inbetween existing resources and shifting further ones to the right which may lead to an issue if you rely on autoincrement values.
Therefore, I strongly recommend to use randomly generated UUIDs as identifier rather than auto-increment values.

Remove HATEOS from spring data rest? [duplicate]

Using Spring Data REST with JPA in version 2.0.2.RELEASE.
How can I disable Hypertext Application Language (HAL) in the JSON ? http://stateless.co/hal_specification.html
I have tried many things already, but to no avail. For example, I have set Accept and Content-type headers to "application/json" instead of "application/hal+json" but I still receive the JSON content with hyper links.
For example, I'd like to get something like:
{
"name" : "Foo",
"street" : "street Bar",
"streetNumber" : 2,
"streetLetter" : "b",
"postCode" : "D-1253",
"town" : "Munchen",
"country" : "Germany",
"phone" : "+34 4410122000",
"vat" : "000000001",
"employees" : 225,
"sector" : {
"description" : "Marketing",
"average profit": 545656665,
"average employees": 75,
"average profit per employee": 4556
}
}
Instead of:
{
"name" : "Foo",
"street" : "street Bar",
"streetNumber" : 2,
"streetLetter" : "b",
"postCode" : "D-1253",
"town" : "Munchen",
"country" : "Germany",
"phone" : "+34 4410122000",
"vat" : "000000001",
"employees" : 225,
"_links" : {
"self" : {
"href" : "http://localhost:8080/app/companies/1"
},
"sector" : {
"href" : "http://localhost:8080/app/companies/1/sector"
}
}
}
Thanks for your help.
(Hyper)media types
The default settings for Spring Data REST use HAL as the default hypermedia representation format, so the server will return the following for the given Accept headers:
No header -> application/hal+json -> HAL
application/hal+json -> application/hal+json -> HAL
application/json -> application/json -> HAL (this is what the default configures)
application/x-spring-data-verbose+json -> application/x-spring-data-verbose+json -> a Spring Data specific format (using links for the links container and content as wrapper for the collection items.
If you configure RepositoryRestConfiguration.setDefaultMediaType(…) to a non-HAL format, the server will return the Spring Data specific JSON format unless you explicitly ask for application/hal+json. Admittedly the configuration option is probably a bit misleading, so I filed DATAREST-294 to improve this. The issue was resolved in 2.1 RC1 (Dijkstra) 2014.
Note that we effectively need a hypermedia format in place to be able to express relations between managed resources and enable discoverability of the server. So there's no way you'll be able to get rid of it completely. This is mostly due to the fact that you could easily crash the server if you expose entities that have bidirectional relationships or make up an enormous object graph.
Inlining related entities
If you never want to have sectors linked to and always inline them, one option is to simply exclude the SectorRepository from being exported as a REST resource in the first place. You can achieve this by annotating the repository interface with #RepositoryRestResource(exported = false).
To get a representation returned as you posted in your lower example have a look at the projections feature introduced in Spring Data REST 2.1 M1. It basically allow you to craft optional views on a resource that can differ from the default one via a simple interface.
You'd basically define an interface:
#Projection(name = "foo", types = YourDomainClass.class)
interface Inlined {
// list all other properties
Sector getSector();
}
If you either put this interface into a (sub)package of your domain class or manually register it via RepositoryRestConfiguration.projectionConfiguration() the resources exposing YourDomainClass will accept a request parameter projection so that passing in foo in this example would render the inlined representation as you want it.
This commit has more info on the feature in general, this commit has an example projection defined.
So you want 2 things:
1) get rid of _links field
2) include the related sector field
Possible solution (works for me :D)
1) get rid of _links
For this create the class below:
[... package declaration, imports ...]
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
public MyRepositoryRestMvcConfiguration(ApplicationContext context, ObjectFactory<ConversionService> conversionService) {
super(context, conversionService);
}
#Bean
protected LinkCollector linkCollector() {
return new LinkCollector(persistentEntities(), selfLinkProvider(), associationLinks()) {
public Links getLinksFor(Object object, List<Link> existingLinks) {
return new Links();
}
};
}
}
and use it e.g.:
[... package declaration, imports ...]
#SpringBootApplication
#Import({MyRepositoryRestMvcConfiguration.class})
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
I'm pretty sure (99%, but not tested) that you won't need this class for removing the _links for the related entity/entities included the way next point (2) is showing.
2) include the related sector field
For this you could use Excerpts (especially made for this scenario). Because the Spring example is so eloquent and it's silly to just copy it here I'll just point it: https://docs.spring.io/spring-data/rest/docs/3.1.x/reference/html/#projections-excerpts.excerpting-commonly-accessed-data.
But just for the record and your convenience I'll paste the main parts of the spring example:
#Projection(name = "inlineAddress", types = { Person.class })
interface InlineAddress {
String getFirstName();
String getLastName();
Address getAddress();
}
see at Projection javadoc that types means The type the projection type is bound to.
The excerpt could be used this way:
#RepositoryRestResource(excerptProjection = InlineAddress.class)
interface PersonRepository extends CrudRepository<Person, Long> {}
in order to get this (when also using MyRepositoryRestMvcConfiguration):
{
"firstName" : "Frodo",
"lastName" : "Baggins",
"address" : {
"street": "Bag End",
"state": "The Shire",
"country": "Middle Earth"
}
}
For you the sector is the equivalent of address.
Final notes
When returning arrays the _links field won't be removed (it's too intrusive to do it); in the end you'll have something like this:
{
"_embedded" : {
"persons" : [ {person1}, {person2}, ..., {personN} ]
},
"_links" : {
e.g. first, next, last, self, profile
},
"page" : {
"size" : 1,
"totalElements" : 10,
"totalPages" : 10,
"number" : 0
}
}
As you can see even if we'd have _links removed that still won't be enough; one would probably also want _embedded replaced by persons which would lead to less maintainable code (too much spring intrusive overrides). But if one really wants these too he should start checking RepositoryRestMvcConfiguration and RepositoryEntityController.getCollectionResource.
Spring is evolving so I feel the need to point that this works with at least:
spring-data-rest-webmvc 3.1.3.RELEASE
or, if you prefeer spring boot version:
spring-boot-starter-parent 2.1.1.RELEASE
If you want to delete _links do the following (worked for me):
Go to your pom.xml and delete the following dependency:
spring-boot-starter-data-rest
Make an "Update project" to update the pom.xml changes.
Now it will be use your own controller for the api rest, deleting _self, _links..., that alike this:
[... package declaration, imports ...]
#RestController
#RequestMapping("/series")
public class SerieController {
#Autowired
private SerieRepositorio serieRepositorio;
public SerieController(SerieRepositorio serieRepositorio) {
this.serieRepositorio = serieRepositorio;
}
#GetMapping
public Iterable<Serie> getAllSeries() {
return serieRepositorio.findAll();
}
}