Monday, February 22, 2016

HCM SOA Registry - Demystified

If you have worked on either HCM or Campus Solutions applications in PeopleSoft then you would have come across the term 'HCM SOA Registry'. Associated with the HCM SOA Registry is a step/process to 'Refresh Cache' which can either be done online or batch.

I have seen many customers (using HCM or Campus Solutions) who run this 'Refresh Cache' on a regular basis and sometimes as a post step to standard migrations. By standard migrations, I mean the weekly/fortnightly migrations which are part of production support release cycles and not necessarily the bundle/patch/upgrade migrations.

What is wrong with running this process regularly as a post step to any migration?

Well, nothing. But of late, I am finding several cases where the 'Refresh Cache' process fails with "RowsetCache::Save: Save failed for xxx/xxx=: unknown error. (2,975)" error particularly since HRMS 9.0 Bundle 26 (last HR bundle for CS).

Since this online/batch cache refresh has been causing a lot of pain, I wanted to find out when it is appropriate to refresh cache (reverse engineering and identifying the events - object changes - that would necessitate a refresh). I ended up building a SQL query to identify whether a migration of a project (say part of weekly/fortnightly production support release) would require a 'HCM SOA - Refresh Cache' just based on the objects it contains.

Before I share the details of the SQL query, I would like to share some of my notes since I did not find any information that was straight forward or easy to understand specifically on HCM Registry - Refresh Cache.

HCM SOA Registry:

HCM SOA Registry, like any other SOA Registry, provides a mechanism for service registration, discovery and binding.

SOA Registry Example:


Reference: Web 2.0 Architectures

HCM SOA Registry:


PeopleBooks Reference: Understanding the HCM Interface Registry

My Process/Flow Diagram: HCM SOA Registry

How do we access HCM SOA Registry?

Main Menu > Set Up HRMS > System Administration > HCM Registry

Service Registry:


Transformation Registry:


Where does HCM SOA Registry data get stored?

According to Doc ID 658098.1: HCM Service Framework Error When Adding, Updating, or Viewing Person Data in Campus Solutions:
"The HCM Service Registry (Set Up HRMS > System Administration > HCM Registry > Service Registry) captures the meta-data about the HCM SOA services: input and output signatures, implementation application classes, web services, component interfaces, etc. This meta-data is stored on the HC_REGISTRY portal (PeopleTools > Portal). This portal contains no other data."

How do we access this HC_REGISTRY portal where the HCM SOA Registry is stored?

- Navigate to Portal – Structure and Content: Main Menu > PeopleTools > Portal > Structure and Content.
- Replace the default portal (EMPLOYEE) with HC_REGISTRY in the URL.

For example:

https://www.test.edu/psp/ps/EMPLOYEE/HRMS/c/PORTAL_ADMIN.PORTAL_OBJ_LIST.GBL
>>>>
https://www.test.edu/psp/ps/HC_REGISTRY/HRMS/c/PORTAL_ADMIN.PORTAL_OBJ_LIST.GBL


HCM SOA Registry Hierarchy:


PeopleSoft Rowset Cache and how is it used by HCM SOA Registry?

- PeopleTools stores application data in a database cache to increase system performance.
- The RowsetCache contains a rowset, and serializes the contained rowset to binary form for speed.
- The RowsetCache class enables you to access this memory structure, created at runtime, and shared by all users.
- As with most PeopleTools objects, RowsetCache objects are cached to memory and file, but they are also cached to the data base.
- Rowset cache is stored in PSCONTDEFN and PSCONTENT.

PeopleBooks Reference:
PeopleSoft Rowset Cache
Using PeopleSoft Rowset Cache

According to Doc ID 658098.1: HCM Service Framework Error When Adding, Updating, or Viewing Person Data in Campus Solutions:
"The meta-data stored in the HC_REGISTRY portal is needed at run-time in order to execute the service. To speed up the retrieval of this meta-data at run-time, it is stored in cache, using PeopleTools Rowset Cache objects."

Layers of HCM Registry Metadata Caching:


App Server Cache*: As with most PeopleTools objects, Rowset cache also gets cached at the app server layer.

HCM Registry - Online Refresh Cache:
  • Main Menu > Setup HRMS > System Administration > HCM Registry > Service Registry > Refresh Cache
  • Refreshes HCM SOA Rowset Cache (PSCONTDEFN and PSCONTENT) with current HCM SOA metadata (HC_REGISTRY Portal).
HCM Registry - Batch Refresh Cache:
  • Main Menu > Setup HRMS > System Administration > HCM Registry > Refresh HCM SOA Portal Access.
  • Refreshes security on HC_REGISTRY portal.
    • Makes sure all folders and CREFs in HC_REGISTRY are PUBLIC.
    • DOES NOT add any roles. Adding a default role to all users is now a deprecated functionality. Refer: Doc ID 1370324.1 - FAQ on Refresh HCM SOA Portal Access - Question 1.
  • Refreshes HCM SOA Rowset Cache (PSCONTDEFN and PSCONTENT) with current HCM SOA metadata (HC_REGISTRY Portal).
SQL to identify if a migration (list of projects) requires a HCM SOA - Refresh Cache:

Based on the HCM SOA Registry Hierarchy diagram above, we can see that all metadata (HC_REGISTRY Portal) and interfaces (App Classes, SQL Views, Messages) are PeopleTools Managed Objects. So the below SQL looks at PeopleTools metadata to figure out if a list of projects (part of a release) contain any objects associated with HCM SOA Registry.

-- Test Value for &&1: 'HCM900_MP11_D','PRJ812865','PRJ889693','PRJ889694','PRJ882259'

/* HCM Registry Objects - Content References */
SELECT 'HC Registry objects (CREFs) found in release. Run SOA Refresh Cache.' AS Found,
  'HC_REGISTRY'                                                               AS OBJECT,
  OBJECTVALUE3                                                                AS PORTAL_OBJNAME
FROM PSPROJECTITEM A
WHERE A.projectname IN (&&1)
AND A.OBJECTTYPE     = 55
AND OBJECTVALUE1     = 'HC_REGISTRY'
UNION

/* Interface Objects - Application Classes (Services, Types, Exceptions) */
SELECT 'HCM metadata objects (services/types/exceptions) found in release. Run HCM SOA Refresh Cache.' AS Found,
  TO_CHAR(I.PORTAL_ATTR_VAL)                                                                           AS OBJECT,
  I.PORTAL_OBJNAME
FROM PSPRSMSYSATTRVL I
WHERE I.PORTAL_NAME   = 'HC_REGISTRY'
AND I.PORTAL_REFTYPE  = 'C'
AND I.PORTAL_OBJNAME IN
  (SELECT A.PORTAL_OBJNAME
  FROM PSPRSMSYSATTRVL A
  WHERE A.PORTAL_NAME   = 'HC_REGISTRY'
  AND A.PORTAL_REFTYPE  = 'C'
  AND A.PORTAL_ATTR_NAM = 'TYPE'
  AND TO_CHAR(A.PORTAL_ATTR_VAL) IN ('EXC', 'SRV', 'TYP')
  )
AND I.PORTAL_ATTR_VAL           like '%:%'
AND TO_CHAR(I.PORTAL_ATTR_VAL) IN
  (SELECT REPLACE (A.objectvalue1 | | ':' | | A.objectvalue2 | | ':' | | A.objectvalue3 | | ':' | | A.objectvalue4, ': ')
  FROM PSPROJECTITEM A
  WHERE A.projectname IN (&&1)
  AND objecttype       = 58
  )
UNION

/*
Interface Objects - Views */
SELECT 'HCM metadata objects (views) found in release. Run HCM SOA Refresh Cache.' AS Found,
  TO_CHAR(I.PORTAL_ATTR_VAL)                                                       AS OBJECT,
  I.PORTAL_OBJNAME
FROM PSPRSMSYSATTRVL I
WHERE I.PORTAL_NAME   = 'HC_REGISTRY'
AND I.PORTAL_REFTYPE  = 'C'
AND I.PORTAL_OBJNAME IN
  (SELECT A.PORTAL_OBJNAME
  FROM PSPRSMSYSATTRVL A
  WHERE A.PORTAL_NAME             = 'HC_REGISTRY'
  AND A.PORTAL_REFTYPE            = 'C'
  AND A.PORTAL_ATTR_NAM           = 'TYPE'
  AND TO_CHAR(A.PORTAL_ATTR_VAL) IN ('IVW')
  )
AND PORTAL_ATTR_NAM             = 'IMPLEMENTATION'
AND TO_CHAR(I.PORTAL_ATTR_VAL) IN
  (SELECT REPLACE (A.objectvalue1 | | ':' | | A.objectvalue2 | | ':' | | A.objectvalue3 | | ':' | | A.objectvalue4, ': ')
  FROM PSPROJECTITEM A
  WHERE A.projectname IN (&&1)
  AND objecttype       = 0
  )
UNION

/*
Interface Objects - HCM Transformation Maps */
SELECT 'HCM metadata objects (messages) found in release. Run HCM SOA Refresh Cache.' AS Found,
  TO_CHAR(I.PORTAL_ATTR_VAL)                                                          AS OBJECT,
  I.PORTAL_OBJNAME
FROM PSPRSMSYSATTRVL I
WHERE I.PORTAL_NAME   = 'HC_REGISTRY'
AND I.PORTAL_REFTYPE  = 'C'
AND I.PORTAL_OBJNAME IN
  (SELECT A.PORTAL_OBJNAME
  FROM PSPRSMSYSATTRVL A
  WHERE A.PORTAL_NAME             = 'HC_REGISTRY'
  AND A.PORTAL_REFTYPE            = 'C'
  AND A.PORTAL_ATTR_NAM           = 'TYPE'
  AND TO_CHAR(A.PORTAL_ATTR_VAL) IN ('TRF')
  )
AND PORTAL_ATTR_NAM            IN ('MSGNAME', 'TO_MSGNAME')
AND TO_CHAR(I.PORTAL_ATTR_VAL) IN
  (SELECT OBJECTVALUE1
  FROM PSPROJECTITEM A
  WHERE A.projectname IN (&&1)
  AND A.OBJECTTYPE     = 37
  );


If the query returns results then we need to run HCM SOA - Refresh Cache. If not, there is no need.

Note: This post is only focusing on the need (if any) for running the HCM SOA - Refresh Cache as a post step to migrations. This does not mean that there would not be other circumstances (outside of migrations) where the Refresh Cache might be necessary.

Fluid - Custom Development - Small Form Factor and Viewport Considerations

While many of us are well underway in either implementing or supporting some of the delivered Fluid applications, it is not very common yet to hear about widespread custom Fluid development. This post might be a handy tip for those embarking on such activities currently or in the future. I also found that Javier has written a post on a similar issue.

As always, I find some really good learning opportunities in the Oracle Technology Network forums. In one such example, someone asked a question related to a custom Fluid page which does not render properly on a small form factor (SFF) device whereas delivered pages seem to be detecting the SFF and displaying correctly.

I realized that I had the exact same issue on one of my test Fluid pages. Here is the problem:

Delivered Fluid page in small form factor works as expected:


Custom Fluid page in small form factor does not display correctly:


The reason my custom fluid page was not rendering correctly is because it does not have appropriate viewport meta set in the code.

I fixed this by adding the following code in the Component PostBuild event:

Declare Function SetViewport PeopleCode PTLAYOUT.FUNCLIB FieldFormula;
SetViewport(""); /* apply the system default viewport setting */

The delivered SetViewport function either uses the viewport setting passed in as parameter or the default viewport setting for SFF/iOS.



The viewport information is added as a meta tag using the delivered AddMetaTag function.

We could also pass a custom viewport setting to the function as follows:

Declare Function SetViewport PeopleCode PTLAYOUT.FUNCLIB FieldFormula;
SetViewport("width=device-width,user-scalable=yes,initial-scale=1.0,minimum-scale=1.0"); /* apply the system default viewport setting */

Or simply use the AddMetaTag function directly as follows:

AddMetaTag("viewport", "width=device-width,user-scalable=yes,initial-scale=1.0,minimum-scale=1.0");

Result of adding viewport meta tag to my custom Fluid page:


It seems to me that using the delivered function SetViewport (with appropriate viewport parameter) might be the better way to go in general. This would take care of maintaining any default viewport values specific to certain devices.

Sunday, February 21, 2016

What is ComponentLife variable declaration?

A few months ago, I came across some peoplecode which had variables declared as ComponentLife. Intrigued, I tried to look it up in PeopleBooks but could not find anything that describes this declaration. Then I raised a SR with Oracle Support seeking clarification and after many days of back and forth and pestering, I finally received some information that made a little sense. This was also documented in Doc ID 2089442.1 (My Oracle Support) later. The information provided in this document is still not self explanatory so I thought I would share a little example that demonstrates how it works and how it differs from a Component variable declaration.

From Doc ID 2089442.1:

"ComponentLife is added for NUI search,.A new type of component PC object “ComponentLife” for search page is used to create the PC application objects. They will be in component scope.

The difference between the Component and Componentlife is that Component scope is for the current row in the component, whereas ComponentLife scope is for all the records. These variable don't lose scope when you navigate from one row to another row. The scope is for the life of the component.
 

Please note that this scope is not recommended anywhere other than the Search use case." 

What I understood is that variables declared with a ComponentLife scope persist across search results. In contrast, variables declared with Component scope will only persist for the current search result.

Why would we need this? As mentioned in Doc ID 2089442.1, it appears that starting with 8.54, the NUI search uses this type of declaration a lot. Also, it seems like a very handy method to pass data across search results.

Note: This declaration only works with Fluid pages. I tried using ComponentLife in a Classic page but it does not work as expected.

I built a small Fluid page to demonstrate the way ComponentLife declaration works.

Test Fluid Page:

I built a fluid page for URL Definitions (Classic Version: Main Menu > PeopleTools > Utilities > Administration > URLs).



Test Fluid Component:

For the purposes of demonstration and saving time, I am using PT_SEARCHPAGE as a search page for my component which is not recommended by Oracle. Please refer Doc ID 2063953.1: E-FLUID: What is the PT_SEARCHPAGE Fluid Page and should it be used? before considering using this as a search page option for Fluid.






Search View:


SearchInit PeopleCode:

In the SearchInit PeopleCode, I declared and assigned a ComponentLife and a Component variable.


PageActivate PeopleCode:

In the PageActivate PeopleCode, I am just printing both the variables to see if the values persists.


Demo Video:

Check out this video >>>> ComponentLife Demo Video

Environment Details: HCM 9.2 PUM Image 12 - PeopleTools 8.54.08