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"
}
Related
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
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.
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();
}
}
I recently started using the "removeUnauthorizedSnapshots" parameter with the LBAPI to avoid permissions errors I was previously experiencing. Using the LBAPI to gather details for all the work items in our workspace is MUCH faster than the WSAPI, however since we have ~25,000 leaf stories in our workspace, this data must be gathered using more than one API request. When adding the "limit : Infinity" parameter to the request, you can see in the network traffic that while the second request was in fact made, the "removeUnauthorizedSnapshots" parameter was not included, therefore resulting in a permissions error.
Is there any plan to add official support for this parameter to the LBAPI, rather than adding it to the request manually?
Thanks!
In the meantime, here is a solution which uses the "loadPage" function, in place of "load":
var allRecords = [];
function getWorkItems(pageNumber) {
Ext.create('Rally.data.lookback.SnapshotStore', {
fetch : ['Name','ObjectID','PlanEstimate'],
filters : [{
property : '__At',
value : 'current'
},{
property : '_TypeHierarchy',
value : 'HierarchicalRequirement'
},{
property : 'Children',
value : null
}]
}).loadPage(pageNumber, {
params : {
compress : true,
removeUnauthorizedSnapshots : true
},
callback : function(records, operation, success) {
allRecords = Ext.Array.merge(allRecords, records);
if (operation.response.StartIndex + operation.response.PageSize >= operation.response.TotalResultCount) {
//All records loaded
} else {
getWorkItems(++pageNumber);
}
}
});
}(1);
I submitted a bug. Thank you for bringing it to our attention. As I commented in the other post we added a story to a backlog to add "removeUnauthorized" to a Rally.data.lookback.SnapshotStore config, but the workaround suggested there in a meantime is apparently flawed and the extra parameters are not applied to subsequent requests, as your scenario with number of total results exceeding 20K shows.
I have the following JSON structure which i get from a RestService:
{
"customer": {
"id": "123456",
[more attributes ....]
"items": [
{
"id": "1234",
},
{
"id": "2345",
}
[more items...]
]
}
}
which i successfully map into Core Data using RestKit. From another RestService (which i can not change) i then get more details to one single item in the items array. the JSON answer looks like
{
"customer": {
"id: "123456",
"item": {
"id": "1234",
"name": "foo",
[other attributes...]
}
}
}
Now the question: How can i map the second answer, so that the single item is added to the items array (or updated if it is already in there)?
Thanks for any ideas!
If you already know how to map JSON to Core Data, all that's left is just fetch theobject you want to add your item attributes to(using id or something else) and then just set it,rewriting the old one,or adding new fields.That's just general approach
If you set the appropriate primaryKeyAttribute of the RKManagedObjectMapping object you should be able to perform the mapping as you want it to.
It would actually be easier to help you, if you would post some of your mapping code, but this is how I meant it to be
Create the mapping for your customer object, defining all possible attributes and declare the mappingObject.primaryKeyAttribute = #"id"
Execute the mapping with the first request (or first answer as you put it)
After the first mapping step is finished execute the second request
This should initially create the customer objects you want and then update them.