[MGNLREST-166] Querying for supertypes does not return subtypes Created: 17/Jan/18  Updated: 02/May/18  Resolved: 26/Apr/18

Status: Closed
Project: Magnolia REST Framework
Component/s: None
Affects Version/s: 2.0.2
Fix Version/s: 2.1.1

Type: Bug Priority: Major
Reporter: Hieu Nguyen Duc Assignee: Hieu Nguyen Duc
Resolution: Fixed Votes: 0
Labels: consolidation
Remaining Estimate: 0.25d
Time Spent: 3.75d
Original Estimate: 4d

Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Documentation update required:
Yes
Date of First Response:
Sprint: Saigon 141, Saigon 142, Saigon 143, Saigon 144
Story Points: 8

 Description   

Given this configuration

class: info.magnolia.rest.delivery.jcr.v2.JcrDeliveryEndpointDefinition
workspace: website
bypassWorkspaceAcls: true

Making this request returns an empty result which is wrong.

curl -X GET 'http://<host>/.rest/delivery/test'

The expectation is a list of pages because "mgnl:page" is subtype of "mgnl:content".

The currently generated query is

SELECT t.* FROM [nt:base] AS t WHERE t.[jcr:primaryType] = 'mgnl:content' ...

To solve this issue, we may consider selecting from configured node types and using JOINs.

SELECT t.* FROM [mgnl:content] INNER JOIN [otherNodeType] ...


 Comments   
Comment by Hieu Nguyen Duc [ 06/Apr/18 ]

3 options spring to my mind:

1) JOIN nodeTypes:

SELECT parent.*
FROM [mgnl:page] AS parent
INNER JOIN [mgnl:area] AS child ON ISCHILDNODE(child,parent)

Since multiple selectors are existing, we may need to implement RowIteratorWriter

Row#getNode(selectorName) to get a node

+ Problem: How can we join two nodeTypes that don't have any relationship?  

   ~ For example: We can even create "mgnl:category" in "website" workspace (using JCR app).

2) Get subTypes of the configured nodeTypes

Bring configured nodeTypes and their subTypes into the query

For example: Given "mgnl:contentNode" configured, the query should be

SELECT t.*
FROM [nt:base] AS t
WHERE t.[jcr:primaryType] = 'mgnl:contentNode'
    OR t.[jcr:primaryType] = 'mgnl:area'
    OR t.[jcr:primaryType] = 'mgnl:component'

because "mgnl:area" and "mgnl:component" are subTypes of "mgnl:contentNode"

+ Problem: There seems no way to check what workspace a nodeType belongs to. Magnolia currently doesn't have that constraint between workspace and nodeType. 

   ~ NodeTypeManager#getAllNodeTypes returns all nodeTypes of all workspaces

   ~ magnolia-nodetypes.xml shows no constraint of workspace and nodeType

=> Could we define this constraint somewhere? 

+ Branch of draft code: https://goo.gl/TqrGBb

3) Restriction!

Define a map of allowed nodeTypes by workspace (aka whitelist?)

For example:

Map<String, String[]> ALLOWED_NODE_TYPES
  website -> mgnl:page, mgnl:area, mgnl:component
  dam     -> mgnl:folder, mgnl:asset, ...

If any configured nodeType doesn't satisfy the above map, throw an exception "The configured nodeType 'xxx' is not allowed in workspace 'yyy'".  

4) Query and wrapper

a) Select from the nodeType that includes every nodeTypes

Given "mgnl:page", "mgnl:area" and "mgnl:component" configured, we have:

SELECT * 
FROM [nt:base]

Because "mgnl:page" is subType of "mgnl:content" while "mgnl:area" and "mgnl:component" are subTypes of "mgnl:contentNode", the possible nodeType "nt:base" that includes all of them will be brought into the query.

b) Use wrapper to filter out the other type rather than the 3 configured nodeTypes.

Problems: Bad performance when querying "nt:base" and trouble with pagination. 

 

Comment by Sang Ngo Huu [ 11/Apr/18 ]

1) JOIN nodeTypes:

When using JOIN, the limit does not work correctly. For eg.: you join 3 times for 3 node types, there are 3 selectors for query result. The offset/limit is 0-10, then you will get 10 rows for 3 selectors = 30 nodes.

I can divide limit for number of selectors, but it is not a good idea

2) Get subTypes of the configured nodeTypes

We cannot get subTypes of configured nodeTypes in a workspace. It returns all nodeTypes in repo instead.

Comment by Hieu Nguyen Duc [ 12/Apr/18 ]

PR created. "strict" mode introduced because of performance concerns.
https://git.magnolia-cms.com/projects/MODULES/repos/rest/pull-requests/78/overview

Comment by Hieu Nguyen Duc [ 26/Apr/18 ]

Updates for documentation:

+ "strict" parameter is introduced for determining whether to include only the exact node type and ignore sub types. This term is similar to NodeTypeDefnition#isStrict.
+ "strict" is applied for both nodeTypes and childNodeTypes and false by default.

For example, given this endpoint

class: info.magnolia.rest.delivery.jcr.v2.JcrDeliveryEndpointDefinition
workspace: website
depth: 2
bypassWorkspaceAcls: true
includeSystemProperties: false

+ Querying returned an empty result before (rest v2.1). 
+ Now we get pages, areas and components because mgnl:page is subType of mgnl:content which is default nodeType, and mgnl:area and mgnl:component are subTypes of mgnl:contentNode which is default childNodeType.

Generated at Mon Feb 12 06:57:16 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.