Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

N hidden gems in hippo forge and experience plugins (dec17)

134 views

Published on

Introducing Hidden Hippo Forge and Experience Plugin Gems, presented in BloomReach Connect 2017 in Amsterdam

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

N hidden gems in hippo forge and experience plugins (dec17)

  1. 1. N Hidden Gems in Hippo Forge and Experience Plugins Woonsan Ko December 6, 2017
  2. 2. Sequel to N Hidden Gems You Didn’t Know… (2016) ● slideshare.net/woonsan ● woonsanko.blogspot.com
  3. 3. The Ecosystem around BR Experience 3 OSS Libraries Hippo Forge Plugins BR Experience Plugins OSS* Frameworks Generic vs. Specific Complexity * OSS: Open Source Software
  4. 4. The Ecosystem around BR Experience (cont.) 4 OSS Libraries Hippo Forge Plugins BR Experience Plugins OSS* Frameworks 1. IFrame Perspective Plugin 2. Copy/Move Folder Plugin 3. External Document Picker 4. Doc. Commenting Plugin 5. HST Content Version Utils 6. Hipshoot for Spring Boot Deploy * OSS: Open Source Software 7. Content HAL API Complexity Generic vs. Specific
  5. 5. Gem #1: Too Simple to iFrame? 5 “Why don’t you simply frame the goody in it?”
  6. 6. Gem #1: Why IFrame Perspective Plugin*? ● Built-in CMS Perspective Plugin to embed an IFrame to include a web application. ● Sometimes it is most cost effective to simply embed an IFrame for a good feature by a web application. 6 * More at https://onehippo-forge.github.io/iframe-perspective/
  7. 7. Gem #1: IFrame Perspective Plugin ● Configurations* ○ title, src, icon infos, any other IFrame element attributes (iframe.*) ○ X-Frame-Options , Content-Security-Policy , X-Content-Security-Policy , X-Webkit-CSP ● WicketSessionFilter in web.xml ○ To limit access only to CMS authenticated users. 7 * More at https://onehippo-forge.github.io/iframe-perspective/install.html
  8. 8. Gem #1: IFrame Perspective Plugin (cont.) 8
  9. 9. Gem #2: Copy or Move Folder in CMS UI 9 “Can I copy or move a folder as a whole in CMS UI?”
  10. 10. Gem #2: Why Folder Context Menus Plugin*? ● Built-in CMS Folder Context Menu(s) to provide business users with features to copy or move folders in CMS UI. ○ Let business users organize content folders by themselves. ● Also provides a common code library for copying/moving folders. ○ Use it in Java / Groovy code. E.g, Batch Processing 10* More at https://onehippo-forge.github.io/folder-context-menus/
  11. 11. Gem #2: Copy or Move Folder* in CMS UI 11
  12. 12. Gem #2: Copy or Move Folder in CMS UI (cont.) 12 ● Code Library Support for Batch Processing - FolderCopyTask // Example: Copy /content/documents/myhippoproject/news/ // to /content/documents/myhippoproject/news2/ String sourceFolderPath = "/content/documents/myhippoproject/news"; String destBaseFolderPath = "/content/documents/myhippoproject"; String destFolderNodeName = "news2"; String destFolderDisplayName = "News 2"; Node sourceFolderNode = jcrSession.getNode(sourceFolderPath); Node destBaseFolderNode = jcrSession.getNode(destBaseFolderPath); FolderCopyTask task = new FolderCopyTask(jcrSession, Locale.ENGLISH, sourceFolderNode, destBaseFolderNode, destFolderNodeName, destFolderDisplayName); task.execute(); jcrSession.save();
  13. 13. Gem #2: Copy or Move Folder in CMS UI (cont.) 13 ● Code Library Support for Batch Processing - FolderMoveTask // Example: Move /content/documents/myhippoproject/news/2011/ // to /content/documents/myhippoproject/common/2011/ String sourceFolderPath = "/content/documents/myhippoproject/news"; String destBaseFolderPath = "/content/documents/myhippoproject"; String destFolderNodeName = "news2"; String destFolderDisplayName = "News 2"; Node sourceFolderNode = jcrSession.getNode(sourceFolderPath); Node destBaseFolderNode = jcrSession.getNode(destBaseFolderPath); FolderMoveTask task = new FolderMoveTask(jcrSession, Locale.ENGLISH, sourceFolderNode, destBaseFolderNode, destFolderNodeName, destFolderDisplayName); task.execute(); jcrSession.save();
  14. 14. Gem #3: External Document Picker (with new feature additions) 14 “Enrich your content by including metadata of related external content in CMS UI!”
  15. 15. Gem #3: Why External Document Picker Plugin*? ● Built-in Generic Picker UI Plugin in CMS for: ○ Selecting an associated external documents for a field in the document editor. ○ Selecting a linked external documents for a RichText field in a document. ○ Selecting external documents from Folder Context Menu to do something. ■ E.g, creating documents in the folder, tagging the folder, etc. ● For both flat-list data and tree-list data. ● Most effective way to enrich your content ○ Highly extensible. ○ CRISP API can be used in backend integration. 15* More at https://onehippo-forge.github.io/external-document-picker/
  16. 16. Gem #3: External Document Picker 16 ExternalDocumentServiceFacade is responsible for data to display each item.
  17. 17. 17 Gem #3: External Document Picker (cont.) ExternalDocumentServiceFacade in Tree List View option, resolving parent-child relationship! * More at https://onehippo-forge.github.io/external-document-picker/field/dev-howto-treeview.html NEW!
  18. 18. 18 Gem #3: External Document Picker (cont.) * More at https://onehippo-forge.github.io/external-document-picker/folder/architecture.html NEW! ExternalDocumentServiceFacade in CMS Folder Menu, allowing custom folder settings or content creation!
  19. 19. Gem #4: Document Commenting in CMS UI 19 “Comment on what you’re doing in collaboration with others!”
  20. 20. Gem #4: Why Document Commenting Plugin*? ● Built-in Field UI Plugin to allow commenting among collaborators in Document Editor. ● Simple, cost-effective collaboration in document authoring and reviewing. ● No burden in document storage level as it’s stored separately. ● Highly extensible. 20* More at https://onehippo-forge.github.io/document-commenting/
  21. 21. 21 Gem #4: Document Commenting Add a commenting field anywhere in a document type!
  22. 22. 22 Gem #4: Document Commenting (cont.)
  23. 23. Gem #4: Document Commenting (cont.) ● Very Extensible for different backends! 23 Document Commenting CMS UI Plugin <<interface>> CommentPersistence Manager* Default JCR CommentPersistence Manager Other Storage-based CommentPersistence Manager? * https://onehippo-forge.github.io/document-commenting/apidocs/org/onehippo/forge/document/commenting/cms/api/CommentPersistenceManager.html Only very simple 9 methods to implement! JCR ES? NoSQL?
  24. 24. Gem #5: Live Version As-Of via HST Content Version Utils 24 “Show content in specific version, live as of December 6, 2017!”
  25. 25. Gem #5: Why HST Content Version Utils*? ● Utility to retrieve JCR Version data through dynamic proxy of HST Content Beans, generated at runtime automatically. ○ Instead of low-level JCR Version API: VersionManager, Frozen Nodes, etc. ● No need to have separate Java code and FreeMarker templates. ○ Just stick with HST Content Beans API, even for versioned, frozen nodes. 25 * More at https://onehippo-forge.github.io/hst-content-version-utils/
  26. 26. Gem #5: Live Version As-Of via HST Content Version Utils ● Retrieve a specific version of content using HST Content Beans API. ○ Dynamic proxying, and automatic link resolutions between versioned documents. ○ cf) JcrVersionUtils , HippoBeanVersionUtils (see javadoc for details) 26 HstRequestContext requestContext = RequestContextProvider.get(); // First, get the current live news document. News curNewsDoc = requestContext.getContentBean(); // Then let’s get the specific version, live as of December 6, 2017 if any. Calendar asOfDate = ISO8601.parse("2017-12-06T00:00:00-04:00"); News newsDocAsOf = HippoBeanVersionUtils.getVersionedBeanAsOf(news.getCanonicalHandlePath(), News.class, asOfDate); // Pass along the News (dynamically proxied) bean to template! request.setAttribute("document", newsDocAsOf);
  27. 27. Gem #6: Spring Boot Deploy Support 27 “Package and deploy it onto PCF Cloud!”
  28. 28. Gem #6: Why hipshoot Spring Boot Deploy Support*? ● Package a CMS project into single Spring Boot executable JAR. ○ Spring Boot is one of the best Framework for 12 Factor Apps (Cloud Native) development. ● Allow to deploy it to PCF (Pivotal Cloud Foundry) cloud env. ● Control the lifecycle of the application yourself. ○ E.g, environment initialization, Lucene index loading from storage, etc. 28 * https://onehippo-forge.github.io/hipshoot/
  29. 29. Gem #6: Spring Boot Support Deploy Support 29 ● Build $ mvn clean verify ● Running Example $ java -Xms512m -Xmx1024m -Drepo.path="storage" -jar spring-boot-deploy/target/myhippoproject-deploy.jar ● Pushing Example to PCF (Pivotal Cloud Foundry) $ cf login -a https://api.run.pivotal.io $ cf push hippo-on-spring-boot -t 180 -f spring-boot-deploy/manifest.yml -p spring-boot-deploy/target/myhippoproject-deploy.jar
  30. 30. Gem #6: What does hipshoot provide? 30 ● Extending TomcatEmbeddedServletContainerFactory ○ To support multi-wars packaging, JNDI resource configuration, etc. ● Demo project for details ○ https://github.com/woonsanko/hippo-on-spring-boot
  31. 31. Gem #6: What does hipshoot provide? (cont.) 31 ● Example application.yaml with hipshoot configuration hipshoot: embedded: catalina: persistSession: 'false' appBase: '${server.tomcat.basedir}/webapps' wars: ${parameters.catalina.deployableWars} server: defaultContext: parameters: - name: 'repository-directory' value: '${catalina.base}/repository' override: 'false' # SNIP namingResources: - name: 'jdbc/repositoryDS' auth: 'Container' type: 'javax.sql.DataSource' properties: # SNIP
  32. 32. Gem #6: Considering Lucene Index Rebuilding 32 ● Each cluster node needs local Lucene on each node. * Load Balancer Node 1 Node N DBMS Lucene Index on local FS Lucene Index on local FS Journal Global Revision Local Revision * https://wiki.apache.org/jackrabbit/Clustering
  33. 33. Gem #6: Considering Lucene Index Rebuilding (cont.) 33 ● Solution Candidate * https://wiki.apache.org/jackrabbit/Clustering Node #N DBMS Lucene Index on local FS Journal Global Revision Local Revision S3, SFTP, WebDAV, ... Download and Restore Lucene Index From New Node Export and Backup Lucene Index From Existing Node Node #M
  34. 34. Gem #6: Considering Lucene Index Rebuilding (cont.) 34 ● Solution Candidate, using Lucene Index Export/Import feature* (v12.1) * https://www.onehippo.org/library/administration/export-the-lucene-index-from-a-running-production-environment.html @SpringBootApplication @RestController public class Application { // --->8--- SNIP --->8--- @PostConstruct public void synchronizeLuceneIndex() { // 1. Check if local lucene index directory exists. // 2. If not existing, download the latest stable lucene export zip file. } @RequestMapping(path = "/backup-lucene-index") public String backupLuceneIndex() { // 1. Download lucene index export from https://{hostname}/cms/ws/indexexport. // 2. Backup to a cloud storage such as S3, SFTP, WebDAV, etc. } }
  35. 35. Gem #7: Content HAL API 35 “Consume Content Right Away in your Apps!”
  36. 36. Gem #7: Why Content HAL API*? ● Another Built-in Generic Content REST API based on HAL (Hypertext Application Language), a specification draft as a HATEOAS (Hypermedia as the Engine of Application State). ● Much easier, more performant and more extensible. 36 * More at https://tools.ietf.org/html/draft-kelly-json-hal-08 and http://stateless.co/hal_specification.html
  37. 37. Gem #7: Content HAL API 37 ● What is HAL? ○ A specification draft for HATEOAS (Hypermedia as the Engine of Application State), a constraint of the REST application architecture. ○ Minimum Valid HAL Resource: an empty JSON object ○ Mostly, a resource SHOULD have a self link ("_links" is reserved): {} { "_links": { "self": { "href" : "/orders/523" } } }
  38. 38. Gem #7: Content HAL API (cont.) 38 ● You can have domain specific links and properties: { "_links": { "self": { "href": "/orders/523" }, "invoice": { "href": "/invoices/873" } }, "currency": "USD", "status": "shipped", "total": 10.20 }
  39. 39. Gem #7: Content HAL API (cont.) 39 ● You can embed other resources in "_embedded" that is reserved: { "_links": { "self": { "href": "/orders" } }, "_embedded": { "orders": [{ "_links": { "self": { "href": "/orders/523" } }, "total": 30.00 },{ "_links": { "self": { "href": "/orders/524" } }, "total": 20.00 }] } "currentlyProcessing": 14, "shippedToday": 20 }
  40. 40. Gem #7: Content HAL API (cont.) 40 ● Better use logical field names which are already defined in Document Types!
  41. 41. Gem #7: Content HAL API (cont.) 41 ● Better use logical field names which are already defined in Document Types! { "_links": { "self": { "href": "/site/api/events/b8f5eb45-7200-3118a0dc60b8" } }, "title": "Breakfast", "introduction": "Start the day with a nice breakfast.", "date": 1478292471762, "enddate": 1478292570000 }
  42. 42. Gem #7: Content HAL API (cont.) 42 ● URL Patterns ○ Collection ■ /{type}/ ■ e.g. http://localhost:8080/site/api/documents , http://localhost:8080/site/api/folders , http://localhost:8080/site/api/newsdocument http://localhost:8080/site/api/resourcebundles ○ Item ■ /{type}/{id} or /{type}/{relPath} ■ e.g. http://localhost:8080/site/api/documents/{id }, http://localhost:8080/site/api/documents/{relPath }, http://localhost:8080/site/api/folders/{id }, http://localhost:8080/site/api/folders/{relPath }, http://localhost:8080/site/api/resourcebundles/{basename }
  43. 43. Gem #7: Content HAL API (cont.) 43 ● Common Query Parameters Name Description Examples _scope Search scope node ID or path _scope=a_UUID or _scope=/content _offset Offset of the iterating query result _offset=10 _limit Limit of the iterating query result _limit=10 _fields Field names to include or exclude _fields=title,introduction,-content _sort Sort field names _sort=title,-date _q Full text search query term _q=lorem+ipsum _expr Custom JCR XPath expression to narrow the search result _expr=jcr:contains(@my:title,'hippo')
  44. 44. Gem #7: Content HAL API (cont.) 44 ● Comparison with other options Content REST API HST Plain JAX-RS REST Content HAL API Standard Hippo Specific Custom HAL Specification Built-in Yes No Yes Chatty Communication Chatty Up to implementation Not Chatty (w/ option to be chatty) Logical Model Support No Yes Yes Need Java Beans No Yes No Extensible Yes No Yes
  45. 45. 45 https://onehippo-forge.github.io/ https://github.com/onehippo-forge
  46. 46. Stay in Touch! ● www.onehippo.org ● slideshare.net/woonsan ● woonsanko.blogspot.com

×