n hidden gems you didn't know hippo delivery tier and hippo (forge) could give
TRANSCRIPT
N Hidden Gems You Didn't KnowHippo Delivery Tier and Hippo Forge Could Give
Woonsan KoSolution Architectw.ko @ onehippo.com
Sharing Information
● SlideShare.net/woonsan ● WoonsanKo.blogspot.com
OSSLibraries
ForgePlugins
EnterprisePlugins
Around Hippo Delivery Tier
OSS*Frameworks
More Hippo specific
Morefeature-rich
* OSS: Open Source Software
OSSLibraries
ForgePlugins
EnterprisePlugins
Around Hippo Delivery Tier
OSS*Frameworks
More Hippo specific
Morefeature-rich
HippoDelivery
Tier
* OSS: Open Source Software
OSSLibraries
ForgePlugins
EnterprisePlugins
Around Hippo Delivery Tier
OSS*Frameworks
More Hippo specific
Morefeature-rich
HippoDelivery
Tier
* OSS: Open Source Software
Gems in Hippo Delivery Tier
#1 Fluent Query
“Made up with fluent style.Don’t confuse me with the flats!”
Fluent Query
HstRequestContext requestContext = RequestContextProvider.get();HstQueryManager qm = requestContext.getQueryManager();HstQuery hstQuery = qm.createQuery(scope, BaseDocument.class);hstQuery.setOffset(0);hstQuery.setLimit(10);hstQuery.addOrderByDescending("my:date");
Filter filter = hstQuery.createFilter();filter.addContains(".", "hippo");hstQuery.setFilter(filter);
HstQueryResult result = hstQuery.execute();
Old, Non-Fluent Style
HstRequestContext requestContext = RequestContextProvider.get();HstQueryManager qm = requestContext.getQueryManager();HstQuery hstQuery = qm.createQuery(scope, BaseDocument.class);hstQuery.setOffset(0);hstQuery.setLimit(10);hstQuery.addOrderByDescending("my:date");
Filter filter = hstQuery.createFilter();filter.addContains(".", "hippo");hstQuery.setFilter(filter);
HstQueryResult result = hstQuery.execute();
Fluent Query
Filter filter = hstQuery.createFilter();filter.addContains(".", "hippo");
Filter sub1 = hstQuery.createFilter();sub1.addGreaterOrEqualThan("my:date", date, DAY);filter.addAndFilter(sub1);
Filter sub2 = hstQuery.createFilter();sub2.addEqualTo("my:createdBy", "editor1");filter.addAndFilter(sub2);
Old, Non-Fluent Style
Nested Filter
Fluent Query
* More at https://www.onehippo.org/library/concepts/fluent-search/hst-fluent-search.html
New, Fluent Style
HstQuery hstQuery = HstQueryBuilder.create(scope) // varargs .ofTypes(BaseDocument.class) // varargs .where(constraint(".").contains("hippo")) // varargs .offset(0) .limit(10) .orderByDescending("my:date") // varargs .build();
HstQueryResult result = hstQuery.execute();
Fluent Query
HstQuery hstQuery = HstQueryBuilder.create(scope) .ofTypes(BaseDocument.class) .where(constraint(".").contains("hippo")) .offset(0) .limit(10) .orderByDescending("my:date") .build();
HstQueryResult result = hstQuery.execute();
.where( and( constraint(".").contains("hippo"), constraint("my:date").greaterOrEqualThan(date, DAY), constraint("my:createdBy").equalTo("editor1") ))
* More at https://www.onehippo.org/library/concepts/fluent-search/hst-fluent-search.html
New, Fluent Style
Nested Constraints
Gems in Hippo Delivery Tier
#2 HDC (Hierarchical Diagnostic Context) API
“Determine performance problems faster!”
HDC API
● Lightweight performance diagnostic tool, for both SITE and CMS.● Hierarchical Diagnostics Reporting on request processing:
- HstFilter (3011ms): {hostName=www.example.com, uri=/site/, query=null} `- Pipeline processing (3002ms): {pipeline=null} |- HstComponentInvokerProfiler (0ms): {method=doBeforeRender, window=main, component=com.example.components.BaseComponent, ref=r46_r1} |- HstComponentInvokerProfiler (471ms): {method=doBeforeRender, window=latestjobs, component=com.example.components.common.LatestItems, ref=r46_r1_r1_r1, HippoBeanIterationCount=1} | `- query (466ms): {statement=//*[(@hippo:paths='a5a24dd3-04a0-4ed1-a59a-ffc960ae69f2') and (@hippo:availability='live') and ((@jcr:primaryType='hippogogreen:job'))] order by @hippogogreen:closingdate descending} ...
HDC API
● Lightweight performance diagnostic tool, for both SITE and CMS.● Hierarchical Diagnostics Reporting on request processing:
- HstFilter (3011ms): {hostName=www.example.com, uri=/site/, query=null} `- Pipeline processing (3002ms): {pipeline=null} |- HstComponentInvokerProfiler (0ms): {method=doBeforeRender, window=main, component=com.example.components.BaseComponent, ref=r46_r1} |- HstComponentInvokerProfiler (471ms): {method=doBeforeRender, window=latestjobs, component=com.example.components.common.LatestItems, ref=r46_r1_r1_r1, HippoBeanIterationCount=1} | `- query (466ms): {statement=//*[(@hippo:paths='a5a24dd3-04a0-4ed1-a59a-ffc960ae69f2') and (@hippo:availability='live') and ((@jcr:primaryType='hippogogreen:job'))] order by @hippogogreen:closingdate descending} ...
Runtime Configuration
HDC API● What if I want to measure the performance of my own business logic?
* More at https://www.onehippo.org/library/concepts/request-handling/hst-page-diagnostics.html
// RelatedArticles.javapublic void doBeforeRender(HstRequest req, HstResponse res) throws HstComponentException {
// ...
List<Articles> articles = getRelatedArticlesIntelligently(); req.setAtttribute("articles", articles);
// ...
}
HDC API● What if I want to measure the performance of my own business logic?
* More at https://www.onehippo.org/library/concepts/request-handling/hst-page-diagnostics.html
// RelatedArticles.javapublic void doBeforeRender(HstRequest req, HstResponse res) throws HstComponentException { Task relDocsTask = null;
try { if (HDC.isStarted()) relDocsTask = HDC.getCurrentTask().startSubtask("relDocs");
List<Articles> articles = getRelatedArticlesIntelligently(); req.setAtttribute("articles", articles);
relDocsTask.setAttribute("count", articles.size()); } finally { if (relDocsTask != null) relDocsTask.stop(); }}
HDC API● What if I want to measure the performance of my own business logic?
// RelatedArticles.javapublic void doBeforeRender(HstRequest req, HstResponse res) throws HstComponentException { Task relDocsTask = null;
try { if (HDC.isStarted()) relDocsTask = HDC.getCurrentTask().startSubtask("relDocs");
List<Articles> articles = getRelatedArticlesIntelligently(); req.setAtttribute("articles", articles);
relDocsTask.setAttribute("count", articles.size()); } finally { if (relDocsTask != null) relDocsTask.stop(); }}
* More at https://www.onehippo.org/library/concepts/request-handling/hst-page-diagnostics.html
|- HstComponentInvokerProfiler (1235ms): {component=c.e.c.RelatedArticles, ...} | `- relDocs (1117ms): {count=330} ...
Outcome
Gems in Hippo Delivery Tier
#3 Spring Managed HstComponent
“Cleaner with Real Dependency Injection!”
Spring Managed HstComponent
package com.example.components;
public class Search extends AbstractSearchComponent {
public void doBeforeRender(HstRequest req, HstResponse res) throws HstComponentException {
// Manual look up the service component, 'catalogServiceBean' ... CatalogService catService = HstServices.getComponentManager().getComponent("catalogServiceBean");
request.setAttribute("item", catService.getItem(req.getParameter("pid"))); }}
Old, Manual Style
Spring Managed HstComponent
package com.example.components;
@Component // for auto-scanning!@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // "prototype" always!@Service("com.example.components.Search") // FQCN as @Service!public class Search extends AbstractSearchComponent {
@Autowired private CatalogService catService;
public void doBeforeRender(HstRequest req, HstResponse res) throws HstComponentException { request.setAttribute("item", catService.getItem(req.getParameter("pid"))); }}
New, Auto-wiring Style
● Annotation scanning on Spring managed HST Components
<!-- e.g. site/src/main/resources/META-INF/hst-assembly/overrides/base.xml-->
<!-- (HST)Components Annotation Scanning --><context:component-scan base-package="com.example.components" />
Spring Managed HstComponent
* More at https://www.onehippo.org/library/concepts/web-application/spring-managed-hst-components.html
● Special Attentions!○ Always set @Scope to prototype!○ Always set @Service to the FQCN of the component class!
● Client-side Asynchronous Rendering○ E.g. A component accessing external services.○ AJAX code, retrieving HST Component Rendering URL
● Server-side Asynchronous Rendering○ E.g. A non-cacheable component in the server side.○ ESI or SSI, retrieving HST Component Rendering URL
Asynchronous Component Rendering
<<header>>
<<footer>>
<<left>> <<content>>
<Store Locator>
● Client-side Asynchronous Component Rendering○ @hst:async = true
Asynchronous Component Rendering
Browser HST Container
<<header>>
<<footer>>
<<left>> <<content>>
<Store Locator>
(1) HST Page Request
(5) HST ComponentRendering URL
(2) Default Pipeline
(6) HST ComponentRendering Pipeline
(3) Page(4) AJAX script seeded
(8) Component Window Response
(7) Component Window
● Server-side Asynchronous Component Rendering○ @hst:async = true, @hst:asyncmode = "esi"
Asynchronous Component Rendering
* More at https://www.onehippo.org/library/concepts/component-development/asynchronous-hst-components-and-containers.html
BrowserHST
Container(1) HST Page Request
<<header>>
<<footer>>
<<left>> <<content>>
<Store Locator>
(3) Default Pipeline
Page Cache
(2) Get Page
ESI Processor
(4) Page
(6) HST ComponentRendering Pipeline
(7) Component Window
(5) Put Page
(8) Dynamically Aggregated Page
HST ESI Processor
Browser ESI Processor Dispatchable
local path
Page Cache
<html><h1>Hello, World!</h1><!--esi:include src="/special..." --></html>
<div>Hi ${user}! Here’s a special deal for you!</div>
<html><h1>Hello, World!</h1>
</html>
<div>Hi Hippo! Here’s a special deal for you!</div>
HST HST Component
● HST ESI Processor dispatches to . . .a Component Rendering URL or Local URI Path (Servlet/JSP).○ Note: HST ESI does NOT support Remote URLs for simplicity!
HST ESI Processor
● What if I want to include remote URLs using ESI tags?○ APA Reverse Proxy Project:
■ Java Servlet or Filter library as Reverse Proxy■ portals.apache.org/applications/webcontent2/reverse-proxy-module.html
○ Map Local Path to Remote URLs!■ e.g. /site/products/ → http://example.com/products/ ,
/site/products/123 → http://example.com/products/123
* More at https://www.onehippo.org/library/concepts/web-application/hst-2-edge-side-includes-support.html
<!--esi:include src="/site/products/123" -->
Gems in Hippo Forge Projects
#1 Integration with External Content
“Link Document to External Content with Metadata(e.g. in CMIS, Commerce, DB, … ).”
Integration with External Content
● External Document Picker Forge Plugin:○ Concept: Separation of UI and Data Service.
■ UI Plugin● UI for searching and displaying of external document item(s), retrieved by
ExternalDocumentServiceFacade component.■ ExternalDocumentServiceFacade Data Service interface
● Configured for the UI Plugin; Invoked by the UI Plugin.● All Data Handling under the hood against backend.
○ Title, icon and description for each external document.○ Store metadata of selected item(s) into Hippo document.
* More at http://exdocpickerbase.forge.onehippo.org/
Integration with External Content
ExternalDocumentServiceFacade is responsible for data to
display each item.
Integration with External Content
Again,ExternalDocumentServiceFacade is responsible for data to display each selection.
Content EXIM
● Lightweight Library to EXport/IMportDocuments and Binaries to/from JSON or XML
● Uses Standard Hippo Workflow/Gallery APIs.● Groovy Updater as primary execution engine● Example Groovy Scripts to start with:
○ to export/import documents and image/assets.○ to create documents from CSV.○ to create image sets from image files.
* More at http://content-exim.forge.onehippo.org/
Content EXIM
* More at http://content-exim.forge.onehippo.org/
Gems in Hippo Forge Projects
#3 Apache Camel Integration
“Synchronize Content with External Systemthrough Enterprise Message Bus!”
Apache Camel Integration● Apache Camel (camel.apache.org):
○ Lightweight framework for the Enterprise Integration Patterns○ Production-ready components:
■ JMS, ActiveMQ, Kafka, File, SFTP, HTTP4, SQL, NoSQLs, ElasticSearch, XMPP, . . .● Apache Camel Integration Forge:
○ Provides a Camel Component to consume Hippo Events (from Hippo Event Bus).■ Component URI: hippoevent:
* More at http://camel-hippoevt.forge.onehippo.org/
<camelContext> <route id="Route-HippoEventBus-to-Queue"> <from uri="hippoevent:?category=workflow&action=publish,depublish" /> <convertBodyTo type="java.lang.String" /> <to uri="activemq:queue:hippo" /> </route></camelContext>
Gems in Hippo Forge Projects
#4 Spring Security Integration
“Secure My Services through JWT, SAML or OAuth!”
Spring Security Integration
● Spring Security Framework:○ Powerful and highly customizable authentication and access-control framework.○ Basic Auth, Spring Security SAML, Spring Security OAuth, etc.
● HST Spring Security Framework Integration Forge adds:○ Hippo Authentication Provider with Hippo UserDetailsService.○ Spring Security Valve injected in HST pipeline.
■ Sitemap Item with @hst:authenticated, @hst:roles, @hst:users.■ JAX-RS Services with JEE Security Annotations such as @RolesAllowed.
* More at http://hst-springsec.forge.onehippo.org/
OSSLibraries
ForgePlugins
EnterprisePlugins
Gems in Summary
OSS*Frameworks
More Hippo specific
Morefeature-rich
HippoDelivery
Tier
* OSS: Open Source Software
OSSLibraries
ForgePlugins
EnterprisePlugins
Gems in Summary
OSS*Frameworks
More Hippo specific
Morefeature-rich
HippoDelivery
Tier
● Delivery Tier○ HST Fluent Query○ HDC○ Spring Managed Components○ Async Components
■ HST ESI Processor
* OSS: Open Source Software
OSSLibraries
ForgePlugins
EnterprisePlugins
Gems in Summary
OSS*Frameworks
More Hippo specific
Morefeature-rich
HippoDelivery
Tier
● Delivery Tier○ HST Fluent Query○ HDC○ Spring Managed Components○ Async Components
■ HST ESI Processor
● Forges○ External Document Picker○ Content EXIM○ Apache Camel Integration○ Spring Security Integration
* OSS: Open Source Software
Stay in Touch
NORTH AMERICA71 Summer StreetBoston, MA 02110USA
EUROPEOosteinde 111017 WT AmsterdamThe Netherlands
CALL US+31 20 522 44 66+44 20 35 14 99 60+49 69 80 88 40 67+1 877 414 47 76
WEB & [email protected]
● SlideShare.net/woonsan ● WoonsanKo.blogspot.com