Page tree
Skip to end of metadata
Go to start of metadata

MGNLPER-19 - Getting issue details... STATUS

Introduction 

Periscope currently has various SearchResultSuppliers however all of them are bound to JCR. One should be able to define a SearchResultSupplier which brings results outside of Magnolia e.g. our documentation can be searchable within Periscope.

The usual way of doing this is to fetch/search this information via REST, hence we should be able to create generic REST based SearchResultSupplier for Periscope.


Problem statement

Providing capabilities as such is not very straightforward due to the fact that JSON response from REST based service will not be in the same format and/or same keys.

For instance:

{
  "results": [
    {
      "title": "foo"
    },
    {
      "url": "fooURL"
    }
  ]
}
{
  "myFunkyResults": [
    {
      "myDifferentTitle": "foo",
      "myDifferentURL": "fooURL"
    }
  ]
}

Proposed Solution (Periscope specific)

In the scope of Periscope, we only need to display results to the user and in order to do that we need a title and an URL that we will navigate to when user selects that particular result.

That means user only need to specify a title and navigation url via some kind of configuration and we will simply try to fetch that information in the SearchResultSupplier.


JsonPath

https://github.com/json-path/JsonPath

http://goessner.net/articles/JsonPath/

With JsonPath, one can easily point to particular values in any JSON result. That being said configuration as such is sufficient to configure a RestSearchResultSupplier.


This is an example of JSON response we get when we query confluence, it's clear that we need to combine 'title's and 'webui's to generate results.

{  
   "results":[  
      {  
         "id":"156405429",
         "type":"page",
         "status":"current",
         "title":"Periscope",
         "restrictions":{  

         },
         "_links":{  
            "webui":"/display/DEV/Periscope",
            "tinyui":"/x/tY5SCQ",
            "self":"https://wiki.magnolia-cms.com/rest/api/content/156405429"
         },
         "_expandable":{  
            "container":"",
            "metadata":"",
            "extensions":"",
            "operations":"",
            "children":"",
            "history":"/rest/api/content/156405429/history",
            "ancestors":"",
            "body":"",
            "version":"",
            "descendants":"",
            "space":"/rest/api/space/DEV"
         }
      }
   ],
   "start":0,
   "limit":25,
   "size":1,
   "_links":{  
      "self":"https://wiki.magnolia-cms.com/rest/api/content/search?cql=(type=page%20AND%20(title~%22Periscope*%22%20OR%20text~%22Periscope*%22))",
      "base":"https://wiki.magnolia-cms.com",
      "context":""
   }
}

With that in mind, one has to define  titleJsonPath and navigationURLJsonPath according to the JSON result above.

// This one for the JSON snippet above
requestURL: "https://documentation.magnolia-cms.com/rest/api/content/search?cql=(type=page AND (title~\"%1$s*\" OR text~\"%1$s*\"))"
navigationBaseURL: "https://documentation.magnolia-cms.com"
titleJsonPath: $..title
navigationURLJsonPath: $..webui
class: info.magnolia.periscope.search.rest.RestSearchResultSupplierDefinition

// Working solution for wikipedia as an general example
requestURL: "https://en.wikipedia.org/w/api.php?format=json&action=query&titles=%s&redirects"
navigationBaseURL: "https://en.wikipedia.org/?curid=%s"
titleJsonPath: $..title
navigationURLJsonPath: $..pageid
class: info.magnolia.periscope.search.rest.RestSearchResultSupplierDefinition

This is how one defines where the specific values will be found, in this example we have '$..title' which translates into all title values which are two levels under the root and same as the '$..webui'.

One has to specific a 'baseURL' and an additional 'URL', those are needed to make the REST request from backend as well as appending the found 'navigationURL' from the JSON result.

Upon search request we append baseURL with URL and do the REST request and the response is parsed with JsonPath library and obtained 'title' and 'navigationURL' is utilised to generate results.

That being said, baseURL is appended with the parsed 'navigationURL' which is utilised to redirect the user when a particular response has been selected.


Getting results in the backend is very straightforward too:

ReadContext context = JsonPath.parse(resultJson);
List<String> read = context.read(definition.getTitleJsonPath());
List<String> read2 = context.read(definition.getNavigationURLJsonPath());



  • No labels