Replace node along with subnodes in a single request - aem

I have a widget that creates a POST request that creates a node and a dynamic number of subnodes, like:
./sling:resourceType:app/component
_charset_:utf-8
:status:browser
./data:data
./a/a:one
./a/b:two
./b/a:one
./b/b:two
This works nice the first time. I get a node along with subnodes a and b.
The problem is in subsequent requests. I need all subnodes to be removed before creating the new ones. So if previously I created subnodes a,b,c and d, the previous request would result just in subnodes a and b to remain.
I know the suffix #Delete,but I would need to know in advance which subnodes need to be deleted, which I don't.
Can this be achieved OOTB with the Sling Post Servlet?
Greetings.

In case you are using CQ 5.6 or 5.6.1 you can use ':applyTo' request parameter to delete multiple items using a single request by passing a trailing star in its value.
For example, to delete all the children of '/content/foo', make a POST request with ':operation' = 'delete', and ':applyTo' = '/content/foo/*'.
$ curl -F":operation=delete" -F":applyTo=/content/foo/*" http://host/content/sample
This was introduced in Sling 2.1.2 and hence is not available in CQ 5.5 and below, as 5.5 runs on 2.1.1.
For 5.5, i suspect you might need to get the list of children and then pass the absolute URL's to the :applyTo as the value to delete them, before adding the new nodes.

The solution I'm using is use the #Delete suffix.
The problem with it is that you need to add one parameter with the #Delete suffix for every node you want to delete. What I'm doing is query the node in advance to check for all the subnodes of the node I'm updating and adding a #Delete parameter for every one of them.
So, If the JCR originally has
-node
\node1
\node2
\node3
I will first get http://example.com/content/node.json and traverse the json. Finally I will send a request with
./sling:resourceType:app/component
./value:value
./node1#Delete
./node2#Delete
./node3#Delete
./node1/value:value1
./node2/value:value2
that will update node1 and node2 while deleting node3 at the same time.

Related

I need Locust to group calls to the same endpoint with different inline parameters together in html reports [duplicate]

I have a task that has two posts requests. The first post request creates the parent and the second uses the key from the parent to create a child of that parent. However in the output, while all the parent post endpoints are rolled up, the child ones are not because they include the parent ID in the endpoint URL.
How can I have the output roll up by endpoint where it uses a placeholder for the id.
Parent Endpoint
/v1/foo/bar
Child Endpoint
/v1/foo/bar/{id}/upload
Actual
With the above examples, I get one line in the output for the parent and it shows the number of requests, failures, etc., and I get one line for each child request. So if the parent has 50 requests on it I will have 50 separate lines one for each child request. Something like this is what currently is in the output.
Type
Name
# Requests
# Fails
...
POST
/v1/foo/bar
3
0
POST
/v1/foo/bar/1/upload
1
0
POST
/v1/foo/bar/2/upload
1
0
POST
/v1/foo/bar/3/upload
1
0
Would Like
I don't want the web or CLI output to show for each unique ID, just to be rolled up under one like shown with a placeholder. Something similar to this, but anything that shows the two lines with the counts matching is fine.
Type
Name
# Requests
# Fails
...
POST
/v1/foo/bar
3
0
POST
/v1/foo/bar/{id}/upload
3
0
When you make the request, you can pass in name='/v1/foo/bar/{id}/upload' and that's what Locust will report it as. From the docs:
Each of the methods for making requests also takes two additional optional arguments which are Locust specific and doesn’t exist in python-requests. These are:
Parameters:
name – (optional) An argument that can be specified to use as label in Locust’s statistics instead of the URL path. This can be used to group different URL’s that are requested into a single entry in Locust’s statistics.

DELETE different resources with one requests - Is it ok or we should try to mix those resources to one

Let assume that I have a collection with /playrequests endpoint. It is a collection (list) for those players who want to find another player to start a match.
The server will check this collection periodically and if it finds two unassigned players, it will create another resource in another collection with /quickmatchs endpoint and also change (for example) a field in the PlayRequests collection for both players to shows that they are assigned to a quickMatch.
At this point, players can send a PUT or PATCH request to set the (for example) "ready" field of their related quickMach resource to true. so the server and each of them can find out that if both of them is ready and the match can be started.
(The Issue Part Is Below Part...)
Also, before a the playRequests assigned to a match and also after they assigned to it, they can send a DELETE request to /playrequests endpoint to tell the server that they want to give up the request. So if the match doesn't create yet, It is ok. the resource related to the player will remove from playRequests collection. but if player assigned to a match, the server must delete the related playRequest and also it must delete the related quickMatch resource from the quickMatchs collection. ( and also we should modify the playRequest related to another player to indicate that it's unassigned now. or we can check and change it later when he to check the status of his related resources in both collection. It is not the main issue for now. )
So, my question is that is it ok to change a resource that is related to the given end point and also change another resource accordingly, If it is necessary? ( I mean is it ok to manipulate different resources with different endpoints in one request? I don't want to send multiple requests.) or I need to mix those two collections to avoid such an action?
I know that many things ( different strategies ) are possible but I want to know that (from the viewpoint of RESTFUL) what is standard/appropriate and what is not? (consider that I am kinda new to restful)
it ok to change a resource that is related to the given end point and also change another resource accordingly
Yes, and there are consequences.
Suppose we have two resources, /fizz and /buzz, and the representations of those resources are related via some implementation details on the server. On the client, we have accessed both of these resources, so we have cached copies of each of them.
The potential issue here is that the server changes the representations of these resources together, but as far as the client is concerned, they are separate.
For instance, if the client sends an unsafe request to change /fizz, a successful response message from the server will invalidate the locally cached copy of that representation, but the stale representation of /buzz does not get evicted. In effect, the client now has a view of the world with version 0 /buzz and version 1 /fizz.
Is that OK? "It depends" -- will expensive things happen to you if your clients are in a state of unmatched representations? Can you patch over the "problem" in other ways (for instance, by telling the client to check resources for updates more often)?

kubernetes strategic merge patch

Hi I am following this doc https://github.com/kubernetes/kubernetes/blob/master/docs/devel/api-conventions.md#strategic-merge-patch for strategic-merge-patch to partially update the JSON objects using PATCH REST API. The document says that it can add or delete the object, but I have tried, whenever I add new object to existing JSON it just replaces that instead of adding new. I am trying this to modify pod definition in OpenShift 3.2. can anyone please help me how it works, probably with example. I need to use delete operation also , where I can delete the value by name.
As documented it depends on annotations of the types. AFAIS the strategic merge only works if patchStrategy and patchMergeKey are given. For example, this is the case in pod.spec.containers and pod.spec.volumes.
For an example you need to provide more information about the type you want to merge.

cq5 not returning child pages json data on '...infinity.json' request

Even though following path http://localhost:4502/content/geometrixx/en/products.infinity.json returning folllowing json.
But same page request in my upper environments (DEV, Stage, QA boxes) returning following json
Can anyone shed some light on this ? I am trying to read child pages data for one of the component and it is working great in local but not in upper environment boxes.
Thank you!
Given that these are stage / production instances, it's possible that additional security measures were taken. If you look at the security checklist, you will see it recommends limiting number of nodes exposed by the Sling Get Servlet [0]:
https://docs.adobe.com/docs/en/aem/6-1/administer/security/security-checklist.html
So if the json.maximumresults property of the Apache Sling Get Servlet was set to 5, the page.infinity.json request won't return all the nodes in the tree.
If you have access to the instance's configuration manager (/system/console/configMgr), you can check the value of the json.maximumresults property for this servlet.
[0] https://github.com/apache/sling-org-apache-sling-servlets-get/blob/dd8af0d1d4c9666ffb16d5324a47e41ba413d973/src/main/java/org/apache/sling/servlets/get/impl/DefaultGetServlet.java#L126
The second response looks like you are hitting the jcr:content sub node directly
/content/geometrixx/en/products/jcr:content.infinity.json
The reason I say this, is that the response in your second request is the same as the graph beneath your jcr:content node in the first response.
If the request is the same, you might want to look at your resource mappings to see if something is modifying your request.

Sling Post Request creating child nodes

Since you can post with sling via form with content application/x-www-urlformencoded. This seems to able to create only one node. If my encoded form has child nodes, how should the encoding look?
&./firstnode=value&./secondNode=value
If I want the secondNode to be the child of the first node, what should I do?
think of all the parameter names as subpaths of the node you're posting to. by default, a single slash would denote a property:
./property=value
to specify a node, you need to set a value under the target node:
./subnode/property=value
i think nt:unstructured is used by default in these cases, but you can explicitly set the nodetype by
./subnode/jcr:primaryType=TYPE&./subnode/property=val&...
ALL nodes that have to be created must be treated independently (counting parent nodes), even if the node is only a parent and doesn't have properties of its own. I am not confident that you can build an entire tree with a single post, because you usually need to save the parent before adding children.
The Sling website has a section on multipart/form-data POSTs for more details.